Re: [PATCH v2 2/2] Input: ads7846: convert to one message

2021-01-20 Thread Dmitry Torokhov
On Wed, Jan 20, 2021 at 08:40:32AM +0100, Oleksij Rempel wrote:
> 
> Hi Dmitry,
> 
> On Tue, Nov 17, 2020 at 04:31:38PM -0800, Dmitry Torokhov wrote:
> > On Tue, Nov 10, 2020 at 09:50:41AM +0100, Oleksij Rempel wrote:
> > > Convert multiple full duplex transfers in to a single transfer to reduce
> > > CPU load.
> > > 
> > > Current driver version support following filtering modes:
> > > - ads7846_no_filter() - not filtered
> > > - ads7846_debounce_filter() - driver specific debounce filter
> > > - pdata->filter - platform specific debounce filter (do any platform
> > >   provides such filter?)
> > > 
> > > Without filter this HW is not really usable, since the physic of
> > > resistive touchscreen can provide some bounce effects. With driver 
> > > internal
> > > filter, we have constant amount of retries + debounce retries if some 
> > > anomaly
> > > was detected.
> > > 
> > > High amount of tiny SPI transfers is the primer reason of high CPU load
> > > and interrupt frequency.
> > > 
> > > This patch create one SPI transfer with all fields and not optional 
> > > retires. If
> > > bounce anomaly was detected, we will make more transfer if needed.
> > > 
> > > Without this patch, we will get about 10% CPU load on iMX6S on pen-down 
> > > event.
> > > For example by holding stylus on the screen.
> > > 
> > > With this patch, depending in the amount of retries, the CPU load will
> > > be 1% with "ti,debounce-rep = <3>".
> > > 
> > > One buffer transfer allows us to use PIO FIFO or DMA engine, depending
> > > on the platform.
> > > 
> > > Signed-off-by: Oleksij Rempel 
> > 
> > Applied, thank you.
> 
> I can't find this patch in your git repository. Should I rebase it
> against latest git and resend it?

Ugh, sorry, now applied for realz.

Thanks.

-- 
Dmitry


Re: [PATCH v2 2/2] Input: ads7846: convert to one message

2021-01-19 Thread Oleksij Rempel


Hi Dmitry,

On Tue, Nov 17, 2020 at 04:31:38PM -0800, Dmitry Torokhov wrote:
> On Tue, Nov 10, 2020 at 09:50:41AM +0100, Oleksij Rempel wrote:
> > Convert multiple full duplex transfers in to a single transfer to reduce
> > CPU load.
> > 
> > Current driver version support following filtering modes:
> > - ads7846_no_filter() - not filtered
> > - ads7846_debounce_filter() - driver specific debounce filter
> > - pdata->filter - platform specific debounce filter (do any platform
> > provides such filter?)
> > 
> > Without filter this HW is not really usable, since the physic of
> > resistive touchscreen can provide some bounce effects. With driver internal
> > filter, we have constant amount of retries + debounce retries if some 
> > anomaly
> > was detected.
> > 
> > High amount of tiny SPI transfers is the primer reason of high CPU load
> > and interrupt frequency.
> > 
> > This patch create one SPI transfer with all fields and not optional 
> > retires. If
> > bounce anomaly was detected, we will make more transfer if needed.
> > 
> > Without this patch, we will get about 10% CPU load on iMX6S on pen-down 
> > event.
> > For example by holding stylus on the screen.
> > 
> > With this patch, depending in the amount of retries, the CPU load will
> > be 1% with "ti,debounce-rep = <3>".
> > 
> > One buffer transfer allows us to use PIO FIFO or DMA engine, depending
> > on the platform.
> > 
> > Signed-off-by: Oleksij Rempel 
> 
> Applied, thank you.

I can't find this patch in your git repository. Should I rebase it
against latest git and resend it?

Regards,
Oleksij
-- 
Pengutronix e.K.   | |
Steuerwalder Str. 21   | http://www.pengutronix.de/  |
31137 Hildesheim, Germany  | Phone: +49-5121-206917-0|
Amtsgericht Hildesheim, HRA 2686   | Fax:   +49-5121-206917- |


Re: [PATCH v2 2/2] Input: ads7846: convert to one message

2020-11-17 Thread Dmitry Torokhov
On Tue, Nov 10, 2020 at 09:50:41AM +0100, Oleksij Rempel wrote:
> Convert multiple full duplex transfers in to a single transfer to reduce
> CPU load.
> 
> Current driver version support following filtering modes:
> - ads7846_no_filter() - not filtered
> - ads7846_debounce_filter() - driver specific debounce filter
> - pdata->filter - platform specific debounce filter (do any platform
>   provides such filter?)
> 
> Without filter this HW is not really usable, since the physic of
> resistive touchscreen can provide some bounce effects. With driver internal
> filter, we have constant amount of retries + debounce retries if some anomaly
> was detected.
> 
> High amount of tiny SPI transfers is the primer reason of high CPU load
> and interrupt frequency.
> 
> This patch create one SPI transfer with all fields and not optional retires. 
> If
> bounce anomaly was detected, we will make more transfer if needed.
> 
> Without this patch, we will get about 10% CPU load on iMX6S on pen-down event.
> For example by holding stylus on the screen.
> 
> With this patch, depending in the amount of retries, the CPU load will
> be 1% with "ti,debounce-rep = <3>".
> 
> One buffer transfer allows us to use PIO FIFO or DMA engine, depending
> on the platform.
> 
> Signed-off-by: Oleksij Rempel 

Applied, thank you.

-- 
Dmitry


[PATCH v2 2/2] Input: ads7846: convert to one message

2020-11-10 Thread Oleksij Rempel
Convert multiple full duplex transfers in to a single transfer to reduce
CPU load.

Current driver version support following filtering modes:
- ads7846_no_filter() - not filtered
- ads7846_debounce_filter() - driver specific debounce filter
- pdata->filter - platform specific debounce filter (do any platform
provides such filter?)

Without filter this HW is not really usable, since the physic of
resistive touchscreen can provide some bounce effects. With driver internal
filter, we have constant amount of retries + debounce retries if some anomaly
was detected.

High amount of tiny SPI transfers is the primer reason of high CPU load
and interrupt frequency.

This patch create one SPI transfer with all fields and not optional retires. If
bounce anomaly was detected, we will make more transfer if needed.

Without this patch, we will get about 10% CPU load on iMX6S on pen-down event.
For example by holding stylus on the screen.

With this patch, depending in the amount of retries, the CPU load will
be 1% with "ti,debounce-rep = <3>".

One buffer transfer allows us to use PIO FIFO or DMA engine, depending
on the platform.

Signed-off-by: Oleksij Rempel 
---
 drivers/input/touchscreen/ads7846.c | 375 ++--
 1 file changed, 193 insertions(+), 182 deletions(-)

diff --git a/drivers/input/touchscreen/ads7846.c 
b/drivers/input/touchscreen/ads7846.c
index e9a520c9ad69..d6c6a13af4ea 100644
--- a/drivers/input/touchscreen/ads7846.c
+++ b/drivers/input/touchscreen/ads7846.c
@@ -64,23 +64,13 @@
 
 struct ads7846_buf {
u8 cmd;
-   /* This union is a temporary hack. The driver does an in-place
-* endianness conversion. This will be cleaned up in the next
-* patch.
-*/
-   union {
-   __be16 data_be16;
-   u16 data;
-   };
+   __be16 data;
 } __attribute__((__packed__));
 
-
-struct ts_event {
-   bool ignore;
-   struct ads7846_buf x;
-   struct ads7846_buf y;
-   struct ads7846_buf z1;
-   struct ads7846_buf z2;
+struct ads7846_buf_layout {
+   unsigned int offset;
+   unsigned int count;
+   unsigned int skip;
 };
 
 /*
@@ -89,12 +79,18 @@ struct ts_event {
  * systems where main memory is not DMA-coherent (most non-x86 boards).
  */
 struct ads7846_packet {
-   struct ts_event tc;
-   struct ads7846_buf read_x_cmd;
-   struct ads7846_buf read_y_cmd;
-   struct ads7846_buf read_z1_cmd;
-   struct ads7846_buf read_z2_cmd;
+   unsigned int count;
+   unsigned int count_skip;
+   unsigned int cmds;
+   unsigned int last_cmd_idx;
+   struct ads7846_buf_layout l[5];
+   struct ads7846_buf *rx;
+   struct ads7846_buf *tx;
+
struct ads7846_buf pwrdown_cmd;
+
+   bool ignore;
+   u16 x, y, z1, z2;
 };
 
 struct ads7846 {
@@ -193,7 +189,6 @@ struct ads7846 {
 #defineREAD_Y(vref)(READ_12BIT_DFR(y,  1, vref))
 #defineREAD_Z1(vref)   (READ_12BIT_DFR(z1, 1, vref))
 #defineREAD_Z2(vref)   (READ_12BIT_DFR(z2, 1, vref))
-
 #defineREAD_X(vref)(READ_12BIT_DFR(x,  1, vref))
 #definePWRDOWN (READ_12BIT_DFR(y,  0, 0))  /* LAST */
 
@@ -206,6 +201,21 @@ struct ads7846 {
 #defineREF_ON  (READ_12BIT_DFR(x, 1, 1))
 #defineREF_OFF (READ_12BIT_DFR(y, 0, 0))
 
+/* Order commands in the most optimal way to reduce Vref switching and
+ * settling time:
+ * Measure:  X; Vref: X+, X-; IN: Y+
+ * Measure:  Y; Vref: Y+, Y-; IN: X+
+ * Measure: Z1; Vref: Y+, X-; IN: X+
+ * Measure: Z2; Vref: Y+, X-; IN: Y-
+ */
+enum ads7846_cmds {
+   ADS7846_X,
+   ADS7846_Y,
+   ADS7846_Z1,
+   ADS7846_Z2,
+   ADS7846_PWDOWN,
+};
+
 static int get_pendown_state(struct ads7846 *ts)
 {
if (ts->get_pendown_state)
@@ -696,26 +706,109 @@ static int ads7846_no_filter(void *ads, int data_idx, 
int *val)
return ADS7846_FILTER_OK;
 }
 
-static int ads7846_get_value(struct ads7846 *ts, struct spi_message *m)
+static int ads7846_get_value(struct ads7846_buf *buf)
 {
int value;
-   struct spi_transfer *t =
-   list_entry(m->transfers.prev, struct spi_transfer, 
transfer_list);
-   struct ads7846_buf *buf = t->rx_buf;
 
-   value = be16_to_cpup(>data_be16);
+   value = be16_to_cpup(>data);
 
/* enforce ADC output is 12 bits width */
return (value >> 3) & 0xfff;
 }
 
-static void ads7846_update_value(struct spi_message *m, int val)
+static void ads7846_set_cmd_val(struct ads7846 *ts, enum ads7846_cmds cmd_idx,
+   u16 val)
+{
+   struct ads7846_packet *packet = ts->packet;
+
+   switch (cmd_idx) {
+   case ADS7846_Y:
+   packet->y = val;
+   break;
+   case ADS7846_X:
+   packet->x = val;
+   break;
+   case ADS7846_Z1:
+   packet->z1 = val;
+   break;
+   case ADS7846_Z2:
+   packet->z2 =