[PATCH v14] staging: fbtft: add tearing signal detect

2021-02-04 Thread Carlis
From: Carlis 

For st7789v IC, when we need continuous full screen refresh, it is best to
wait for the tearing effect line signal to arrive to avoid screen tearing.

Signed-off-by: Carlis 
---
v14: change to define TE completion and TE irq only in st7789v.
v13: change TE completion to par data struct member and add a new
 function to deal te gpio request, add new write_vmem function.
v12: change dev_err to dev_err_probe and add space in comments start, and
 delete te_mutex, change te wait logic.
v11: remove devm_gpio_put and change a dev_err to dev_info.
v10: additional notes.
v9: change pr_* to dev_*.
v8: delete a log line.
v7: return error value when request fail.
v6: add te gpio request fail deal logic.
v5: fix log print.
v4: modify some code style and change te irq set function name.
v3: modify author and signed-off-by name.
v2: add release te gpio after irq request fail.
---
 drivers/staging/fbtft/fb_st7789v.c | 115 +
 1 file changed, 115 insertions(+)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..ee8866d 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -7,9 +7,13 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
 #include 
+
 #include 
 
 #include "fbtft.h"
@@ -66,6 +70,62 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+/* 60Hz for 16.6ms, configured as 2*16.6ms */
+#define PANEL_TE_TIMEOUT_MS  33
+
+static struct completion panel_te; /* completion for panel TE line */
+static int irq_te; /* Linux IRQ for LCD TE line */
+
+static irqreturn_t panel_te_handler(int irq, void *data)
+{
+   complete(&panel_te);
+   return IRQ_HANDLED;
+}
+
+/*
+ * init_tearing_effect_line() - init tearing effect line.
+ * @par: FBTFT parameter object.
+ *
+ * Return: 0 on success, or a negative error code otherwise.
+ */
+static int init_tearing_effect_line(struct fbtft_par *par)
+{
+   struct device *dev = par->info->device;
+   struct gpio_desc *te;
+   int rc, irq;
+
+   te = gpiod_get_optional(dev, "te", GPIOD_IN);
+   if (IS_ERR(te))
+   return dev_err_probe(dev, PTR_ERR(te), "Failed to request te 
GPIO\n");
+
+   /* if te is NULL, indicating no configuration, directly return success 
*/
+   if (!te) {
+   irq_te = 0;
+   return 0;
+   }
+
+   irq = gpiod_to_irq(te);
+
+   /* GPIO is locked as an IRQ, we may drop the reference */
+   gpiod_put(te);
+
+   if (irq < 0)
+   return irq;
+
+   irq_te = irq;
+   init_completion(&panel_te);
+
+   /* The effective state is high and lasts no more than 1000 microseconds 
*/
+   rc = devm_request_irq(dev, irq_te, panel_te_handler,
+ IRQF_TRIGGER_RISING, "TE_GPIO", par);
+   if (rc)
+   return dev_err_probe(dev, rc, "TE IRQ request failed.\n");
+
+   disable_irq_nosync(irq_te);
+
+   return 0;
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +142,12 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+
+   rc = init_tearing_effect_line(par);
+   if (rc)
+   return rc;
+
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +203,10 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+   /* TE line output is off by default when powering on */
+   if (irq_te)
+   write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00);
+
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +215,50 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ * write_vmem() - write data to display.
+ * @par: FBTFT parameter object.
+ * @offset: offset from screen_buffer.
+ * @len: the length of data to be writte.
+ *
+ * Return: 0 on success, or a negative error code otherwise.
+ */
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+   struct device *dev = par->info->device;
+   int ret;
+
+   if (irq_te) {
+   enable_irq(irq_te);
+   reinit_completion(&panel_te);
+   ret = wait_for_completion_timeout(&panel_te,
+ 
msecs_to_jiffies(PANEL_TE_TIMEOUT_MS));
+   if (ret == 0)
+   dev_err(dev, "wait panel TE timeout\n");
+
+   disable_irq(irq_te);
+   }
+
+   ret = 0;
+   switch (par->pdata->display.buswidth) {
+   case 8:
+   ret = fbtft_write_vmem16_bus8(par, offset, len);
+   break;
+

[PATCH v15] staging: fbtft: add tearing signal detect

2021-02-07 Thread Carlis
From: Carlis 

For st7789v IC, when we need continuous full screen refresh, it is best to
wait for the tearing effect line signal to arrive to avoid screen tearing.

Signed-off-by: Carlis 
---
v15: change ret value return logic in write_vmem.
v14: change to define TE completion and TE irq only in st7789v.
v13: change TE completion to par data struct member and add a new
 function to deal te gpio request, add new write_vmem function.
v12: change dev_err to dev_err_probe and add space in comments start, and
 delete te_mutex, change te wait logic.
v11: remove devm_gpio_put and change a dev_err to dev_info.
v10: additional notes.
v9: change pr_* to dev_*.
v8: delete a log line.
v7: return error value when request fail.
v6: add te gpio request fail deal logic.
v5: fix log print.
v4: modify some code style and change te irq set function name.
v3: modify author and signed-off-by name.
v2: add release te gpio after irq request fail.
---
 drivers/staging/fbtft/fb_st7789v.c | 115 +
 1 file changed, 115 insertions(+)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..abe9395 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -7,9 +7,13 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
 #include 
+
 #include 
 
 #include "fbtft.h"
@@ -66,6 +70,62 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+/* 60Hz for 16.6ms, configured as 2*16.6ms */
+#define PANEL_TE_TIMEOUT_MS  33
+
+static struct completion panel_te; /* completion for panel TE line */
+static int irq_te; /* Linux IRQ for LCD TE line */
+
+static irqreturn_t panel_te_handler(int irq, void *data)
+{
+   complete(&panel_te);
+   return IRQ_HANDLED;
+}
+
+/*
+ * init_tearing_effect_line() - init tearing effect line.
+ * @par: FBTFT parameter object.
+ *
+ * Return: 0 on success, or a negative error code otherwise.
+ */
+static int init_tearing_effect_line(struct fbtft_par *par)
+{
+   struct device *dev = par->info->device;
+   struct gpio_desc *te;
+   int rc, irq;
+
+   te = gpiod_get_optional(dev, "te", GPIOD_IN);
+   if (IS_ERR(te))
+   return dev_err_probe(dev, PTR_ERR(te), "Failed to request te 
GPIO\n");
+
+   /* if te is NULL, indicating no configuration, directly return success 
*/
+   if (!te) {
+   irq_te = 0;
+   return 0;
+   }
+
+   irq = gpiod_to_irq(te);
+
+   /* GPIO is locked as an IRQ, we may drop the reference */
+   gpiod_put(te);
+
+   if (irq < 0)
+   return irq;
+
+   irq_te = irq;
+   init_completion(&panel_te);
+
+   /* The effective state is high and lasts no more than 1000 microseconds 
*/
+   rc = devm_request_irq(dev, irq_te, panel_te_handler,
+ IRQF_TRIGGER_RISING, "TE_GPIO", par);
+   if (rc)
+   return dev_err_probe(dev, rc, "TE IRQ request failed.\n");
+
+   disable_irq_nosync(irq_te);
+
+   return 0;
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +142,12 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+
+   rc = init_tearing_effect_line(par);
+   if (rc)
+   return rc;
+
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +203,10 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+   /* TE line output is off by default when powering on */
+   if (irq_te)
+   write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00);
+
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +215,50 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ * write_vmem() - write data to display.
+ * @par: FBTFT parameter object.
+ * @offset: offset from screen_buffer.
+ * @len: the length of data to be writte.
+ *
+ * Return: 0 on success, or a negative error code otherwise.
+ */
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+   struct device *dev = par->info->device;
+   int ret;
+
+   if (irq_te) {
+   enable_irq(irq_te);
+   reinit_completion(&panel_te);
+   ret = wait_for_completion_timeout(&panel_te,
+ 
msecs_to_jiffies(PANEL_TE_TIMEOUT_MS));
+   if (ret == 0)
+   dev_err(dev, "wait panel TE timeout\n");
+
+   disable_irq(irq_te);
+   }
+
+   switch (par->pdata->display.buswidth) {
+   case 8:
+   ret = fbtft_write_vmem16_bus8(par, offset, len);

[PATCH] staging: fbtft: change snprintf() to scnprintf()

2021-04-02 Thread Carlis
From: Xuezhi Zhang 

show() must not use snprintf() when formatting the value to
be returned to user space.

Signed-off-by: Xuezhi Zhang 
---
 drivers/staging/fbtft/fbtft-sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fbtft-sysfs.c 
b/drivers/staging/fbtft/fbtft-sysfs.c
index 26e52cc2de64..7df92db648d6 100644
--- a/drivers/staging/fbtft/fbtft-sysfs.c
+++ b/drivers/staging/fbtft/fbtft-sysfs.c
@@ -199,7 +199,7 @@ static ssize_t show_debug(struct device *device,
struct fb_info *fb_info = dev_get_drvdata(device);
struct fbtft_par *par = fb_info->par;
 
-   return snprintf(buf, PAGE_SIZE, "%lu\n", par->debug);
+   return scnprintf(buf, PAGE_SIZE, "%lu\n", par->debug);
 }
 
 static struct device_attribute debug_device_attr =
-- 
2.25.1

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] staging: fbtft: convert sysfs snprintf to sysfs_emit

2021-04-03 Thread Carlis
From: Xuezhi Zhang 

Fix the following coccicheck warning:
drivers/staging/fbtft//fbtft-sysfs.c:202:8-16: 
WARNING: use scnprintf or sprintf

Signed-off-by: Xuezhi Zhang 
---
 drivers/staging/fbtft/fbtft-sysfs.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fbtft-sysfs.c 
b/drivers/staging/fbtft/fbtft-sysfs.c
index 26e52cc2d..39e8d2806 100644
--- a/drivers/staging/fbtft/fbtft-sysfs.c
+++ b/drivers/staging/fbtft/fbtft-sysfs.c
@@ -199,7 +199,7 @@ static ssize_t show_debug(struct device *device,
struct fb_info *fb_info = dev_get_drvdata(device);
struct fbtft_par *par = fb_info->par;
 
-   return snprintf(buf, PAGE_SIZE, "%lu\n", par->debug);
+   return sysfs_emit(buf, "%lu\n", par->debug);
 }
 
 static struct device_attribute debug_device_attr =
-- 
2.25.1


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH] fbtft: add tearing signal detect

2021-01-24 Thread Carlis
From: "carlis.zhang_cp" 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: carlis.zhang_cp 
---
 drivers/staging/fbtft/fb_st7789v.c | 133 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..c687b58 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,38 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void enable_spi_panel_te_irq(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   if (!par->gpio.te) {
+   pr_err("%s:%d,SPI panel TE GPIO not configured\n",
+  __func__, __LINE__);
+   return;
+   }
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +117,28 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   pr_err("TE request_irq failed.\n");
+   par->gpio.te = NULL;
+   } else {
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   pr_err("TE request_irq completion.\n");
+   }
+   } else {
+   pr_err("%s:%d, TE gpio not specified\n",
+  __func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +194,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +205,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int rc, ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   txbuf16[i] = cpu_to_be16(vmem16[i]);
+
+   vmem16 = vmem16 + to_copy;
+   if (par-

[PATCH v2] fbtft: add tearing signal detect

2021-01-25 Thread Carlis
From: "carlis.zhang_cp" 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: carlis.zhang_cp 
---
v2:add release te gpio after irq request fail
---
 drivers/staging/fbtft/fb_st7789v.c | 134 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 134 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..5426276 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,38 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void enable_spi_panel_te_irq(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   if (!par->gpio.te) {
+   pr_err("%s:%d,SPI panel TE GPIO not configured\n",
+  __func__, __LINE__);
+   return;
+   }
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +117,29 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   pr_err("TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   par->gpio.te = NULL;
+   } else {
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   pr_info("TE request_irq completion.\n");
+   }
+   } else {
+   pr_err("%s:%d, TE gpio not specified\n",
+  __func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +195,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +206,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int rc, ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   

[PATCH v3] fbtft: add tearing signal detect

2021-01-25 Thread Carlis
From: zhangxuezhi 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v3:modify author name
---
 drivers/staging/fbtft/fb_st7789v.c | 134 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 134 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..5426276 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,38 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void enable_spi_panel_te_irq(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   if (!par->gpio.te) {
+   pr_err("%s:%d,SPI panel TE GPIO not configured\n",
+  __func__, __LINE__);
+   return;
+   }
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +117,29 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   pr_err("TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   par->gpio.te = NULL;
+   } else {
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   pr_info("TE request_irq completion.\n");
+   }
+   } else {
+   pr_err("%s:%d, TE gpio not specified\n",
+  __func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +195,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +206,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int rc, ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   txbuf16[i] = cpu_to_be16(vmem1

[PATCH v4] fbtft: add tearing signal detect

2021-01-26 Thread Carlis
From: zhangxuezhi 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v4:modify some code style and change te irq set function name
---
 drivers/staging/fbtft/fb_st7789v.c | 128 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..11a490de 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,32 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +111,29 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   pr_err("TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   par->gpio.te = NULL;
+   } else {
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   pr_info("TE request_irq completion.\n");
+   }
+   } else {
+   pr_err("%s:%d, TE gpio not specified\n",
+  __func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +189,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +200,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   txbuf16[i] = cpu_to_be16(vmem16[i]);
+
+   vmem16 = vmem16 + to_copy;
+   if (par->gpio.te) {
+   set_spi_panel_te_irq_st

Re: [PATCH] fbtft: add tearing signal detect

2021-01-26 Thread carlis
On Tue, 26 Jan 2021 10:54:41 +0300
Dan Carpenter  wrote:

> On Sun, Jan 24, 2021 at 11:35:37PM +0800, Carlis wrote:
> > +static irqreturn_t spi_panel_te_handler(int irq, void *data)
> > +{
> > +   complete(&spi_panel_te);
> > +   return IRQ_HANDLED;
> > +}
> > +
> > +static void enable_spi_panel_te_irq(struct fbtft_par *par, bool
> > enable)  
> 
> It quite confused me that enable actually disables.  I always feel
> like it's clearer to write these as two separate functions.
> 
> > +{
> > +   static int te_irq_count;
> > +
> > +   if (!par->gpio.te) {  
> 
> This is always checked in the caller.  And it's when it's NULL that
> means it's deliberate so don't print a message.
> 
> > +   pr_err("%s:%d,SPI panel TE GPIO not configured\n",
> > +  __func__, __LINE__);
> > +   return;
> > +   }
> > +
> > +   mutex_lock(&te_mutex);
> > +
> > +   if (enable) {
> > +   if (++te_irq_count == 1)
> > +   enable_irq(gpiod_to_irq(par->gpio.te));
> > +   } else {
> > +   if (--te_irq_count == 0)
> > +   disable_irq(gpiod_to_irq(par->gpio.te));
> > +   }
> > +   mutex_unlock(&te_mutex);
> > +}
> > +
> >  /**
> >   * init_display() - initialize the display controller
> >   *
> > @@ -82,6 +117,28 @@ enum st7789v_command {
> >   */
> >  static int init_display(struct fbtft_par *par)
> >  {
> > +   int rc;
> > +   struct device *dev = par->info->device;
> > +
> > +   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN);
> > +   if (par->gpio.te) {  
> 
> devm_gpiod_get_index_optional() can return NULL or error pointers.  If
> it returns NULL then don't print an error message.  NULL reports are
> deliberate.
> 
>   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> GPIOD_IN); if (IS_ERR(par->gpio.te)) {
>   pr_err("%s:%d, TE gpio not specified\n", __func__,
> __LINE__); return PTR_ERR(par->gpio.te);
>   }
> 
>   if (par->gpio.te) {
> 
> 
> > +   init_completion(&spi_panel_te);
> > +   mutex_init(&te_mutex);
> > +   rc = devm_request_irq(dev,
> > + gpiod_to_irq(par->gpio.te),
> > +spi_panel_te_handler,
> > IRQF_TRIGGER_RISING,
> > +"TE_GPIO", par);
> > +   if (rc) {
> > +   pr_err("TE request_irq failed.\n");
> > +   par->gpio.te = NULL;
> > +   } else {
> > +
> > disable_irq_nosync(gpiod_to_irq(par->gpio.te));
> > +   pr_err("TE request_irq completion.\n");  
> 
> Why is this printing an error message if devm_request_irq() succeeds?
> 
> > +   }
> > +   } else {
> > +   pr_err("%s:%d, TE gpio not specified\n",
> > +  __func__, __LINE__);
> > +   }
> > /* turn off sleep mode */
> > write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
> > mdelay(120);
> > @@ -137,6 +194,9 @@ static int init_display(struct fbtft_par *par)
> >  */
> > write_reg(par, PWCTRL1, 0xA4, 0xA1);
> >  
> > +/*Tearing Effect Line On*/
> > +   if (par->gpio.te)
> > +   write_reg(par, 0x35, 0x00);
> > write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
> >  
> > if (HSD20_IPS)
> > @@ -145,6 +205,76 @@ static int init_display(struct fbtft_par *par)
> > return 0;
> >  }
> >  
> > +/*
> > + *
> > + *   int (*write_vmem)(struct fbtft_par *par);
> > + *
> > +
> > */
> > + +/* 16 bit pixel over 8-bit databus */
> > +int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t
> > offset, size_t len) +{
> > +   u16 *vmem16;
> > +   __be16 *txbuf16 = par->txbuf.buf;
> > +   size_t remain;
> > +   size_t to_copy;
> > +   size_t tx_array_size;
> > +   int i;
> > +   int rc, ret = 0;  
> 
> Delete one of these "rc" or "rec" variables.
> 
> > +   size_t startbyte_size = 0;
> > +
> > +   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v
> > ---%s(offset=%zu, len=%zu)\n",
> > + 

Re: [PATCH v2] fbtft: add tearing signal detect

2021-01-26 Thread carlis
On Tue, 26 Jan 2021 11:17:45 +0300
Dan Carpenter  wrote:

> On Mon, Jan 25, 2021 at 04:44:12PM +0800, Carlis wrote:
> > From: "carlis.zhang_cp"   
> 
> I was really expecting that you would fix this and Signed-off-by as
> well.
> 
> regards,
> dan carpenter
> 
I have fix this in patch v3
> regards,
> zhangxuezhi
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v4] fbtft: add tearing signal detect

2021-01-26 Thread carlis
On Tue, 26 Jan 2021 20:51:41 +0300
Dan Carpenter  wrote:

> On Tue, Jan 26, 2021 at 08:40:35PM +0800, Carlis wrote:
> > @@ -82,6 +111,29 @@ enum st7789v_command {
> >   */
> >  static int init_display(struct fbtft_par *par)
> >  {
> > +   int rc;
> > +   struct device *dev = par->info->device;
> > +
> > +   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN);
> > +   if (par->gpio.te) {  
> 
> I explained in my earlier review that devm_gpiod_get_index_optional()
> can return error pointers...  There was quite a bit of detail about
> how to handle this correctly in my earlier review, but I think you
> might not have noticed it.  Please read it again.
> 
> > +   init_completion(&spi_panel_te);
> > +   mutex_init(&te_mutex);
> > +   rc = devm_request_irq(dev,
> > + gpiod_to_irq(par->gpio.te),
> > +spi_panel_te_handler,
> > IRQF_TRIGGER_RISING,
> > +"TE_GPIO", par);
> > +   if (rc) {
> > +   pr_err("TE request_irq failed.\n");
> > +   devm_gpiod_put(dev, par->gpio.te);
> > +   par->gpio.te = NULL;
> > +   } else {
> > +
> > disable_irq_nosync(gpiod_to_irq(par->gpio.te));
> > +   pr_info("TE request_irq completion.\n");
> > +   }
> > +   } else {
> > +   pr_err("%s:%d, TE gpio not specified\n",
> > +  __func__, __LINE__);
> > +   }  
> 
> regards,
> dan carpenter
> 
Thank you for your correction,i will change pr_err to pr_info in next
patch v5

regards,
dan carpenter
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v5] fbtft: add tearing signal detect

2021-01-26 Thread Carlis
From: zhangxuezhi 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v5:fix log print
---
 drivers/staging/fbtft/fb_st7789v.c | 128 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 128 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..ab10235 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,32 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +111,29 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   pr_err("TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   par->gpio.te = NULL;
+   } else {
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   pr_info("TE request_irq completion.\n");
+   }
+   } else {
+   pr_info("%s:%d, TE gpio not specified\n",
+   __func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +189,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +200,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, 
size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   txbuf16[i] = cpu_to_be16(vmem16[i]);
+
+   vmem16 = vmem16 + to_copy;
+   if (par->gpio.te) {
+   set_spi_panel_te_irq_status(par, true);
+  

Re: [PATCH v5] fbtft: add tearing signal detect

2021-01-26 Thread carlis
On Wed, 27 Jan 2021 08:45:23 +0300
Dan Carpenter  wrote:

> On Wed, Jan 27, 2021 at 09:32:20AM +0800, Carlis wrote:
> > @@ -82,6 +111,29 @@ enum st7789v_command {
> >   */
> >  static int init_display(struct fbtft_par *par)
> >  {
> > +   int rc;
> > +   struct device *dev = par->info->device;
> > +
> > +   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN);
> > +   if (par->gpio.te) {
> > +   init_completion(&spi_panel_te);
> > +   mutex_init(&te_mutex);
> > +   rc = devm_request_irq(dev,
> > + gpiod_to_irq(par->gpio.te),
> > +spi_panel_te_handler,
> > IRQF_TRIGGER_RISING,
> > +"TE_GPIO", par);
> > +   if (rc) {
> > +   pr_err("TE request_irq failed.\n");
> > +   devm_gpiod_put(dev, par->gpio.te);
> > +   par->gpio.te = NULL;
> > +   } else {
> > +
> > disable_irq_nosync(gpiod_to_irq(par->gpio.te));
> > +   pr_info("TE request_irq completion.\n");
> > +   }
> > +   } else {
> > +   pr_info("%s:%d, TE gpio not specified\n",
> > +   __func__, __LINE__);
> > +   }  
> 
> I'm sorry that I was not clear before.  This code will crash if
> devm_gpiod_get_index_optional() returns an error.  You *NEED* to check
> for error pointers and return the error code.  Write it exactly like
> this:
> 
>   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> GPIOD_IN); if (IS_ERR(par->gpio.te))
>   return PTR_ERR(par->gpio.te);
> 
>   if (par->gpio.te) {
>   init_completion(&spi_panel_te);
> 
> 
> regards,
> dan carpenter
> 

hi,i will fix it like below:
par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
GPIOD_IN); if (IS_ERR(par->gpio.te)) {
rc = PTR_ERR(par->gpio.te);
pr_err("Failed to request  te gpio: %d\n", rc);
par->gpio.te = NULL;
}
if (par->gpio.te) {
init_completion(&spi_panel_te);
mutex_init(&te_mutex);
rc = devm_request_irq(dev,
  gpiod_to_irq(par->gpio.te),
 spi_panel_te_handler,
IRQF_TRIGGER_RISING, "TE_GPIO", par);
if (rc) {
pr_err("TE request_irq failed.\n");
devm_gpiod_put(dev, par->gpio.te);
par->gpio.te = NULL;
} else {
disable_irq_nosync(gpiod_to_irq(par->gpio.te));
pr_info("TE request_irq completion.\n");
}
} else {
pr_info("%s:%d, TE gpio not specified\n",
__func__, __LINE__);
}

regards,
zhangxuezhi
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v6] fbtft: add tearing signal detect

2021-01-26 Thread Carlis
From: zhangxuezhi 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v6: add te gpio request fail deal logic
---
 drivers/staging/fbtft/fb_st7789v.c | 133 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..777391e 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,32 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +111,34 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (IS_ERR(par->gpio.te)) {
+   rc = PTR_ERR(par->gpio.te);
+   pr_err("Failed to request te gpio: %d\n", rc);
+   par->gpio.te = NULL;
+   }
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   pr_err("TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   par->gpio.te = NULL;
+   } else {
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   pr_info("TE request_irq completion.\n");
+   }
+   } else {
+   pr_info("%s:%d, TE gpio not specified\n",
+   __func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +194,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +205,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, 
size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   

Re: [PATCH v6] fbtft: add tearing signal detect

2021-01-27 Thread carlis
On Wed, 27 Jan 2021 10:00:13 +0100
Geert Uytterhoeven  wrote:

> Hi Carlis,
> 
> On Wed, Jan 27, 2021 at 9:52 AM Carlis  wrote:
> > From: zhangxuezhi 
> >
> > For st7789v ic,add tearing signal detect to avoid screen tearing
> >
> > Signed-off-by: zhangxuezhi   
> 
> Thanks for your patch!
> 
> > --- a/drivers/staging/fbtft/fb_st7789v.c
> > +++ b/drivers/staging/fbtft/fb_st7789v.c  
> 
> > @@ -82,6 +111,34 @@ enum st7789v_command {
> >   */
> >  static int init_display(struct fbtft_par *par)
> >  {
> > +   int rc;
> > +   struct device *dev = par->info->device;
> > +
> > +   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN);
> > +   if (IS_ERR(par->gpio.te)) {
> > +   rc = PTR_ERR(par->gpio.te);
> > +   pr_err("Failed to request te gpio: %d\n", rc);
> > +   par->gpio.te = NULL;  
> 
> Errors (e.g. -EPROBE_DEFER) should be propagated upstream,
> not ignored.
> 
> > +   }
> > +   if (par->gpio.te) {
> > +   init_completion(&spi_panel_te);
> > +   mutex_init(&te_mutex);
> > +   rc = devm_request_irq(dev,
> > + gpiod_to_irq(par->gpio.te),
> > +spi_panel_te_handler,
> > IRQF_TRIGGER_RISING,
> > +"TE_GPIO", par);
> > +   if (rc) {
> > +   pr_err("TE request_irq failed.\n");
> > +   devm_gpiod_put(dev, par->gpio.te);
> > +   par->gpio.te = NULL;  
> 
> Errors (e.g. -EPROBE_DEFER) should be propagated upstream,
> not ignored.
> 
> > +   } else {
> > +
> > disable_irq_nosync(gpiod_to_irq(par->gpio.te));
> > +   pr_info("TE request_irq completion.\n");
> > +   }
> > +   } else {
> > +   pr_info("%s:%d, TE gpio not specified\n",
> > +   __func__, __LINE__);
> > +   }
> > /* turn off sleep mode */
> > write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
> > mdelay(120);  
> 
> Gr{oetje,eeting}s,
> 
> Geert
> 

hi,i will fix in the patch v7
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v7] fbtft: add tearing signal detect

2021-01-27 Thread Carlis
From: zhangxuezhi 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v7: request fail to return error value
---
 drivers/staging/fbtft/fb_st7789v.c | 133 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 133 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..c964cc1 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,32 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +111,34 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (IS_ERR(par->gpio.te)) {
+   rc = PTR_ERR(par->gpio.te);
+   pr_err("Failed to request te gpio: %d\n", rc);
+   return rc;
+   }
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   pr_err("TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   return rc;
+   }
+
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   pr_info("TE request_irq completion.\n");
+   } else {
+   pr_info("%s:%d, TE gpio not specified\n",
+   __func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +194,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +205,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, 
size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   txbuf16[i] = cpu_to_be16(vmem16[i]);
+
+

Re: [PATCH v6] fbtft: add tearing signal detect

2021-01-27 Thread carlis
On Wed, 27 Jan 2021 11:59:51 +0300
Dan Carpenter  wrote:

> On Wed, Jan 27, 2021 at 03:28:22PM +0800, Carlis wrote:
> >  static int init_display(struct fbtft_par *par)
> >  {
> > +   int rc;
> > +   struct device *dev = par->info->device;
> > +
> > +   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN);
> > +   if (IS_ERR(par->gpio.te)) {
> > +   rc = PTR_ERR(par->gpio.te);
> > +   pr_err("Failed to request te gpio: %d\n", rc);
> > +   par->gpio.te = NULL;
> > +   }
> > +   if (par->gpio.te) {
> > +   init_completion(&spi_panel_te);
> > +   mutex_init(&te_mutex);
> > +   rc = devm_request_irq(dev,
> > + gpiod_to_irq(par->gpio.te),
> > +spi_panel_te_handler,
> > IRQF_TRIGGER_RISING,
> > +"TE_GPIO", par);
> > +   if (rc) {
> > +   pr_err("TE request_irq failed.\n");
> > +   devm_gpiod_put(dev, par->gpio.te);
> > +   par->gpio.te = NULL;
> > +   } else {
> > +
> > disable_irq_nosync(gpiod_to_irq(par->gpio.te));
> > +   pr_info("TE request_irq completion.\n");  
> 
> #SadFaceEmoji
> 
> > +   }
> > +   } else {
> > +   pr_info("%s:%d, TE gpio not specified\n",
> > +   __func__, __LINE__);
> > +   }  
> 
> regards,
> dan carpenter
> 
Sorry,i will delete this log in patch v8
regards
zhangxuezhi
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v8] fbtft: add tearing signal detect

2021-01-27 Thread Carlis
From: zhangxuezhi 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v8: delete a log line
---
 drivers/staging/fbtft/fb_st7789v.c | 132 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..de7460c 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,32 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +111,33 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (IS_ERR(par->gpio.te)) {
+   rc = PTR_ERR(par->gpio.te);
+   pr_err("Failed to request te gpio: %d\n", rc);
+   return rc;
+   }
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   pr_err("TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   return rc;
+   }
+
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   } else {
+   pr_info("%s:%d, TE gpio not specified\n",
+   __func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +193,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +204,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, 
size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   txbuf16[i] = cpu_to_be16(vmem16[i]);
+
+   vmem16 = vmem16 + to_copy;
+   if (par->gpio.te) {
+   

[PATCH v9] staging: fbtft: add tearing signal detect

2021-01-27 Thread Carlis
From: zhangxuezhi 

For st7789v ic,add tearing signal detect to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v9: change pr_* to dev_*
---
 drivers/staging/fbtft/fb_st7789v.c | 132 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..9aa2f36 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,32 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400
+static struct mutex te_mutex;/*mutex for tearing line*/
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +111,33 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (IS_ERR(par->gpio.te)) {
+   rc = PTR_ERR(par->gpio.te);
+   dev_err(par->info->device, "Failed to request te gpio: %d\n", 
rc);
+   return rc;
+   }
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   dev_err(par->info->device, "TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   return rc;
+   }
+
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   } else {
+   dev_info(par->info->device, "%s:%d, TE gpio not specified\n",
+__func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +193,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +204,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, 
size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+   startbyte_size = 1;
+   }
+
+   while (remain) {
+   to_copy = min(tx_array_size, remain);
+   dev_dbg(par->info->device, "to_copy=%zu, remain=%zu\n",
+   to_copy, remain - to_copy);
+
+   for (i = 0; i < to_copy; i++)
+   txbuf16[i] = cpu_to_be16(vmem16[i]);
+
+   vm

[PATCH v10] staging: fbtft: add tearing signal detect

2021-01-27 Thread Carlis
From: zhangxuezhi 

For st7789v ic,when we need continuous full screen refresh, it is best to
wait for the TE signal arrive to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v10: additional notes
v9: change pr_* to dev_*
v8: delete a log line
v7: return error value when request fail
v6: add te gpio request fail deal logic
v5: fix log print
v4: modify some code style and change te irq set function name
v3: modify author and signed-off-by name
v2: add release te gpio after irq request fail
---
 drivers/staging/fbtft/fb_st7789v.c | 132 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 132 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..cba08a8 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,32 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400 /* msecs */
+static struct mutex te_mutex;/* mutex for set te gpio irq status */
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +111,33 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (IS_ERR(par->gpio.te)) {
+   rc = PTR_ERR(par->gpio.te);
+   dev_err(par->info->device, "Failed to request te gpio: %d\n", 
rc);
+   return rc;
+   }
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   dev_err(par->info->device, "TE request_irq failed.\n");
+   devm_gpiod_put(dev, par->gpio.te);
+   return rc;
+   }
+
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   } else {
+   dev_info(par->info->device, "%s:%d, TE gpio not specified\n",
+__func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +193,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +204,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, 
size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+  

Re: [PATCH v9] staging: fbtft: add tearing signal detect

2021-01-27 Thread carlis
On Wed, 27 Jan 2021 14:11:31 +0100
Greg KH  wrote:

> On Wed, Jan 27, 2021 at 08:57:37PM +0800, Carlis wrote:
> > From: zhangxuezhi 
> > 
> > For st7789v ic,add tearing signal detect to avoid screen tearing  
> 
> I need a much better changelog description here please.
> 
> > 
> > Signed-off-by: zhangxuezhi 
> > ---
> > v9: change pr_* to dev_*
> > ---  
> 
> What changed in all of your previous versions?  All of them should be
> listed here, right?
> 
> 
> 
> >  drivers/staging/fbtft/fb_st7789v.c | 132
> > - drivers/staging/fbtft/fbtft.h
> >  |   1 + 2 files changed, 132 insertions(+), 1 deletion(-)
> > 
> > diff --git a/drivers/staging/fbtft/fb_st7789v.c
> > b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..9aa2f36 100644
> > --- a/drivers/staging/fbtft/fb_st7789v.c
> > +++ b/drivers/staging/fbtft/fb_st7789v.c
> > @@ -9,9 +9,12 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> > +#include 
> >  #include 
> >  #include 
> > -
> > +#include 
> >  #include "fbtft.h"
> >  
> >  #define DRVNAME "fb_st7789v"
> > @@ -66,6 +69,32 @@ enum st7789v_command {
> >  #define MADCTL_MX BIT(6) /* bitmask for column address order */
> >  #define MADCTL_MY BIT(7) /* bitmask for page address order */
> >  
> > +#define SPI_PANEL_TE_TIMEOUT   400  
> 
> What is the units here?  Where did this value come from?

hi,the units is msecs,and i got this value from a qcom mdp spi
drivers,and i will add the notes you need in the patch v10
> 
> > +static struct mutex te_mutex;/*mutex for tearing line*/  
> 
> Does that look correct???
> 
> thanks,
> 
> greg k-h

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v11] staging: fbtft: add tearing signal detect

2021-01-27 Thread Carlis
From: zhangxuezhi 

For st7789v ic,when we need continuous full screen refresh, it is best to
wait for the TE signal arrive to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v11: remove devm_gpio_put and change a dev_err to dev_info
v10: additional notes
v9: change pr_* to dev_*
v8: delete a log line
v7: return error value when request fail
v6: add te gpio request fail deal logic
v5: fix log print
v4: modify some code style and change te irq set function name
v3: modify author and signed-off-by name
v2: add release te gpio after irq request fail
---
 drivers/staging/fbtft/fb_st7789v.c | 131 -
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 131 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..cfb54a4 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,9 +9,12 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
 #include 
 #include 
-
+#include 
 #include "fbtft.h"
 
 #define DRVNAME "fb_st7789v"
@@ -66,6 +69,32 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400 /* msecs */
+static struct mutex te_mutex;/* mutex for set te gpio irq status */
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
+static void set_spi_panel_te_irq_status(struct fbtft_par *par, bool enable)
+{
+   static int te_irq_count;
+
+   mutex_lock(&te_mutex);
+
+   if (enable) {
+   if (++te_irq_count == 1)
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   } else {
+   if (--te_irq_count == 0)
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   mutex_unlock(&te_mutex);
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +111,32 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (IS_ERR(par->gpio.te)) {
+   rc = PTR_ERR(par->gpio.te);
+   dev_info(par->info->device, "Failed to request te gpio: %d\n", 
rc);
+   return rc;
+   }
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   mutex_init(&te_mutex);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (rc) {
+   dev_err(par->info->device, "TE request_irq failed.\n");
+   return rc;
+   }
+
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   } else {
+   dev_info(par->info->device, "%s:%d, TE gpio not specified\n",
+__func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +192,9 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+/*Tearing Effect Line On*/
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +203,76 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ *
+ *   int (*write_vmem)(struct fbtft_par *par);
+ *
+ */
+
+/* 16 bit pixel over 8-bit databus */
+static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, 
size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+ 

Re: [PATCH v9] staging: fbtft: add tearing signal detect

2021-01-27 Thread carlis
On Wed, 27 Jan 2021 14:47:04 +0100
Geert Uytterhoeven  wrote:

> Hi Carlis,
> 
> On Wed, Jan 27, 2021 at 2:03 PM Carlis  wrote:
> > From: zhangxuezhi 
> >
> > For st7789v ic,add tearing signal detect to avoid screen tearing
> >
> > Signed-off-by: zhangxuezhi 
> > ---
> > v9: change pr_* to dev_*  
> 
> Thanks for the update!
> 
> > --- a/drivers/staging/fbtft/fb_st7789v.c
> > +++ b/drivers/staging/fbtft/fb_st7789v.c
> > @@ -9,9 +9,12 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> > +#include 
> >  #include 
> >  #include 
> > -
> > +#include 
> >  #include "fbtft.h"
> >
> >  #define DRVNAME "fb_st7789v"
> > @@ -66,6 +69,32 @@ enum st7789v_command {
> >  #define MADCTL_MX BIT(6) /* bitmask for column address order */
> >  #define MADCTL_MY BIT(7) /* bitmask for page address order */
> >
> > +#define SPI_PANEL_TE_TIMEOUT   400
> > +static struct mutex te_mutex;/*mutex for tearing line*/
> > +static struct completion spi_panel_te;
> > +
> > +static irqreturn_t spi_panel_te_handler(int irq, void *data)
> > +{
> > +   complete(&spi_panel_te);
> > +   return IRQ_HANDLED;
> > +}
> > +
> > +static void set_spi_panel_te_irq_status(struct fbtft_par *par,
> > bool enable) +{
> > +   static int te_irq_count;
> > +
> > +   mutex_lock(&te_mutex);
> > +
> > +   if (enable) {
> > +   if (++te_irq_count == 1)
> > +   enable_irq(gpiod_to_irq(par->gpio.te));
> > +   } else {
> > +   if (--te_irq_count == 0)
> > +   disable_irq(gpiod_to_irq(par->gpio.te));
> > +   }
> > +   mutex_unlock(&te_mutex);
> > +}
> > +
> >  /**
> >   * init_display() - initialize the display controller
> >   *
> > @@ -82,6 +111,33 @@ enum st7789v_command {
> >   */
> >  static int init_display(struct fbtft_par *par)
> >  {
> > +   int rc;
> > +   struct device *dev = par->info->device;
> > +
> > +   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN);
> > +   if (IS_ERR(par->gpio.te)) {
> > +   rc = PTR_ERR(par->gpio.te);
> > +   dev_err(par->info->device, "Failed to request te
> > gpio: %d\n", rc);  
> 
> This also prints an error in case of -EPROBE_DEFER.
> dev_err_probe()?
> 
> > +   return rc;
> > +   }
> > +   if (par->gpio.te) {
> > +   init_completion(&spi_panel_te);
> > +   mutex_init(&te_mutex);
> > +   rc = devm_request_irq(dev,
> > + gpiod_to_irq(par->gpio.te),
> > +spi_panel_te_handler,
> > IRQF_TRIGGER_RISING,
> > +"TE_GPIO", par);
> > +   if (rc) {
> > +   dev_err(par->info->device, "TE request_irq
> > failed.\n");
> > +   devm_gpiod_put(dev, par->gpio.te);  
> 
> No need to call devm_gpiod_put() here, as it's managed automatically.
> 
> Gr{oetje,eeting}s,
> 
> Geert
> 

hi,i will fix in patch v11
regards
zhangxuezhi1


___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v10] staging: fbtft: add tearing signal detect

2021-01-27 Thread carlis
On Wed, 27 Jan 2021 14:51:55 +0100
Greg KH  wrote:

> On Wed, Jan 27, 2021 at 09:42:52PM +0800, Carlis wrote:
> > From: zhangxuezhi 
> > 
> > For st7789v ic,when we need continuous full screen refresh, it is
> > best to wait for the TE signal arrive to avoid screen tearing
> > 
> > Signed-off-by: zhangxuezhi   
> 
> Please slow down and wait at least a day between patch submissions,
> there is no rush here.
> 
> And also, ALWAYS run scripts/checkpatch.pl on your submissions, so
> that you don't have a maintainer asking you about basic problems,
> like are in this current patch :(
> 
> thanks,
> 
> greg k-h

hi,
  This is my first patch contribution to Linux, so some of the rules
are not very clear .In addition, I can confirm that before sending
patch, I check it with checkPatch.py every time.Thank you very much for
your help

regards
zhangxuezhi
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v10] staging: fbtft: add tearing signal detect

2021-01-27 Thread carlis
On Wed, 27 Jan 2021 15:13:05 +0100
Greg KH  wrote:

> On Wed, Jan 27, 2021 at 10:08:09PM +0800, carlis wrote:
> > On Wed, 27 Jan 2021 14:51:55 +0100
> > Greg KH  wrote:
> >   
> > > On Wed, Jan 27, 2021 at 09:42:52PM +0800, Carlis wrote:  
> > > > From: zhangxuezhi 
> > > > 
> > > > For st7789v ic,when we need continuous full screen refresh, it
> > > > is best to wait for the TE signal arrive to avoid screen tearing
> > > > 
> > > > Signed-off-by: zhangxuezhi 
> > > 
> > > Please slow down and wait at least a day between patch
> > > submissions, there is no rush here.
> > > 
> > > And also, ALWAYS run scripts/checkpatch.pl on your submissions, so
> > > that you don't have a maintainer asking you about basic problems,
> > > like are in this current patch :(
> > > 
> > > thanks,
> > > 
> > > greg k-h  
> > 
> > hi,
> >   This is my first patch contribution to Linux, so some of the rules
> > are not very clear .In addition, I can confirm that before sending
> > patch, I check it with checkPatch.py every time.Thank you very much
> > for your help  
> 
> Please read Documentation/SubmittingPatches which has a link to the
> checklist and other documentation you should read.
> 
> And I doubt you are running checkpatch on your submission, as there is
> obvious coding style issues in it.  If so, please provide the output
> as it must be broken :(
> 
> thanks,
> 
> greg k-h
hi, the patch v11 checkpatch.pl output is below:

carlis@bf-rmsz-10:~/work/linux-kernel/linux$ ./scripts/checkpatch.pl
0001-staging-fbtft-add-tearing-signal-detect.patch total: 0 errors, 0
warnings, 0 checks, 176 lines checked

0001-staging-fbtft-add-tearing-signal-detect.patch has no obvious style
problems and is ready for submission.


regards
zhangxuezhi

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v10] staging: fbtft: add tearing signal detect

2021-01-27 Thread carlis
On Wed, 27 Jan 2021 16:02:35 +0100
Greg KH  wrote:

> On Wed, Jan 27, 2021 at 05:49:46PM +0300, Dan Carpenter wrote:
> > On Wed, Jan 27, 2021 at 03:25:20PM +0100, Greg KH wrote:  
> > > On Wed, Jan 27, 2021 at 10:17:08PM +0800, carlis wrote:  
> > > > On Wed, 27 Jan 2021 15:13:05 +0100
> > > > Greg KH  wrote:
> > > >   
> > > > > On Wed, Jan 27, 2021 at 10:08:09PM +0800, carlis wrote:  
> > > > > > On Wed, 27 Jan 2021 14:51:55 +0100
> > > > > > Greg KH  wrote:
> > > > > > 
> > > > > > > On Wed, Jan 27, 2021 at 09:42:52PM +0800, Carlis wrote:
> > > > > > >  
> > > > > > > > From: zhangxuezhi 
> > > > > > > > 
> > > > > > > > For st7789v ic,when we need continuous full screen
> > > > > > > > refresh, it is best to wait for the TE signal arrive to
> > > > > > > > avoid screen tearing
> > > > > > > > 
> > > > > > > > Signed-off-by: zhangxuezhi 
> > > > > > > >   
> > > > > > > 
> > > > > > > Please slow down and wait at least a day between patch
> > > > > > > submissions, there is no rush here.
> > > > > > > 
> > > > > > > And also, ALWAYS run scripts/checkpatch.pl on your
> > > > > > > submissions, so that you don't have a maintainer asking
> > > > > > > you about basic problems, like are in this current patch
> > > > > > > :(
> > > > > > > 
> > > > > > > thanks,
> > > > > > > 
> > > > > > > greg k-h
> > > > > > 
> > > > > > hi,
> > > > > >   This is my first patch contribution to Linux, so some of
> > > > > > the rules are not very clear .In addition, I can confirm
> > > > > > that before sending patch, I check it with checkPatch.py
> > > > > > every time.Thank you very much for your help
> > > > > 
> > > > > Please read Documentation/SubmittingPatches which has a link
> > > > > to the checklist and other documentation you should read.
> > > > > 
> > > > > And I doubt you are running checkpatch on your submission, as
> > > > > there is obvious coding style issues in it.  If so, please
> > > > > provide the output as it must be broken :(
> > > > > 
> > > > > thanks,
> > > > > 
> > > > > greg k-h  
> > > > hi, the patch v11 checkpatch.pl output is below:
> > > > 
> > > > carlis@bf-rmsz-10:~/work/linux-kernel/linux$
> > > > ./scripts/checkpatch.pl
> > > > 0001-staging-fbtft-add-tearing-signal-detect.patch total: 0
> > > > errors, 0 warnings, 0 checks, 176 lines checked
> > > > 
> > > > 0001-staging-fbtft-add-tearing-signal-detect.patch has no
> > > > obvious style problems and is ready for submission.  
> > > 
> > > Wow, my apologies!
> > > 
> > > Andy and Joe, there's something wrong here that is missing the
> > > fact that a line is being indented with spaces and not tabs in
> > > the patch at
> > > https://lore.kernel.org/r/1611754972-151016-1-git-send-email-zhangxuez...@gmail.com
> > > 
> > > Any ideas what broke?
> > >   
> > 
> > /*Tearing Effect Line On*/
> > 
> > Comments are the exception to the "no spaces at the start of a line"
> > rule.  I was expecting that the kbuild-bot would send a Smatch
> > warning for inconsistent indenting, but comments are not counted
> > there either.
> > 
> > I'm sort of surprised that we don't have checkpatch rule about the
> > missing space characters.  It should be: "/* Tearing Effect Line On
> > */".  
> 
> That was going to be my next question, lots of comments added in this
> patch don't have spaces...
> 
> thanks,
> 
> greg k-h

Ok,i will fix it in patch v12 tomorrow

regards,
zhangxuezhi
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v10] staging: fbtft: add tearing signal detect

2021-01-27 Thread carlis
On Thu, 28 Jan 2021 00:32:22 +0200
Kari Argillander  wrote:

> On Wed, Jan 27, 2021 at 09:42:52PM +0800, Carlis wrote:
> > For st7789v ic,when we need continuous full screen refresh, it is
> > best to wait for the TE signal arrive to avoid screen tearing  
>  
> > diff --git a/drivers/staging/fbtft/fb_st7789v.c
> > b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..cba08a8 100644
> > --- a/drivers/staging/fbtft/fb_st7789v.c
> > +++ b/drivers/staging/fbtft/fb_st7789v.c
> > @@ -9,9 +9,12 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> > +#include 
> >  #include 
> >  #include 
> > -
> > +#include   
> 
> Space after local headers. Also this should one up so all Linux
> headers are group together. You agreed?
> 
OK,i will fix it in patch v12 tomorrow

> >  #include "fbtft.h"
> >  
> >  #define DRVNAME "fb_st7789v"
> > @@ -66,6 +69,32 @@ enum st7789v_command {
> >  #define MADCTL_MX BIT(6) /* bitmask for column address order */
> >  #define MADCTL_MY BIT(7) /* bitmask for page address order */
> >  
> > +#define SPI_PANEL_TE_TIMEOUT   400 /* msecs */
> > +static struct mutex te_mutex;/* mutex for set te gpio irq status
> > */  
> 
> Space after ;
hi, i have fix it in the patch v11
> 
> > +static struct completion spi_panel_te;  
> 
> What if multiple displays? Is this possible for user?
I will check it carefully again about this logic.
> 
> > +
> > +static irqreturn_t spi_panel_te_handler(int irq, void *data)
> > +{
> > +   complete(&spi_panel_te);
> > +   return IRQ_HANDLED;
> > +}
> > +
> > +static void set_spi_panel_te_irq_status(struct fbtft_par *par,
> > bool enable) +{
> > +   static int te_irq_count;  
> 
> Same here. Maybe you can think better way and then this code would
> also be cleaner.
> 
> > +
> > +   mutex_lock(&te_mutex);  
> 
> So locking should be done if we really do action and not just in case.
> 
> > +
> > +   if (enable) {
> > +   if (++te_irq_count == 1)
> > +   enable_irq(gpiod_to_irq(par->gpio.te));
> > +   } else {
> > +   if (--te_irq_count == 0)
> > +   disable_irq(gpiod_to_irq(par->gpio.te));
> > +   }
> > +   mutex_unlock(&te_mutex);
> > +}
> > +
> >  /**
> >   * init_display() - initialize the display controller
> >   *
> > @@ -82,6 +111,33 @@ enum st7789v_command {
> >   */
> >  static int init_display(struct fbtft_par *par)
> >  {
> > +   int rc;
> > +   struct device *dev = par->info->device;
> > +
> > +   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN);
> > +   if (IS_ERR(par->gpio.te)) {
> > +   rc = PTR_ERR(par->gpio.te);
> > +   dev_err(par->info->device, "Failed to request te
> > gpio: %d\n", rc);
> > +   return rc;
> > +   }  
> 
> You request with optinal and you still want to error out? We could
> just continue and not care about that error. User will be happier if
> device still works somehow.
You mean i just delete this dev_err print ?!
like this:
par->gpio.te = devm_gpiod_get_index_optional(dev, "te",
0,GPIOD_IN); 
if (IS_ERR(par->gpio.te))
return PTR_ERR(par->gpio.te);
> 
> > +   if (par->gpio.te) {
> > +   init_completion(&spi_panel_te);
> > +   mutex_init(&te_mutex);
> > +   rc = devm_request_irq(dev,
> > + gpiod_to_irq(par->gpio.te),
> > +spi_panel_te_handler,
> > IRQF_TRIGGER_RISING,
> > +"TE_GPIO", par);
> > +   if (rc) {
> > +   dev_err(par->info->device, "TE request_irq
> > failed.\n");
> > +   devm_gpiod_put(dev, par->gpio.te);
> > +   return rc;
> > +   }
> > +
> > +   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
> > +   } else {
> > +   dev_info(par->info->device, "%s:%d, TE gpio not
> > specified\n",
> > +__func__, __LINE__);
> > +   }
> > /* turn off sleep mode */
> > write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
> > mdelay(120);
> > @@ -137,6 +193,9 @@ static int init_display(struct fbtft_par *par)
> >  */
> > write_reg(par, PWCTRL1, 0xA4, 0xA1);
> >  
&

Re: [PATCH v10] staging: fbtft: add tearing signal detect

2021-01-28 Thread carlis
On Thu, 28 Jan 2021 08:52:33 +0200
Kari Argillander  wrote:

> On Thu, Jan 28, 2021 at 09:42:58AM +0800, carlis wrote:
> > On Thu, 28 Jan 2021 00:32:22 +0200
> > Kari Argillander  wrote:  
> > > >  #include "fbtft.h"
> > > >  
> > > >  #define DRVNAME "fb_st7789v"
> > > > @@ -66,6 +69,32 @@ enum st7789v_command {
> > > >  #define MADCTL_MX BIT(6) /* bitmask for column address order */
> > > >  #define MADCTL_MY BIT(7) /* bitmask for page address order */
> > > >  
> > > > +#define SPI_PANEL_TE_TIMEOUT   400 /* msecs */
> > > > +static struct mutex te_mutex;/* mutex for set te gpio irq
> > > > status */
> > > 
> > > Space after ;  
> > hi, i have fix it in the patch v11  
> > >   
> 
> Yeah sorry. I accidentally review wrong patch. But mostly stuff are
> still relevant.
> 
> > > > @@ -82,6 +111,33 @@ enum st7789v_command {
> > > >   */
> > > >  static int init_display(struct fbtft_par *par)
> > > >  {
> > > > +   int rc;
> > > > +   struct device *dev = par->info->device;
> > > > +
> > > > +   par->gpio.te = devm_gpiod_get_index_optional(dev,
> > > > "te", 0, GPIOD_IN);
> > > > +   if (IS_ERR(par->gpio.te)) {
> > > > +   rc = PTR_ERR(par->gpio.te);
> > > > +   dev_err(par->info->device, "Failed to request
> > > > te gpio: %d\n", rc);
> > > > +   return rc;
> > > > +   }
> > > 
> > > You request with optinal and you still want to error out? We could
> > > just continue and not care about that error. User will be happier
> > > if device still works somehow.  
> > You mean i just delete this dev_err print ?!
> > like this:
> > par->gpio.te = devm_gpiod_get_index_optional(dev, "te",
> > 0,GPIOD_IN); 
> > if (IS_ERR(par->gpio.te))
> > return PTR_ERR(par->gpio.te);  
> 
> Not exactly. I'm suggesting something like this.
> 
> if (IS_ERR(par->gpio.te) == -EPROBE_DEFER) {
>   return -EPROBE_DEFER;
> 
> if (IS_ERR(par->gpio.te))
>   par-gpio.te = NULL;
> 
> This like beginning of your patch series but the difference is that if
> EPROBE_DEFER then we will try again later. Any other error and we will
> just ignore TE gpio. But this is up to you what you want to do. To me
> this just seems place where this kind of logic can work.
> 
> > > > +   if (par->gpio.te) {
> > > > +   set_spi_panel_te_irq_status(par, true);
> > > > +   reinit_completion(&spi_panel_te);
> > > > +   ret =
> > > > wait_for_completion_timeout(&spi_panel_te,
> > > > +
> > > > msecs_to_jiffies(SPI_PANEL_TE_TIMEOUT));
> > > > +   if (ret == 0)
> > > 
> > > !ret
> > >   
> > > > +   dev_err(par->info->device,
> > > > "wait panel TE time out\n");
> > > > +   }
> > > > +   ret = par->fbtftops.write(par, par->txbuf.buf,
> > > > +startbyte_size +
> > > > to_copy
> > > > * 2);
> > > > +   if (par->gpio.te)
> > > > +   set_spi_panel_te_irq_status(par,
> > > > false);
> > > > +   if (ret < 0)
> > > > +   return ret;
> > > > +   remain -= to_copy;
> > > > +   }
> > > > +
> > > > +   return ret;
> > > 
> > > Do we want to return something over 0? If not then this can be
> > > return 0. And then you do not need to even init ret value at the
> > > beginning.
> > > 
> > > Also wait little bit like Greg sayd before sending new version.
> > > Someone might nack about what I say or say something more.
> > >   
> > hi, i copy fbtft_write_vmem16_bus8 from file fbtft_bus.c and modify
> > it ,just add te wait logic, i will take more time to check this
> > original function.  
> 
> It might be ok or not. You should still check.

hi, i will check more carefully, now i have a new problem, Is there a
way to clear the interrupt pending state before opening it again?



___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v10] staging: fbtft: add tearing signal detect

2021-01-28 Thread carlis
On Thu, 28 Jan 2021 10:42:54 +0100
Geert Uytterhoeven  wrote:

> Hi Kari,
> 
> On Thu, Jan 28, 2021 at 7:53 AM Kari Argillander
>  wrote:
> > On Thu, Jan 28, 2021 at 09:42:58AM +0800, carlis wrote:  
> > > On Thu, 28 Jan 2021 00:32:22 +0200
> > > Kari Argillander  wrote:  
> > > > >  #include "fbtft.h"
> > > > >
> > > > >  #define DRVNAME "fb_st7789v"
> > > > > @@ -66,6 +69,32 @@ enum st7789v_command {
> > > > >  #define MADCTL_MX BIT(6) /* bitmask for column address order
> > > > > */ #define MADCTL_MY BIT(7) /* bitmask for page address order
> > > > > */
> > > > >
> > > > > +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */
> > > > > +static struct mutex te_mutex;/* mutex for set te gpio irq
> > > > > status */  
> > > >
> > > > Space after ;  
> > > hi, i have fix it in the patch v11  
> > > >  
> >
> > Yeah sorry. I accidentally review wrong patch. But mostly stuff are
> > still relevant.
> >  
> > > > > @@ -82,6 +111,33 @@ enum st7789v_command {
> > > > >   */
> > > > >  static int init_display(struct fbtft_par *par)
> > > > >  {
> > > > > + int rc;
> > > > > + struct device *dev = par->info->device;
> > > > > +
> > > > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > > > > GPIOD_IN);
> > > > > + if (IS_ERR(par->gpio.te)) {
> > > > > + rc = PTR_ERR(par->gpio.te);
> > > > > + dev_err(par->info->device, "Failed to request te
> > > > > gpio: %d\n", rc);
> > > > > + return rc;
> > > > > + }  
> > > >
> > > > You request with optinal and you still want to error out? We
> > > > could just continue and not care about that error. User will be
> > > > happier if device still works somehow.  
> 
> devm_gpiod_get_index_optional() returns NULL, not an error, if the
> GPIO is not found.  So if IS_ERR() is the right check.
> 
> And checks for -EPROBE_DEFER can be handled automatically
> by using dev_err_probe() instead of dev_err().
> 
hi, i fix it like below!?
par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
GPIOD_IN); if (IS_ERR(par->gpio.te)) {
rc = PTR_ERR(par->gpio.te);
dev_err_probe(par->info->device, rc, "Failed to request
te gpio\n"); return rc;
}
if (par->gpio.te) {
init_completion(&spi_panel_te);
rc = devm_request_irq(dev,
  gpiod_to_irq(par->gpio.te),
 spi_panel_te_handler,
IRQF_TRIGGER_RISING, "TE_GPIO", par);
if (rc) {
dev_err(par->info->device, "TE request_irq
failed.\n"); return rc;
}

disable_irq_nosync(gpiod_to_irq(par->gpio.te));
} else {
dev_info(par->info->device, "%s:%d, TE gpio not
specified\n", __func__, __LINE__);
}


> > > You mean i just delete this dev_err print ?!
> > > like this:
> > >   par->gpio.te = devm_gpiod_get_index_optional(dev, "te",
> > > 0,GPIOD_IN);
> > > if (IS_ERR(par->gpio.te))
> > >   return PTR_ERR(par->gpio.te);  
> >
> > Not exactly. I'm suggesting something like this.
> >
> > if (IS_ERR(par->gpio.te) == -EPROBE_DEFER) {
> > return -EPROBE_DEFER;
> >
> > if (IS_ERR(par->gpio.te))
> > par-gpio.te = NULL;
> >
> > This like beginning of your patch series but the difference is that
> > if EPROBE_DEFER then we will try again later. Any other error and
> > we will just ignore TE gpio. But this is up to you what you want to
> > do. To me this just seems place where this kind of logic can work.  
> 
> Gr{oetje,eeting}s,
> 
> Geert
> 

regards,
zhangxuezhi
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v10] staging: fbtft: add tearing signal detect

2021-01-28 Thread carlis
On Thu, 28 Jan 2021 12:15:28 +0100
Geert Uytterhoeven  wrote:

> Hi Carlis,
> 
> On Thu, Jan 28, 2021 at 12:03 PM carlis 
> wrote:
> > On Thu, 28 Jan 2021 10:42:54 +0100
> > Geert Uytterhoeven  wrote:  
> > > On Thu, Jan 28, 2021 at 7:53 AM Kari Argillander
> > >  wrote:  
> > > > On Thu, Jan 28, 2021 at 09:42:58AM +0800, carlis wrote:  
> > > > > On Thu, 28 Jan 2021 00:32:22 +0200
> > > > > Kari Argillander  wrote:  
> > > > > > >  #include "fbtft.h"
> > > > > > >
> > > > > > >  #define DRVNAME "fb_st7789v"
> > > > > > > @@ -66,6 +69,32 @@ enum st7789v_command {
> > > > > > >  #define MADCTL_MX BIT(6) /* bitmask for column address
> > > > > > > order */ #define MADCTL_MY BIT(7) /* bitmask for page
> > > > > > > address order */
> > > > > > >
> > > > > > > +#define SPI_PANEL_TE_TIMEOUT 400 /* msecs */
> > > > > > > +static struct mutex te_mutex;/* mutex for set te gpio irq
> > > > > > > status */  
> > > > > >
> > > > > > Space after ;  
> > > > > hi, i have fix it in the patch v11  
> > > > > >  
> > > >
> > > > Yeah sorry. I accidentally review wrong patch. But mostly stuff
> > > > are still relevant.
> > > >  
> > > > > > > @@ -82,6 +111,33 @@ enum st7789v_command {
> > > > > > >   */
> > > > > > >  static int init_display(struct fbtft_par *par)
> > > > > > >  {
> > > > > > > + int rc;
> > > > > > > + struct device *dev = par->info->device;
> > > > > > > +
> > > > > > > + par->gpio.te = devm_gpiod_get_index_optional(dev, "te",
> > > > > > > 0, GPIOD_IN);
> > > > > > > + if (IS_ERR(par->gpio.te)) {
> > > > > > > + rc = PTR_ERR(par->gpio.te);
> > > > > > > + dev_err(par->info->device, "Failed to request te
> > > > > > > gpio: %d\n", rc);
> > > > > > > + return rc;
> > > > > > > + }  
> > > > > >
> > > > > > You request with optinal and you still want to error out? We
> > > > > > could just continue and not care about that error. User
> > > > > > will be happier if device still works somehow.  
> > >
> > > devm_gpiod_get_index_optional() returns NULL, not an error, if the
> > > GPIO is not found.  So if IS_ERR() is the right check.
> > >
> > > And checks for -EPROBE_DEFER can be handled automatically
> > > by using dev_err_probe() instead of dev_err().
> > >  
> > hi, i fix it like below!?
> > par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN); if (IS_ERR(par->gpio.te)) {
> > rc = PTR_ERR(par->gpio.te);
> > dev_err_probe(par->info->device, rc, "Failed to
> > request te gpio\n"); return rc;
> > }
> > if (par->gpio.te) {
> > init_completion(&spi_panel_te);
> > rc = devm_request_irq(dev,
> >   gpiod_to_irq(par->gpio.te),
> >  spi_panel_te_handler,
> > IRQF_TRIGGER_RISING, "TE_GPIO", par);
> > if (rc) {
> > dev_err(par->info->device, "TE request_irq
> > failed.\n"); return rc;  
> 
> dev_err_probe()
> 
> > }
> >
> > disable_irq_nosync(gpiod_to_irq(par->gpio.te));
> > } else {
> > dev_info(par->info->device, "%s:%d, TE gpio not
> > specified\n", __func__, __LINE__);
> > }  
> 
> Gr{oetje,eeting}s,
> 
> Geert
> 

hi,i will fix it like below:


par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
GPIOD_IN); if (IS_ERR(par->gpio.te))
return dev_err_probe(par->info->device,
PTR_ERR(par->gpio.te), "Failed to request te gpio\n");

if (par->gpio.te) {
init_completion(&spi_panel_te);
rc = devm_request_irq(dev,
  gpiod_to_irq(par->gpio.te),
 spi_panel_te_handler,
IRQF_TRIGGER_RISING, "TE_GPIO", par);
if (IS_ERR(rc))
return dev_err_probe(par->info->device,
PTR_ERR(rc), "TE request_irq failed.\n");

disable_irq_nosync(gpiod_to_irq(par->gpio.te));
} else {
dev_info(par->info->device, "%s:%d, TE gpio not
specified\n", __func__, __LINE__);
}


regards,
zhangxuezhi
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


[PATCH v12] staging: fbtft: add tearing signal detect

2021-01-28 Thread Carlis
From: zhangxuezhi 

For st7789v ic,when we need continuous full screen refresh, it is best to
wait for the TE signal arrive to avoid screen tearing

Signed-off-by: zhangxuezhi 
---
v12: change dev_err to dev_err_probe and add space in comments start, and
 delete te_mutex, change te wait logic
v11: remove devm_gpio_put and change a dev_err to dev_info
v10: additional notes
v9: change pr_* to dev_*
v8: delete a log line
v7: return error value when request fail
v6: add te gpio request fail deal logic
v5: fix log print
v4: modify some code style and change te irq set function name
v3: modify author and signed-off-by name
v2: add release te gpio after irq request fail
---
 drivers/staging/fbtft/fb_st7789v.c | 116 +
 drivers/staging/fbtft/fbtft.h  |   1 +
 2 files changed, 117 insertions(+)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..f08e9da 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -9,7 +9,11 @@
 #include 
 #include 
 #include 
+#include 
+#include 
 #include 
+#include 
+
 #include 
 
 #include "fbtft.h"
@@ -66,6 +70,15 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+#define SPI_PANEL_TE_TIMEOUT   400 /* msecs */
+static struct completion spi_panel_te;
+
+static irqreturn_t spi_panel_te_handler(int irq, void *data)
+{
+   complete(&spi_panel_te);
+   return IRQ_HANDLED;
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +95,29 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+   struct device *dev = par->info->device;
+
+   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0, GPIOD_IN);
+   if (IS_ERR(par->gpio.te))
+   return dev_err_probe(par->info->device, PTR_ERR(par->gpio.te),
+"Failed to request te gpio\n");
+
+   if (par->gpio.te) {
+   init_completion(&spi_panel_te);
+   rc = devm_request_irq(dev,
+ gpiod_to_irq(par->gpio.te),
+spi_panel_te_handler, IRQF_TRIGGER_RISING,
+"TE_GPIO", par);
+   if (IS_ERR(rc))
+   return dev_err_probe(par->info->device, PTR_ERR(rc),
+"TE request_irq failed.\n");
+
+   disable_irq_nosync(gpiod_to_irq(par->gpio.te));
+   } else {
+   dev_info(par->info->device, "%s:%d, TE gpio not specified\n",
+__func__, __LINE__);
+   }
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +173,10 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+   /* tearing effect line on */
+   if (par->gpio.te)
+   write_reg(par, 0x35, 0x00);
+
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -146,6 +186,81 @@ static int init_display(struct fbtft_par *par)
 }
 
 /**
+ * st7789v_write_vmem16_bus8() -  write data to display
+ *
+ * @par: FBTFT parameter object
+ * @offset: offset from screen_buffer
+ * @len: the length of data to be written
+ *
+ * 16 bit pixel over 8-bit databus
+ *
+ * Return: 0 on success, < 0 if error occurred.
+ */
+
+static int st7789v_write_vmem16_bus8(struct fbtft_par *par, size_t offset, 
size_t len)
+{
+   u16 *vmem16;
+   __be16 *txbuf16 = par->txbuf.buf;
+   size_t remain;
+   size_t to_copy;
+   size_t tx_array_size;
+   int i;
+   int ret = 0;
+   size_t startbyte_size = 0;
+
+   fbtft_par_dbg(DEBUG_WRITE_VMEM, par, "st7789v ---%s(offset=%zu, 
len=%zu)\n",
+ __func__, offset, len);
+
+   remain = len / 2;
+   vmem16 = (u16 *)(par->info->screen_buffer + offset);
+
+   if (par->gpio.dc)
+   gpiod_set_value(par->gpio.dc, 1);
+
+   if (par->gpio.te) {
+   enable_irq(gpiod_to_irq(par->gpio.te));
+   reinit_completion(&spi_panel_te);
+   ret = wait_for_completion_timeout(&spi_panel_te,
+ 
msecs_to_jiffies(SPI_PANEL_TE_TIMEOUT));
+   if (ret == 0)
+   dev_err(par->info->device, "wait panel TE time out\n");
+
+   disable_irq(gpiod_to_irq(par->gpio.te));
+   }
+   /* non buffered write */
+   if (!par->txbuf.buf)
+   return par->fbtftops.write(par, vmem16, len);
+
+   /* buffered write */
+   tx_array_size = par->txbuf.len / 2;
+
+   if (par->startbyte) {
+   txbuf16 = par->txbuf.buf + 1;
+   tx_array_size -= 2;
+   *(u8 *)(par->txbuf.buf) = par->startbyte | 0x2;
+  

Re: [PATCH v12] staging: fbtft: add tearing signal detect

2021-01-28 Thread carlis
On Thu, 28 Jan 2021 16:33:02 +0200
Andy Shevchenko  wrote:

> On Thu, Jan 28, 2021 at 2:58 PM Carlis  wrote:
> 
> Thanks for your contribution, my comments below.
> 
> > From: zhangxuezhi   
> 
> You probably have to configure your Git to use the same account for
> author and committer.

hi,you mean like below:
Carlis 
?
> 
> > For st7789v ic,when we need continuous full screen refresh, it is
> > best to  
> 
> 'ic,when' -> 'IC, when'
> 
> > wait for the TE signal arrive to avoid screen tearing  
> 
> Decode TE for people who are not familiar with the abbreviation.
> 
> Missed period at the end of sentence.
> 
> ...
> 
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> > +#include 
> >  #include 
> > +#include 
> > +  
> 
> Good, but I would rather squeeze it above to be more or less ordered,
> like just after delay.h inclusion.
> 
> >  #include   
> 
> ...
> 
> > +#define SPI_PANEL_TE_TIMEOUT   400 /* msecs */  
> 
> Useless comment. Instead use _MS suffix in the name of constant.
> Besides that please add a comment explaining why this value has been
> chosen.
> 
> ...
> 
> > +static struct completion spi_panel_te;  
> 
> As Greg said.
> 
> ...
> 
> >  static int init_display(struct fbtft_par *par)
> >  {
> > +   int rc;
> > +   struct device *dev = par->info->device;  
> 
> Keep reversed xmas tree order:
> 
>struct device *dev = par->info->device;
>int rc;
> 
> ...
> 
> > +   par->gpio.te = devm_gpiod_get_index_optional(dev, "te", 0,
> > GPIOD_IN);  
> 
> No need to have it requested for all time since you use it as an IRQ
> later on. The IRQ chip will call the GPIO library framework to lock a
> pin as IRQ anyway.
> 
> > +   if (IS_ERR(par->gpio.te))
> > +   return dev_err_probe(par->info->device,
> > PTR_ERR(par->gpio.te),
> > +"Failed to request te
> > gpio\n");  
> 
> > +   if (par->gpio.te) {  
> 
> Instead you should probably do the following:
> 
> int irq;
> 
> irq = gpiod_to_irq(...);
> if (irq > 0)
> 
> > +   init_completion(&spi_panel_te);
> > +   rc = devm_request_irq(dev,  
> 
> > + gpiod_to_irq(par->gpio.te),  
> 
> ...and here simply use irq.
> 
> > +spi_panel_te_handler,
> > IRQF_TRIGGER_RISING,
> > +"TE_GPIO", par);  
> 
> > +   if (IS_ERR(rc))  
> 
> This is wrong. rc is integer no IS_ERR() is required. Ditto for
> PTR_ERR(). Have you even looked for these macros implementations?
> 
> > +   return dev_err_probe(par->info->device,
> > PTR_ERR(rc),  
> 
> Use your temporary variable and move...
> 
> > +"TE request_irq
> > failed.\n");  
> 
> ...this on the previous line.
> 
> > +   disable_irq_nosync(gpiod_to_irq(par->gpio.te));  
> 
> Why do you call gpio_to_irq() twice?
> 
> 
> > +   } else {
> > +   dev_info(par->info->device, "%s:%d, TE gpio not
> > specified\n",
> > +__func__, __LINE__);  
> 
> Remove this noise (besides the fact that we don't use __file__ and
> __LINE__ in messages like this.
> 
> > +   }  
> 
> Taking all together you probably need to create a helper and use it
> inside init_display(), like
> 
> static int init_tearing_effect_line(struct fbtft_par *par)
> {
>   struct device *dev = par->info->device;
>   struct gpio_desc *te;
>   int irq, rc;
> 
>   te = gpiod_get_optional(dev, "te", GPIOD_IN);
>   if (IS_ERR(te))
>return dev_err_probe(dev, PTR_ERR(te), "Failed to request
> te GPIO\n");
> 
>   irq = gpiod_to_irq(te); // this value you have to save in the
> driver's (per device) data structure.
> 
>   /* GPIO is locked as an IRQ, we may drop the reference */
>   gpiod_put(te);


 
> 
>   init_completion(&spi_panel_te); // should be in the (per device)
> data structure
>   rc = devm_request_irq(dev, irq,  spi_panel_te_handler,
> IRQF_TRIGGER_RISING, "TE_GPIO", par);
>   if (rc)
> return dev_err_probe(dev, rc, "TE IRQ request
> failed.\n"); disable_irq_nosync(irq);
>   return irq;
> }
>

h

Re: [PATCH v12] staging: fbtft: add tearing signal detect

2021-01-29 Thread carlis
On Fri, 29 Jan 2021 12:23:08 +0200
Andy Shevchenko  wrote:

> On Fri, Jan 29, 2021 at 7:01 AM carlis  wrote:
> > On Thu, 28 Jan 2021 16:33:02 +0200
> > Andy Shevchenko  wrote:  
> > > On Thu, Jan 28, 2021 at 2:58 PM Carlis 
> > > wrote:
> > >
> > > Thanks for your contribution, my comments below.
> > >  
> > > > From: zhangxuezhi   
> > >
> > > You probably have to configure your Git to use the same account
> > > for author and committer.  
> >
> > hi,you mean like below:
> > Carlis 
> > ?  
> 
> I meant that you shouldn't probably have a From: line in the commit
> message.
> 
> ...
> 
> > hi, i have modified it according to your suggestion like below:  
> 
> Please, go again thru my comments and comments from others and
> carefully address all of them everywhere in your contribution. If you
> have questions, ask them in reply in the corresponding context.
> 
> ...
> 
> > /**
> >  * init_tearing_effect_line() - init tearing effect line  
> 
> >  *  
> 
> For example, above was commented on and hasn't been addressed here.
> 
hi,here i can not get you.
> >  * @par: FBTFT parameter object
> >  *
> >  * Return: 0 on success, < 0 if error occurred.
> >  */
> > static int init_tearing_effect_line(struct fbtft_par *par)
> > {
> > struct device *dev = par->info->device;
> > struct gpio_desc *te;
> > int rc;
> >
> > te = gpiod_get_optional(dev, "te", GPIOD_IN);
> > if (IS_ERR(te))
> > return dev_err_probe(dev, PTR_ERR(te), "Failed to
> > request te GPIO\n");
> >  
> 
> > if (te) {  
> 
> This one is not like I suggested.
Why? My thinking is that if the TE is not configured and NULL is
returned, the initialization can still proceed.
> 
> > par->irq_te = gpiod_to_irq(te);
> > gpiod_put(te);
> >  
> 
> > if (par->irq_te) {  
> 
> This is wrong.

Why? i have read gpiod_to_irq code, if an error occurs, a negative
value is returned, and zero is not possible,so I need this value to
determine if TE IRQ is configured

> 
> > rc = devm_request_irq(dev,
> >   par->irq_te,
> > panel_te_handler,
> >   IRQF_TRIGGER_RISING,
> > "TE_GPIO", par);  
> 
> Try to use less LOCs.
> 
> > if (rc)
> > return dev_err_probe(dev, rc, "TE
> > IRQ request failed.\n");
> >
> > disable_irq_nosync(par->irq_te);
> > init_completion(&par->panel_te);  
> 
> > } else {
> > return dev_err_probe(dev, par->irq_te,
> > "gpiod to TE IRQ failed.\n");
> > }  
> 
> Again, it is not what had been suggested.
> 
> > }
> >
> > return 0;
> > }  
> 
> The rest is better, but we will see later on when you submit a new
> version (And I feel it won't be last).
> 

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v12] staging: fbtft: add tearing signal detect

2021-01-29 Thread carlis
On Fri, 29 Jan 2021 12:23:08 +0200
Andy Shevchenko  wrote:

> On Fri, Jan 29, 2021 at 7:01 AM carlis  wrote:
> > On Thu, 28 Jan 2021 16:33:02 +0200
> > Andy Shevchenko  wrote:  
> > > On Thu, Jan 28, 2021 at 2:58 PM Carlis 
> > > wrote:
> > >
> > > Thanks for your contribution, my comments below.
> > >  
> > > > From: zhangxuezhi   
> > >
> > > You probably have to configure your Git to use the same account
> > > for author and committer.  
> >
> > hi,you mean like below:
> > Carlis 
> > ?  
> 
> I meant that you shouldn't probably have a From: line in the commit
> message.
> 
> ...
> 
> > hi, i have modified it according to your suggestion like below:  
> 
> Please, go again thru my comments and comments from others and
> carefully address all of them everywhere in your contribution. If you
> have questions, ask them in reply in the corresponding context.
> 
> ...
> 
> > /**
> >  * init_tearing_effect_line() - init tearing effect line  
> 
> >  *  
> 
> For example, above was commented on and hasn't been addressed here.
> 
> >  * @par: FBTFT parameter object
> >  *
> >  * Return: 0 on success, < 0 if error occurred.
> >  */
> > static int init_tearing_effect_line(struct fbtft_par *par)
> > {
> > struct device *dev = par->info->device;
> > struct gpio_desc *te;
> > int rc;
> >
> > te = gpiod_get_optional(dev, "te", GPIOD_IN);
> > if (IS_ERR(te))
> > return dev_err_probe(dev, PTR_ERR(te), "Failed to
> > request te GPIO\n");
> >  
> 
> > if (te) {  
> 
> This one is not like I suggested.
I don't think I have a problem here, if te GPIO is not configured, it
should return NULL, if it is configured, it should be greater than 0 
> 
> > par->irq_te = gpiod_to_irq(te);
> > gpiod_put(te);
> >  
> 
> > if (par->irq_te) {  
> 
> This is wrong.
> 
> > rc = devm_request_irq(dev,
> >   par->irq_te,
> > panel_te_handler,
> >   IRQF_TRIGGER_RISING,
> > "TE_GPIO", par);  
> 
> Try to use less LOCs.

LOCs i can not get you 
> 
> > if (rc)
> > return dev_err_probe(dev, rc, "TE
> > IRQ request failed.\n");
> >
> > disable_irq_nosync(par->irq_te);
> > init_completion(&par->panel_te);  
> 
> > } else {
> > return dev_err_probe(dev, par->irq_te,
> > "gpiod to TE IRQ failed.\n");
> > }  
> 
> Again, it is not what had been suggested.
> 
> > }
> >
> > return 0;
> > }  
> 
> The rest is better, but we will see later on when you submit a new
> version (And I feel it won't be last).
> 

___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel


Re: [PATCH v12] staging: fbtft: add tearing signal detect

2021-01-29 Thread carlis
On Fri, 29 Jan 2021 12:23:08 +0200
Andy Shevchenko  wrote:

> On Fri, Jan 29, 2021 at 7:01 AM carlis  wrote:
> > On Thu, 28 Jan 2021 16:33:02 +0200
> > Andy Shevchenko  wrote:  
> > > On Thu, Jan 28, 2021 at 2:58 PM Carlis 
> > > wrote:
> > >
> > > Thanks for your contribution, my comments below.
> > >  
> > > > From: zhangxuezhi   
> > >
> > > You probably have to configure your Git to use the same account
> > > for author and committer.  
> >
> > hi,you mean like below:
> > Carlis 
> > ?  
> 
> I meant that you shouldn't probably have a From: line in the commit
> message.
> 
> ...
> 
> > hi, i have modified it according to your suggestion like below:  
> 
> Please, go again thru my comments and comments from others and
> carefully address all of them everywhere in your contribution. If you
> have questions, ask them in reply in the corresponding context.
> 
> ...
> 
> > /**
> >  * init_tearing_effect_line() - init tearing effect line  
> 
> >  *  
> 
> For example, above was commented on and hasn't been addressed here.
> 
> >  * @par: FBTFT parameter object
> >  *
> >  * Return: 0 on success, < 0 if error occurred.
> >  */
> > static int init_tearing_effect_line(struct fbtft_par *par)
> > {
> > struct device *dev = par->info->device;
> > struct gpio_desc *te;
> > int rc;
> >
> > te = gpiod_get_optional(dev, "te", GPIOD_IN);
> > if (IS_ERR(te))
> > return dev_err_probe(dev, PTR_ERR(te), "Failed to
> > request te GPIO\n");
> >  
> 
> > if (te) {  
> 
> This one is not like I suggested.
> 
> > par->irq_te = gpiod_to_irq(te);
> > gpiod_put(te);
> >  
> 
> > if (par->irq_te) {  
> 
> This is wrong.
> 
> > rc = devm_request_irq(dev,
> >   par->irq_te,
> > panel_te_handler,
> >   IRQF_TRIGGER_RISING,
> > "TE_GPIO", par);  
> 
> Try to use less LOCs.
> 
> > if (rc)
> > return dev_err_probe(dev, rc, "TE
> > IRQ request failed.\n");
> >
> > disable_irq_nosync(par->irq_te);
> > init_completion(&par->panel_te);  
> 
> > } else {
> > return dev_err_probe(dev, par->irq_te,
> > "gpiod to TE IRQ failed.\n");
> > }  
> 
> Again, it is not what had been suggested.
> 
> > }
> >
> > return 0;
> > }  
> 
> The rest is better, but we will see later on when you submit a new
> version (And I feel it won't be last).
> 

Hi, I apologize for what I said in the previous two emails. I missed
one email you sent before, and now I probably understand what you
meant. Here is a version I modified according to your suggestion:

>From 399e7fb91d1dcba4924cd38cc8283393c80b97e4 Mon Sep 17 00:00:00 2001
From: Carlis 
Date: Sun, 24 Jan 2021 22:43:21 +0800
Subject: [PATCH v13] staging: fbtft: add tearing signal detect

For st7789v IC,when we need continuous full screen refresh, it is best
to wait for the tearing effect line signal arrive to avoid screen
tearing.

Signed-off-by: Carlis 
---
v13: change te completion to par data struct member and add a new
 function to deal te gpio request.
v12: change dev_err to dev_err_probe and add space in comments start,
and delete te_mutex, change te wait logic.
v11: remove devm_gpio_put and change a dev_err to dev_info.
v10: additional notes.
v9: change pr_* to dev_*.
v8: delete a log line.
v7: return error value when request fail.
v6: add te gpio request fail deal logic.
v5: fix log print.
v4: modify some code style and change te irq set function name.
v3: modify author and signed-off-by name.
v2: add release te gpio after irq request fail.
---
 drivers/staging/fbtft/fb_st7789v.c | 138
+ drivers/staging/fbtft/fbtft.h
 |   5 ++ 2 files changed, 143 insertions(+)

diff --git a/drivers/staging/fbtft/fb_st7789v.c
b/drivers/staging/fbtft/fb_st7789v.c index 3a280cc..8faae7a 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -7,9 +7,13 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
 #include 
+
 #include 
 
 #include "fbtft.h"
@@ -66,6 +70,55 @@ enum s

Re: [PATCH v12] staging: fbtft: add tearing signal detect

2021-01-29 Thread carlis
On Fri, 29 Jan 2021 16:26:12 +0200
Andy Shevchenko  wrote:

> On Fri, Jan 29, 2021 at 3:56 PM carlis  wrote:
> > On Fri, 29 Jan 2021 12:23:08 +0200
> > Andy Shevchenko  wrote:  
> 
> We are almost there, I have no idea what Noralf or others are going to
> say though.
> 
> ...
> 
> > Hi, I apologize for what I said in the previous two emails. I missed
> > one email you sent before, and now I probably understand what you
> > meant. Here is a version I modified according to your suggestion:
> >
> > From 399e7fb91d1dcba4924cd38cc8283393c80b97e4 Mon Sep 17 00:00:00
> > 2001 From: Carlis 
> > Date: Sun, 24 Jan 2021 22:43:21 +0800
> > Subject: [PATCH v13] staging: fbtft: add tearing signal detect
> >
> > For st7789v IC,when we need continuous full screen refresh, it is
> > best  
> 
> Missed space after comma.
> 
> > to wait for the tearing effect line signal arrive to avoid screen  
> 
> to arrive
> 
> > tearing.  
> 
> ...
> 
> > +#define PANEL_TE_TIMEOUT_MS  34 /* 60Hz for 16.6ms, configured as
> > 2*16.6ms */ +  
> 
> Move comment before the definition
> /* comment */
> #define DEFINITION
> 
> Also consider to use 33 ms as closest to what you mentioned in the
> comment. Or leave it with mention that you are using ceil() value.
> 
> ...
> 
> > +/**
> > + * init_tearing_effect_line() - init tearing effect line  
> 
> > + *  
> 
> As per a few previous reviews.
> Okay, I have noticed that the existing kernel-doc is written like
> this, but it doesn't prevent you from avoiding this little mistake.
> 
> > + * @par: FBTFT parameter object
> > + *
> > + * Return: 0 on success, or a negative error code otherwise.
> > + */
> > +static int init_tearing_effect_line(struct fbtft_par *par)
> > +{
> > +   struct device *dev = par->info->device;
> > +   struct gpio_desc *te;
> > +   int rc;
> > +
> > +   te = gpiod_get_optional(dev, "te", GPIOD_IN);
> > +   if (IS_ERR(te))
> > +   return dev_err_probe(dev, PTR_ERR(te), "Failed to
> > request te GPIO\n"); +  
> 
> Below is okay, but needs a comment explaining why we return a success.
> 
> > +   if (!te)
> > +   return 0;
> > +
> > +   par->irq_te = gpiod_to_irq(te);
> > +
> > +   /* GPIO is locked as an IRQ, we may drop the reference */
> > +   gpiod_put(te);
> > +
> > +   if (par->irq_te < 0)
> > +   return par->irq_te;  
> 
> I recommend using a temporary variable. In such a case you won't need
> to specifically check for negative error code. So, something like
> 
> int irq;
> 
> irq = ...
> 
> if (irq < 0)
>   return irq;
> 
> ->irq_te = irq;  
> 
> > +   init_completion(&par->panel_te);
> > +   rc = devm_request_irq(dev, par->irq_te, panel_te_handler,
> > + IRQF_TRIGGER_RISING, "TE_GPIO", par);
> >  
> 
> Right. Now it needs a comment explaining the choice of rising edge
> type of IRQ.
> 
> > +   if (rc)
> > +   return dev_err_probe(dev, rc, "TE IRQ request
> > failed.\n"); +
> > +   disable_irq_nosync(par->irq_te);
> > +
> > +   return 0;
> > +}  
> 
> ...
> 
> > +   rc = init_tearing_effect_line(par);  
> 
> > +   if (rc < 0)  
> 
> Here is no need to specifically check against less than 0,
>   if (ret)
> will work nicely.
> 
> > +   return rc;  
> 
> ...
> 
> > +   if (par->irq_te)
> > +   write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00);  
> 
> Do you need to call MIPI_DCS_SET_TEAR_SCANLINE in this case?
> 
Hi, TE line output is off by default when powering on, and I use
Qualcomm SDX55 chip, SPI top speed is only 50MHz, its data transmission
speed( It takes about 24ms to transmit a frame) is slower than 60Hz
refresh(a frame only need 16.6ms), so i think there is no need to call
MIPI_DCS_SET_TEAR_SCANLINE 

> Alos, when there is no IRQ, shouldn't we explicitly call
>write_reg(par, MIPI_DCS_SET_TEAR_OFF);
> ?
> 
> ...
> 
> >  /**
> > + * st7789v_write_vmem16_bus8() - write data to display  
> 
> > + *  
> 
> Redundant.
> 
> > + * @par: FBTFT parameter object
> > + * @offset: offset from screen_buffer
> > + * @len: the length of data to be written
> > + *  
> 
> > + * 16 bit pixel over 8-bit databus  
> 
> Write 16-bit pix

[PATCH v13] staging: fbtft: add tearing signal detect

2021-02-01 Thread Carlis
From: Carlis 

For st7789v IC, when we need continuous full screen refresh, it is best to
wait for the tearing effect line signal to arrive to avoid screen tearing.

Signed-off-by: Carlis 
---
v13: change TE completion to par data struct member and add a new
 function to deal te gpio request, move wait logic to 
fbtft_write_vmem16_bus8.
v12: change dev_err to dev_err_probe and add space in comments start, and
 delete te_mutex, change te wait logic.
v11: remove devm_gpio_put and change a dev_err to dev_info.
v10: additional notes.
v9: change pr_* to dev_*.
v8: delete a log line.
v7: return error value when request fail.
v6: add te gpio request fail deal logic.
v5: fix log print.
v4: modify some code style and change te irq set function name.
v3: modify author and signed-off-by name.
v2: add release te gpio after irq request fail.
---
 drivers/staging/fbtft/fb_st7789v.c | 112 +
 drivers/staging/fbtft/fbtft.h  |   5 ++
 2 files changed, 117 insertions(+)

diff --git a/drivers/staging/fbtft/fb_st7789v.c 
b/drivers/staging/fbtft/fb_st7789v.c
index 3a280cc..7b41bad 100644
--- a/drivers/staging/fbtft/fb_st7789v.c
+++ b/drivers/staging/fbtft/fb_st7789v.c
@@ -7,9 +7,13 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
+#include 
+#include 
 #include 
+
 #include 
 
 #include "fbtft.h"
@@ -66,6 +70,59 @@ enum st7789v_command {
 #define MADCTL_MX BIT(6) /* bitmask for column address order */
 #define MADCTL_MY BIT(7) /* bitmask for page address order */
 
+/* 60Hz for 16.6ms, configured as 2*16.6ms */
+#define PANEL_TE_TIMEOUT_MS  33
+
+static irqreturn_t panel_te_handler(int irq, void *data)
+{
+   struct fbtft_par *par = (struct fbtft_par *)data;
+
+   complete(&par->panel_te);
+   return IRQ_HANDLED;
+}
+
+/*
+ * init_tearing_effect_line() - init tearing effect line.
+ * @par: FBTFT parameter object.
+ *
+ * Return: 0 on success, or a negative error code otherwise.
+ */
+static int init_tearing_effect_line(struct fbtft_par *par)
+{
+   struct device *dev = par->info->device;
+   struct gpio_desc *te;
+   int rc, irq;
+
+   te = gpiod_get_optional(dev, "te", GPIOD_IN);
+   if (IS_ERR(te))
+   return dev_err_probe(dev, PTR_ERR(te), "Failed to request te 
GPIO\n");
+
+   /* if te is NULL, indicating no configuration, directly return success 
*/
+   if (!te)
+   return 0;
+
+   irq = gpiod_to_irq(te);
+
+   /* GPIO is locked as an IRQ, we may drop the reference */
+   gpiod_put(te);
+
+   if (irq < 0)
+   return irq;
+
+   par->irq_te = irq;
+   init_completion(&par->panel_te);
+
+   /* The effective state is high and lasts no more than 1000 microseconds 
*/
+   rc = devm_request_irq(dev, par->irq_te, panel_te_handler,
+ IRQF_TRIGGER_RISING, "TE_GPIO", par);
+   if (rc)
+   return dev_err_probe(dev, rc, "TE IRQ request failed.\n");
+
+   disable_irq_nosync(par->irq_te);
+
+   return 0;
+}
+
 /**
  * init_display() - initialize the display controller
  *
@@ -82,6 +139,12 @@ enum st7789v_command {
  */
 static int init_display(struct fbtft_par *par)
 {
+   int rc;
+
+   rc = init_tearing_effect_line(par);
+   if (rc)
+   return rc;
+
/* turn off sleep mode */
write_reg(par, MIPI_DCS_EXIT_SLEEP_MODE);
mdelay(120);
@@ -137,6 +200,10 @@ static int init_display(struct fbtft_par *par)
 */
write_reg(par, PWCTRL1, 0xA4, 0xA1);
 
+   /* TE line output is off by default when powering on */
+   if (par->irq_te)
+   write_reg(par, MIPI_DCS_SET_TEAR_ON, 0x00);
+
write_reg(par, MIPI_DCS_SET_DISPLAY_ON);
 
if (HSD20_IPS)
@@ -145,6 +212,50 @@ static int init_display(struct fbtft_par *par)
return 0;
 }
 
+/*
+ * write_vmem() - write data to display.
+ * @par: FBTFT parameter object.
+ * @offset: offset from screen_buffer.
+ * @len: the length of data to be writte.
+ *
+ * Return: 0 on success, or a negative error code otherwise.
+ */
+static int write_vmem(struct fbtft_par *par, size_t offset, size_t len)
+{
+   struct device *dev = par->info->device;
+   int ret;
+
+   if (par->irq_te) {
+   enable_irq(par->irq_te);
+   reinit_completion(&par->panel_te);
+   ret = wait_for_completion_timeout(&par->panel_te,
+ 
msecs_to_jiffies(PANEL_TE_TIMEOUT_MS));
+   if (ret == 0)
+   dev_err(dev, "wait panel TE timeout\n");
+
+   disable_irq(par->irq_te);
+   }
+
+   ret = 0;
+   switch (par->pdata->display.buswidth) {
+   case 8:
+   ret = fbtft_write_vmem16_bus8(par, offset, len);
+   break;
+   ca

Re: [PATCH v12] staging: fbtft: add tearing signal detect

2021-02-01 Thread Carlis
On Mon, 1 Feb 2021 19:40:21 +0200
Andy Shevchenko  wrote:

> On Sat, Jan 30, 2021 at 8:39 AM carlis  wrote:
> > On Fri, 29 Jan 2021 16:26:12 +0200
> > Andy Shevchenko  wrote:  
> > > On Fri, Jan 29, 2021 at 3:56 PM carlis 
> > > wrote:  
> > > > On Fri, 29 Jan 2021 12:23:08 +0200
> > > > Andy Shevchenko  wrote:  
> 
> ...
> 
> > > > Hi, I apologize for what I said in the previous two emails. I
> > > > missed one email you sent before, and now I probably understand
> > > > what you meant. Here is a version I modified according to your
> > > > suggestion:  
> 
> I have realized that you are mocking stuff in the generic fbtft
> structure for all drivers while only a single one is going to use
> that. Consider moving everything to the driver in question.
> 
> 

hi, 
   Do you mean that i define the TE completion and irq_te in the
   fb_st7789v.c as i did before?
___
devel mailing list
de...@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel