Re: [PATCH 2/2] serial: 8250-mtk: modify uart DMA rx

2019-05-30 Thread Long Cheng
On Thu, 2019-05-23 at 15:35 +0800, Long Cheng wrote:


Hi Greg,

Just a gentle ping!

thanks.

> Modify uart rx and complete for DMA
> 
> Signed-off-by: Long Cheng 
> ---
>  drivers/tty/serial/8250/8250_mtk.c |   49 
> +++-
>  1 file changed, 20 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/8250_mtk.c 
> b/drivers/tty/serial/8250/8250_mtk.c
> index 417c7c8..f470ded 100644
> --- a/drivers/tty/serial/8250/8250_mtk.c
> +++ b/drivers/tty/serial/8250/8250_mtk.c
> @@ -47,7 +47,6 @@
>  #define MTK_UART_DMA_EN_RX   0x5
>  
>  #define MTK_UART_ESCAPE_CHAR 0x77/* Escape char added under sw fc */
> -#define MTK_UART_TX_SIZE UART_XMIT_SIZE
>  #define MTK_UART_RX_SIZE 0x8000
>  #define MTK_UART_TX_TRIGGER  1
>  #define MTK_UART_RX_TRIGGER  MTK_UART_RX_SIZE
> @@ -89,28 +88,30 @@ static void mtk8250_dma_rx_complete(void *param)
>   struct mtk8250_data *data = up->port.private_data;
>   struct tty_port *tty_port = >port.state->port;
>   struct dma_tx_state state;
> + int copied, total, cnt;
>   unsigned char *ptr;
> - int copied;
>  
> - dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
> - dma->rx_size, DMA_FROM_DEVICE);
> + if (data->rx_status == DMA_RX_SHUTDOWN)
> + return;
>  
>   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
> + total = dma->rx_size - state.residue;
> + cnt = total;
>  
> - if (data->rx_status == DMA_RX_SHUTDOWN)
> - return;
> + if ((data->rx_pos + cnt) > dma->rx_size)
> + cnt = dma->rx_size - data->rx_pos;
>  
> - if ((data->rx_pos + state.residue) <= dma->rx_size) {
> - ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> - copied = tty_insert_flip_string(tty_port, ptr, state.residue);
> - } else {
> - ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> - copied = tty_insert_flip_string(tty_port, ptr,
> - dma->rx_size - data->rx_pos);
> + ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> + copied = tty_insert_flip_string(tty_port, ptr, cnt);
> + data->rx_pos += cnt;
> +
> + if (total > cnt) {
>   ptr = (unsigned char *)(dma->rx_buf);
> - copied += tty_insert_flip_string(tty_port, ptr,
> - data->rx_pos + state.residue - dma->rx_size);
> + cnt = total - cnt;
> + copied += tty_insert_flip_string(tty_port, ptr, cnt);
> + data->rx_pos = cnt;
>   }
> +
>   up->port.icount.rx += copied;
>  
>   tty_flip_buffer_push(tty_port);
> @@ -121,9 +122,7 @@ static void mtk8250_dma_rx_complete(void *param)
>  static void mtk8250_rx_dma(struct uart_8250_port *up)
>  {
>   struct uart_8250_dma *dma = up->dma;
> - struct mtk8250_data *data = up->port.private_data;
>   struct dma_async_tx_descriptor  *desc;
> - struct dma_tx_state  state;
>  
>   desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
>  dma->rx_size, DMA_DEV_TO_MEM,
> @@ -138,12 +137,6 @@ static void mtk8250_rx_dma(struct uart_8250_port *up)
>  
>   dma->rx_cookie = dmaengine_submit(desc);
>  
> - dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
> - data->rx_pos = state.residue;
> -
> - dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
> -dma->rx_size, DMA_FROM_DEVICE);
> -
>   dma_async_issue_pending(dma->rxchan);
>  }
>  
> @@ -156,13 +149,11 @@ static void mtk8250_dma_enable(struct uart_8250_port 
> *up)
>   if (data->rx_status != DMA_RX_START)
>   return;
>  
> - dma->rxconf.direction   = DMA_DEV_TO_MEM;
> - dma->rxconf.src_addr_width  = dma->rx_size / 1024;
> - dma->rxconf.src_addr= dma->rx_addr;
> + dma->rxconf.src_port_window_size= dma->rx_size;
> + dma->rxconf.src_addr= dma->rx_addr;
>  
> - dma->txconf.direction   = DMA_MEM_TO_DEV;
> - dma->txconf.dst_addr_width  = MTK_UART_TX_SIZE / 1024;
> - dma->txconf.dst_addr= dma->tx_addr;
> + dma->txconf.dst_port_window_size= UART_XMIT_SIZE;
> + dma->txconf.dst_addr= dma->tx_addr;
>  
>   serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
>   UART_FCR_CLEAR_XMIT);




[PATCH v13 0/2] add uart DMA function

2019-05-23 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma/mediatek.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v12
-rename parameters
-remove direction
Changes compared to v11
-modify TX/RX
-pause function by software
Changes compared to v10
-modify DMA tx status function
-modify 8250_mtk for DMA rx
-add notes to binding Document.
Changes compared to v9
-rename dt-bindings file
-remove direction from device_config
-simplified code
Changes compared to v8
-revise missing items
Changes compared to v7:
-modify apdma uart tx
Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (2):
  arm: dts: mt2712: add uart APDMA to device tree
  serial: 8250-mtk: modify uart DMA rx

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   51 +
 drivers/tty/serial/8250/8250_mtk.c|   49 +++
 2 files changed, 71 insertions(+), 29 deletions(-)

-- 
1.7.9.5



[PATCH v13 1/2] arm: dts: mt2712: add uart APDMA to device tree

2019-05-23 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   51 +
 1 file changed, 51 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 43307ba..a7a7362 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -369,6 +372,39 @@
 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   dma-requests = <12>;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
auxadc: adc@11001000 {
compatible = "mediatek,mt2712-auxadc";
reg = <0 0x11001000 0 0x1000>;
@@ -385,6 +421,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +434,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +447,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +460,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +677,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH 2/2] serial: 8250-mtk: modify uart DMA rx

2019-05-23 Thread Long Cheng
Modify uart rx and complete for DMA

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |   49 +++-
 1 file changed, 20 insertions(+), 29 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index 417c7c8..f470ded 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -47,7 +47,6 @@
 #define MTK_UART_DMA_EN_RX 0x5
 
 #define MTK_UART_ESCAPE_CHAR   0x77/* Escape char added under sw fc */
-#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
 #define MTK_UART_RX_SIZE   0x8000
 #define MTK_UART_TX_TRIGGER1
 #define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
@@ -89,28 +88,30 @@ static void mtk8250_dma_rx_complete(void *param)
struct mtk8250_data *data = up->port.private_data;
struct tty_port *tty_port = >port.state->port;
struct dma_tx_state state;
+   int copied, total, cnt;
unsigned char *ptr;
-   int copied;
 
-   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
-   dma->rx_size, DMA_FROM_DEVICE);
+   if (data->rx_status == DMA_RX_SHUTDOWN)
+   return;
 
dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   total = dma->rx_size - state.residue;
+   cnt = total;
 
-   if (data->rx_status == DMA_RX_SHUTDOWN)
-   return;
+   if ((data->rx_pos + cnt) > dma->rx_size)
+   cnt = dma->rx_size - data->rx_pos;
 
-   if ((data->rx_pos + state.residue) <= dma->rx_size) {
-   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
-   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
-   } else {
-   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
-   copied = tty_insert_flip_string(tty_port, ptr,
-   dma->rx_size - data->rx_pos);
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, cnt);
+   data->rx_pos += cnt;
+
+   if (total > cnt) {
ptr = (unsigned char *)(dma->rx_buf);
-   copied += tty_insert_flip_string(tty_port, ptr,
-   data->rx_pos + state.residue - dma->rx_size);
+   cnt = total - cnt;
+   copied += tty_insert_flip_string(tty_port, ptr, cnt);
+   data->rx_pos = cnt;
}
+
up->port.icount.rx += copied;
 
tty_flip_buffer_push(tty_port);
@@ -121,9 +122,7 @@ static void mtk8250_dma_rx_complete(void *param)
 static void mtk8250_rx_dma(struct uart_8250_port *up)
 {
struct uart_8250_dma *dma = up->dma;
-   struct mtk8250_data *data = up->port.private_data;
struct dma_async_tx_descriptor  *desc;
-   struct dma_tx_state  state;
 
desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
   dma->rx_size, DMA_DEV_TO_MEM,
@@ -138,12 +137,6 @@ static void mtk8250_rx_dma(struct uart_8250_port *up)
 
dma->rx_cookie = dmaengine_submit(desc);
 
-   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
-   data->rx_pos = state.residue;
-
-   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
-  dma->rx_size, DMA_FROM_DEVICE);
-
dma_async_issue_pending(dma->rxchan);
 }
 
@@ -156,13 +149,11 @@ static void mtk8250_dma_enable(struct uart_8250_port *up)
if (data->rx_status != DMA_RX_START)
return;
 
-   dma->rxconf.direction   = DMA_DEV_TO_MEM;
-   dma->rxconf.src_addr_width  = dma->rx_size / 1024;
-   dma->rxconf.src_addr= dma->rx_addr;
+   dma->rxconf.src_port_window_size= dma->rx_size;
+   dma->rxconf.src_addr= dma->rx_addr;
 
-   dma->txconf.direction   = DMA_MEM_TO_DEV;
-   dma->txconf.dst_addr_width  = MTK_UART_TX_SIZE / 1024;
-   dma->txconf.dst_addr= dma->tx_addr;
+   dma->txconf.dst_port_window_size= UART_XMIT_SIZE;
+   dma->txconf.dst_addr= dma->tx_addr;
 
serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT);
-- 
1.7.9.5



Re: [PATCH 4/4] serial: 8250-mtk: modify uart DMA rx

2019-05-21 Thread Long Cheng
On Fri, 2019-05-17 at 15:36 +0800, Long Cheng wrote:
> On Wed, 2019-05-15 at 21:48 +0800, Nicolas Boichat wrote:
> > On Sat, Apr 27, 2019 at 11:36 AM Long Cheng  wrote:
> > >
> > > Modify uart rx and complete for DMA.
> > 
> > I don't know much about the DMA framework, but can you please explain
> > why you are making the changes in this CL? I see that you are dropping
> > dma_sync_single_for_device calls, for example, why?
> > 
> 
> the rx buffer is create by 'dma_alloc_coherent'. in the function, the
> buffer is uncache. We don't need to sync between CPU and DMA. So I
> remove it.
> 
> > >
> > > Signed-off-by: Long Cheng 
> > > ---
> > >  drivers/tty/serial/8250/8250_mtk.c |   53 
> > > 
> > >  1 file changed, 23 insertions(+), 30 deletions(-)
> > >
> > > diff --git a/drivers/tty/serial/8250/8250_mtk.c 
> > > b/drivers/tty/serial/8250/8250_mtk.c
> > > index c1fdbc0..04081a6 100644
> > > --- a/drivers/tty/serial/8250/8250_mtk.c
> > > +++ b/drivers/tty/serial/8250/8250_mtk.c
> > > @@ -30,7 +30,6 @@
> > >  #define MTK_UART_DMA_EN_TX 0x2
> > >  #define MTK_UART_DMA_EN_RX 0x5
> > >
> > > -#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
> > >  #define MTK_UART_RX_SIZE   0x8000
> > >  #define MTK_UART_TX_TRIGGER1
> > >  #define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
> > > @@ -64,28 +63,30 @@ static void mtk8250_dma_rx_complete(void *param)
> > > struct mtk8250_data *data = up->port.private_data;
> > > struct tty_port *tty_port = >port.state->port;
> > > struct dma_tx_state state;
> > > +   int copied, cnt, tmp;
> > > unsigned char *ptr;
> > > -   int copied;
> > >
> > > -   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
> > > -   dma->rx_size, DMA_FROM_DEVICE);
> > > +   if (data->rx_status == DMA_RX_SHUTDOWN)
> > > +   return;
> > >
> > > dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
> > > +   cnt = dma->rx_size - state.residue;
> > > +   tmp = cnt;
> > 
> > I ponder, maybe we should rename cnt to left? (like, how many bytes
> > are left to transfer, in total) Or maybe "total"
> > Then maybe rename tmp to cnt.
> > 
> like better.
> 
> > >
> > > -   if (data->rx_status == DMA_RX_SHUTDOWN)
> > > -   return;
> > > +   if ((data->rx_pos + cnt) > dma->rx_size)
> > > +   tmp = dma->rx_size - data->rx_pos;
> > 
> > Maybe replace this and the line above:
> > tmp = max_t(int, cnt, dma->rx_size - data->rx_pos);
> > 
> Yes. It's better.
> 

can't replace by 'max_t'. So I will keep original code.

> > >
> > > -   if ((data->rx_pos + state.residue) <= dma->rx_size) {
> > > -   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > > -   copied = tty_insert_flip_string(tty_port, ptr, 
> > > state.residue);
> > > -   } else {
> > > -   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > > -   copied = tty_insert_flip_string(tty_port, ptr,
> > > -   dma->rx_size - 
> > > data->rx_pos);
> > > +   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > > +   copied = tty_insert_flip_string(tty_port, ptr, tmp);
> > > +   data->rx_pos += tmp;
> > > +
> > > +   if (cnt > tmp) {
> > > ptr = (unsigned char *)(dma->rx_buf);
> > > -   copied += tty_insert_flip_string(tty_port, ptr,
> > > -   data->rx_pos + state.residue - 
> > > dma->rx_size);
> > > +   tmp = cnt - tmp;
> > > +   copied += tty_insert_flip_string(tty_port, ptr, tmp);
> > > +   data->rx_pos = tmp;
> > > }
> > > +
> > > up->port.icount.rx += copied;
> > >
> > > tty_flip_buffer_push(tty_port);
> > > @@ -96,9 +97,7 @@ static void mtk8250_dma_rx_complete(void *param)
> > >  static void mtk8250_rx_dma(struct uart_8250_port *up)
> > >  {
> > > struct uart_8250_dma *dma = up->dma;
> > > -   struct mtk8250_data *data 

Re: [PATCH 4/4] serial: 8250-mtk: modify uart DMA rx

2019-05-17 Thread Long Cheng
On Wed, 2019-05-15 at 21:48 +0800, Nicolas Boichat wrote:
> On Sat, Apr 27, 2019 at 11:36 AM Long Cheng  wrote:
> >
> > Modify uart rx and complete for DMA.
> 
> I don't know much about the DMA framework, but can you please explain
> why you are making the changes in this CL? I see that you are dropping
> dma_sync_single_for_device calls, for example, why?
> 

the rx buffer is create by 'dma_alloc_coherent'. in the function, the
buffer is uncache. We don't need to sync between CPU and DMA. So I
remove it.

> >
> > Signed-off-by: Long Cheng 
> > ---
> >  drivers/tty/serial/8250/8250_mtk.c |   53 
> > 
> >  1 file changed, 23 insertions(+), 30 deletions(-)
> >
> > diff --git a/drivers/tty/serial/8250/8250_mtk.c 
> > b/drivers/tty/serial/8250/8250_mtk.c
> > index c1fdbc0..04081a6 100644
> > --- a/drivers/tty/serial/8250/8250_mtk.c
> > +++ b/drivers/tty/serial/8250/8250_mtk.c
> > @@ -30,7 +30,6 @@
> >  #define MTK_UART_DMA_EN_TX 0x2
> >  #define MTK_UART_DMA_EN_RX 0x5
> >
> > -#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
> >  #define MTK_UART_RX_SIZE   0x8000
> >  #define MTK_UART_TX_TRIGGER1
> >  #define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
> > @@ -64,28 +63,30 @@ static void mtk8250_dma_rx_complete(void *param)
> > struct mtk8250_data *data = up->port.private_data;
> > struct tty_port *tty_port = >port.state->port;
> > struct dma_tx_state state;
> > +   int copied, cnt, tmp;
> > unsigned char *ptr;
> > -   int copied;
> >
> > -   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
> > -   dma->rx_size, DMA_FROM_DEVICE);
> > +   if (data->rx_status == DMA_RX_SHUTDOWN)
> > +   return;
> >
> > dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
> > +   cnt = dma->rx_size - state.residue;
> > +   tmp = cnt;
> 
> I ponder, maybe we should rename cnt to left? (like, how many bytes
> are left to transfer, in total) Or maybe "total"
> Then maybe rename tmp to cnt.
> 
like better.

> >
> > -   if (data->rx_status == DMA_RX_SHUTDOWN)
> > -   return;
> > +   if ((data->rx_pos + cnt) > dma->rx_size)
> > +   tmp = dma->rx_size - data->rx_pos;
> 
> Maybe replace this and the line above:
> tmp = max_t(int, cnt, dma->rx_size - data->rx_pos);
> 
Yes. It's better.

> >
> > -   if ((data->rx_pos + state.residue) <= dma->rx_size) {
> > -   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > -   copied = tty_insert_flip_string(tty_port, ptr, 
> > state.residue);
> > -   } else {
> > -   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > -   copied = tty_insert_flip_string(tty_port, ptr,
> > -   dma->rx_size - 
> > data->rx_pos);
> > +   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > +   copied = tty_insert_flip_string(tty_port, ptr, tmp);
> > +   data->rx_pos += tmp;
> > +
> > +   if (cnt > tmp) {
> > ptr = (unsigned char *)(dma->rx_buf);
> > -   copied += tty_insert_flip_string(tty_port, ptr,
> > -   data->rx_pos + state.residue - 
> > dma->rx_size);
> > +   tmp = cnt - tmp;
> > +   copied += tty_insert_flip_string(tty_port, ptr, tmp);
> > +   data->rx_pos = tmp;
> > }
> > +
> > up->port.icount.rx += copied;
> >
> > tty_flip_buffer_push(tty_port);
> > @@ -96,9 +97,7 @@ static void mtk8250_dma_rx_complete(void *param)
> >  static void mtk8250_rx_dma(struct uart_8250_port *up)
> >  {
> > struct uart_8250_dma *dma = up->dma;
> > -   struct mtk8250_data *data = up->port.private_data;
> > struct dma_async_tx_descriptor  *desc;
> > -   struct dma_tx_state  state;
> >
> > desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
> >dma->rx_size, DMA_DEV_TO_MEM,
> > @@ -113,12 +112,6 @@ static void mtk8250_rx_dma(struct uart_8250_port *up)
> >
> > dma->rx_cookie = dmaengine_submit(desc);
> >
> > -   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
> > -   data->rx_pos = state.r

[PATCH 4/4] serial: 8250-mtk: modify uart DMA rx

2019-04-26 Thread Long Cheng
Modify uart rx and complete for DMA.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |   53 
 1 file changed, 23 insertions(+), 30 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index c1fdbc0..04081a6 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -30,7 +30,6 @@
 #define MTK_UART_DMA_EN_TX 0x2
 #define MTK_UART_DMA_EN_RX 0x5
 
-#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
 #define MTK_UART_RX_SIZE   0x8000
 #define MTK_UART_TX_TRIGGER1
 #define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
@@ -64,28 +63,30 @@ static void mtk8250_dma_rx_complete(void *param)
struct mtk8250_data *data = up->port.private_data;
struct tty_port *tty_port = >port.state->port;
struct dma_tx_state state;
+   int copied, cnt, tmp;
unsigned char *ptr;
-   int copied;
 
-   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
-   dma->rx_size, DMA_FROM_DEVICE);
+   if (data->rx_status == DMA_RX_SHUTDOWN)
+   return;
 
dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   cnt = dma->rx_size - state.residue;
+   tmp = cnt;
 
-   if (data->rx_status == DMA_RX_SHUTDOWN)
-   return;
+   if ((data->rx_pos + cnt) > dma->rx_size)
+   tmp = dma->rx_size - data->rx_pos;
 
-   if ((data->rx_pos + state.residue) <= dma->rx_size) {
-   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
-   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
-   } else {
-   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
-   copied = tty_insert_flip_string(tty_port, ptr,
-   dma->rx_size - data->rx_pos);
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, tmp);
+   data->rx_pos += tmp;
+
+   if (cnt > tmp) {
ptr = (unsigned char *)(dma->rx_buf);
-   copied += tty_insert_flip_string(tty_port, ptr,
-   data->rx_pos + state.residue - dma->rx_size);
+   tmp = cnt - tmp;
+   copied += tty_insert_flip_string(tty_port, ptr, tmp);
+   data->rx_pos = tmp;
}
+
up->port.icount.rx += copied;
 
tty_flip_buffer_push(tty_port);
@@ -96,9 +97,7 @@ static void mtk8250_dma_rx_complete(void *param)
 static void mtk8250_rx_dma(struct uart_8250_port *up)
 {
struct uart_8250_dma *dma = up->dma;
-   struct mtk8250_data *data = up->port.private_data;
struct dma_async_tx_descriptor  *desc;
-   struct dma_tx_state  state;
 
desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
   dma->rx_size, DMA_DEV_TO_MEM,
@@ -113,12 +112,6 @@ static void mtk8250_rx_dma(struct uart_8250_port *up)
 
dma->rx_cookie = dmaengine_submit(desc);
 
-   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
-   data->rx_pos = state.residue;
-
-   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
-  dma->rx_size, DMA_FROM_DEVICE);
-
dma_async_issue_pending(dma->rxchan);
 }
 
@@ -131,13 +124,13 @@ static void mtk8250_dma_enable(struct uart_8250_port *up)
if (data->rx_status != DMA_RX_START)
return;
 
-   dma->rxconf.direction   = DMA_DEV_TO_MEM;
-   dma->rxconf.src_addr_width  = dma->rx_size / 1024;
-   dma->rxconf.src_addr= dma->rx_addr;
+   dma->rxconf.direction   = DMA_DEV_TO_MEM;
+   dma->rxconf.src_port_window_size= dma->rx_size;
+   dma->rxconf.src_addr= dma->rx_addr;
 
-   dma->txconf.direction   = DMA_MEM_TO_DEV;
-   dma->txconf.dst_addr_width  = MTK_UART_TX_SIZE / 1024;
-   dma->txconf.dst_addr= dma->tx_addr;
+   dma->txconf.direction   = DMA_MEM_TO_DEV;
+   dma->txconf.dst_port_window_size= UART_XMIT_SIZE;
+   dma->txconf.dst_addr= dma->tx_addr;
 
serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT);
@@ -217,7 +210,7 @@ static void mtk8250_shutdown(struct uart_port *port)
 * Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS)
 *
 * We need to recalcualte the quot register, as the claculation depends
-* on the vaule in the highspeed register.
+* on the value in the highspeed register.
 *
 * Some baudrates are not supported by the chip, so we use the next
 * lower rate supported and update termios c_flag.
-- 
1.7.9.5



[PATCH 1/4] dmaengine: mediatek: Add MediaTek UART APDMA support

2019-04-26 Thread Long Cheng
Add 8250 UART APDMA to support MediaTek UART. If MediaTek UART is
enabled by SERIAL_8250_MT6577, and we can enable this driver to offload
the UART device moving bytes.

Signed-off-by: Long Cheng 
Signed-off-by: Sean Wang 
---
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 drivers/dma/mediatek/mtk-uart-apdma.c |  666 +
 3 files changed, 678 insertions(+)
 create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c

diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 680fc05..ac49eb6 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -24,3 +24,14 @@ config MTK_CQDMA
 
  This controller provides the channels which is dedicated to
  memory-to-memory transfer to offload from CPU.
+
+config MTK_UART_APDMA
+   tristate "MediaTek SoCs APDMA support for UART"
+   depends on OF && SERIAL_8250_MT6577
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Support for the UART DMA engine found on MediaTek MTK SoCs.
+ When SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
+ you can enable the config. The DMA engine can only be used
+ with MediaTek SoCs.
diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
index 41bb381..61a6d29 100644
--- a/drivers/dma/mediatek/Makefile
+++ b/drivers/dma/mediatek/Makefile
@@ -1,2 +1,3 @@
+obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o
 obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
 obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o
diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c 
b/drivers/dma/mediatek/mtk-uart-apdma.c
new file mode 100644
index 000..546995c
--- /dev/null
+++ b/drivers/dma/mediatek/mtk-uart-apdma.c
@@ -0,0 +1,666 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek UART APDMA driver.
+ *
+ * Copyright (c) 2019 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+/* The default number of virtual channel */
+#define MTK_UART_APDMA_NR_VCHANS   8
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_EN_BBIT(0)
+/* rx valid size >=  vff thre */
+#define VFF_RX_INT_EN_B(BIT(0) | BIT(1))
+/* tx left size >= vff thre */
+#define VFF_TX_INT_EN_BBIT(0)
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_CLR_B   (BIT(0) | BIT(1))
+#define VFF_TX_INT_CLR_B   0
+#define VFF_STOP_CLR_B 0
+#define VFF_EN_CLR_B   0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/*
+ * interrupt trigger level for tx
+ * if threshold is n, no polling is required to start tx.
+ * otherwise need polling VFF_FLUSH.
+ */
+#define VFF_TX_THRE(n) (n)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define VFF_RING_SIZE  0x
+/* invert this bit when wrap ring head again */
+#define VFF_RING_WRAP  0x1
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/* TX: the buffer size HW can read. RX: the buffer size SW can read. */
+#define VFF_VALID_SIZE 0x3c
+/* TX: the buffer size SW can write. RX: the buffer size HW can write. */
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_uart_apdmadev {
+   struct dma_device ddev;
+   struct clk *clk;
+   bool support_33bits;
+   unsigned int dma_requests;
+};
+
+struct mtk_uart_apdma_desc {
+   struct virt_dma_desc vd;
+
+   dma_addr_t addr;
+   unsigned int avail_len;
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct dma_slave_config cfg;
+   struct mtk_uart_apdma_desc *desc;
+   enum dma_transfer_direction dir;
+
+   void __iomem *base;
+   unsigned int irq;
+
+   unsigned int rx_status;
+};
+
+static inline struct mtk_uart_apdmadev *
+to_mtk_uart_apdma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_uart_apdmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_uart_apdma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_uart_apdma_desc *to_mtk_uart_apdma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_uar

[PATCH 3/4] dt-bindings: dma: uart: rename binding

2019-04-26 Thread Long Cheng
The filename matches mtk-uart-apdma.c.
So using "mtk-uart-apdma.txt" should be better.
And add some property.

Signed-off-by: Long Cheng 
---
 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 
 .../devicetree/bindings/dma/mtk-uart-apdma.txt |   55 
 2 files changed, 55 insertions(+), 33 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt

diff --git a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt 
b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
deleted file mode 100644
index 3fe0961..000
--- a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-* Mediatek UART APDMA Controller
-
-Required properties:
-- compatible should contain:
-  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
-  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
-
-- reg: The base address of the APDMA register bank.
-
-- interrupts: A single interrupt specifier.
-
-- clocks : Must contain an entry for each entry in clock-names.
-  See ../clocks/clock-bindings.txt for details.
-- clock-names: The APDMA clock for register accesses
-
-Examples:
-
-   apdma: dma-controller@11000380 {
-   compatible = "mediatek,mt2712-uart-dma";
-   reg = <0 0x11000380 0 0x400>;
-   interrupts = ,
-,
-,
-,
-,
-,
-,
-;
-   clocks = < CLK_PERI_AP_DMA>;
-   clock-names = "apdma";
-   #dma-cells = <1>;
-   };
-
diff --git a/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt 
b/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
new file mode 100644
index 000..e0424b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
@@ -0,0 +1,55 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+ One interrupt per dma-requests, or 8 if no dma-requests property is present
+
+- dma-requests: The number of DMA channels
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+- mediatek,dma-33bits: Present if the DMA requires support
+
+Examples:
+
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   dma-requests = <12>;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   mediatek,dma-33bits;
+   #dma-cells = <1>;
+   };
+
-- 
1.7.9.5



[PATCH v12 0/4] add uart DMA function

2019-04-26 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma/mediatek.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v11
-modify TX/RX
-pause function by software
Changes compared to v10
-modify DMA tx status function
-modify 8250_mtk for DMA rx
-add notes to binding Document.
Changes compared to v9
-rename dt-bindings file
-remove direction from device_config
-simplified code
Changes compared to v8
-revise missing items
Changes compared to v7:
-modify apdma uart tx
Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (4):
  dmaengine: mediatek: Add MediaTek UART APDMA support
  arm: dts: mt2712: add uart APDMA to device tree
  dt-bindings: dma: uart: rename binding
  serial: 8250-mtk: modify uart DMA rx

 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 -
 .../devicetree/bindings/dma/mtk-uart-apdma.txt |   55 ++
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi  |   51 ++
 drivers/dma/mediatek/Kconfig   |   11 +
 drivers/dma/mediatek/Makefile  |1 +
 drivers/dma/mediatek/mtk-uart-apdma.c  |  666 
 drivers/tty/serial/8250/8250_mtk.c |   53 +-
 7 files changed, 807 insertions(+), 63 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
 create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c

-- 
1.7.9.5




[PATCH 2/4] arm: dts: mt2712: add uart APDMA to device tree

2019-04-26 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   51 +
 1 file changed, 51 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..f1e419e 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -369,6 +372,39 @@
 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   dma-requests = <12>;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
auxadc: adc@11001000 {
compatible = "mediatek,mt2712-auxadc";
reg = <0 0x11001000 0 0x1000>;
@@ -385,6 +421,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +434,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +447,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +460,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +677,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



Re: [PATCH 1/2] serial: 8250-mtk: add follow control

2019-04-25 Thread Long Cheng
On Thu, 2019-04-25 at 12:40 +0200, Matthias Brugger wrote:
> 
> On 25/04/2019 10:41, Long Cheng wrote:
> > Add SW and HW follow control function.
> 
> Can you please explain a bit more what you are doing in this patch.
> You change the setting of the registers for different baud rates. Please
> elaborate what is happening there.
> 
Clock source is different. Sometimes, baudrate is greater than or equal
to 115200, we use highspeed of 3 algorithm and fractional divider to
ensure more accurate baudrate.

Next release version, I will update this to commit message

> > 
> > Signed-off-by: Long Cheng 
> > ---
> >  drivers/tty/serial/8250/8250_mtk.c |   60 
> > ++--
> >  1 file changed, 37 insertions(+), 23 deletions(-)
> > 
> > diff --git a/drivers/tty/serial/8250/8250_mtk.c 
> > b/drivers/tty/serial/8250/8250_mtk.c
> > index c1fdbc0..959fd85 100644
> > --- a/drivers/tty/serial/8250/8250_mtk.c
> > +++ b/drivers/tty/serial/8250/8250_mtk.c
> > @@ -21,12 +21,14 @@
> >  
> >  #include "8250.h"
> >  
> > -#define UART_MTK_HIGHS 0x09/* Highspeed register */
> > -#define UART_MTK_SAMPLE_COUNT  0x0a/* Sample count register */
> > -#define UART_MTK_SAMPLE_POINT  0x0b/* Sample point register */
> > +#define MTK_UART_HIGHS 0x09/* Highspeed register */
> > +#define MTK_UART_SAMPLE_COUNT  0x0a/* Sample count register */
> > +#define MTK_UART_SAMPLE_POINT  0x0b/* Sample point register */
> 
> Rename looks good to me. But I'd prefer to have it in a separate patch.
> 
OK.

> >  #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
> > -
> >  #define MTK_UART_DMA_EN0x13/* DMA Enable register */
> > +#define MTK_UART_RXTRI_AD  0x14/* RX Trigger address */
> > +#define MTK_UART_FRACDIV_L 0x15/* Fractional divider LSB address */
> > +#define MTK_UART_FRACDIV_M 0x16/* Fractional divider MSB address */
> >  #define MTK_UART_DMA_EN_TX 0x2
> >  #define MTK_UART_DMA_EN_RX 0x5
> >  
> > @@ -46,6 +48,7 @@ enum dma_rx_status {
> >  struct mtk8250_data {
> > int line;
> > unsigned intrx_pos;
> > +   unsigned intclk_count;
> 
> What is that for, not used in this patch.
> 
It's for other patch. Sorry, I will remove it.

> > struct clk  *uart_clk;
> > struct clk  *bus_clk;
> > struct uart_8250_dma*dma;
> > @@ -196,9 +199,15 @@ static void mtk8250_shutdown(struct uart_port *port)
> >  mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
> > struct ktermios *old)
> >  {
> > +   unsigned short fraction_L_mapping[] = {
> > +   0, 1, 0x5, 0x15, 0x55, 0x57, 0x57, 0x77, 0x7F, 0xFF, 0xFF
> > +   };
> > +   unsigned short fraction_M_mapping[] = {
> > +   0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3
> > +   };
> > struct uart_8250_port *up = up_to_u8250p(port);
> > +   unsigned int baud, quot, fraction;
> > unsigned long flags;
> > -   unsigned int baud, quot;
> >  
> >  #ifdef CONFIG_SERIAL_8250_DMA
> > if (up->dma) {
> > @@ -214,7 +223,7 @@ static void mtk8250_shutdown(struct uart_port *port)
> > serial8250_do_set_termios(port, termios, old);
> >  
> > /*
> > -* Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS)
> > +* Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS)
> >  *
> >  * We need to recalcualte the quot register, as the claculation depends
> >  * on the vaule in the highspeed register.
> > @@ -230,18 +239,11 @@ static void mtk8250_shutdown(struct uart_port *port)
> >   port->uartclk / 16 / UART_DIV_MAX,
> >   port->uartclk);
> >  
> > -   if (baud <= 115200) {
> > -   serial_port_out(port, UART_MTK_HIGHS, 0x0);
> > +   if (baud < 115200) {
> > +   serial_port_out(port, MTK_UART_HIGHS, 0x0);
> > quot = uart_get_divisor(port, baud);
> > -   } else if (baud <= 576000) {
> > -   serial_port_out(port, UART_MTK_HIGHS, 0x2);
> > -
> > -   /* Set to next lower baudrate supported */
> > -   if ((baud == 50) || (baud == 576000))
> > -   baud = 460800;
> > -   quot = DIV_ROUND_UP(port->uartclk, 4 * baud);
> 
> So we allow now also these baud rates? Then you have to update the comment as 
> well.
> 
Yes.

When clock sour

[PATCH 2/2] serial: 8250-mtk: modify baudrate setting

2019-04-25 Thread Long Cheng
In termios function, add Fractional divider to adjust baudrate.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |  102 
 1 file changed, 102 insertions(+)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index 959fd85..417c7c8 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -25,13 +25,28 @@
 #define MTK_UART_SAMPLE_COUNT  0x0a/* Sample count register */
 #define MTK_UART_SAMPLE_POINT  0x0b/* Sample point register */
 #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
+#define MTK_UART_ESCAPE_DAT0x10/* Escape Character register */
+#define MTK_UART_ESCAPE_EN 0x11/* Escape Enable register */
 #define MTK_UART_DMA_EN0x13/* DMA Enable register */
 #define MTK_UART_RXTRI_AD  0x14/* RX Trigger address */
 #define MTK_UART_FRACDIV_L 0x15/* Fractional divider LSB address */
 #define MTK_UART_FRACDIV_M 0x16/* Fractional divider MSB address */
+#define MTK_UART_IER_XOFFI 0x20/* Enable XOFF character interrupt */
+#define MTK_UART_IER_RTSI  0x40/* Enable RTS Modem status interrupt */
+#define MTK_UART_IER_CTSI  0x80/* Enable CTS Modem status interrupt */
+
+#define MTK_UART_EFR_EN0x10/* Enable enhancement feature */
+#define MTK_UART_EFR_RTS   0x40/* Enable hardware rx flow control */
+#define MTK_UART_EFR_CTS   0x80/* Enable hardware tx flow control */
+#define MTK_UART_EFR_NO_SW_FC  0x0 /* no sw flow control */
+#define MTK_UART_EFR_XON1_XOFF10xa /* XON1/XOFF1 as sw flow 
control */
+#define MTK_UART_EFR_XON2_XOFF20x5 /* XON2/XOFF2 as sw flow 
control */
+#define MTK_UART_EFR_SW_FC_MASK0xf /* Enable CTS Modem status 
interrupt */
+#define MTK_UART_EFR_HW_FC (MTK_UART_EFR_RTS | MTK_UART_EFR_CTS)
 #define MTK_UART_DMA_EN_TX 0x2
 #define MTK_UART_DMA_EN_RX 0x5
 
+#define MTK_UART_ESCAPE_CHAR   0x77/* Escape char added under sw fc */
 #define MTK_UART_TX_SIZE   UART_XMIT_SIZE
 #define MTK_UART_RX_SIZE   0x8000
 #define MTK_UART_TX_TRIGGER1
@@ -57,6 +72,13 @@ struct mtk8250_data {
 #endif
 };
 
+/* flow control mode */
+enum {
+   MTK_UART_FC_NONE,
+   MTK_UART_FC_SW,
+   MTK_UART_FC_HW,
+};
+
 #ifdef CONFIG_SERIAL_8250_DMA
 static void mtk8250_rx_dma(struct uart_8250_port *up);
 
@@ -195,6 +217,75 @@ static void mtk8250_shutdown(struct uart_port *port)
return serial8250_do_shutdown(port);
 }
 
+static void mtk8250_disable_intrs(struct uart_8250_port *up, int mask)
+{
+   serial_out(up, UART_IER, serial_in(up, UART_IER) & (~mask));
+}
+
+static void mtk8250_enable_intrs(struct uart_8250_port *up, int mask)
+{
+   serial_out(up, UART_IER, serial_in(up, UART_IER) | mask);
+}
+
+static void mtk8250_set_flow_ctrl(struct uart_8250_port *up, int mode)
+{
+   struct uart_port *port = >port;
+   int lcr = serial_in(up, UART_LCR);
+
+   serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+   serial_out(up, UART_EFR, UART_EFR_ECB);
+   serial_out(up, UART_LCR, lcr);
+   lcr = serial_in(up, UART_LCR);
+
+   switch (mode) {
+   case MTK_UART_FC_NONE:
+   serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);
+   serial_out(up, MTK_UART_ESCAPE_EN, 0x00);
+   serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+   serial_out(up, UART_EFR, serial_in(up, UART_EFR) &
+   (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK)));
+   serial_out(up, UART_LCR, lcr);
+   mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI |
+   MTK_UART_IER_RTSI | MTK_UART_IER_CTSI);
+   break;
+
+   case MTK_UART_FC_HW:
+   serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);
+   serial_out(up, MTK_UART_ESCAPE_EN, 0x00);
+   serial_out(up, UART_MCR, UART_MCR_RTS);
+   serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+   /*enable hw flow control*/
+   serial_out(up, UART_EFR, MTK_UART_EFR_HW_FC |
+   (serial_in(up, UART_EFR) &
+   (~(MTK_UART_EFR_HW_FC | MTK_UART_EFR_SW_FC_MASK;
+
+   serial_out(up, UART_LCR, lcr);
+   mtk8250_disable_intrs(up, MTK_UART_IER_XOFFI);
+   mtk8250_enable_intrs(up, MTK_UART_IER_CTSI | MTK_UART_IER_RTSI);
+   break;
+
+   case MTK_UART_FC_SW:/*MTK software flow control */
+   serial_out(up, MTK_UART_ESCAPE_DAT, MTK_UART_ESCAPE_CHAR);
+   serial_out(up, MTK_UART_ESCAPE_EN, 0x01);
+   serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+   /*enable sw flow control */
+   serial_out(up, UART_EFR, MTK_UART_EFR_XON1_XOFF1 |
+   (serial_

[PATCH 0/2] Perfect 8250 mtk uart function.

2019-04-25 Thread Long Cheng
Perfect 8250 mtk uart function,
1.Modify baudrate setting
2.Add follow control function

Long Cheng (2):
  serial: 8250-mtk: add follow control
  serial: 8250-mtk: modify baudrate setting

 drivers/tty/serial/8250/8250_mtk.c | 162 +++--
 1 file changed, 139 insertions(+), 23 deletions(-)

-- 
1.9.1



[PATCH 1/2] serial: 8250-mtk: add follow control

2019-04-25 Thread Long Cheng
Add SW and HW follow control function.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |   60 ++--
 1 file changed, 37 insertions(+), 23 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index c1fdbc0..959fd85 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -21,12 +21,14 @@
 
 #include "8250.h"
 
-#define UART_MTK_HIGHS 0x09/* Highspeed register */
-#define UART_MTK_SAMPLE_COUNT  0x0a/* Sample count register */
-#define UART_MTK_SAMPLE_POINT  0x0b/* Sample point register */
+#define MTK_UART_HIGHS 0x09/* Highspeed register */
+#define MTK_UART_SAMPLE_COUNT  0x0a/* Sample count register */
+#define MTK_UART_SAMPLE_POINT  0x0b/* Sample point register */
 #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
-
 #define MTK_UART_DMA_EN0x13/* DMA Enable register */
+#define MTK_UART_RXTRI_AD  0x14/* RX Trigger address */
+#define MTK_UART_FRACDIV_L 0x15/* Fractional divider LSB address */
+#define MTK_UART_FRACDIV_M 0x16/* Fractional divider MSB address */
 #define MTK_UART_DMA_EN_TX 0x2
 #define MTK_UART_DMA_EN_RX 0x5
 
@@ -46,6 +48,7 @@ enum dma_rx_status {
 struct mtk8250_data {
int line;
unsigned intrx_pos;
+   unsigned intclk_count;
struct clk  *uart_clk;
struct clk  *bus_clk;
struct uart_8250_dma*dma;
@@ -196,9 +199,15 @@ static void mtk8250_shutdown(struct uart_port *port)
 mtk8250_set_termios(struct uart_port *port, struct ktermios *termios,
struct ktermios *old)
 {
+   unsigned short fraction_L_mapping[] = {
+   0, 1, 0x5, 0x15, 0x55, 0x57, 0x57, 0x77, 0x7F, 0xFF, 0xFF
+   };
+   unsigned short fraction_M_mapping[] = {
+   0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 3
+   };
struct uart_8250_port *up = up_to_u8250p(port);
+   unsigned int baud, quot, fraction;
unsigned long flags;
-   unsigned int baud, quot;
 
 #ifdef CONFIG_SERIAL_8250_DMA
if (up->dma) {
@@ -214,7 +223,7 @@ static void mtk8250_shutdown(struct uart_port *port)
serial8250_do_set_termios(port, termios, old);
 
/*
-* Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS)
+* Mediatek UARTs use an extra highspeed register (MTK_UART_HIGHS)
 *
 * We need to recalcualte the quot register, as the claculation depends
 * on the vaule in the highspeed register.
@@ -230,18 +239,11 @@ static void mtk8250_shutdown(struct uart_port *port)
  port->uartclk / 16 / UART_DIV_MAX,
  port->uartclk);
 
-   if (baud <= 115200) {
-   serial_port_out(port, UART_MTK_HIGHS, 0x0);
+   if (baud < 115200) {
+   serial_port_out(port, MTK_UART_HIGHS, 0x0);
quot = uart_get_divisor(port, baud);
-   } else if (baud <= 576000) {
-   serial_port_out(port, UART_MTK_HIGHS, 0x2);
-
-   /* Set to next lower baudrate supported */
-   if ((baud == 50) || (baud == 576000))
-   baud = 460800;
-   quot = DIV_ROUND_UP(port->uartclk, 4 * baud);
} else {
-   serial_port_out(port, UART_MTK_HIGHS, 0x3);
+   serial_port_out(port, MTK_UART_HIGHS, 0x3);
quot = DIV_ROUND_UP(port->uartclk, 256 * baud);
}
 
@@ -258,17 +260,29 @@ static void mtk8250_shutdown(struct uart_port *port)
/* reset DLAB */
serial_port_out(port, UART_LCR, up->lcr);
 
-   if (baud > 460800) {
+   if (baud >= 115200) {
unsigned int tmp;
 
-   tmp = DIV_ROUND_CLOSEST(port->uartclk, quot * baud);
-   serial_port_out(port, UART_MTK_SAMPLE_COUNT, tmp - 1);
-   serial_port_out(port, UART_MTK_SAMPLE_POINT,
-   (tmp - 2) >> 1);
+   tmp = (port->uartclk / (baud *  quot)) - 1;
+   serial_port_out(port, MTK_UART_SAMPLE_COUNT, tmp);
+   serial_port_out(port, MTK_UART_SAMPLE_POINT,
+   (tmp >> 1) - 1);
+
+   /*count fraction to set fractoin register */
+   fraction = ((port->uartclk  * 100) / baud / quot) % 100;
+   fraction = DIV_ROUND_CLOSEST(fraction, 10);
+   serial_port_out(port, MTK_UART_FRACDIV_L,
+   fraction_L_mapping[fraction]);
+   serial_port_out(port, MTK_UART_FRACDIV_M,
+   fraction_M_mapping[fraction]);
} else {
-   serial_port_out(port, UART_MTK_SAMPLE_COUNT, 0x

Re: [PATCH v11 1/4] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-04-11 Thread Long Cheng
On Sun, 2019-03-10 at 17:31 -0700, Sean Wang wrote:
> Hi, Long
> 
> List some comments as the below and this week I will find a board to
> test and then improve the driver.
> 
>  Sean
> 
> On Wed, Mar 6, 2019 at 5:45 PM Long Cheng  wrote:
> >
> > In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> > If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> > the performance, can enable the function.
> >
> > Signed-off-by: Long Cheng 
> > ---
> >  drivers/dma/mediatek/Kconfig  |   11 +
> >  drivers/dma/mediatek/Makefile |1 +
> >  drivers/dma/mediatek/mtk-uart-apdma.c |  660 
> > +
> >  3 files changed, 672 insertions(+)
> >  create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c
> >
> > diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
> > index 680fc05..ac49eb6 100644
> > --- a/drivers/dma/mediatek/Kconfig
> > +++ b/drivers/dma/mediatek/Kconfig
> > @@ -24,3 +24,14 @@ config MTK_CQDMA
> >
> >   This controller provides the channels which is dedicated to
> >   memory-to-memory transfer to offload from CPU.
> > +
> > +config MTK_UART_APDMA
> > +   tristate "MediaTek SoCs APDMA support for UART"
> > +   depends on OF && SERIAL_8250_MT6577
> > +   select DMA_ENGINE
> > +   select DMA_VIRTUAL_CHANNELS
> > +   help
> > + Support for the UART DMA engine found on MediaTek MTK SoCs.
> > + When SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
> > + you can enable the config. The DMA engine can only be used
> > + with MediaTek SoCs.
> > diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
> > index 41bb381..61a6d29 100644
> > --- a/drivers/dma/mediatek/Makefile
> > +++ b/drivers/dma/mediatek/Makefile
> > @@ -1,2 +1,3 @@
> > +obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o
> >  obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
> >  obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o
> > diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c 
> > b/drivers/dma/mediatek/mtk-uart-apdma.c
> > new file mode 100644
> > index 000..9ed7a49
> > --- /dev/null
> > +++ b/drivers/dma/mediatek/mtk-uart-apdma.c
> > @@ -0,0 +1,660 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * MediaTek Uart APDMA driver.
> > + *
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Long Cheng 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "../virt-dma.h"
> > +
> > +/* The default number of virtual channel */
> > +#define MTK_UART_APDMA_NR_VCHANS   8
> > +
> > +#define VFF_EN_B   BIT(0)
> > +#define VFF_STOP_B BIT(0)
> > +#define VFF_FLUSH_BBIT(0)
> > +#define VFF_4G_SUPPORT_B   BIT(0)
> > +#define VFF_RX_INT_EN0_B   BIT(0)  /* rx valid size >=  vff thre */
> > +#define VFF_RX_INT_EN1_B   BIT(1)
> > +#define VFF_TX_INT_EN_BBIT(0)  /* tx left size >= vff thre 
> > */
> > +#define VFF_WARM_RST_B BIT(0)
> > +#define VFF_RX_INT_CLR_B   (BIT(0) | BIT(1))
> > +#define VFF_TX_INT_CLR_B   0
> > +#define VFF_STOP_CLR_B 0
> > +#define VFF_INT_EN_CLR_B   0
> > +#define VFF_4G_SUPPORT_CLR_B   0
> > +
> > +/* interrupt trigger level for tx */
> > +#define VFF_TX_THRE(n) ((n) * 7 / 8)
> > +/* interrupt trigger level for rx */
> > +#define VFF_RX_THRE(n) ((n) * 3 / 4)
> > +
> > +#define VFF_RING_SIZE  0xU
> > +/* invert this bit when wrap ring head again */
> > +#define VFF_RING_WRAP  0x1U
> > +
> > +#define VFF_INT_FLAG   0x00
> > +#define VFF_INT_EN 0x04
> > +#define VFF_EN 0x08
> > +#define VFF_RST0x0c
> > +#define VFF_STOP   0x10
> > +#define VFF_FLUSH  0x14
> > +#define VFF_ADDR   0x1c
> > +#define VFF_LEN0x24
> > +#define VFF_THRE   0x28
> > +#define VFF_WPT0x2c
> > +#define VFF_RPT0x30
> > +/* TX: the buffer s

Re: [PATCH v11 1/4] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-04-09 Thread Long Cheng
On Sun, 2019-03-10 at 19:15 +0800, Nicolas Boichat wrote:
> On Thu, Mar 7, 2019 at 9:45 AM Long Cheng  wrote:
> >
> > In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> > If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> > the performance, can enable the function.
> >
> > Signed-off-by: Long Cheng 
> > ---
> >  drivers/dma/mediatek/Kconfig  |   11 +
> >  drivers/dma/mediatek/Makefile |1 +
> >  drivers/dma/mediatek/mtk-uart-apdma.c |  660 
> > +
> >  3 files changed, 672 insertions(+)
> >  create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c
> >
> > diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
> > index 680fc05..ac49eb6 100644
> > --- a/drivers/dma/mediatek/Kconfig
> > +++ b/drivers/dma/mediatek/Kconfig
> > @@ -24,3 +24,14 @@ config MTK_CQDMA
> >
> >   This controller provides the channels which is dedicated to
> >   memory-to-memory transfer to offload from CPU.
> > +
> > +config MTK_UART_APDMA
> > +   tristate "MediaTek SoCs APDMA support for UART"
> > +   depends on OF && SERIAL_8250_MT6577
> > +   select DMA_ENGINE
> > +   select DMA_VIRTUAL_CHANNELS
> > +   help
> > + Support for the UART DMA engine found on MediaTek MTK SoCs.
> > + When SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
> > + you can enable the config. The DMA engine can only be used
> > + with MediaTek SoCs.
> > diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
> > index 41bb381..61a6d29 100644
> > --- a/drivers/dma/mediatek/Makefile
> > +++ b/drivers/dma/mediatek/Makefile
> > @@ -1,2 +1,3 @@
> > +obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o
> >  obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
> >  obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o
> > diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c 
> > b/drivers/dma/mediatek/mtk-uart-apdma.c
> > new file mode 100644
> > index 000..9ed7a49
> > --- /dev/null
> > +++ b/drivers/dma/mediatek/mtk-uart-apdma.c
> > @@ -0,0 +1,660 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * MediaTek Uart APDMA driver.
> > + *
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Long Cheng 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "../virt-dma.h"
> > +
> > +/* The default number of virtual channel */
> > +#define MTK_UART_APDMA_NR_VCHANS   8
> > +
> > +#define VFF_EN_B   BIT(0)
> > +#define VFF_STOP_B BIT(0)
> > +#define VFF_FLUSH_BBIT(0)
> > +#define VFF_4G_SUPPORT_B   BIT(0)
> > +#define VFF_RX_INT_EN0_B   BIT(0)  /* rx valid size >=  vff thre */
> > +#define VFF_RX_INT_EN1_B   BIT(1)
> > +#define VFF_TX_INT_EN_BBIT(0)  /* tx left size >= vff thre 
> > */
> > +#define VFF_WARM_RST_B BIT(0)
> > +#define VFF_RX_INT_CLR_B   (BIT(0) | BIT(1))
> > +#define VFF_TX_INT_CLR_B   0
> > +#define VFF_STOP_CLR_B 0
> > +#define VFF_INT_EN_CLR_B   0
> > +#define VFF_4G_SUPPORT_CLR_B   0
> > +
> > +/* interrupt trigger level for tx */
> > +#define VFF_TX_THRE(n) ((n) * 7 / 8)
> > +/* interrupt trigger level for rx */
> > +#define VFF_RX_THRE(n) ((n) * 3 / 4)
> > +
> > +#define VFF_RING_SIZE  0xU
> 
> Drop the U, it's not very useful (there are a a few more below, grep
> for [0-9a-f]U).
> 

OK, i will fix these.

> > +/* invert this bit when wrap ring head again */
> > +#define VFF_RING_WRAP  0x1U
> > +
> > +#define VFF_INT_FLAG   0x00
> > +#define VFF_INT_EN 0x04
> > +#define VFF_EN 0x08
> > +#define VFF_RST0x0c
> > +#define VFF_STOP   0x10
> > +#define VFF_FLUSH  0x14
> > +#define VFF_ADDR   0x1c
> > +#define VFF_LEN0x24
> > +#define VFF_THRE   0x28
> > +#define VFF_WPT0x2c
> > +#define VFF_RPT0x30
> > +/* TX: the buffer size HW can re

[PATCH v11 1/4] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-03-06 Thread Long Cheng
In DMA engine framework, add 8250 uart dma to support MediaTek uart.
If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
the performance, can enable the function.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 drivers/dma/mediatek/mtk-uart-apdma.c |  660 +
 3 files changed, 672 insertions(+)
 create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c

diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 680fc05..ac49eb6 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -24,3 +24,14 @@ config MTK_CQDMA
 
  This controller provides the channels which is dedicated to
  memory-to-memory transfer to offload from CPU.
+
+config MTK_UART_APDMA
+   tristate "MediaTek SoCs APDMA support for UART"
+   depends on OF && SERIAL_8250_MT6577
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Support for the UART DMA engine found on MediaTek MTK SoCs.
+ When SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
+ you can enable the config. The DMA engine can only be used
+ with MediaTek SoCs.
diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
index 41bb381..61a6d29 100644
--- a/drivers/dma/mediatek/Makefile
+++ b/drivers/dma/mediatek/Makefile
@@ -1,2 +1,3 @@
+obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o
 obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
 obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o
diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c 
b/drivers/dma/mediatek/mtk-uart-apdma.c
new file mode 100644
index 000..9ed7a49
--- /dev/null
+++ b/drivers/dma/mediatek/mtk-uart-apdma.c
@@ -0,0 +1,660 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek Uart APDMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+/* The default number of virtual channel */
+#define MTK_UART_APDMA_NR_VCHANS   8
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /* rx valid size >=  vff thre */
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /* tx left size >= vff thre */
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_CLR_B   (BIT(0) | BIT(1))
+#define VFF_TX_INT_CLR_B   0
+#define VFF_STOP_CLR_B 0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define VFF_RING_SIZE  0xU
+/* invert this bit when wrap ring head again */
+#define VFF_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/* TX: the buffer size HW can read. RX: the buffer size SW can read. */
+#define VFF_VALID_SIZE 0x3c
+/* TX: the buffer size SW can write. RX: the buffer size HW can write. */
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_uart_apdmadev {
+   struct dma_device ddev;
+   struct clk *clk;
+   bool support_33bits;
+   unsigned int dma_requests;
+   unsigned int *dma_irq;
+};
+
+struct mtk_uart_apdma_desc {
+   struct virt_dma_desc vd;
+
+   unsigned int avail_len;
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_uart_apdma_desc *desc;
+
+   enum dma_transfer_direction dir;
+
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+static inline struct mtk_uart_apdmadev *
+to_mtk_uart_apdma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_uart_apdmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_uart_apdma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_uart_apdma_desc *to_mtk_uart_apdma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_uart_apdma_desc, vd.tx);
+}
+
+static void mtk_uart_apdma_write(struct mtk_chan *c,
+  

[PATCH v11 3/4] dt-bindings: dma: uart: rename binding

2019-03-06 Thread Long Cheng
The filename matches mtk-uart-apdma.c.
So using "mtk-uart-apdma.txt" should be better.
And add some property.

Signed-off-by: Long Cheng 
Reviewed-by: Rob Herring  
---
 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 
 .../devicetree/bindings/dma/mtk-uart-apdma.txt |   55 
 2 files changed, 55 insertions(+), 33 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt

diff --git a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt 
b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
deleted file mode 100644
index 3fe0961..000
--- a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-* Mediatek UART APDMA Controller
-
-Required properties:
-- compatible should contain:
-  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
-  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
-
-- reg: The base address of the APDMA register bank.
-
-- interrupts: A single interrupt specifier.
-
-- clocks : Must contain an entry for each entry in clock-names.
-  See ../clocks/clock-bindings.txt for details.
-- clock-names: The APDMA clock for register accesses
-
-Examples:
-
-   apdma: dma-controller@11000380 {
-   compatible = "mediatek,mt2712-uart-dma";
-   reg = <0 0x11000380 0 0x400>;
-   interrupts = ,
-,
-,
-,
-,
-,
-,
-;
-   clocks = < CLK_PERI_AP_DMA>;
-   clock-names = "apdma";
-   #dma-cells = <1>;
-   };
-
diff --git a/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt 
b/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
new file mode 100644
index 000..e0424b3
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
@@ -0,0 +1,55 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+ One interrupt per dma-requests, or 8 if no dma-requests property is present
+
+- dma-requests: The number of DMA channels
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+- mediatek,dma-33bits: Present if the DMA requires support
+
+Examples:
+
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   dma-requests = <12>;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   mediatek,dma-33bits;
+   #dma-cells = <1>;
+   };
+
-- 
1.7.9.5



[PATCH v11 4/4] serial: 8250-mtk: modify uart DMA rx

2019-03-06 Thread Long Cheng
Modify uart rx and complete for DMA.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |   53 
 1 file changed, 23 insertions(+), 30 deletions(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index e2c4076..f9b2fd5 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -30,7 +30,6 @@
 #define MTK_UART_DMA_EN_TX 0x2
 #define MTK_UART_DMA_EN_RX 0x5
 
-#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
 #define MTK_UART_RX_SIZE   0x8000
 #define MTK_UART_TX_TRIGGER1
 #define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
@@ -64,28 +63,30 @@ static void mtk8250_dma_rx_complete(void *param)
struct mtk8250_data *data = up->port.private_data;
struct tty_port *tty_port = >port.state->port;
struct dma_tx_state state;
+   int copied, cnt, tmp;
unsigned char *ptr;
-   int copied;
 
-   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
-   dma->rx_size, DMA_FROM_DEVICE);
+   if (data->rx_status == DMA_RX_SHUTDOWN)
+   return;
 
dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   cnt = dma->rx_size - state.residue;
+   tmp = cnt;
 
-   if (data->rx_status == DMA_RX_SHUTDOWN)
-   return;
+   if ((data->rx_pos + cnt) > dma->rx_size)
+   tmp = dma->rx_size - data->rx_pos;
 
-   if ((data->rx_pos + state.residue) <= dma->rx_size) {
-   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
-   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
-   } else {
-   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
-   copied = tty_insert_flip_string(tty_port, ptr,
-   dma->rx_size - data->rx_pos);
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, tmp);
+   data->rx_pos += tmp;
+
+   if (cnt > tmp) {
ptr = (unsigned char *)(dma->rx_buf);
-   copied += tty_insert_flip_string(tty_port, ptr,
-   data->rx_pos + state.residue - dma->rx_size);
+   tmp = cnt - tmp;
+   copied += tty_insert_flip_string(tty_port, ptr, tmp);
+   data->rx_pos = tmp;
}
+
up->port.icount.rx += copied;
 
tty_flip_buffer_push(tty_port);
@@ -96,9 +97,7 @@ static void mtk8250_dma_rx_complete(void *param)
 static void mtk8250_rx_dma(struct uart_8250_port *up)
 {
struct uart_8250_dma *dma = up->dma;
-   struct mtk8250_data *data = up->port.private_data;
struct dma_async_tx_descriptor  *desc;
-   struct dma_tx_state  state;
 
desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
   dma->rx_size, DMA_DEV_TO_MEM,
@@ -113,12 +112,6 @@ static void mtk8250_rx_dma(struct uart_8250_port *up)
 
dma->rx_cookie = dmaengine_submit(desc);
 
-   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
-   data->rx_pos = state.residue;
-
-   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
-  dma->rx_size, DMA_FROM_DEVICE);
-
dma_async_issue_pending(dma->rxchan);
 }
 
@@ -131,13 +124,13 @@ static void mtk8250_dma_enable(struct uart_8250_port *up)
if (data->rx_status != DMA_RX_START)
return;
 
-   dma->rxconf.direction   = DMA_DEV_TO_MEM;
-   dma->rxconf.src_addr_width  = dma->rx_size / 1024;
-   dma->rxconf.src_addr= dma->rx_addr;
+   dma->rxconf.direction   = DMA_DEV_TO_MEM;
+   dma->rxconf.src_port_window_size= dma->rx_size;
+   dma->rxconf.src_addr= dma->rx_addr;
 
-   dma->txconf.direction   = DMA_MEM_TO_DEV;
-   dma->txconf.dst_addr_width  = MTK_UART_TX_SIZE / 1024;
-   dma->txconf.dst_addr= dma->tx_addr;
+   dma->txconf.direction   = DMA_MEM_TO_DEV;
+   dma->txconf.dst_port_window_size= UART_XMIT_SIZE;
+   dma->txconf.dst_addr= dma->tx_addr;
 
serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
UART_FCR_CLEAR_XMIT);
@@ -217,7 +210,7 @@ static void mtk8250_shutdown(struct uart_port *port)
 * Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS)
 *
 * We need to recalcualte the quot register, as the claculation depends
-* on the vaule in the highspeed register.
+* on the value in the highspeed register.
 *
 * Some baudrates are not supported by the chip, so we use the next
 * lower rate supported and update termios c_flag.
-- 
1.7.9.5



[PATCH v11 2/4] arm: dts: mt2712: add uart APDMA to device tree

2019-03-06 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   51 +
 1 file changed, 51 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index ee627a7..3469a6c 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -298,6 +298,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -346,6 +349,39 @@
 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   dma-requests = <12>;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
auxadc: adc@11001000 {
compatible = "mediatek,mt2712-auxadc";
reg = <0 0x11001000 0 0x1000>;
@@ -362,6 +398,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -372,6 +411,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -382,6 +424,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -392,6 +437,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -402,6 +450,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v11 0/4] add uart DMA function

2019-03-06 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma/mediatek.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v10
-modify DMA tx status function
-modify 8250_mtk for DMA rx
-add notes to binding Document.
Changes compared to v9
-rename dt-bindings file
-remove direction from device_config
-simplified code
Changes compared to v8
-revise missing items
Changes compared to v7:
-modify apdma uart tx
Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (4):
  dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
  arm: dts: mt2712: add uart APDMA to device tree
  dt-bindings: dma: uart: rename binding
  serial: 8250-mtk: modify uart DMA rx

 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 -
 .../devicetree/bindings/dma/mtk-uart-apdma.txt |   55 ++
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi  |   51 ++
 drivers/dma/mediatek/Kconfig   |   11 +
 drivers/dma/mediatek/Makefile  |1 +
 drivers/dma/mediatek/mtk-uart-apdma.c  |  660 
 drivers/tty/serial/8250/8250_mtk.c |   53 +-
 7 files changed, 801 insertions(+), 63 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
 create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c

-- 
1.7.9.5



Re: [PATCH v10 1/3] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-02-13 Thread Long Cheng
On Mon, 2019-02-04 at 12:51 +0530, Vinod Koul wrote:

Hi Vinod sir,

> On 18-01-19, 11:10, Long Cheng wrote:
> > +static enum dma_status mtk_uart_apdma_tx_status(struct dma_chan *chan,
> > +dma_cookie_t cookie,
> > +struct dma_tx_state *txstate)
> > +{
> > +   struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> > +   enum dma_status ret;
> > +   unsigned long flags;
> > +
> > +   if (!txstate)
> > +   return DMA_ERROR;
> 
> Why, it is not a mandatory arg!

Next version, I will remove it.
> 
> > +   ret = dma_cookie_status(chan, cookie, txstate);
> > +   spin_lock_irqsave(>vc.lock, flags);
> > +   if (ret == DMA_IN_PROGRESS) {
> > +   c->rx_status = mtk_uart_apdma_read(c, VFF_RPT) & VFF_RING_SIZE;
> > +   dma_set_residue(txstate, c->rx_status);
> > +   } else if (ret == DMA_COMPLETE && c->dir == DMA_DEV_TO_MEM) {
> > +   dma_set_residue(txstate, c->rx_status);
> 
> what is the point is setting residue to comleted txn, it is zero!
> 
> > +   } else {
> > +   dma_set_residue(txstate, 0);
> 
> naah that doesnt sound correct!
> 
Next version, I will modify the function.

> > +static void mtk_uart_apdma_config_write(struct dma_chan *chan,
> > +  struct dma_slave_config *cfg,
> > +  enum dma_transfer_direction dir)
> > +{
> > +   struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> > +   struct mtk_uart_apdmadev *mtkd =
> > +   to_mtk_uart_apdma_dev(c->vc.chan.device);
> > +   unsigned int tmp;
> > +
> > +   if (mtk_uart_apdma_read(c, VFF_EN) == VFF_EN_B)
> > +   return;
> > +
> > +   c->dir = dir;
> > +
> > +   if (dir == DMA_DEV_TO_MEM) {
> > +   tmp = cfg->src_addr_width * 1024;
> 
> why multiply by 1024?
> 
Next version, I will modify the this, with 'src_port_window_size' &&
'dst_port_window_size'.

> > +static int mtk_uart_apdma_device_pause(struct dma_chan *chan)
> > +{
> > +   /* just for check caps pass */
> > +   return 0;
> > +}
> 
> please remove, this is not a mandatory fn

Can't remove it. Before the mail, i had explained it. in 8250 uart
framework, will check the function..

thanks.



Re: [PATCH v10 1/3] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-01-27 Thread Long Cheng
On Fri, 2019-01-18 at 11:10 +0800, Long Cheng wrote:

Hi Vinod Koul,

Just a gentle ping!

thanks.

> In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> the performance, can enable the function.
> 
> Signed-off-by: Long Cheng 
> ---
>  drivers/dma/mediatek/Kconfig  |   11 +
>  drivers/dma/mediatek/Makefile |1 +
>  drivers/dma/mediatek/mtk-uart-apdma.c |  669 
> +
>  3 files changed, 681 insertions(+)
>  create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c
> 
> diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
> index 680fc05..ac49eb6 100644
> --- a/drivers/dma/mediatek/Kconfig
> +++ b/drivers/dma/mediatek/Kconfig
> @@ -24,3 +24,14 @@ config MTK_CQDMA
>  
> This controller provides the channels which is dedicated to
> memory-to-memory transfer to offload from CPU.
> +
> +config MTK_UART_APDMA
> + tristate "MediaTek SoCs APDMA support for UART"
> + depends on OF && SERIAL_8250_MT6577
> + select DMA_ENGINE
> + select DMA_VIRTUAL_CHANNELS
> + help
> +   Support for the UART DMA engine found on MediaTek MTK SoCs.
> +   When SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
> +   you can enable the config. The DMA engine can only be used
> +   with MediaTek SoCs.
> diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
> index 41bb381..61a6d29 100644
> --- a/drivers/dma/mediatek/Makefile
> +++ b/drivers/dma/mediatek/Makefile
> @@ -1,2 +1,3 @@
> +obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o
>  obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
>  obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o
> diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c 
> b/drivers/dma/mediatek/mtk-uart-apdma.c
> new file mode 100644
> index 000..427db69
> --- /dev/null
> +++ b/drivers/dma/mediatek/mtk-uart-apdma.c
> @@ -0,0 +1,669 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * MediaTek Uart APDMA driver.
> + *
> + * Copyright (c) 2018 MediaTek Inc.
> + * Author: Long Cheng 
> + */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include "../virt-dma.h"
> +
> +/* The default number of virtual channel */
> +#define MTK_UART_APDMA_NR_VCHANS 8
> +
> +#define VFF_EN_B BIT(0)
> +#define VFF_STOP_B   BIT(0)
> +#define VFF_FLUSH_B  BIT(0)
> +#define VFF_4G_SUPPORT_B BIT(0)
> +#define VFF_RX_INT_EN0_B BIT(0)  /* rx valid size >=  vff thre */
> +#define VFF_RX_INT_EN1_B BIT(1)
> +#define VFF_TX_INT_EN_B  BIT(0)  /* tx left size >= vff thre */
> +#define VFF_WARM_RST_B   BIT(0)
> +#define VFF_RX_INT_CLR_B (BIT(0) | BIT(1))
> +#define VFF_TX_INT_CLR_B 0
> +#define VFF_STOP_CLR_B   0
> +#define VFF_INT_EN_CLR_B 0
> +#define VFF_4G_SUPPORT_CLR_B 0
> +
> +/* interrupt trigger level for tx */
> +#define VFF_TX_THRE(n)   ((n) * 7 / 8)
> +/* interrupt trigger level for rx */
> +#define VFF_RX_THRE(n)   ((n) * 3 / 4)
> +
> +#define VFF_RING_SIZE0xU
> +/* invert this bit when wrap ring head again */
> +#define VFF_RING_WRAP0x1U
> +
> +#define VFF_INT_FLAG 0x00
> +#define VFF_INT_EN   0x04
> +#define VFF_EN   0x08
> +#define VFF_RST  0x0c
> +#define VFF_STOP 0x10
> +#define VFF_FLUSH0x14
> +#define VFF_ADDR 0x1c
> +#define VFF_LEN  0x24
> +#define VFF_THRE 0x28
> +#define VFF_WPT  0x2c
> +#define VFF_RPT  0x30
> +/* TX: the buffer size HW can read. RX: the buffer size SW can read. */
> +#define VFF_VALID_SIZE   0x3c
> +/* TX: the buffer size SW can write. RX: the buffer size HW can write. */
> +#define VFF_LEFT_SIZE0x40
> +#define VFF_DEBUG_STATUS 0x50
> +#define VFF_4G_SUPPORT   0x54
> +
> +struct mtk_uart_apdmadev {
> + struct dma_device ddev;
> + struct clk *clk;
> + bool support_33bits;
> + unsigned int dma_requests;
> + unsigned int *dma_irq;
> +};
> +
> +struct mtk_uart_apdma_desc {
> + struct virt_dma_desc vd;
> +
> + unsigned int avail_len;
> +};
> +
> +struct mtk_chan {
> + struct virt_dma_chan vc;
> + struct dma_slave_config

Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-01-21 Thread Long Cheng
On Sun, 2019-01-20 at 10:57 +0530, Vinod Koul wrote:
> On 10-01-19, 18:33, Long Cheng wrote:
> > On Fri, 2019-01-04 at 22:49 +0530, Vinod Koul wrote:
> > > On 02-01-19, 10:12, Long Cheng wrote:
> > > > In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> > > > If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> > > > the performance, can enable the function.
> > > 
> > > Is the DMA controller UART specific, can it work with other controllers
> > > as well, if so you should get rid of uart name in patch
> > 
> > I don't know that it can work or not on other controller. but it's for
> > MediaTek SOC
> 
> What I meant was that if can work with other controllers (users) apart
> from UART, how about say audio, spi etc!!
> 

it's just for UART APDMA. can't work on spi ...

> > 
> > > > +#define MTK_UART_APDMA_CHANNELS
> > > > (CONFIG_SERIAL_8250_NR_UARTS * 2)
> > > 
> > > Why are the channels not coming from DT?
> > > 
> > 
> > i will using dma-requests install of it.
> > 
> > > > +
> > > > +#define VFF_EN_B   BIT(0)
> > > > +#define VFF_STOP_B BIT(0)
> > > > +#define VFF_FLUSH_BBIT(0)
> > > > +#define VFF_4G_SUPPORT_B   BIT(0)
> > > > +#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
> > > > +#define VFF_RX_INT_EN1_B   BIT(1)
> > > > +#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff 
> > > > thre*/
> > > 
> > > space around /* space */ also run checkpatch to check for style errors
> > > 
> > 
> > ok.
> > 
> > > > +static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
> > > > +{
> > > > +   unsigned int len, send, left, wpt, d_wpt, tmp;
> > > > +   int ret;
> > > > +
> > > > +   left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE);
> > > > +   if (!left) {
> > > > +   mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> > > > +   return;
> > > > +   }
> > > > +
> > > > +   /* Wait 1sec for flush,  can't sleep*/
> > > > +   ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
> > > > +   tmp != VFF_FLUSH_B, 0, 100);
> > > > +   if (ret)
> > > > +   dev_warn(c->vc.chan.device->dev, "tx: fail, 
> > > > debug=0x%x\n",
> > > > +   mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
> > > > +
> > > > +   send = min_t(unsigned int, left, c->desc->avail_len);
> > > > +   wpt = mtk_uart_apdma_read(c, VFF_WPT);
> > > > +   len = mtk_uart_apdma_read(c, VFF_LEN);
> > > > +
> > > > +   d_wpt = wpt + send;
> > > > +   if ((d_wpt & VFF_RING_SIZE) >= len) {
> > > > +   d_wpt = d_wpt - len;
> > > > +   d_wpt = d_wpt ^ VFF_RING_WRAP;
> > > > +   }
> > > > +   mtk_uart_apdma_write(c, VFF_WPT, d_wpt);
> > > > +
> > > > +   c->desc->avail_len -= send;
> > > > +
> > > > +   mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> > > > +   if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U)
> > > > +   mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B);
> > > > +}
> > > > +
> > > > +static void mtk_uart_apdma_start_rx(struct mtk_chan *c)
> > > > +{
> > > > +   struct mtk_uart_apdma_desc *d = c->desc;
> > > > +   unsigned int len, wg, rg, cnt;
> > > > +
> > > > +   if ((mtk_uart_apdma_read(c, VFF_VALID_SIZE) == 0U) ||
> > > > +   !d || !vchan_next_desc(>vc))
> > > > +   return;
> > > > +
> > > > +   len = mtk_uart_apdma_read(c, VFF_LEN);
> > > > +   rg = mtk_uart_apdma_read(c, VFF_RPT);
> > > > +   wg = mtk_uart_apdma_read(c, VFF_WPT);
> > > > +   if ((rg ^ wg) & VFF_RING_WRAP)
> > > > +   cnt = (wg & VFF_RING_SIZE) + len - (rg & VFF_RING_SIZE);
> > > > +   else
> > > > +   cnt = (wg & VFF_RING_SIZE) - (rg & VFF_RING_SIZE);
> > > > +
> > > > +   c->rx_status = cnt;
> > > > +   mt

[PATCH v10 1/3] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-01-17 Thread Long Cheng
In DMA engine framework, add 8250 uart dma to support MediaTek uart.
If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
the performance, can enable the function.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 drivers/dma/mediatek/mtk-uart-apdma.c |  669 +
 3 files changed, 681 insertions(+)
 create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c

diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
index 680fc05..ac49eb6 100644
--- a/drivers/dma/mediatek/Kconfig
+++ b/drivers/dma/mediatek/Kconfig
@@ -24,3 +24,14 @@ config MTK_CQDMA
 
  This controller provides the channels which is dedicated to
  memory-to-memory transfer to offload from CPU.
+
+config MTK_UART_APDMA
+   tristate "MediaTek SoCs APDMA support for UART"
+   depends on OF && SERIAL_8250_MT6577
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Support for the UART DMA engine found on MediaTek MTK SoCs.
+ When SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
+ you can enable the config. The DMA engine can only be used
+ with MediaTek SoCs.
diff --git a/drivers/dma/mediatek/Makefile b/drivers/dma/mediatek/Makefile
index 41bb381..61a6d29 100644
--- a/drivers/dma/mediatek/Makefile
+++ b/drivers/dma/mediatek/Makefile
@@ -1,2 +1,3 @@
+obj-$(CONFIG_MTK_UART_APDMA) += mtk-uart-apdma.o
 obj-$(CONFIG_MTK_HSDMA) += mtk-hsdma.o
 obj-$(CONFIG_MTK_CQDMA) += mtk-cqdma.o
diff --git a/drivers/dma/mediatek/mtk-uart-apdma.c 
b/drivers/dma/mediatek/mtk-uart-apdma.c
new file mode 100644
index 000..427db69
--- /dev/null
+++ b/drivers/dma/mediatek/mtk-uart-apdma.c
@@ -0,0 +1,669 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek Uart APDMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+/* The default number of virtual channel */
+#define MTK_UART_APDMA_NR_VCHANS   8
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /* rx valid size >=  vff thre */
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /* tx left size >= vff thre */
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_CLR_B   (BIT(0) | BIT(1))
+#define VFF_TX_INT_CLR_B   0
+#define VFF_STOP_CLR_B 0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define VFF_RING_SIZE  0xU
+/* invert this bit when wrap ring head again */
+#define VFF_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/* TX: the buffer size HW can read. RX: the buffer size SW can read. */
+#define VFF_VALID_SIZE 0x3c
+/* TX: the buffer size SW can write. RX: the buffer size HW can write. */
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_uart_apdmadev {
+   struct dma_device ddev;
+   struct clk *clk;
+   bool support_33bits;
+   unsigned int dma_requests;
+   unsigned int *dma_irq;
+};
+
+struct mtk_uart_apdma_desc {
+   struct virt_dma_desc vd;
+
+   unsigned int avail_len;
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_uart_apdma_desc *desc;
+
+   enum dma_transfer_direction dir;
+
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+static inline struct mtk_uart_apdmadev *
+to_mtk_uart_apdma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_uart_apdmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_uart_apdma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_uart_apdma_desc *to_mtk_uart_apdma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_uart_apdma_desc, vd.tx);
+}
+
+static void mtk_uart_apdma_write(struct mtk_chan *c,
+  

[PATCH v10 2/3] arm: dts: mt2712: add uart APDMA to device tree

2019-01-17 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   51 +
 1 file changed, 51 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index ee627a7..3469a6c 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -298,6 +298,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -346,6 +349,39 @@
 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   dma-requests = <12>;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
auxadc: adc@11001000 {
compatible = "mediatek,mt2712-auxadc";
reg = <0 0x11001000 0 0x1000>;
@@ -362,6 +398,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -372,6 +411,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -382,6 +424,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -392,6 +437,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -402,6 +450,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v10 0/3] add uart DMA function

2019-01-17 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma/mediatek.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v9
-rename dt-bindings file
-remove direction from device_config
-simplified code
Changes compared to v8
-revise missing items
Changes compared to v7:
-modify apdma uart tx
Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (3):
  dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
  arm: dts: mt2712: add uart APDMA to device tree
  dt-bindings: dma: uart: rename binding

 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 -
 .../devicetree/bindings/dma/mtk-uart-apdma.txt |   33 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi  |   51 ++
 drivers/dma/mediatek/Kconfig   |   11 +
 drivers/dma/mediatek/Makefile  |1 +
 drivers/dma/mediatek/mtk-uart-apdma.c  |  669 
 6 files changed, 765 insertions(+), 33 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
 create mode 100644 drivers/dma/mediatek/mtk-uart-apdma.c

-- 
1.7.9.5



[PATCH v10 3/3] dt-bindings: dma: uart: rename binding

2019-01-17 Thread Long Cheng
The filename matches mtk-uart-apdma.c.
So using "mtk-uart-apdma.txt" should be better.

Signed-off-by: Long Cheng 
---
 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 
 .../devicetree/bindings/dma/mtk-uart-apdma.txt |   33 
 2 files changed, 33 insertions(+), 33 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt

diff --git a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt 
b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
deleted file mode 100644
index 3fe0961..000
--- a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
+++ /dev/null
@@ -1,33 +0,0 @@
-* Mediatek UART APDMA Controller
-
-Required properties:
-- compatible should contain:
-  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
-  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
-
-- reg: The base address of the APDMA register bank.
-
-- interrupts: A single interrupt specifier.
-
-- clocks : Must contain an entry for each entry in clock-names.
-  See ../clocks/clock-bindings.txt for details.
-- clock-names: The APDMA clock for register accesses
-
-Examples:
-
-   apdma: dma-controller@11000380 {
-   compatible = "mediatek,mt2712-uart-dma";
-   reg = <0 0x11000380 0 0x400>;
-   interrupts = ,
-,
-,
-,
-,
-,
-,
-;
-   clocks = < CLK_PERI_AP_DMA>;
-   clock-names = "apdma";
-   #dma-cells = <1>;
-   };
-
diff --git a/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt 
b/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
new file mode 100644
index 000..3fe0961
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mtk-uart-apdma.txt
@@ -0,0 +1,33 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+Examples:
+
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2712-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
-- 
1.7.9.5



Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-01-10 Thread Long Cheng
On Thu, 2019-01-10 at 18:33 +0800, Long Cheng wrote:
fix spell error

> On Fri, 2019-01-04 at 22:49 +0530, Vinod Koul wrote:
> > On 02-01-19, 10:12, Long Cheng wrote:
> > > In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> > > If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> > > the performance, can enable the function.
> > 
> > Is the DMA controller UART specific, can it work with other controllers
> > as well, if so you should get rid of uart name in patch
> > 
> 
> I don't know that it can work or not on other controller. but it's for
> MediaTek SOC
> 
> > > +#define MTK_UART_APDMA_CHANNELS  (CONFIG_SERIAL_8250_NR_UARTS * 
> > > 2)
> > 
> > Why are the channels not coming from DT?
> > 
> 
> i will using dma-requests install of it.
> 
i will using 'dma-requests' instead of it.

> > > +
> > > +#define VFF_EN_B BIT(0)
> > > +#define VFF_STOP_B   BIT(0)
> > > +#define VFF_FLUSH_B  BIT(0)
> > > +#define VFF_4G_SUPPORT_B BIT(0)
> > > +#define VFF_RX_INT_EN0_B BIT(0)  /*rx valid size >=  vff thre*/
> > > +#define VFF_RX_INT_EN1_B BIT(1)
> > > +#define VFF_TX_INT_EN_B  BIT(0)  /*tx left size >= vff thre*/
> > 
> > space around /* space */ also run checkpatch to check for style errors
> > 
> 
> ok.
> 
> > > +static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
> > > +{
> > > + unsigned int len, send, left, wpt, d_wpt, tmp;
> > > + int ret;
> > > +
> > > + left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE);
> > > + if (!left) {
> > > + mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> > > + return;
> > > + }
> > > +
> > > + /* Wait 1sec for flush,  can't sleep*/
> > > + ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
> > > + tmp != VFF_FLUSH_B, 0, 100);
> > > + if (ret)
> > > + dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n",
> > > + mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
> > > +
> > > + send = min_t(unsigned int, left, c->desc->avail_len);
> > > + wpt = mtk_uart_apdma_read(c, VFF_WPT);
> > > + len = mtk_uart_apdma_read(c, VFF_LEN);
> > > +
> > > + d_wpt = wpt + send;
> > > + if ((d_wpt & VFF_RING_SIZE) >= len) {
> > > + d_wpt = d_wpt - len;
> > > + d_wpt = d_wpt ^ VFF_RING_WRAP;
> > > + }
> > > + mtk_uart_apdma_write(c, VFF_WPT, d_wpt);
> > > +
> > > + c->desc->avail_len -= send;
> > > +
> > > + mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> > > + if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U)
> > > + mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B);
> > > +}
> > > +
> > > +static void mtk_uart_apdma_start_rx(struct mtk_chan *c)
> > > +{
> > > + struct mtk_uart_apdma_desc *d = c->desc;
> > > + unsigned int len, wg, rg, cnt;
> > > +
> > > + if ((mtk_uart_apdma_read(c, VFF_VALID_SIZE) == 0U) ||
> > > + !d || !vchan_next_desc(>vc))
> > > + return;
> > > +
> > > + len = mtk_uart_apdma_read(c, VFF_LEN);
> > > + rg = mtk_uart_apdma_read(c, VFF_RPT);
> > > + wg = mtk_uart_apdma_read(c, VFF_WPT);
> > > + if ((rg ^ wg) & VFF_RING_WRAP)
> > > + cnt = (wg & VFF_RING_SIZE) + len - (rg & VFF_RING_SIZE);
> > > + else
> > > + cnt = (wg & VFF_RING_SIZE) - (rg & VFF_RING_SIZE);
> > > +
> > > + c->rx_status = cnt;
> > > + mtk_uart_apdma_write(c, VFF_RPT, wg);
> > > +
> > > + list_del(>vd.node);
> > > + vchan_cookie_complete(>vd);
> > > +}
> > 
> > this looks odd, why do you have different rx and tx start routines?
> > 
> 
> Would you like explain it in more detail? thanks.
> In tx function, will wait the last data flush done. and the count the
> size that send.
> In Rx function, will count the size that receive.
> Any way, in rx / tx, need andle WPT or RPT.
> 
Any way, in rx / tx, need handle WPT or RPT.

> > > +static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan)
> > > +{
> > > + struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device);
> > > + struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> > > + u32 tmp;
> > > + int ret;
> > > +
> > > 

Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-01-10 Thread Long Cheng
On Fri, 2019-01-04 at 22:49 +0530, Vinod Koul wrote:
> On 02-01-19, 10:12, Long Cheng wrote:
> > In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> > If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> > the performance, can enable the function.
> 
> Is the DMA controller UART specific, can it work with other controllers
> as well, if so you should get rid of uart name in patch
> 

I don't know that it can work or not on other controller. but it's for
MediaTek SOC

> > +#define MTK_UART_APDMA_CHANNELS(CONFIG_SERIAL_8250_NR_UARTS * 
> > 2)
> 
> Why are the channels not coming from DT?
> 

i will using dma-requests install of it.

> > +
> > +#define VFF_EN_B   BIT(0)
> > +#define VFF_STOP_B BIT(0)
> > +#define VFF_FLUSH_BBIT(0)
> > +#define VFF_4G_SUPPORT_B   BIT(0)
> > +#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
> > +#define VFF_RX_INT_EN1_B   BIT(1)
> > +#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
> 
> space around /* space */ also run checkpatch to check for style errors
> 

ok.

> > +static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
> > +{
> > +   unsigned int len, send, left, wpt, d_wpt, tmp;
> > +   int ret;
> > +
> > +   left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE);
> > +   if (!left) {
> > +   mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> > +   return;
> > +   }
> > +
> > +   /* Wait 1sec for flush,  can't sleep*/
> > +   ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
> > +   tmp != VFF_FLUSH_B, 0, 100);
> > +   if (ret)
> > +   dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n",
> > +   mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
> > +
> > +   send = min_t(unsigned int, left, c->desc->avail_len);
> > +   wpt = mtk_uart_apdma_read(c, VFF_WPT);
> > +   len = mtk_uart_apdma_read(c, VFF_LEN);
> > +
> > +   d_wpt = wpt + send;
> > +   if ((d_wpt & VFF_RING_SIZE) >= len) {
> > +   d_wpt = d_wpt - len;
> > +   d_wpt = d_wpt ^ VFF_RING_WRAP;
> > +   }
> > +   mtk_uart_apdma_write(c, VFF_WPT, d_wpt);
> > +
> > +   c->desc->avail_len -= send;
> > +
> > +   mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> > +   if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U)
> > +   mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B);
> > +}
> > +
> > +static void mtk_uart_apdma_start_rx(struct mtk_chan *c)
> > +{
> > +   struct mtk_uart_apdma_desc *d = c->desc;
> > +   unsigned int len, wg, rg, cnt;
> > +
> > +   if ((mtk_uart_apdma_read(c, VFF_VALID_SIZE) == 0U) ||
> > +   !d || !vchan_next_desc(>vc))
> > +   return;
> > +
> > +   len = mtk_uart_apdma_read(c, VFF_LEN);
> > +   rg = mtk_uart_apdma_read(c, VFF_RPT);
> > +   wg = mtk_uart_apdma_read(c, VFF_WPT);
> > +   if ((rg ^ wg) & VFF_RING_WRAP)
> > +   cnt = (wg & VFF_RING_SIZE) + len - (rg & VFF_RING_SIZE);
> > +   else
> > +   cnt = (wg & VFF_RING_SIZE) - (rg & VFF_RING_SIZE);
> > +
> > +   c->rx_status = cnt;
> > +   mtk_uart_apdma_write(c, VFF_RPT, wg);
> > +
> > +   list_del(>vd.node);
> > +   vchan_cookie_complete(>vd);
> > +}
> 
> this looks odd, why do you have different rx and tx start routines?
> 

Would you like explain it in more detail? thanks.
In tx function, will wait the last data flush done. and the count the
size that send.
In Rx function, will count the size that receive.
Any way, in rx / tx, need andle WPT or RPT.

> > +static int mtk_uart_apdma_alloc_chan_resources(struct dma_chan *chan)
> > +{
> > +   struct mtk_uart_apdmadev *mtkd = to_mtk_uart_apdma_dev(chan->device);
> > +   struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
> > +   u32 tmp;
> > +   int ret;
> > +
> > +   pm_runtime_get_sync(mtkd->ddev.dev);
> > +
> > +   mtk_uart_apdma_write(c, VFF_ADDR, 0);
> > +   mtk_uart_apdma_write(c, VFF_THRE, 0);
> > +   mtk_uart_apdma_write(c, VFF_LEN, 0);
> > +   mtk_uart_apdma_write(c, VFF_RST, VFF_WARM_RST_B);
> > +
> > +   ret = readx_poll_timeout(readl, c->base + VFF_EN, tmp,
> > +   tmp == 0, 10, 100);
> > +   if (ret) {
> > +   dev_err(chan->device->dev, "dma reset: fail, timeout\n");
> > +   return ret;
> > +   

Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-01-10 Thread Long Cheng
On Wed, 2019-01-02 at 18:03 -0800, Randy Dunlap wrote:
> Hi,
> 
> While you are making changes, here are a few more:
> 

hi

OK, thanks for your comments.

> 
> On 1/2/19 5:39 PM, Nicolas Boichat wrote:
> > diff --git a/drivers/dma/mediatek/Kconfig b/drivers/dma/mediatek/Kconfig
> > index 27bac0b..1a523c87 100644
> > --- a/drivers/dma/mediatek/Kconfig
> > +++ b/drivers/dma/mediatek/Kconfig
> > @@ -1,4 +1,15 @@
> > 
> > +config DMA_MTK_UART
> > +   tristate "MediaTek SoCs APDMA support for UART"
> > +   depends on OF && SERIAL_8250_MT6577
> > +   select DMA_ENGINE
> > +   select DMA_VIRTUAL_CHANNELS
> > +   help
> > + Support for the UART DMA engine found on MediaTek MTK SoCs.
> > + when SERIAL_8250_MT6577 is enabled, and if you want to use DMA,
> 
>   When
> 
> > + you can enable the config. the DMA engine can only be used
> 
>  The
> 
> > + with MediaTek SoCs.
> > +
> 

above, i will modify.

> Also, use tabs to indent instead of spaces.
> The lines (tristate, depends, select, and help) should be indented with one 
> tab.
> The help text lines should be indented with one tab + 2 spaces.
> 

in my patch, i already do this. So don't need modify.

> >  config MTK_HSDMA
> > tristate "MediaTek High-Speed DMA controller support"
> > depends on ARCH_MEDIATEK || COMPILE_TEST
> 
> 
> thanks,




Re: [PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-01-10 Thread Long Cheng
On Thu, 2019-01-03 at 09:39 +0800, Nicolas Boichat wrote:
> On Wed, Jan 2, 2019 at 10:13 AM Long Cheng  wrote:
> >

.

> > +/* interrupt trigger level for tx */
> > +#define VFF_TX_THRE(n) ((n) * 7 / 8)
> > +/* interrupt trigger level for rx */
> > +#define VFF_RX_THRE(n) ((n) * 3 / 4)
> > +
> > +#define VFF_RING_SIZE  0xU
> 
> Well, the size is actually 0x1. Maybe call this VFF_RING_SIZE_MASK?
> 

the max length is 0x.  the bit 16 is wrap bit. our buffer is ring
buffer. So not mask.

> > +/* invert this bit when wrap ring head again*/
> > +#define VFF_RING_WRAP  0x1U
> > +
> > +   writel(val, c->base + reg);
> > +}
> > +

..

> > +static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
> > +{
> > +   unsigned int len, send, left, wpt, d_wpt, tmp;
> > +   int ret;
> > +
> > +   left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE);
> > +   if (!left) {
> > +   mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> > +   return;
> > +   }
> > +
> > +   /* Wait 1sec for flush,  can't sleep*/
> 
> nit: one space after ',', period after 'sleep', space before '*'.
> 
> > +   ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
> > +   tmp != VFF_FLUSH_B, 0, 100);
> > +   if (ret)
> > +   dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n",
> > +   mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
> 
> Why do we need to wait for flush now? The previous implementation did
> not require this...
> 

because our HW buffer is cyclic. at one tx, if the size of data is
bigger, data maybe cover. So must wait flush finish. confirm the data is
right. like 128 bytes size, small length can't reproduce the issue.

> > +
> > +   send = min_t(unsigned int, left, c->desc->avail_len);
> > +   wpt = mtk_uart_apdma_read(c, VFF_WPT);
> > +   len = mtk_uart_apdma_read(c, VFF_LEN);
> > +
> > +   d_wpt = wpt + send;
> > +   if ((d_wpt & VFF_RING_SIZE) >= len) {
> 
> I don't get why you need to add "& VFF_RING_SIZE". If wpt + send >
> VFF_RING_SIZE, don't you need to toggle VFF_RING_WRAP too?

the longest actual length is VFF_RING_SIZE. one cyclic, will set bit[16]
to ~bit[16]. the bit[0 ~ 15] is actual address. So need get rid of
bit[16]

> 
> > +   d_wpt = d_wpt - len;
> > +   d_wpt = d_wpt ^ VFF_RING_WRAP;
> > +   }
> > +   mtk_uart_apdma_write(c, VFF_WPT, d_wpt);
> > +
> > +   c->desc->avail_len -= send;
> > +
> > +   mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
> > +   if (mtk_uart_apdma_read(c, VFF_FLUSH) == 0U)
> > +   mtk_uart_apdma_write(c, VFF_FLUSH, VFF_FLUSH_B);
> > +}
> 
> (thanks for the rest of the changes, this looks much more readable)
> 
> > +
..

> > +
> > +static int mtk_uart_apdma_device_pause(struct dma_chan *chan)
> > +{
> > +   /* just for check caps pass */
> > +   return 0;
> > +}
> 
> This is still not right... Hopefully somebody more familiar with the
> DMA subsystem can weigh in, but maybe it's enough to wait for the
> current transfer to be flushed and temporarily disable interrupts?
> e.g. call mtk_uart_apdma_terminate_all above?
> 

i had review the 8250 UART framework. just check the function pointer,
not use. and our HW can't support the feature. So i just keep it at
first version.

> > +
> > +static int mtk_uart_apdma_device_resume(struct dma_chan *chan)
> > +{
> > +   /* just for check caps pass */
> > +   return 0;
> > +}
> 
> Drop this one since you don't really need it.
> 

ok, i will remove it.

> > +
> > +static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd)
> > +{
> > +   while (list_empty(>ddev.channels) == 0) {
> 
> !list_empty(
> 
> > +   struct mtk_chan *c = list_first_entry(>ddev.channels,
> > +   struct mtk_chan, vc.chan.device_node);
> > +
> > +   list_del(>vc.chan.device_node);
> > +   tasklet_kill(>vc.task);
> > +   }
> > +}
> > +
> > +static const struct of_device_id mtk_uart_apdma_match[] = {
> > +   { .compatible = "mediatek,mt6577-uart-dma", },
> > +   { /* sentinel */ },
> > +};
> > +MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match);
> > +
> > +static int mtk_uart_apdma_probe(struct platform_device *pdev)
> &

[PATCH v9 2/2] arm: dts: mt2712: add uart APDMA to device tree

2019-01-01 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..be1a22a 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -369,6 +372,38 @@
 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
auxadc: adc@11001000 {
compatible = "mediatek,mt2712-auxadc";
reg = <0 0x11001000 0 0x1000>;
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v9 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2019-01-01 Thread Long Cheng
In DMA engine framework, add 8250 uart dma to support MediaTek uart.
If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
the performance, can enable the function.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  652 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 664 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..dbf811e
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,652 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_UART_APDMA_CHANNELS(CONFIG_SERIAL_8250_NR_UARTS * 
2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define VFF_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define VFF_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_uart_apdmadev {
+   struct dma_device ddev;
+   struct clk *clk;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_UART_APDMA_CHANNELS];
+};
+
+struct mtk_uart_apdma_desc {
+   struct virt_dma_desc vd;
+
+   unsigned int avail_len;
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_uart_apdma_desc *desc;
+
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+static inline struct mtk_uart_apdmadev *
+to_mtk_uart_apdma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_uart_apdmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_uart_apdma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_uart_apdma_desc *to_mtk_uart_apdma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_uart_apdma_desc, vd.tx);
+}
+
+static void mtk_uart_apdma_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int mtk_uart_apdma_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+
+   kfree(c->desc);
+}
+
+static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
+{
+   unsigned int len, send, left, wpt, d_wpt, tmp;
+   int ret;
+
+   left = mtk_uart_apdma_read(c, VFF_LEFT_SIZE);
+   if (!left) {
+   mtk_uart_apdma_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+   return;
+   }
+
+   /* Wait 1sec for flush,  can't sleep*/
+   ret = readx_poll_timeout(readl, c->base + VFF_FLUSH, tmp,
+   tmp != VFF_FLUSH_B, 0, 100);
+   if (ret)
+   dev_warn(c->vc.chan.device->dev, "tx: fail, debug=0x%x\n",
+   mtk_uart_apdma_read(c, VFF_DEBUG_STATUS));
+
+   send = min_t(unsigned int, left, c->desc->avail_len);
+   wpt = mtk_uart_apdma_read(c, VFF_WPT);
+   l

[PATCH v9 0/2] add uart DMA function

2019-01-01 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v8
-revise missing items
Changes compared to v7:
-modify apdma uart tx
Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation



[PATCH v8 0/2] add uart DMA function

2018-12-29 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v7:
-modify apdma uart tx
Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation


Long Cheng (2):
  dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
  arm: dts: mt2712: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +++
 drivers/dma/mediatek/8250_mtk_dma.c   |  694 +
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 4 files changed, 756 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5



[PATCH v8 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2018-12-29 Thread Long Cheng
In DMA engine framework, add 8250 uart dma to support MediaTek uart.
If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
the performance, can enable the function.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  694 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 706 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..c4090f2
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,694 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_UART_APDMA_CHANNELS(CONFIG_SERIAL_8250_NR_UARTS * 
2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_UART_APDMA_RING_SIZE   0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_UART_APDMA_RING_WRAP   0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_uart_apdmadev {
+   struct dma_device ddev;
+   struct clk *clk;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_UART_APDMA_CHANNELS];
+};
+
+struct mtk_uart_apdma_desc {
+   struct virt_dma_desc vd;
+
+   unsigned int avail_len;
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_uart_apdma_desc *desc;
+
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+static inline struct mtk_uart_apdmadev *
+to_mtk_uart_apdma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_uart_apdmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_uart_apdma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_uart_apdma_desc *to_mtk_uart_apdma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_uart_apdma_desc, vd.tx);
+}
+
+static void mtk_uart_apdma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int
+mtk_uart_apdma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
+{
+   unsigned int txcount = c->desc->avail_len;
+   unsigned int len, send, left, wpt, wrap;
+
+   if (mtk_uart_apdma_chan_read(c, VFF_LEFT_SIZE) == 0U) {
+   mtk_uart_apdma_chan_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+   } else {
+   len = mtk_uart_apdma_chan_read(c, VFF_LEN);
+
+   while (((left = mtk_uart_apdma_chan_read(c,
+   VFF_LEFT_SIZE)) > 0U)
+   && (c->desc->avail_len != 0U)) {
+   send = min_t(unsigned int, left, c->desc->avail_le

[PATCH v8 2/2] arm: dts: mt2712: add uart APDMA to device tree

2018-12-29 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..be1a22a 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -369,6 +372,38 @@
 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
auxadc: adc@11001000 {
compatible = "mediatek,mt2712-auxadc";
reg = <0 0x11001000 0 0x1000>;
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



Re: [PATCH v7 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2018-12-26 Thread Long Cheng
On Wed, 2018-12-26 at 17:28 +0800, Nicolas Boichat wrote:

..

> > > > > > +static int mtk_uart_apdma_device_pause(struct dma_chan *chan)
> > > > > > +{
> > > > > > +   /* just for check caps pass */
> > > > > > +   return 0;
> > > > > > +}
> > > > > > +
> > > > > > +static int mtk_uart_apdma_device_resume(struct dma_chan *chan)
> > > > > > +{
> > > > > > +   /* just for check caps pass */
> > > > > > +   return 0;
> > > > > > +}
> > >
> > > Why do you need these? Seems wrong to advertise device_pause/resume
> > > (and the caps) if we don't actually support that?
> > >
> >
> > in serial 8250_dma.c file, when request DMA, will calll
> > 'dma_get_slave_caps' to get the caps. and the will check caps.cmd_pause.
> > the pause is device_pause.  our device can't support the functions. but
> > to check pass, need add the fake function. or you can give better
> > comments. thanks.
> 
> Well, then I guess this is a hack... I'm not too familiar with
> 8250_dma.c, but I guess that if it requires pause/resume to be
> implemented, then we should implement them, not just stub them out...
> 
> Is this something that can be implemented with 8250_mtk DMA?
> 

the HW can't support it.

> Also, I don't see where you need resume, so maybe implementing pause is 
> enough?
> 

yes. pause is enough. for symmetry, add resume function.
anyway, the pause function need to keep.

> > > > > > +
> > > > > > +static void mtk_uart_apdma_free(struct mtk_uart_apdmadev *mtkd)
> > > > > > +{
> > > > > > +   while (list_empty(>ddev.channels) == 0) {
> > > > > > +   struct mtk_chan *c = 
> > > > > > list_first_entry(>ddev.channels,
> > > > > > +   struct mtk_chan, vc.chan.device_node);
> > > > > > +
> > > > > > +   list_del(>vc.chan.device_node);
> > > > > > +   tasklet_kill(>vc.task);
> > > > > > +   }
> > > > > > +}
> > > > > > +
> > > > > > +static const struct of_device_id mtk_uart_apdma_match[] = {
> > > > > > +   { .compatible = "mediatek,mt6577-uart-dma", },
> > > > > > +   { /* sentinel */ },
> > > > > > +};
> > > > > > +MODULE_DEVICE_TABLE(of, mtk_uart_apdma_match);
> > > > > > +
> > > > > > +static int mtk_uart_apdma_probe(struct platform_device *pdev)
> > > > > > +{
> > > > > > +   struct mtk_uart_apdmadev *mtkd;
> > > > > > +   struct resource *res;
> > > > > > +   struct mtk_chan *c;
> > > > > > +   unsigned int i;
> > > > > > +   int rc;
> > > > > > +

..




Re: [PATCH v7 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2018-12-25 Thread Long Cheng
On Wed, 2018-12-26 at 08:05 +0800, Nicolas Boichat wrote:

thanks. 

> On Tue, Dec 25, 2018 at 8:06 PM Long Cheng  wrote:
> >
> > Thanks for your comments.
> >
> > On Tue, 2018-12-25 at 15:16 +0800, Nicolas Boichat wrote:
> > > Not a full review, a few comments below.
> > >
> > > Thanks,
> > >
> >
> > would you like help to full review at this version patch?  and then i
> > can modify these at next version patch. thanks.
> 
> Added a few more comments ,-)
> 
> > > On Tue, Dec 25, 2018 at 9:27 AM Long Cheng  
> > > wrote:
> > > >
> > > > In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> > > > If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> > > > the performance, can enable the function.
> > > >
> > > > Signed-off-by: Long Cheng 
> > > > ---
> > > >  drivers/dma/mediatek/8250_mtk_dma.c |  694 
> > > > +++
> > > >  drivers/dma/mediatek/Kconfig|   11 +
> > > >  drivers/dma/mediatek/Makefile   |1 +
> > > >  3 files changed, 706 insertions(+)
> > > >  create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
> > > >
> > > > diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
> > > > b/drivers/dma/mediatek/8250_mtk_dma.c
> > > > new file mode 100644
> > > > index 000..c4090f2
> > > > --- /dev/null
> > > > +++ b/drivers/dma/mediatek/8250_mtk_dma.c
> > > > @@ -0,0 +1,694 @@
> > > > +// SPDX-License-Identifier: GPL-2.0
> > > > +/*
> > > > + * MediaTek 8250 DMA driver.
> > > > + *
> > > > + * Copyright (c) 2018 MediaTek Inc.
> > > > + * Author: Long Cheng 
> > > > + */
> > > > +
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > > > +#include 
> > >
> > > Alphabetical order.
> >
> > ok, i will order.
> >
> > >
> > > > +
> > > > +#include "../virt-dma.h"
> > > > +
> > > > +#define MTK_UART_APDMA_CHANNELS
> > > > (CONFIG_SERIAL_8250_NR_UARTS * 2)
> > > > +
> > > > +#define VFF_EN_B   BIT(0)
> > > > +#define VFF_STOP_B BIT(0)
> > > > +#define VFF_FLUSH_BBIT(0)
> > > > +#define VFF_4G_SUPPORT_B   BIT(0)
> > > > +#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
> > > > +#define VFF_RX_INT_EN1_B   BIT(1)
> > > > +#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff 
> > > > thre*/
> > > > +#define VFF_WARM_RST_B BIT(0)
> > > > +#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
> > > > +#define VFF_TX_INT_FLAG_CLR_B  0
> > > > +#define VFF_STOP_CLR_B 0
> > > > +#define VFF_FLUSH_CLR_B0
> > > > +#define VFF_INT_EN_CLR_B   0
> > > > +#define VFF_4G_SUPPORT_CLR_B   0
> > > > +
> > > > +/* interrupt trigger level for tx */
> > > > +#define VFF_TX_THRE(n) ((n) * 7 / 8)
> > > > +/* interrupt trigger level for rx */
> > > > +#define VFF_RX_THRE(n) ((n) * 3 / 4)
> > > > +
> > > > +#define MTK_UART_APDMA_RING_SIZE   0xU
> > > > +/* invert this bit when wrap ring head again*/
> > > > +#define MTK_UART_APDMA_RING_WRAP   0x1U
> > > > +
> > > > +#define VFF_INT_FLAG   0x00
> > > > +#define VFF_INT_EN 0x04
> > > > +#define VFF_EN 0x08
> > > > +#define VFF_RST0x0c
> > > > +#define VFF_STOP   0x10
> > > > +#define VFF_FLUSH  0x14
> > > > +#define VFF_ADDR   0x1c
> > > > +#define VFF_LEN0x24
> > > > +#define VFF_THRE   0x28
> > > > +#define VFF_WPT0x2c
> > > > +#define VFF_RPT0x30
> >

Re: [PATCH v7 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2018-12-25 Thread Long Cheng
Thanks for your comments.

On Tue, 2018-12-25 at 15:16 +0800, Nicolas Boichat wrote:
> Not a full review, a few comments below.
> 
> Thanks,
> 

would you like help to full review at this version patch?  and then i
can modify these at next version patch. thanks.

> On Tue, Dec 25, 2018 at 9:27 AM Long Cheng  wrote:
> >
> > In DMA engine framework, add 8250 uart dma to support MediaTek uart.
> > If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
> > the performance, can enable the function.
> >
> > Signed-off-by: Long Cheng 
> > ---
> >  drivers/dma/mediatek/8250_mtk_dma.c |  694 
> > +++
> >  drivers/dma/mediatek/Kconfig|   11 +
> >  drivers/dma/mediatek/Makefile   |1 +
> >  3 files changed, 706 insertions(+)
> >  create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
> >
> > diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
> > b/drivers/dma/mediatek/8250_mtk_dma.c
> > new file mode 100644
> > index 000..c4090f2
> > --- /dev/null
> > +++ b/drivers/dma/mediatek/8250_mtk_dma.c
> > @@ -0,0 +1,694 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * MediaTek 8250 DMA driver.
> > + *
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Long Cheng 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> 
> Alphabetical order.

ok, i will order.

> 
> > +
> > +#include "../virt-dma.h"
> > +
> > +#define MTK_UART_APDMA_CHANNELS
> > (CONFIG_SERIAL_8250_NR_UARTS * 2)
> > +
> > +#define VFF_EN_B   BIT(0)
> > +#define VFF_STOP_B BIT(0)
> > +#define VFF_FLUSH_BBIT(0)
> > +#define VFF_4G_SUPPORT_B   BIT(0)
> > +#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
> > +#define VFF_RX_INT_EN1_B   BIT(1)
> > +#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
> > +#define VFF_WARM_RST_B BIT(0)
> > +#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
> > +#define VFF_TX_INT_FLAG_CLR_B  0
> > +#define VFF_STOP_CLR_B 0
> > +#define VFF_FLUSH_CLR_B0
> > +#define VFF_INT_EN_CLR_B   0
> > +#define VFF_4G_SUPPORT_CLR_B   0
> > +
> > +/* interrupt trigger level for tx */
> > +#define VFF_TX_THRE(n) ((n) * 7 / 8)
> > +/* interrupt trigger level for rx */
> > +#define VFF_RX_THRE(n) ((n) * 3 / 4)
> > +
> > +#define MTK_UART_APDMA_RING_SIZE   0xU
> > +/* invert this bit when wrap ring head again*/
> > +#define MTK_UART_APDMA_RING_WRAP   0x1U
> > +
> > +#define VFF_INT_FLAG   0x00
> > +#define VFF_INT_EN 0x04
> > +#define VFF_EN 0x08
> > +#define VFF_RST0x0c
> > +#define VFF_STOP   0x10
> > +#define VFF_FLUSH  0x14
> > +#define VFF_ADDR   0x1c
> > +#define VFF_LEN0x24
> > +#define VFF_THRE   0x28
> > +#define VFF_WPT0x2c
> > +#define VFF_RPT0x30
> > +/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
> > +#define VFF_VALID_SIZE 0x3c
> > +/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
> > +#define VFF_LEFT_SIZE  0x40
> > +#define VFF_DEBUG_STATUS   0x50
> > +#define VFF_4G_SUPPORT 0x54
> > +
> > +struct mtk_uart_apdmadev {
> > +   struct dma_device ddev;
> > +   struct clk *clk;
> > +   bool support_33bits;
> > +   unsigned int dma_irq[MTK_UART_APDMA_CHANNELS];
> > +};
> > +
> > +struct mtk_uart_apdma_desc {
> > +   struct virt_dma_desc vd;
> > +
> > +   unsigned int avail_len;
> > +};
> > +
> > +struct mtk_chan {
> > +   struct virt_dma_chan vc;
> > +   struct dma_slave_config cfg;
> > +   void __iomem *base;
> > +   struct mtk_uart_apdma_desc *desc;
> > +
> > +   bool requested;
> > +
> > +   unsigned int rx_status;
> > +};
> > +
> > +static inline struct mtk_uart_apdmadev *
> > +to_mtk_uart_apdma_dev(struct dma_device *d)
> > +{
> > +   retur

[PATCH v7 2/2] arm: dts: mt2712: add uart APDMA to device tree

2018-12-24 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..be1a22a 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -369,6 +372,38 @@
 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
auxadc: adc@11001000 {
compatible = "mediatek,mt2712-auxadc";
reg = <0 0x11001000 0 0x1000>;
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v7 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2018-12-24 Thread Long Cheng
In DMA engine framework, add 8250 uart dma to support MediaTek uart.
If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
the performance, can enable the function.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  694 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 706 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..c4090f2
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,694 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_UART_APDMA_CHANNELS(CONFIG_SERIAL_8250_NR_UARTS * 
2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_UART_APDMA_RING_SIZE   0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_UART_APDMA_RING_WRAP   0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_uart_apdmadev {
+   struct dma_device ddev;
+   struct clk *clk;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_UART_APDMA_CHANNELS];
+};
+
+struct mtk_uart_apdma_desc {
+   struct virt_dma_desc vd;
+
+   unsigned int avail_len;
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_uart_apdma_desc *desc;
+
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+static inline struct mtk_uart_apdmadev *
+to_mtk_uart_apdma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_uart_apdmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_uart_apdma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_uart_apdma_desc *to_mtk_uart_apdma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_uart_apdma_desc, vd.tx);
+}
+
+static void mtk_uart_apdma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int
+mtk_uart_apdma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
+{
+   unsigned int txcount = c->desc->avail_len;
+   unsigned int len, send, left, wpt, wrap;
+
+   if (mtk_uart_apdma_chan_read(c, VFF_LEFT_SIZE) == 0U) {
+   mtk_uart_apdma_chan_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+   } else {
+   len = mtk_uart_apdma_chan_read(c, VFF_LEN);
+
+   while (((left = mtk_uart_apdma_chan_read(c,
+   VFF_LEFT_SIZE)) > 0U)
+   && (c->desc->avail_len != 0U)) {
+   send = min_t(unsigned int, left, c->desc->avail_le

[PATCH v7 0/2] add uart DMA function

2018-12-24 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA

Changes compared to v6:
-Correct spelling
Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation


Long Cheng (2):
  dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
  arm: dts: mt2712: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +++
 drivers/dma/mediatek/8250_mtk_dma.c   |  694 +
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 4 files changed, 756 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5



[PATCH v6 2/2] arm: dts: mt2712: add uart APDMA to device tree

2018-12-18 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..be1a22a 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -369,6 +372,38 @@
 (GIC_CPU_MASK_RAW(0x13) | IRQ_TYPE_LEVEL_HIGH)>;
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
auxadc: adc@11001000 {
compatible = "mediatek,mt2712-auxadc";
reg = <0 0x11001000 0 0x1000>;
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v6 0/2] add uart DMA function

2018-12-18 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DM

Changes compared to v5:
-move 'requst irqs' to alloc channel
-remove tasklet.
Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (2):
  dmaengine: 8250_mtk_dma: add MediaTek uart DMA support
  arm: dts: mt2712: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +++
 drivers/dma/mediatek/8250_mtk_dma.c   |  694 +
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 4 files changed, 756 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5



[PATCH v6 1/2] dmaengine: 8250_mtk_dma: add MediaTek uart DMA support

2018-12-18 Thread Long Cheng
In DMA engine framework, add 8250 uart dma to support MediaTek uart.
If MediaTek uart enabled(SERIAL_8250_MT6577), and want to improve
the performance, can enable the function.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  694 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 706 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..c4090f2
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,694 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * MediaTek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_UART_APDMA_CHANNELS(CONFIG_SERIAL_8250_NR_UARTS * 
2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_UART_APDMA_RING_SIZE   0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_UART_APDMA_RING_WRAP   0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_uart_apdmadev {
+   struct dma_device ddev;
+   struct clk *clk;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_UART_APDMA_CHANNELS];
+};
+
+struct mtk_uart_apdma_desc {
+   struct virt_dma_desc vd;
+
+   unsigned int avail_len;
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_uart_apdma_desc *desc;
+
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+static inline struct mtk_uart_apdmadev *
+to_mtk_uart_apdma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_uart_apdmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_uart_apdma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_uart_apdma_desc *to_mtk_uart_apdma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_uart_apdma_desc, vd.tx);
+}
+
+static void mtk_uart_apdma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int
+mtk_uart_apdma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_uart_apdma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_uart_apdma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static void mtk_uart_apdma_start_tx(struct mtk_chan *c)
+{
+   unsigned int txcount = c->desc->avail_len;
+   unsigned int len, send, left, wpt, wrap;
+
+   if (mtk_uart_apdma_chan_read(c, VFF_LEFT_SIZE) == 0U) {
+   mtk_uart_apdma_chan_write(c, VFF_INT_EN, VFF_TX_INT_EN_B);
+   } else {
+   len = mtk_uart_apdma_chan_read(c, VFF_LEN);
+
+   while (((left = mtk_uart_apdma_chan_read(c,
+   VFF_LEFT_SIZE)) > 0U)
+   && (c->desc->avail_len != 0U)) {
+   send = min_t(unsigned int, left, c->desc->avail_le

Re: [PATCH v5 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support

2018-12-17 Thread Long Cheng
On Mon, 2018-12-17 at 02:07 -0800, Sean Wang wrote:
> On Mon, Dec 17, 2018 at 12:40 AM Long Cheng  wrote:
> >
> > On Fri, 2018-12-14 at 12:09 -0800, Sean Wang wrote:
> 
> < ... >
> 
> > > > > > +
> > > > > > +   mtk_dma_chan_write(c, VFF_ADDR, cfg->src_addr);
> > > > > > +   mtk_dma_chan_write(c, VFF_LEN, rx_len);
> > > > > > +   mtk_dma_chan_write(c, VFF_THRE, 
> > > > > > VFF_RX_THRE(rx_len));
> > > > > > +   mtk_dma_chan_write(c,
> > > > > > +  VFF_INT_EN, VFF_RX_INT_EN0_B
> > > > > > +  | VFF_RX_INT_EN1_B);
> > > > > > +   mtk_dma_chan_write(c, VFF_INT_FLAG, 
> > > > > > VFF_RX_INT_FLAG_CLR_B);
> > > > > > +   mtk_dma_chan_write(c, VFF_EN, VFF_EN_B);
> > > > >
> > > > > I'd prefer to move those channel interrupt enablement to
> > > > > .device_alloc_chan_resources
> > > > > and related disablement to .device_free_chan_resources
> > > > >
> > > >
> > > > i think that, first need set the config to HW, and the enable the DMA.
> > > >
> > >
> > > I've read through the client driver and the dmaengine, I probably know
> > > how interaction they work and find out there is something you seem
> > > completely make a wrong.
> > >
> > > You can't do enable DMA with enabling VFF here. That causes a big
> > > problem, DMA would self decide to move data and not managed and issued
> > > by the dmaengine framework. For instance in DMA Tx path, because you
> > > enable the DMA and DMA  buffer (VFF) and UART Tx ring uses the same
> > > memory area,  DMA would self start to move data once data from
> > > userland go in Tx ring even without being issued by dmaengine.
> > >
> > > Instead, you should ensure all descriptors are being batched by
> > > .device_prep_slave_sg and DMA does not start moving data until
> > > .device_issue_pending done and once descriptors are issued, DMA
> > > hardware or software have to do it as fast as possible.
> > >
> >
> > the VFF enable just enable the DMA function. DMA can't move data here.
> > Now, the code get length of the data in '.device_prep_slave_sg'.
> > And let DMA move data in '.device_issue_pending function'. in here, just
> > enable the function.
> >
> 
> My all curiosity are all from the descriptor programmed in
> .device_issue_pending in the other drivers at least includes
> information such data length, target address, and hardware control
> code, but in the driver only includes data length and even the target
> address is set up at device_config, that seems unusual.
> 
> And, It does too for DMA_DEV_TO_MEM?  What I see is there is almost no
> any code be programmed for kick off the hardware for the direction but
> DMA still can move. That is another point I got confused.
> 

8250_dma in tty, mapping xmit buffer to DMA buffer. and the tx just use
the only one buffer. it's ring buffer. 8250_dma set the begin address
and length of the buffer by means of '.deivce_config' function. 
when TX happen, tty_write will write data to xmit buffer. in 8250_dma,
will set the address and length of the data by means of
'.device_prep_slave_sg'. but the address is in the xmit buffer rang. the
WPT(write pointer), RPT(read pointer) registers are recored the DMA data
transfer status, include the current location of transmission. and the
apdma is only for UART. So don't need recored the the address of data ,
target address in '.device_prep_slave_sg'.
in '.device_issue_pending', just using the data length from descriptor,
WPT ,  we can figure out what's data need to move. then update the WPT
and flush TX.

RX too. RX use other buffer in instead of XMIT buffer. when RX interrupt
coming, will update the RPT, and 8250_dma will get the length from vchan
complete. then 8250_dma can get the data.

> > > > > > +
> > > > > > +   if (!c->requested) {
> > > > > > +   c->requested = true;
> > > > > > +   ret = 
> > > > > > request_irq(mtkd->dma_irq[chan->chan_id],
> > > > > > + mtk_dma_rx_interrupt,
> > > > > > + IRQF_TRIGGER_NONE,
> > > > > > + KBUILD_M

Re: [PATCH v5 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support

2018-12-17 Thread Long Cheng
On Fri, 2018-12-14 at 12:09 -0800, Sean Wang wrote:

thanks for your reply.

> On Thu, Dec 13, 2018 at 3:36 AM Long Cheng  wrote:
> 
> Hope those comments did not get a response that means they're fine with you.
> 
> < ... >
> 
> > > > +struct mtk_dmadev {
> > > > +   struct dma_device ddev;
> > > > +   void __iomem *mem_base[MTK_APDMA_CHANNELS];
> > > > +   spinlock_t lock; /* dma dev lock */
> > > > +   struct tasklet_struct task;
> > >
> > > we can drop tasklet and instead allows descriptors to be handled as
> > > fast as possible.
> > > similar suggestions have been made in the other dmaengine [1] and 
> > > mtk-hsdma.c
> > >
> >
> > OK, i will remove these, and improve it.
> >
> 
> Thanks, that would be great.
> 
> > > [1] https://lkml.org/lkml/2018/11/11/146
> > >
> > > > +   struct list_head pending;
> > > > +   struct clk *clk;
> > > > +   unsigned int dma_requests;
> > > > +   bool support_33bits;
> > > > +   unsigned int dma_irq[MTK_APDMA_CHANNELS];
> > > > +   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
> > > > +};
> > > > +
> 
> < ... >
> 
> > > > +static struct dma_async_tx_descriptor *mtk_dma_prep_slave_sg
> > > > +   (struct dma_chan *chan, struct scatterlist *sgl,
> > > > +   unsigned int sglen, enum dma_transfer_direction dir,
> > > > +   unsigned long tx_flags, void *context)
> > > > +{
> > > > +   struct mtk_chan *c = to_mtk_dma_chan(chan);
> > > > +   struct scatterlist *sgent;
> > > > +   struct mtk_dma_desc *d;
> > > > +   struct mtk_dma_sg *sg;
> > > > +   unsigned int size, i, j, en;
> > > > +
> > > > +   en = 1;
> > > > +
> > > > +   if ((dir != DMA_DEV_TO_MEM) &&
> > > > +   (dir != DMA_MEM_TO_DEV)) {
> > > > +   dev_err(chan->device->dev, "bad direction\n");
> > > > +   return NULL;
> > > > +   }
> > > > +
> > > > +   /* Now allocate and setup the descriptor. */
> > > > +   d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
> > > > +   if (!d)
> > > > +   return NULL;
> > > > +
> > > > +   d->dir = dir;
> > > > +
> > > > +   j = 0;
> > > > +   for_each_sg(sgl, sgent, sglen, i) {
> > > > +   d->sg[j].addr = sg_dma_address(sgent);
> > > > +   d->sg[j].en = en;
> > > > +   d->sg[j].fn = sg_dma_len(sgent) / en;
> > > > +   j++;
> > > > +   }
> > > > +
> > > > +   d->sglen = j;
> > > > +
> > > > +   if (dir == DMA_MEM_TO_DEV) {
> > > > +   for (size = i = 0; i < d->sglen; i++) {
> > > > +   sg = >sg[i];
> > > > +   size += sg->en * sg->fn;
> > > > +   }
> > > > +   d->len = size;
> > > > +   }
> > > > +
> > >
> > > The driver always only handles data move for the single contiguous
> > > area, but it seems the callback must provide the scatter-gather
> > > function to the dmaegine. otherwise, why is the callback be called
> > > device_prep_slave_sg?
> > >
> >
> > because in 8250 UART native code, call the device_prep_slave_sg. we just
> > use one ring buffer.
> >
> 
> If it really did specifically for UART, you should show the function
> only can handle only one entry in sg for the DMA in a few comments and
> a sanity check for these invalid requests (more one entries in sg).
> Otherwise, the hardware will get a failure and even function doesn't
> complain or warn anything if more one entries in sg requested in.
> Additionally, the code can be simplified much if it's just for the
> specific use case.
> 

ok. i will add some comments. and let the code be simplified.

> > > > +   return vchan_tx_prep(>vc, >vd, tx_flags);
> > > > +}
> > > > +
> > > > +static void mtk_dma_issue_pending(struct dma_chan *chan)
> > > > +{
> > > > +   struct mtk_chan *c = to_mtk_dma_chan(chan);
> > > > +   struct virt_dma_desc *vd;
&g

Re: [PATCH v5 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support

2018-12-13 Thread Long Cheng
On Tue, 2018-12-11 at 15:12 -0800, Sean Wang wrote:
> Sorry for that I didn't have a full review at one time in the earlier version
> 
>On Mon, Dec 10, 2018 at 9:37 PM Long Cheng
>  wrote:
> >
> > In DMA engine framework, add 8250 mtk dma to support it.
> 
> It looks like there are still many rooms to improve the description,
> especially it's a totally new driver.
> 
> >
> > Signed-off-by: Long Cheng 
> > ---
> >  drivers/dma/mediatek/8250_mtk_dma.c |  830 
> > +++
> >  drivers/dma/mediatek/Kconfig|   11 +
> >  drivers/dma/mediatek/Makefile   |1 +
> >  3 files changed, 842 insertions(+)
> >  create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
> >
> > diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
> > b/drivers/dma/mediatek/8250_mtk_dma.c
> > new file mode 100644
> > index 000..f79d180
> > --- /dev/null
> > +++ b/drivers/dma/mediatek/8250_mtk_dma.c
> > @@ -0,0 +1,830 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Mediatek 8250 DMA driver.
> 
> MediaTek
> 
> > + *
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Long Cheng 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "../virt-dma.h"
> > +
> > +#define MTK_APDMA_DEFAULT_REQUESTS 127
> > +#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
> > +
> > +#define VFF_EN_B   BIT(0)
> > +#define VFF_STOP_B BIT(0)
> > +#define VFF_FLUSH_BBIT(0)
> > +#define VFF_4G_SUPPORT_B   BIT(0)
> > +#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
> > +#define VFF_RX_INT_EN1_B   BIT(1)
> > +#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
> > +#define VFF_WARM_RST_B BIT(0)
> > +#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
> > +#define VFF_TX_INT_FLAG_CLR_B  0
> > +#define VFF_STOP_CLR_B 0
> > +#define VFF_FLUSH_CLR_B0
> > +#define VFF_INT_EN_CLR_B   0
> > +#define VFF_4G_SUPPORT_CLR_B   0
> > +
> > +/* interrupt trigger level for tx */
> > +#define VFF_TX_THRE(n) ((n) * 7 / 8)
> > +/* interrupt trigger level for rx */
> > +#define VFF_RX_THRE(n) ((n) * 3 / 4)
> > +
> > +#define MTK_DMA_RING_SIZE  0xU
> > +/* invert this bit when wrap ring head again*/
> > +#define MTK_DMA_RING_WRAP  0x1U
> > +
> > +#define VFF_INT_FLAG   0x00
> > +#define VFF_INT_EN 0x04
> > +#define VFF_EN 0x08
> > +#define VFF_RST0x0c
> > +#define VFF_STOP   0x10
> > +#define VFF_FLUSH  0x14
> > +#define VFF_ADDR   0x1c
> > +#define VFF_LEN0x24
> > +#define VFF_THRE   0x28
> > +#define VFF_WPT0x2c
> > +#define VFF_RPT0x30
> > +/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
> > +#define VFF_VALID_SIZE 0x3c
> > +/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
> > +#define VFF_LEFT_SIZE  0x40
> > +#define VFF_DEBUG_STATUS   0x50
> > +#define VFF_4G_SUPPORT 0x54
> > +
> > +struct mtk_dmadev {
> > +   struct dma_device ddev;
> > +   void __iomem *mem_base[MTK_APDMA_CHANNELS];
> > +   spinlock_t lock; /* dma dev lock */
> > +   struct tasklet_struct task;
> 
> we can drop tasklet and instead allows descriptors to be handled as
> fast as possible.
> similar suggestions have been made in the other dmaengine [1] and mtk-hsdma.c
> 

OK, i will remove these, and improve it.

> [1] https://lkml.org/lkml/2018/11/11/146
> 
> > +   struct list_head pending;
> > +   struct clk *clk;
> > +   unsigned int dma_requests;
> > +   bool support_33bits;
> > +   unsigned int dma_irq[MTK_APDMA_CHANNELS];
> > +   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
> > +};
> > +
> > +struct mtk_chan {
> > +   struct virt_dma_chan vc;
> > +   struct list_head node;
> > +   struct dma_slave_config cfg;
> > +   void __iomem *base;
> &g

[PATCH v5 2/2] arm: dts: mt2712: add uart APDMA to device tree

2018-12-10 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -378,6 +381,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v5 0/2] add uart DMA function

2018-12-10 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DM

Changes compared to v4:
-modify Kconfig depends on.
Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (2):
  dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
  arm: dts: mt2712: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 ++
 drivers/dma/mediatek/8250_mtk_dma.c   |  830 +
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 4 files changed, 892 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5



[PATCH v5 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support

2018-12-10 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  830 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 842 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..f79d180
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_APDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_APDMA_CHANNELS];
+   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_dma_desc *desc;
+
+   bool stop;
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+
+   unsigned int len;
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static void mtk_dma_tx_flush(struct dma_chan *chan)
+{
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   if (mtk_dma_chan_read(c, VFF_FLUSH) == 0U)
+   mtk_dma_chan_write(c, VFF_FLUSH, VFF_FLUSH_B);
+}
+
+static void mtk_dma_tx_write(struct dma_chan *chan

[resend PATCH v4 2/2] arm: dts: mt2712: add uart APDMA to device tree

2018-12-09 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -378,6 +381,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[resend PATCH v4 0/2] add uart DMA function

2018-12-09 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DM

Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (2):
  dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
  arm: dts: mt2712: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 ++
 drivers/dma/mediatek/8250_mtk_dma.c   |  830 +
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 4 files changed, 892 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5



[resend PATCH v4 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support

2018-12-09 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  830 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 842 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..f79d180
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_APDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_APDMA_CHANNELS];
+   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_dma_desc *desc;
+
+   bool stop;
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+
+   unsigned int len;
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static void mtk_dma_tx_flush(struct dma_chan *chan)
+{
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   if (mtk_dma_chan_read(c, VFF_FLUSH) == 0U)
+   mtk_dma_chan_write(c, VFF_FLUSH, VFF_FLUSH_B);
+}
+
+static void mtk_dma_tx_write(struct dma_chan *chan

[PATCH v4 2/2] arm: dts: mt2701: add uart APDMA to device tree

2018-12-09 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -378,6 +381,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v4 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support

2018-12-09 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  830 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 842 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..f79d180
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,830 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_APDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_APDMA_CHANNELS];
+   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_dma_desc *desc;
+
+   bool stop;
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+
+   unsigned int len;
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static void mtk_dma_tx_flush(struct dma_chan *chan)
+{
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   if (mtk_dma_chan_read(c, VFF_FLUSH) == 0U)
+   mtk_dma_chan_write(c, VFF_FLUSH, VFF_FLUSH_B);
+}
+
+static void mtk_dma_tx_write(struct dma_chan *chan

[PATCH v4 0/2] add uart DMA function

2018-12-09 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DM

Changes compared to v3:
-fix CONFIG_PM, will cause build fail
Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (2):
  dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 ++
 drivers/dma/mediatek/8250_mtk_dma.c   |  830 +
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 4 files changed, 892 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5



[PATCH v3 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support

2018-12-06 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  847 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 859 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..a2db9ec
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,847 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_APDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_APDMA_CHANNELS];
+   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_dma_desc *desc;
+
+   bool stop;
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+
+   unsigned int len;
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static int mtk_dma_clk_enable(struct mtk_dmadev *mtkd)
+{
+   int ret;
+
+   ret = clk_prepare_enable(mtkd->clk);
+   if (ret) {
+   dev_err(mtkd->ddev.dev, "Couldn't enable the clock\n");
+   return ret;
+   }
+
+   return 

[PATCH v3 1/2] dmaengine: 8250_mtk_dma: add Mediatek uart DMA support

2018-12-06 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  847 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 859 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..a2db9ec
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,847 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_APDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_APDMA_CHANNELS];
+   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_dma_desc *desc;
+
+   bool stop;
+   bool requested;
+
+   unsigned int rx_status;
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+
+   unsigned int len;
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static int mtk_dma_clk_enable(struct mtk_dmadev *mtkd)
+{
+   int ret;
+
+   ret = clk_prepare_enable(mtkd->clk);
+   if (ret) {
+   dev_err(mtkd->ddev.dev, "Couldn't enable the clock\n");
+   return ret;
+   }
+
+   return 

[PATCH v3 0/2] add uart DMA function

2018-12-06 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DM

Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (2):
  dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 ++
 drivers/dma/mediatek/8250_mtk_dma.c   |  847 +
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 4 files changed, 909 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5




[PATCH v3 2/2] arm: dts: mt2701: add uart APDMA to device tree

2018-12-06 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -378,6 +381,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v3 0/2] add uart DMA function

2018-12-06 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DM

Changes compared to v2:
-remove unimportant parameters
-instead of cookie, use APIs of virtual channel.
-use of_dma_xlate_by_chan_id.
Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (2):
  dmaengine: 8250_mtk_dma: add Mediatek uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 ++
 drivers/dma/mediatek/8250_mtk_dma.c   |  847 +
 drivers/dma/mediatek/Kconfig  |   11 +
 drivers/dma/mediatek/Makefile |1 +
 4 files changed, 909 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

-- 
1.7.9.5




[PATCH v3 2/2] arm: dts: mt2701: add uart APDMA to device tree

2018-12-06 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -378,6 +381,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



Re: [PATCH v2 2/4] dmaengine: mtk_uart_dma: add Mediatek uart DMA support

2018-12-06 Thread Long Cheng
On Wed, 2018-12-05 at 13:07 -0800, Sean Wang wrote:
> .
> On Wed, Dec 5, 2018 at 1:31 AM Long Cheng  wrote:
> >
> > In DMA engine framework, add 8250 mtk dma to support it.
> >
> > Signed-off-by: Long Cheng 
> > ---
> >  drivers/dma/mediatek/8250_mtk_dma.c |  894 
> > +++
> >  drivers/dma/mediatek/Kconfig|   11 +
> >  drivers/dma/mediatek/Makefile   |1 +
> >  3 files changed, 906 insertions(+)
> >  create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
> >
> > diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
> > b/drivers/dma/mediatek/8250_mtk_dma.c
> > new file mode 100644
> > index 000..3454679
> > --- /dev/null
> > +++ b/drivers/dma/mediatek/8250_mtk_dma.c
> > @@ -0,0 +1,894 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Mediatek 8250 DMA driver.
> > + *
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Long Cheng 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "../virt-dma.h"
> > +
> > +#define MTK_APDMA_DEFAULT_REQUESTS 127
> > +#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
> > +
> > +#define VFF_EN_B   BIT(0)
> > +#define VFF_STOP_B BIT(0)
> > +#define VFF_FLUSH_BBIT(0)
> > +#define VFF_4G_SUPPORT_B   BIT(0)
> > +#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
> > +#define VFF_RX_INT_EN1_B   BIT(1)
> > +#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
> > +#define VFF_WARM_RST_B BIT(0)
> > +#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
> > +#define VFF_TX_INT_FLAG_CLR_B  0
> > +#define VFF_STOP_CLR_B 0
> > +#define VFF_FLUSH_CLR_B0
> > +#define VFF_INT_EN_CLR_B   0
> > +#define VFF_4G_SUPPORT_CLR_B   0
> > +
> > +/* interrupt trigger level for tx */
> > +#define VFF_TX_THRE(n) ((n) * 7 / 8)
> > +/* interrupt trigger level for rx */
> > +#define VFF_RX_THRE(n) ((n) * 3 / 4)
> > +
> > +#define MTK_DMA_RING_SIZE  0xU
> > +/* invert this bit when wrap ring head again*/
> > +#define MTK_DMA_RING_WRAP  0x1U
> > +
> > +#define VFF_INT_FLAG   0x00
> > +#define VFF_INT_EN 0x04
> > +#define VFF_EN 0x08
> > +#define VFF_RST0x0c
> > +#define VFF_STOP   0x10
> > +#define VFF_FLUSH  0x14
> > +#define VFF_ADDR   0x1c
> > +#define VFF_LEN0x24
> > +#define VFF_THRE   0x28
> > +#define VFF_WPT0x2c
> > +#define VFF_RPT0x30
> > +/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
> > +#define VFF_VALID_SIZE 0x3c
> > +/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
> > +#define VFF_LEFT_SIZE  0x40
> > +#define VFF_DEBUG_STATUS   0x50
> > +#define VFF_4G_SUPPORT 0x54
> > +
> > +struct mtk_dmadev {
> > +   struct dma_device ddev;
> > +   void __iomem *mem_base[MTK_APDMA_CHANNELS];
> > +   spinlock_t lock; /* dma dev lock */
> > +   struct tasklet_struct task;
> > +   struct list_head pending;
> > +   struct clk *clk;
> > +   unsigned int dma_requests;
> > +   bool support_33bits;
> > +   unsigned int dma_irq[MTK_APDMA_CHANNELS];
> > +   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
> > +};
> > +
> > +struct mtk_chan {
> > +   struct virt_dma_chan vc;
> > +   struct list_head node;
> > +   struct dma_slave_config cfg;
> > +   void __iomem *base;
> > +   struct mtk_dma_desc *desc;
> > +
> > +   bool stop;
> > +   bool requested;
> > +
> > +   unsigned int dma_sig;
> 
> the member can be removed as no real user would refer to it
> 

Ok, i will remove it at next patch

> > +   unsigned int dma_ch;
> 
> a chan_id is already included in struct dma_chan, we can reuse it
> 

chan_id is start from 0. but in this driver, dma info is stored to list.
if use port1, in filter_fn function, will set dma_ch to 2, 3(tx, rx). So
c

Re: [PATCH v2 2/4] dmaengine: mtk_uart_dma: add Mediatek uart DMA support

2018-12-06 Thread Long Cheng
On Wed, 2018-12-05 at 13:07 -0800, Sean Wang wrote:
> .
> On Wed, Dec 5, 2018 at 1:31 AM Long Cheng  wrote:
> >
> > In DMA engine framework, add 8250 mtk dma to support it.
> >
> > Signed-off-by: Long Cheng 
> > ---
> >  drivers/dma/mediatek/8250_mtk_dma.c |  894 
> > +++
> >  drivers/dma/mediatek/Kconfig|   11 +
> >  drivers/dma/mediatek/Makefile   |1 +
> >  3 files changed, 906 insertions(+)
> >  create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c
> >
> > diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
> > b/drivers/dma/mediatek/8250_mtk_dma.c
> > new file mode 100644
> > index 000..3454679
> > --- /dev/null
> > +++ b/drivers/dma/mediatek/8250_mtk_dma.c
> > @@ -0,0 +1,894 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * Mediatek 8250 DMA driver.
> > + *
> > + * Copyright (c) 2018 MediaTek Inc.
> > + * Author: Long Cheng 
> > + */
> > +
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +#include 
> > +
> > +#include "../virt-dma.h"
> > +
> > +#define MTK_APDMA_DEFAULT_REQUESTS 127
> > +#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
> > +
> > +#define VFF_EN_B   BIT(0)
> > +#define VFF_STOP_B BIT(0)
> > +#define VFF_FLUSH_BBIT(0)
> > +#define VFF_4G_SUPPORT_B   BIT(0)
> > +#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
> > +#define VFF_RX_INT_EN1_B   BIT(1)
> > +#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
> > +#define VFF_WARM_RST_B BIT(0)
> > +#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
> > +#define VFF_TX_INT_FLAG_CLR_B  0
> > +#define VFF_STOP_CLR_B 0
> > +#define VFF_FLUSH_CLR_B0
> > +#define VFF_INT_EN_CLR_B   0
> > +#define VFF_4G_SUPPORT_CLR_B   0
> > +
> > +/* interrupt trigger level for tx */
> > +#define VFF_TX_THRE(n) ((n) * 7 / 8)
> > +/* interrupt trigger level for rx */
> > +#define VFF_RX_THRE(n) ((n) * 3 / 4)
> > +
> > +#define MTK_DMA_RING_SIZE  0xU
> > +/* invert this bit when wrap ring head again*/
> > +#define MTK_DMA_RING_WRAP  0x1U
> > +
> > +#define VFF_INT_FLAG   0x00
> > +#define VFF_INT_EN 0x04
> > +#define VFF_EN 0x08
> > +#define VFF_RST0x0c
> > +#define VFF_STOP   0x10
> > +#define VFF_FLUSH  0x14
> > +#define VFF_ADDR   0x1c
> > +#define VFF_LEN0x24
> > +#define VFF_THRE   0x28
> > +#define VFF_WPT0x2c
> > +#define VFF_RPT0x30
> > +/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
> > +#define VFF_VALID_SIZE 0x3c
> > +/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
> > +#define VFF_LEFT_SIZE  0x40
> > +#define VFF_DEBUG_STATUS   0x50
> > +#define VFF_4G_SUPPORT 0x54
> > +
> > +struct mtk_dmadev {
> > +   struct dma_device ddev;
> > +   void __iomem *mem_base[MTK_APDMA_CHANNELS];
> > +   spinlock_t lock; /* dma dev lock */
> > +   struct tasklet_struct task;
> > +   struct list_head pending;
> > +   struct clk *clk;
> > +   unsigned int dma_requests;
> > +   bool support_33bits;
> > +   unsigned int dma_irq[MTK_APDMA_CHANNELS];
> > +   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
> > +};
> > +
> > +struct mtk_chan {
> > +   struct virt_dma_chan vc;
> > +   struct list_head node;
> > +   struct dma_slave_config cfg;
> > +   void __iomem *base;
> > +   struct mtk_dma_desc *desc;
> > +
> > +   bool stop;
> > +   bool requested;
> > +
> > +   unsigned int dma_sig;
> 
> the member can be removed as no real user would refer to it
> 

Ok, i will remove it at next patch

> > +   unsigned int dma_ch;
> 
> a chan_id is already included in struct dma_chan, we can reuse it
> 

chan_id is start from 0. but in this driver, dma info is stored to list.
if use port1, in filter_fn function, will set dma_ch to 2, 3(tx, rx). So
c

[PATCH v2 0/4] add uart DMA function

2018-12-05 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DM

Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (4):
  dt-bindings: dma: uart: add uart dma bindings
  dmaengine: mtk_uart_dma: add Mediatek uart DMA support
  serial: 8250-mtk: add uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi  |   50 ++
 drivers/dma/mediatek/8250_mtk_dma.c|  894 
 drivers/dma/mediatek/Kconfig   |   11 +
 drivers/dma/mediatek/Makefile  |1 +
 drivers/tty/serial/8250/8250_mtk.c |  210 -
 6 files changed, 1198 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c



[PATCH v2 1/4] dt-bindings: dma: uart: add uart dma bindings

2018-12-05 Thread Long Cheng
add uart dma bindings

Signed-off-by: Long Cheng 
Reviewed-by: Rob Herring  
---
 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt 
b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
new file mode 100644
index 000..3fe0961
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
@@ -0,0 +1,33 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+Examples:
+
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2712-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
-- 
1.7.9.5



[PATCH v2 0/4] add uart DMA function

2018-12-05 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DM

Changes compared to v1:
-mian revised file, 8250_mtk_dma.c
--parameters renamed for standard
--remove atomic operation

Long Cheng (4):
  dt-bindings: dma: uart: add uart dma bindings
  dmaengine: mtk_uart_dma: add Mediatek uart DMA support
  serial: 8250-mtk: add uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi  |   50 ++
 drivers/dma/mediatek/8250_mtk_dma.c|  894 
 drivers/dma/mediatek/Kconfig   |   11 +
 drivers/dma/mediatek/Makefile  |1 +
 drivers/tty/serial/8250/8250_mtk.c |  210 -
 6 files changed, 1198 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c



[PATCH v2 1/4] dt-bindings: dma: uart: add uart dma bindings

2018-12-05 Thread Long Cheng
add uart dma bindings

Signed-off-by: Long Cheng 
Reviewed-by: Rob Herring  
---
 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   33 
 1 file changed, 33 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt 
b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
new file mode 100644
index 000..3fe0961
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
@@ -0,0 +1,33 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+Examples:
+
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2712-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
-- 
1.7.9.5



[PATCH v2 4/4] arm: dts: mt2701: add uart APDMA to device tree

2018-12-05 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -378,6 +381,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v2 4/4] arm: dts: mt2701: add uart APDMA to device tree

2018-12-05 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3/4/5 DMA function

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 976d92a..a59728b 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -300,6 +300,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -378,6 +381,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -385,6 +420,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -395,6 +433,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -405,6 +446,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -415,6 +459,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -629,6 +676,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH v2 3/4] serial: 8250-mtk: add uart DMA support

2018-12-05 Thread Long Cheng
Modify uart register to support DMA function.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |  210 +++-
 1 file changed, 209 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index dd5e1ce..1da73e8 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -14,6 +14,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include "8250.h"
 
@@ -22,12 +26,172 @@
 #define UART_MTK_SAMPLE_POINT  0x0b/* Sample point register */
 #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
 
+#define MTK_UART_DMA_EN0x13/* DMA Enable register */
+#define MTK_UART_DMA_EN_TX 0x2
+#define MTK_UART_DMA_EN_RX 0x5
+
+#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
+#define MTK_UART_RX_SIZE   0x8000
+#define MTK_UART_TX_TRIGGER1
+#define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
+
+#ifdef CONFIG_SERIAL_8250_DMA
+enum dma_rx_status {
+   DMA_RX_START = 0,
+   DMA_RX_RUNNING = 1,
+   DMA_RX_SHUTDOWN = 2,
+};
+#endif
+
 struct mtk8250_data {
int line;
+   unsigned intrx_pos;
struct clk  *uart_clk;
struct clk  *bus_clk;
+   struct uart_8250_dma*dma;
+#ifdef CONFIG_SERIAL_8250_DMA
+   enum dma_rx_status  rx_status;
+#endif
 };
 
+#ifdef CONFIG_SERIAL_8250_DMA
+static void mtk8250_rx_dma(struct uart_8250_port *up);
+
+static void mtk8250_dma_rx_complete(void *param)
+{
+   struct uart_8250_port *up = param;
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct tty_port *tty_port = >port.state->port;
+   struct dma_tx_state state;
+   unsigned char *ptr;
+   int copied;
+
+   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
+   dma->rx_size, DMA_FROM_DEVICE);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+
+   if (data->rx_status == DMA_RX_SHUTDOWN)
+   return;
+
+   if ((data->rx_pos + state.residue) <= dma->rx_size) {
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
+   } else {
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr,
+   dma->rx_size - data->rx_pos);
+   ptr = (unsigned char *)(dma->rx_buf);
+   copied += tty_insert_flip_string(tty_port, ptr,
+   data->rx_pos + state.residue - dma->rx_size);
+   }
+   up->port.icount.rx += copied;
+
+   tty_flip_buffer_push(tty_port);
+
+   mtk8250_rx_dma(up);
+}
+
+static void mtk8250_rx_dma(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct dma_async_tx_descriptor  *desc;
+   struct dma_tx_state  state;
+
+   desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
+  dma->rx_size, DMA_DEV_TO_MEM,
+  DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!desc) {
+   pr_err("failed to prepare rx slave single\n");
+   return;
+   }
+
+   desc->callback = mtk8250_dma_rx_complete;
+   desc->callback_param = up;
+
+   dma->rx_cookie = dmaengine_submit(desc);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   data->rx_pos = state.residue;
+
+   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
+  dma->rx_size, DMA_FROM_DEVICE);
+
+   dma_async_issue_pending(dma->rxchan);
+}
+
+static void mtk8250_dma_enable(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   int lcr = serial_in(up, UART_LCR);
+
+   if (data->rx_status != DMA_RX_START)
+   return;
+
+   dma->rxconf.direction   = DMA_DEV_TO_MEM;
+   dma->rxconf.src_addr_width  = dma->rx_size / 1024;
+   dma->rxconf.src_addr= dma->rx_addr;
+
+   dma->txconf.direction   = DMA_MEM_TO_DEV;
+   dma->txconf.dst_addr_width  = MTK_UART_TX_SIZE / 1024;
+   dma->txconf.dst_addr= dma->tx_addr;
+
+   serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
+   UART_FCR_CLEAR_XMIT);
+   serial_out(up, MTK_UART_DMA_EN,
+  MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX);

[PATCH v2 3/4] serial: 8250-mtk: add uart DMA support

2018-12-05 Thread Long Cheng
Modify uart register to support DMA function.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |  210 +++-
 1 file changed, 209 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index dd5e1ce..1da73e8 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -14,6 +14,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include "8250.h"
 
@@ -22,12 +26,172 @@
 #define UART_MTK_SAMPLE_POINT  0x0b/* Sample point register */
 #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
 
+#define MTK_UART_DMA_EN0x13/* DMA Enable register */
+#define MTK_UART_DMA_EN_TX 0x2
+#define MTK_UART_DMA_EN_RX 0x5
+
+#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
+#define MTK_UART_RX_SIZE   0x8000
+#define MTK_UART_TX_TRIGGER1
+#define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
+
+#ifdef CONFIG_SERIAL_8250_DMA
+enum dma_rx_status {
+   DMA_RX_START = 0,
+   DMA_RX_RUNNING = 1,
+   DMA_RX_SHUTDOWN = 2,
+};
+#endif
+
 struct mtk8250_data {
int line;
+   unsigned intrx_pos;
struct clk  *uart_clk;
struct clk  *bus_clk;
+   struct uart_8250_dma*dma;
+#ifdef CONFIG_SERIAL_8250_DMA
+   enum dma_rx_status  rx_status;
+#endif
 };
 
+#ifdef CONFIG_SERIAL_8250_DMA
+static void mtk8250_rx_dma(struct uart_8250_port *up);
+
+static void mtk8250_dma_rx_complete(void *param)
+{
+   struct uart_8250_port *up = param;
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct tty_port *tty_port = >port.state->port;
+   struct dma_tx_state state;
+   unsigned char *ptr;
+   int copied;
+
+   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
+   dma->rx_size, DMA_FROM_DEVICE);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+
+   if (data->rx_status == DMA_RX_SHUTDOWN)
+   return;
+
+   if ((data->rx_pos + state.residue) <= dma->rx_size) {
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
+   } else {
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr,
+   dma->rx_size - data->rx_pos);
+   ptr = (unsigned char *)(dma->rx_buf);
+   copied += tty_insert_flip_string(tty_port, ptr,
+   data->rx_pos + state.residue - dma->rx_size);
+   }
+   up->port.icount.rx += copied;
+
+   tty_flip_buffer_push(tty_port);
+
+   mtk8250_rx_dma(up);
+}
+
+static void mtk8250_rx_dma(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct dma_async_tx_descriptor  *desc;
+   struct dma_tx_state  state;
+
+   desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
+  dma->rx_size, DMA_DEV_TO_MEM,
+  DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!desc) {
+   pr_err("failed to prepare rx slave single\n");
+   return;
+   }
+
+   desc->callback = mtk8250_dma_rx_complete;
+   desc->callback_param = up;
+
+   dma->rx_cookie = dmaengine_submit(desc);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   data->rx_pos = state.residue;
+
+   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
+  dma->rx_size, DMA_FROM_DEVICE);
+
+   dma_async_issue_pending(dma->rxchan);
+}
+
+static void mtk8250_dma_enable(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   int lcr = serial_in(up, UART_LCR);
+
+   if (data->rx_status != DMA_RX_START)
+   return;
+
+   dma->rxconf.direction   = DMA_DEV_TO_MEM;
+   dma->rxconf.src_addr_width  = dma->rx_size / 1024;
+   dma->rxconf.src_addr= dma->rx_addr;
+
+   dma->txconf.direction   = DMA_MEM_TO_DEV;
+   dma->txconf.dst_addr_width  = MTK_UART_TX_SIZE / 1024;
+   dma->txconf.dst_addr= dma->tx_addr;
+
+   serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
+   UART_FCR_CLEAR_XMIT);
+   serial_out(up, MTK_UART_DMA_EN,
+  MTK_UART_DMA_EN_RX | MTK_UART_DMA_EN_TX);

[PATCH v2 2/4] dmaengine: mtk_uart_dma: add Mediatek uart DMA support

2018-12-05 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  894 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 906 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..3454679
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,894 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_APDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_APDMA_CHANNELS];
+   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_dma_desc *desc;
+
+   bool stop;
+   bool requested;
+
+   unsigned int dma_sig;
+   unsigned int dma_ch;
+   unsigned int sgidx;
+   unsigned int remain_size;
+   unsigned int rx_ptr;
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+};
+
+static bool mtk_dma_filter_fn(struct dma_chan *chan, void *param);
+static struct of_dma_filter_info mtk_dma_info = {
+   .filter_fn = mtk_dma_filter_fn,
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static int mtk_dma_clk_enable(struct mtk_d

[PATCH v2 2/4] dmaengine: mtk_uart_dma: add Mediatek uart DMA support

2018-12-05 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/mediatek/8250_mtk_dma.c |  894 +++
 drivers/dma/mediatek/Kconfig|   11 +
 drivers/dma/mediatek/Makefile   |1 +
 3 files changed, 906 insertions(+)
 create mode 100644 drivers/dma/mediatek/8250_mtk_dma.c

diff --git a/drivers/dma/mediatek/8250_mtk_dma.c 
b/drivers/dma/mediatek/8250_mtk_dma.c
new file mode 100644
index 000..3454679
--- /dev/null
+++ b/drivers/dma/mediatek/8250_mtk_dma.c
@@ -0,0 +1,894 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "../virt-dma.h"
+
+#define MTK_APDMA_DEFAULT_REQUESTS 127
+#define MTK_APDMA_CHANNELS (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_EN_B   BIT(0)
+#define VFF_STOP_B BIT(0)
+#define VFF_FLUSH_BBIT(0)
+#define VFF_4G_SUPPORT_B   BIT(0)
+#define VFF_RX_INT_EN0_B   BIT(0)  /*rx valid size >=  vff thre*/
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)  /*tx left size >= vff thre*/
+#define VFF_WARM_RST_B BIT(0)
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0) | BIT(1))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_CLR_B0
+#define VFF_INT_EN_CLR_B   0
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+#define VFF_INT_FLAG   0x00
+#define VFF_INT_EN 0x04
+#define VFF_EN 0x08
+#define VFF_RST0x0c
+#define VFF_STOP   0x10
+#define VFF_FLUSH  0x14
+#define VFF_ADDR   0x1c
+#define VFF_LEN0x24
+#define VFF_THRE   0x28
+#define VFF_WPT0x2c
+#define VFF_RPT0x30
+/*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+#define VFF_VALID_SIZE 0x3c
+/*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+#define VFF_LEFT_SIZE  0x40
+#define VFF_DEBUG_STATUS   0x50
+#define VFF_4G_SUPPORT 0x54
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_APDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_APDMA_CHANNELS];
+   struct mtk_chan *ch[MTK_APDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *base;
+   struct mtk_dma_desc *desc;
+
+   bool stop;
+   bool requested;
+
+   unsigned int dma_sig;
+   unsigned int dma_ch;
+   unsigned int sgidx;
+   unsigned int remain_size;
+   unsigned int rx_ptr;
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+};
+
+static bool mtk_dma_filter_fn(struct dma_chan *chan, void *param);
+static struct of_dma_filter_info mtk_dma_info = {
+   .filter_fn = mtk_dma_filter_fn,
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsigned int reg)
+{
+   return readl(c->base + reg);
+}
+
+static void mtk_dma_desc_free(struct virt_dma_desc *vd)
+{
+   struct dma_chan *chan = vd->tx.chan;
+   struct mtk_chan *c = to_mtk_dma_chan(chan);
+
+   kfree(c->desc);
+   c->desc = NULL;
+}
+
+static int mtk_dma_clk_enable(struct mtk_d

[PATCH 1/4] dt-bindings: dma: uart: add uart dma bindings

2018-09-20 Thread Long Cheng
add uart dma bindings

Signed-off-by: Long Cheng 
---
 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   32 
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt 
b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
new file mode 100644
index 000..b140cf4
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
@@ -0,0 +1,32 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+Examples:
+
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2712-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
\ No newline at end of file
-- 
1.7.9.5



[PATCH 0/4] add uart DMA function

2018-09-20 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA 
function.

Long Cheng (4):
  dt-bindings: dma: uart: add uart dma bindings
  dmaengine: mtk_uart_dma: add Mediatek uart DMA support
  serial: 8250-mtk: add uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   32 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi  |   50 +
 drivers/dma/8250_mtk_dma.c | 1049 
 drivers/dma/Kconfig|   11 +
 drivers/dma/Makefile   |1 +
 drivers/tty/serial/8250/8250_mtk.c |  211 +++-
 6 files changed, 1353 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 drivers/dma/8250_mtk_dma.c

-- 
1.7.9.5




[PATCH 1/4] dt-bindings: dma: uart: add uart dma bindings

2018-09-20 Thread Long Cheng
add uart dma bindings

Signed-off-by: Long Cheng 
---
 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   32 
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt 
b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
new file mode 100644
index 000..b140cf4
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
@@ -0,0 +1,32 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2712-uart-dma" for MT2712 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+Examples:
+
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2712-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
\ No newline at end of file
-- 
1.7.9.5



[PATCH 0/4] add uart DMA function

2018-09-20 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA 
function.

Long Cheng (4):
  dt-bindings: dma: uart: add uart dma bindings
  dmaengine: mtk_uart_dma: add Mediatek uart DMA support
  serial: 8250-mtk: add uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 .../devicetree/bindings/dma/8250_mtk_dma.txt   |   32 +
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi  |   50 +
 drivers/dma/8250_mtk_dma.c | 1049 
 drivers/dma/Kconfig|   11 +
 drivers/dma/Makefile   |1 +
 drivers/tty/serial/8250/8250_mtk.c |  211 +++-
 6 files changed, 1353 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/8250_mtk_dma.txt
 create mode 100644 drivers/dma/8250_mtk_dma.c

-- 
1.7.9.5




[PATCH 2/4] dmaengine: mtk_uart_dma: add Mediatek uart DMA support

2018-09-20 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/8250_mtk_dma.c | 1049 
 drivers/dma/Kconfig|   11 +
 drivers/dma/Makefile   |1 +
 3 files changed, 1061 insertions(+)
 create mode 100644 drivers/dma/8250_mtk_dma.c

diff --git a/drivers/dma/8250_mtk_dma.c b/drivers/dma/8250_mtk_dma.c
new file mode 100644
index 000..a07844e
--- /dev/null
+++ b/drivers/dma/8250_mtk_dma.c
@@ -0,0 +1,1049 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#define pr_fmt(fmt) "8250-mtk-dma: " fmt
+#define DRV_NAME"8250-mtk-dma"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define MTK_SDMA_REQUESTS  127
+#define MTK_SDMA_CHANNELS  (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0U) | BIT(1U))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_RX_INT_EN0_B   BIT(0U) /*rx valid size >=  vff thre */
+#define VFF_RX_INT_EN1_B   BIT(1U)
+#define VFF_TX_INT_EN_BBIT(0U) /*tx left size >= vff thre */
+#define VFF_INT_EN_CLR_B   0
+#define VFF_WARM_RST_B BIT(0U)
+#define VFF_EN_B   BIT(0U)
+#define VFF_STOP_B BIT(0U)
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_BBIT(0U)
+#define VFF_FLUSH_CLR_B0
+#define VFF_4G_SUPPORT_B   BIT(0U)
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_SDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_SDMA_CHANNELS];
+   struct mtk_chan *lch_map[MTK_SDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *channel_base;
+   struct mtk_dma_desc *desc;
+
+   bool paused;
+   bool requested;
+
+   unsigned int dma_sig;
+   unsigned int dma_ch;
+   unsigned int sgidx;
+   unsigned int remain_size;
+   unsigned int rx_ptr;
+
+   /*sync*/
+   struct completion done; /* dma transfer done */
+   spinlock_t lock; /* channel lock */
+   atomic_t loopcnt;
+   atomic_t entry; /* entry count */
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+   dma_addr_t dev_addr;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+};
+
+enum {
+   VFF_INT_FLAG= 0x00,
+   VFF_INT_EN  = 0x04,
+   VFF_EN  = 0x08,
+   VFF_RST = 0x0c,
+   VFF_STOP= 0x10,
+   VFF_FLUSH   = 0x14,
+   VFF_ADDR= 0x1c,
+   VFF_LEN = 0x24,
+   VFF_THRE= 0x28,
+   VFF_WPT = 0x2c,
+   VFF_RPT = 0x30,
+   /*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+   VFF_VALID_SIZE  = 0x3c,
+   /*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+   VFF_LEFT_SIZE   = 0x40,
+   VFF_DEBUG_STATUS= 0x50,
+   VFF_4G_SUPPORT  = 0x54,
+};
+
+static bool mtk_dma_filter_fn(struct dma_chan *chan, void *param);
+static struct of_dma_filter_info mtk_dma_info = {
+   .filter_fn = mtk_dma_filter_fn,
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->channel_base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsi

[PATCH 3/4] serial: 8250-mtk: add uart DMA support

2018-09-20 Thread Long Cheng
Modify uart register to support DMA function.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |  211 +++-
 1 file changed, 210 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index dd5e1ce..9da9db4 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -14,6 +14,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include "8250.h"
 
@@ -22,12 +26,173 @@
 #define UART_MTK_SAMPLE_POINT  0x0b/* Sample point register */
 #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
 
+#define MTK_UART_DMA_EN0x13/* DMA Enable register */
+#define MTK_UART_DMA_EN_TX 0x2
+#define MTK_UART_DMA_EN_RX 0x5
+
+#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
+#define MTK_UART_RX_SIZE   0x8000
+#define MTK_UART_TX_TRIGGER1
+#define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
+
+#ifdef CONFIG_SERIAL_8250_DMA
+enum dma_rx_status {
+   DMA_RX_START = 0,
+   DMA_RX_RUNNING = 1,
+   DMA_RX_SHUTDOWN = 2,
+};
+#endif
+
 struct mtk8250_data {
int line;
+   unsigned intrx_pos;
struct clk  *uart_clk;
struct clk  *bus_clk;
+   struct uart_8250_dma*dma;
+#ifdef CONFIG_SERIAL_8250_DMA
+   enum dma_rx_status  rx_status;
+#endif
 };
 
+#ifdef CONFIG_SERIAL_8250_DMA
+static void mtk8250_rx_dma(struct uart_8250_port *up);
+
+static void mtk8250_dma_rx_complete(void *param)
+{
+   struct uart_8250_port *up = param;
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct tty_port *tty_port = >port.state->port;
+   struct dma_tx_state state;
+   unsigned char *ptr;
+   int copied;
+
+   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
+   dma->rx_size, DMA_FROM_DEVICE);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   dmaengine_terminate_all(dma->rxchan);
+
+   if (data->rx_status == DMA_RX_SHUTDOWN)
+   return;
+
+   if ((data->rx_pos + state.residue) <= dma->rx_size) {
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
+   } else {
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr,
+   dma->rx_size - data->rx_pos);
+   ptr = (unsigned char *)(dma->rx_buf);
+   copied += tty_insert_flip_string(tty_port, ptr,
+   data->rx_pos + state.residue - dma->rx_size);
+   }
+   up->port.icount.rx += copied;
+
+   tty_flip_buffer_push(tty_port);
+
+   mtk8250_rx_dma(up);
+}
+
+static void mtk8250_rx_dma(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct dma_async_tx_descriptor  *desc;
+   struct dma_tx_state  state;
+
+   desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
+  dma->rx_size, DMA_DEV_TO_MEM,
+  DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!desc) {
+   pr_err("failed to prepare rx slave single\n");
+   return;
+   }
+
+   desc->callback = mtk8250_dma_rx_complete;
+   desc->callback_param = up;
+
+   dma->rx_cookie = dmaengine_submit(desc);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   data->rx_pos = state.residue;
+
+   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
+  dma->rx_size, DMA_FROM_DEVICE);
+
+   dma_async_issue_pending(dma->rxchan);
+}
+
+static void mtk8250_dma_enable(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   int lcr = serial_in(up, UART_LCR);
+
+   if (data->rx_status != DMA_RX_START)
+   return;
+
+   dma->rxconf.direction   = DMA_DEV_TO_MEM;
+   dma->rxconf.src_addr_width  = dma->rx_size / 1024;
+   dma->rxconf.src_addr= dma->rx_addr;
+
+   dma->txconf.direction   = DMA_MEM_TO_DEV;
+   dma->txconf.dst_addr_width  = MTK_UART_TX_SIZE / 1024;
+   dma->txconf.dst_addr= dma->tx_addr;
+
+   serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
+   UART_FCR_CLEAR_XMIT);
+   serial_out(up, MTK_UART_DMA_EN,
+

[PATCH 2/4] dmaengine: mtk_uart_dma: add Mediatek uart DMA support

2018-09-20 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/8250_mtk_dma.c | 1049 
 drivers/dma/Kconfig|   11 +
 drivers/dma/Makefile   |1 +
 3 files changed, 1061 insertions(+)
 create mode 100644 drivers/dma/8250_mtk_dma.c

diff --git a/drivers/dma/8250_mtk_dma.c b/drivers/dma/8250_mtk_dma.c
new file mode 100644
index 000..a07844e
--- /dev/null
+++ b/drivers/dma/8250_mtk_dma.c
@@ -0,0 +1,1049 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Mediatek 8250 DMA driver.
+ *
+ * Copyright (c) 2018 MediaTek Inc.
+ * Author: Long Cheng 
+ */
+
+#define pr_fmt(fmt) "8250-mtk-dma: " fmt
+#define DRV_NAME"8250-mtk-dma"
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define MTK_SDMA_REQUESTS  127
+#define MTK_SDMA_CHANNELS  (CONFIG_SERIAL_8250_NR_UARTS * 2)
+
+#define VFF_RX_INT_FLAG_CLR_B  (BIT(0U) | BIT(1U))
+#define VFF_TX_INT_FLAG_CLR_B  0
+#define VFF_RX_INT_EN0_B   BIT(0U) /*rx valid size >=  vff thre */
+#define VFF_RX_INT_EN1_B   BIT(1U)
+#define VFF_TX_INT_EN_BBIT(0U) /*tx left size >= vff thre */
+#define VFF_INT_EN_CLR_B   0
+#define VFF_WARM_RST_B BIT(0U)
+#define VFF_EN_B   BIT(0U)
+#define VFF_STOP_B BIT(0U)
+#define VFF_STOP_CLR_B 0
+#define VFF_FLUSH_BBIT(0U)
+#define VFF_FLUSH_CLR_B0
+#define VFF_4G_SUPPORT_B   BIT(0U)
+#define VFF_4G_SUPPORT_CLR_B   0
+
+/* interrupt trigger level for tx */
+#define VFF_TX_THRE(n) ((n) * 7 / 8)
+/* interrupt trigger level for rx */
+#define VFF_RX_THRE(n) ((n) * 3 / 4)
+
+#define MTK_DMA_RING_SIZE  0xU
+/* invert this bit when wrap ring head again*/
+#define MTK_DMA_RING_WRAP  0x1U
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   void __iomem *mem_base[MTK_SDMA_CHANNELS];
+   spinlock_t lock; /* dma dev lock */
+   struct tasklet_struct task;
+   struct list_head pending;
+   struct clk *clk;
+   unsigned int dma_requests;
+   bool support_33bits;
+   unsigned int dma_irq[MTK_SDMA_CHANNELS];
+   struct mtk_chan *lch_map[MTK_SDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   struct dma_slave_config cfg;
+   void __iomem *channel_base;
+   struct mtk_dma_desc *desc;
+
+   bool paused;
+   bool requested;
+
+   unsigned int dma_sig;
+   unsigned int dma_ch;
+   unsigned int sgidx;
+   unsigned int remain_size;
+   unsigned int rx_ptr;
+
+   /*sync*/
+   struct completion done; /* dma transfer done */
+   spinlock_t lock; /* channel lock */
+   atomic_t loopcnt;
+   atomic_t entry; /* entry count */
+};
+
+struct mtk_dma_sg {
+   dma_addr_t addr;
+   unsigned int en;/* number of elements (24-bit) */
+   unsigned int fn;/* number of frames (16-bit) */
+};
+
+struct mtk_dma_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+   dma_addr_t dev_addr;
+
+   unsigned int sglen;
+   struct mtk_dma_sg sg[0];
+};
+
+enum {
+   VFF_INT_FLAG= 0x00,
+   VFF_INT_EN  = 0x04,
+   VFF_EN  = 0x08,
+   VFF_RST = 0x0c,
+   VFF_STOP= 0x10,
+   VFF_FLUSH   = 0x14,
+   VFF_ADDR= 0x1c,
+   VFF_LEN = 0x24,
+   VFF_THRE= 0x28,
+   VFF_WPT = 0x2c,
+   VFF_RPT = 0x30,
+   /*TX: the buffer size HW can read. RX: the buffer size SW can read.*/
+   VFF_VALID_SIZE  = 0x3c,
+   /*TX: the buffer size SW can write. RX: the buffer size HW can write.*/
+   VFF_LEFT_SIZE   = 0x40,
+   VFF_DEBUG_STATUS= 0x50,
+   VFF_4G_SUPPORT  = 0x54,
+};
+
+static bool mtk_dma_filter_fn(struct dma_chan *chan, void *param);
+static struct of_dma_filter_info mtk_dma_info = {
+   .filter_fn = mtk_dma_filter_fn,
+};
+
+static inline struct mtk_dmadev *to_mtk_dma_dev(struct dma_device *d)
+{
+   return container_of(d, struct mtk_dmadev, ddev);
+}
+
+static inline struct mtk_chan *to_mtk_dma_chan(struct dma_chan *c)
+{
+   return container_of(c, struct mtk_chan, vc.chan);
+}
+
+static inline struct mtk_dma_desc *to_mtk_dma_desc
+   (struct dma_async_tx_descriptor *t)
+{
+   return container_of(t, struct mtk_dma_desc, vd.tx);
+}
+
+static void mtk_dma_chan_write(struct mtk_chan *c,
+  unsigned int reg, unsigned int val)
+{
+   writel(val, c->channel_base + reg);
+}
+
+static unsigned int mtk_dma_chan_read(struct mtk_chan *c, unsi

[PATCH 3/4] serial: 8250-mtk: add uart DMA support

2018-09-20 Thread Long Cheng
Modify uart register to support DMA function.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |  211 +++-
 1 file changed, 210 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index dd5e1ce..9da9db4 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -14,6 +14,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include "8250.h"
 
@@ -22,12 +26,173 @@
 #define UART_MTK_SAMPLE_POINT  0x0b/* Sample point register */
 #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
 
+#define MTK_UART_DMA_EN0x13/* DMA Enable register */
+#define MTK_UART_DMA_EN_TX 0x2
+#define MTK_UART_DMA_EN_RX 0x5
+
+#define MTK_UART_TX_SIZE   UART_XMIT_SIZE
+#define MTK_UART_RX_SIZE   0x8000
+#define MTK_UART_TX_TRIGGER1
+#define MTK_UART_RX_TRIGGERMTK_UART_RX_SIZE
+
+#ifdef CONFIG_SERIAL_8250_DMA
+enum dma_rx_status {
+   DMA_RX_START = 0,
+   DMA_RX_RUNNING = 1,
+   DMA_RX_SHUTDOWN = 2,
+};
+#endif
+
 struct mtk8250_data {
int line;
+   unsigned intrx_pos;
struct clk  *uart_clk;
struct clk  *bus_clk;
+   struct uart_8250_dma*dma;
+#ifdef CONFIG_SERIAL_8250_DMA
+   enum dma_rx_status  rx_status;
+#endif
 };
 
+#ifdef CONFIG_SERIAL_8250_DMA
+static void mtk8250_rx_dma(struct uart_8250_port *up);
+
+static void mtk8250_dma_rx_complete(void *param)
+{
+   struct uart_8250_port *up = param;
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct tty_port *tty_port = >port.state->port;
+   struct dma_tx_state state;
+   unsigned char *ptr;
+   int copied;
+
+   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
+   dma->rx_size, DMA_FROM_DEVICE);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   dmaengine_terminate_all(dma->rxchan);
+
+   if (data->rx_status == DMA_RX_SHUTDOWN)
+   return;
+
+   if ((data->rx_pos + state.residue) <= dma->rx_size) {
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
+   } else {
+   ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr,
+   dma->rx_size - data->rx_pos);
+   ptr = (unsigned char *)(dma->rx_buf);
+   copied += tty_insert_flip_string(tty_port, ptr,
+   data->rx_pos + state.residue - dma->rx_size);
+   }
+   up->port.icount.rx += copied;
+
+   tty_flip_buffer_push(tty_port);
+
+   mtk8250_rx_dma(up);
+}
+
+static void mtk8250_rx_dma(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct dma_async_tx_descriptor  *desc;
+   struct dma_tx_state  state;
+
+   desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
+  dma->rx_size, DMA_DEV_TO_MEM,
+  DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!desc) {
+   pr_err("failed to prepare rx slave single\n");
+   return;
+   }
+
+   desc->callback = mtk8250_dma_rx_complete;
+   desc->callback_param = up;
+
+   dma->rx_cookie = dmaengine_submit(desc);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   data->rx_pos = state.residue;
+
+   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
+  dma->rx_size, DMA_FROM_DEVICE);
+
+   dma_async_issue_pending(dma->rxchan);
+}
+
+static void mtk8250_dma_enable(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   int lcr = serial_in(up, UART_LCR);
+
+   if (data->rx_status != DMA_RX_START)
+   return;
+
+   dma->rxconf.direction   = DMA_DEV_TO_MEM;
+   dma->rxconf.src_addr_width  = dma->rx_size / 1024;
+   dma->rxconf.src_addr= dma->rx_addr;
+
+   dma->txconf.direction   = DMA_MEM_TO_DEV;
+   dma->txconf.dst_addr_width  = MTK_UART_TX_SIZE / 1024;
+   dma->txconf.dst_addr= dma->tx_addr;
+
+   serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
+   UART_FCR_CLEAR_XMIT);
+   serial_out(up, MTK_UART_DMA_EN,
+

[PATCH 4/4] arm: dts: mt2701: add uart APDMA to device tree

2018-09-20 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3 DMA function
3. uart0 is console, So disable DMA
4. enable uart2 port to test DMA function.

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 593ddc7..ff94437 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -299,6 +299,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -366,6 +369,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -373,6 +408,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -383,6 +421,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -393,6 +434,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -403,6 +447,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -503,6 +550,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH 4/4] arm: dts: mt2701: add uart APDMA to device tree

2018-09-20 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3 DMA function
3. uart0 is console, So disable DMA
4. enable uart2 port to test DMA function.

Signed-off-by: Long Cheng 
---
 arch/arm64/boot/dts/mediatek/mt2712e.dtsi |   50 +
 1 file changed, 50 insertions(+)

diff --git a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi 
b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
index 593ddc7..ff94437 100644
--- a/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
+++ b/arch/arm64/boot/dts/mediatek/mt2712e.dtsi
@@ -299,6 +299,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 10
+11>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -366,6 +369,38 @@
status = "disabled";
};
 
+   apdma: dma-controller@11000400 {
+   compatible = "mediatek,mt2712-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000400 0 0x80>,
+ <0 0x11000480 0 0x80>,
+ <0 0x11000500 0 0x80>,
+ <0 0x11000580 0 0x80>,
+ <0 0x11000600 0 0x80>,
+ <0 0x11000680 0 0x80>,
+ <0 0x11000700 0 0x80>,
+ <0 0x11000780 0 0x80>,
+ <0 0x11000800 0 0x80>,
+ <0 0x11000880 0 0x80>,
+ <0 0x11000900 0 0x80>,
+ <0 0x11000980 0 0x80>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2712-uart",
 "mediatek,mt6577-uart";
@@ -373,6 +408,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -383,6 +421,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -393,6 +434,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -403,6 +447,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -503,6 +550,9 @@
interrupts = ;
clocks = <_clk>, <_clk>;
clock-names = "baud", "bus";
+   dmas = < 8
+9>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
-- 
1.7.9.5



[PATCH 2/4] dmaengine: mtk_uart_dma: add Mediatek uart DMA support

2017-02-16 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng <long.ch...@mediatek.com>
---
 drivers/dma/Kconfig|9 +
 drivers/dma/Makefile   |1 +
 drivers/dma/mtk_uart_dma.c |  955 
 3 files changed, 965 insertions(+)
 create mode 100644 drivers/dma/mtk_uart_dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 263495d..d76dc96 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -128,6 +128,15 @@ config DMA_JZ4780
  If you have a board based on such a SoC and wish to use DMA for
  devices which can use the DMA controller, say Y or M here.
 
+config DMA_MTK_UART
+   tristate "MediaTek SoCs APDMA support for UART"
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Support for the UART DMA engine found on MediaTek MTK SoCs.
+ This DMA engine just only if used when 8250 mtk uart is enabled.
+
 config DMA_OMAP
tristate "OMAP DMA support"
depends on ARCH_OMAP || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index a4fa336..5f0404a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
 obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
 obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o
+obj-$(CONFIG_DMA_MTK_UART) += mtk_uart_dma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 obj-$(CONFIG_DMA_SUN4I) += sun4i-dma.o
diff --git a/drivers/dma/mtk_uart_dma.c b/drivers/dma/mtk_uart_dma.c
new file mode 100644
index 000..b884079
--- /dev/null
+++ b/drivers/dma/mtk_uart_dma.c
@@ -0,0 +1,955 @@
+/*
+ * MTK DMAengine support
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Long Cheng (Long) <long.ch...@mediatek.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define MTK_SDMA_REQUESTS  127
+#define MTK_SDMA_CHANNELS  8
+#define MTK_POLLING_CNT1
+
+#define DRV_NAME   "mtk-uart-dma"
+
+/*---*/
+#define VFF_INT_FLAG_CLR_B 0
+/*VFF_INT_EN*/
+#define VFF_RX_INT_EN0_B   BIT(0)
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)
+#define VFF_INT_EN_CLR_B   0
+/*VFF_RST*/
+#define VFF_WARM_RST_B BIT(0)
+/*VFF_EN*/
+#define VFF_EN_B   BIT(0)
+/*VFF_STOP*/
+#define VFF_STOP_B BIT(0)
+#define VFF_STOP_CLR_B 0
+/*VFF_FLUSH*/
+#define VFF_FLUSH_BBIT(0)
+#define VFF_FLUSH_CLR_B0
+
+#define VFF_TX_THRE(n) ((n)*7/8)
+#define VFF_RX_THRE(n) ((n)*3/4)
+
+/*---*/
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   spinlock_t lock;
+   struct tasklet_struct task;
+   struct list_head pending;
+   void __iomem *base;
+   int irq;
+   struct clk *clk;
+   unsigned int dma_requests;
+   uint32_t irq_enable_mask;
+   struct mtk_chan *lch_map[MTK_SDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   void __iomem *channel_base;
+   uint32_t ccr;
+
+   struct dma_slave_config cfg;
+   unsigned int dma_sig;
+   bool paused;
+   bool requested;
+
+   int dma_ch;
+   struct mtk_desc *desc;
+   unsigned int sgidx;
+
+   size_t trig;
+   size_t remain_size;
+   size_t rx_ptr;
+
+   /*sync*/
+   struct completion done; /* dma transfer done */
+   spinlock_t lock;
+   atomic_t loopcnt;
+   atomic_t entry; /* entry count */
+};
+
+struct mtk_sg {
+   dma_addr_t addr;
+   uint32_t en;/* number of elements (24-bit) */
+   uint32_t fn;/* number of frames (16-bit) */
+};
+
+struct mtk_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+   dma_addr_t dev_addr;
+
+   unsigned int sglen;
+   struct mtk_sg sg[0];
+};
+
+enum {
+   VFF_INT_FLAG= 0x00,
+   VFF_INT_EN  = 0x04,
+   VFF_EN  = 0x08,
+   VFF_RST = 0x0c,
+   VFF_STOP= 0x10,
+   VFF_FLUSH   = 0x14,
+   VFF_ADDR= 0x1c,
+   VFF_LEN = 0x24,
+   VFF_THRE= 0x28,
+   VFF_WPT = 0x2c,
+   VFF_RPT = 0x30,
+   V

[PATCH 4/4] arm: dts: mt2701: add uart APDMA to device tree

2017-02-16 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3 DMA function
3. uart0 is console, So disable DMA
4. enable uart2 port to test DMA function.

Signed-off-by: Long Cheng <long.ch...@mediatek.com>
---
 arch/arm/boot/dts/mt2701-evb.dts |   22 ++
 arch/arm/boot/dts/mt2701.dtsi|   29 +
 2 files changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
index 082ca88..2f92bf9 100644
--- a/arch/arm/boot/dts/mt2701-evb.dts
+++ b/arch/arm/boot/dts/mt2701-evb.dts
@@ -24,6 +24,28 @@
};
 };
 
+ {
+   uart2_default_cfg: uart2default {
+   pins_cmd_dat {
+   pinmux = ,
+,
+,
+;
+   bias-pull-up;
+   };
+   };
+};
+
  {
+   dmas = "";
+   dma-names = "";
+
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_default_cfg>;
+
status = "okay";
 };
diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 7eab6f4..62b3ec9 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -175,6 +175,23 @@
  <0 0x10216000 0 0x2000>;
};
 
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2701-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2701-uart",
 "mediatek,mt6577-uart";
@@ -182,6 +199,9 @@
interrupts = ;
clocks = < CLK_PERI_UART0_SEL>, < 
CLK_PERI_UART0>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -192,6 +212,9 @@
interrupts = ;
clocks = < CLK_PERI_UART1_SEL>, < 
CLK_PERI_UART1>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -202,6 +225,9 @@
interrupts = ;
clocks = < CLK_PERI_UART2_SEL>, < 
CLK_PERI_UART2>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -212,6 +238,9 @@
interrupts = ;
clocks = < CLK_PERI_UART3_SEL>, < 
CLK_PERI_UART3>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 };
-- 
1.7.9.5



[PATCH 2/4] dmaengine: mtk_uart_dma: add Mediatek uart DMA support

2017-02-16 Thread Long Cheng
In DMA engine framework, add 8250 mtk dma to support it.

Signed-off-by: Long Cheng 
---
 drivers/dma/Kconfig|9 +
 drivers/dma/Makefile   |1 +
 drivers/dma/mtk_uart_dma.c |  955 
 3 files changed, 965 insertions(+)
 create mode 100644 drivers/dma/mtk_uart_dma.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 263495d..d76dc96 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -128,6 +128,15 @@ config DMA_JZ4780
  If you have a board based on such a SoC and wish to use DMA for
  devices which can use the DMA controller, say Y or M here.
 
+config DMA_MTK_UART
+   tristate "MediaTek SoCs APDMA support for UART"
+   depends on OF
+   select DMA_ENGINE
+   select DMA_VIRTUAL_CHANNELS
+   help
+ Support for the UART DMA engine found on MediaTek MTK SoCs.
+ This DMA engine just only if used when 8250 mtk uart is enabled.
+
 config DMA_OMAP
tristate "OMAP DMA support"
depends on ARCH_OMAP || COMPILE_TEST
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index a4fa336..5f0404a 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -21,6 +21,7 @@ obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
 obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
 obj-$(CONFIG_DMA_JZ4780) += dma-jz4780.o
+obj-$(CONFIG_DMA_MTK_UART) += mtk_uart_dma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 obj-$(CONFIG_DMA_SUN4I) += sun4i-dma.o
diff --git a/drivers/dma/mtk_uart_dma.c b/drivers/dma/mtk_uart_dma.c
new file mode 100644
index 000..b884079
--- /dev/null
+++ b/drivers/dma/mtk_uart_dma.c
@@ -0,0 +1,955 @@
+/*
+ * MTK DMAengine support
+ *
+ * Copyright (c) 2016 MediaTek Inc.
+ * Author: Long Cheng (Long) 
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "virt-dma.h"
+
+#define MTK_SDMA_REQUESTS  127
+#define MTK_SDMA_CHANNELS  8
+#define MTK_POLLING_CNT1
+
+#define DRV_NAME   "mtk-uart-dma"
+
+/*---*/
+#define VFF_INT_FLAG_CLR_B 0
+/*VFF_INT_EN*/
+#define VFF_RX_INT_EN0_B   BIT(0)
+#define VFF_RX_INT_EN1_B   BIT(1)
+#define VFF_TX_INT_EN_BBIT(0)
+#define VFF_INT_EN_CLR_B   0
+/*VFF_RST*/
+#define VFF_WARM_RST_B BIT(0)
+/*VFF_EN*/
+#define VFF_EN_B   BIT(0)
+/*VFF_STOP*/
+#define VFF_STOP_B BIT(0)
+#define VFF_STOP_CLR_B 0
+/*VFF_FLUSH*/
+#define VFF_FLUSH_BBIT(0)
+#define VFF_FLUSH_CLR_B0
+
+#define VFF_TX_THRE(n) ((n)*7/8)
+#define VFF_RX_THRE(n) ((n)*3/4)
+
+/*---*/
+
+struct mtk_dmadev {
+   struct dma_device ddev;
+   spinlock_t lock;
+   struct tasklet_struct task;
+   struct list_head pending;
+   void __iomem *base;
+   int irq;
+   struct clk *clk;
+   unsigned int dma_requests;
+   uint32_t irq_enable_mask;
+   struct mtk_chan *lch_map[MTK_SDMA_CHANNELS];
+};
+
+struct mtk_chan {
+   struct virt_dma_chan vc;
+   struct list_head node;
+   void __iomem *channel_base;
+   uint32_t ccr;
+
+   struct dma_slave_config cfg;
+   unsigned int dma_sig;
+   bool paused;
+   bool requested;
+
+   int dma_ch;
+   struct mtk_desc *desc;
+   unsigned int sgidx;
+
+   size_t trig;
+   size_t remain_size;
+   size_t rx_ptr;
+
+   /*sync*/
+   struct completion done; /* dma transfer done */
+   spinlock_t lock;
+   atomic_t loopcnt;
+   atomic_t entry; /* entry count */
+};
+
+struct mtk_sg {
+   dma_addr_t addr;
+   uint32_t en;/* number of elements (24-bit) */
+   uint32_t fn;/* number of frames (16-bit) */
+};
+
+struct mtk_desc {
+   struct virt_dma_desc vd;
+   enum dma_transfer_direction dir;
+   dma_addr_t dev_addr;
+
+   unsigned int sglen;
+   struct mtk_sg sg[0];
+};
+
+enum {
+   VFF_INT_FLAG= 0x00,
+   VFF_INT_EN  = 0x04,
+   VFF_EN  = 0x08,
+   VFF_RST = 0x0c,
+   VFF_STOP= 0x10,
+   VFF_FLUSH   = 0x14,
+   VFF_ADDR= 0x1c,
+   VFF_LEN = 0x24,
+   VFF_THRE= 0x28,
+   VFF_WPT = 0x2c,
+   VFF_RPT = 0x30,
+   VFF_VALID_SIZE  = 0x3c,
+   VFF_LEFT_SIZE   

[PATCH 4/4] arm: dts: mt2701: add uart APDMA to device tree

2017-02-16 Thread Long Cheng
1. add uart APDMA controller device node
2. add uart 0/1/2/3 DMA function
3. uart0 is console, So disable DMA
4. enable uart2 port to test DMA function.

Signed-off-by: Long Cheng 
---
 arch/arm/boot/dts/mt2701-evb.dts |   22 ++
 arch/arm/boot/dts/mt2701.dtsi|   29 +
 2 files changed, 51 insertions(+)

diff --git a/arch/arm/boot/dts/mt2701-evb.dts b/arch/arm/boot/dts/mt2701-evb.dts
index 082ca88..2f92bf9 100644
--- a/arch/arm/boot/dts/mt2701-evb.dts
+++ b/arch/arm/boot/dts/mt2701-evb.dts
@@ -24,6 +24,28 @@
};
 };
 
+ {
+   uart2_default_cfg: uart2default {
+   pins_cmd_dat {
+   pinmux = ,
+,
+,
+;
+   bias-pull-up;
+   };
+   };
+};
+
  {
+   dmas = "";
+   dma-names = "";
+
+   status = "okay";
+};
+
+ {
+   pinctrl-names = "default";
+   pinctrl-0 = <_default_cfg>;
+
status = "okay";
 };
diff --git a/arch/arm/boot/dts/mt2701.dtsi b/arch/arm/boot/dts/mt2701.dtsi
index 7eab6f4..62b3ec9 100644
--- a/arch/arm/boot/dts/mt2701.dtsi
+++ b/arch/arm/boot/dts/mt2701.dtsi
@@ -175,6 +175,23 @@
  <0 0x10216000 0 0x2000>;
};
 
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2701-uart-dma",
+"mediatek,mt6577-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
+
uart0: serial@11002000 {
compatible = "mediatek,mt2701-uart",
 "mediatek,mt6577-uart";
@@ -182,6 +199,9 @@
interrupts = ;
clocks = < CLK_PERI_UART0_SEL>, < 
CLK_PERI_UART0>;
clock-names = "baud", "bus";
+   dmas = < 0
+1>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -192,6 +212,9 @@
interrupts = ;
clocks = < CLK_PERI_UART1_SEL>, < 
CLK_PERI_UART1>;
clock-names = "baud", "bus";
+   dmas = < 2
+3>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -202,6 +225,9 @@
interrupts = ;
clocks = < CLK_PERI_UART2_SEL>, < 
CLK_PERI_UART2>;
clock-names = "baud", "bus";
+   dmas = < 4
+5>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 
@@ -212,6 +238,9 @@
interrupts = ;
clocks = < CLK_PERI_UART3_SEL>, < 
CLK_PERI_UART3>;
clock-names = "baud", "bus";
+   dmas = < 6
+7>;
+   dma-names = "tx", "rx";
status = "disabled";
};
 };
-- 
1.7.9.5



[PATCH 1/4] dt-bindings: dma: uart: add uart dma bindings

2017-02-16 Thread Long Cheng
add uart dma bindings

Signed-off-by: Long Cheng <long.ch...@mediatek.com>
---
 .../devicetree/bindings/dma/mtk_uart_dma.txt   |   32 
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mtk_uart_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mtk_uart_dma.txt 
b/Documentation/devicetree/bindings/dma/mtk_uart_dma.txt
new file mode 100644
index 000..b8aa7f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mtk_uart_dma.txt
@@ -0,0 +1,32 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2701-uart-dma" for MT2701 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+Examples:
+
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2701-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
-- 
1.7.9.5



[PATCH 1/4] dt-bindings: dma: uart: add uart dma bindings

2017-02-16 Thread Long Cheng
add uart dma bindings

Signed-off-by: Long Cheng 
---
 .../devicetree/bindings/dma/mtk_uart_dma.txt   |   32 
 1 file changed, 32 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/mtk_uart_dma.txt

diff --git a/Documentation/devicetree/bindings/dma/mtk_uart_dma.txt 
b/Documentation/devicetree/bindings/dma/mtk_uart_dma.txt
new file mode 100644
index 000..b8aa7f4
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/mtk_uart_dma.txt
@@ -0,0 +1,32 @@
+* Mediatek UART APDMA Controller
+
+Required properties:
+- compatible should contain:
+  * "mediatek,mt2701-uart-dma" for MT2701 compatible APDMA
+  * "mediatek,mt6577-uart-dma" for MT6577 and all of the above
+
+- reg: The base address of the APDMA register bank.
+
+- interrupts: A single interrupt specifier.
+
+- clocks : Must contain an entry for each entry in clock-names.
+  See ../clocks/clock-bindings.txt for details.
+- clock-names: The APDMA clock for register accesses
+
+Examples:
+
+   apdma: dma-controller@11000380 {
+   compatible = "mediatek,mt2701-uart-dma";
+   reg = <0 0x11000380 0 0x400>;
+   interrupts = ,
+,
+,
+,
+,
+,
+,
+;
+   clocks = < CLK_PERI_AP_DMA>;
+   clock-names = "apdma";
+   #dma-cells = <1>;
+   };
-- 
1.7.9.5



[PATCH 3/4] serial: 8250-mtk: add uart DMA support

2017-02-16 Thread Long Cheng
Modify uart register to support DMA function.

Signed-off-by: Long Cheng <long.ch...@mediatek.com>
---
 drivers/tty/serial/8250/8250_mtk.c |  194 +++-
 1 file changed, 193 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index ce0cc47..7d7a864 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -23,6 +23,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include "8250.h"
 
@@ -30,13 +34,165 @@
 #define UART_MTK_SAMPLE_COUNT  0x0a/* Sample count register */
 #define UART_MTK_SAMPLE_POINT  0x0b/* Sample point register */
 #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
-
+#define UART_MTK_DMA_EN0x13
+#define TX_TRIGGER 1
+#define RX_TRIGGER 8192
+
+#ifdef CONFIG_SERIAL_8250_DMA
+enum dma_rx_status {
+   DMA_RX_START = 0,
+   DMA_RX_RUNNING = 1,
+   DMA_RX_SHUTDOWN = 2,
+};
+#endif
 struct mtk8250_data {
int line;
+   int rxpos;
struct clk  *uart_clk;
struct clk  *bus_clk;
+   struct uart_8250_dma*dma;
+#ifdef CONFIG_SERIAL_8250_DMA
+   enum dma_rx_status  rxstatus;
+#endif
 };
 
+#ifdef CONFIG_SERIAL_8250_DMA
+static int mtk8250_rx_dma(struct uart_8250_port *up);
+
+static void __mtkdma_rx_complete(void *param)
+{
+   struct uart_8250_port *up = param;
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct tty_port *tty_port = >port.state->port;
+   struct dma_tx_state state;
+   unsigned char *ptr;
+   int copied;
+
+   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
+   dma->rx_size, DMA_FROM_DEVICE);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   dmaengine_terminate_all(dma->rxchan);
+
+   if (data->rxstatus == DMA_RX_SHUTDOWN)
+   return;
+
+   if ((data->rxpos + state.residue) <= dma->rx_size) {
+   ptr = (unsigned char *)(data->rxpos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
+   } else {
+   ptr = (unsigned char *)(data->rxpos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr,
+   (dma->rx_size - data->rxpos));
+   ptr = (unsigned char *)(dma->rx_buf);
+   copied += tty_insert_flip_string(tty_port, ptr,
+   (data->rxpos + state.residue - dma->rx_size));
+   }
+   up->port.icount.rx += copied;
+
+   tty_flip_buffer_push(tty_port);
+
+   mtk8250_rx_dma(up);
+}
+
+static int mtk8250_rx_dma(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct dma_async_tx_descriptor  *desc;
+   struct dma_tx_state  state;
+
+   desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
+  dma->rx_size, DMA_DEV_TO_MEM,
+  DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!desc)
+   return -EBUSY;
+
+   desc->callback = __mtkdma_rx_complete;
+   desc->callback_param = up;
+
+   dma->rx_cookie = dmaengine_submit(desc);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   data->rxpos = state.residue;
+
+   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
+  dma->rx_size, DMA_FROM_DEVICE);
+
+   dma_async_issue_pending(dma->rxchan);
+
+   return 0;
+}
+
+static void mtk_dma_enable(struct uart_8250_port *up)
+{
+   struct uart_port *port = >port;
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   int tmp = 0;
+
+   if (data->rxstatus != DMA_RX_START)
+   return;
+
+   dma->rxconf.direction   = DMA_DEV_TO_MEM;
+   dma->rxconf.src_addr_width  = dma->rx_size/1024;
+   dma->rxconf.src_addr= dma->rx_addr;
+
+   dma->txconf.direction   = DMA_MEM_TO_DEV;
+   dma->txconf.dst_addr_width  = UART_XMIT_SIZE/1024;
+   dma->txconf.dst_addr= dma->tx_addr;
+
+   serial_port_out(port, UART_FCR, ((1 << 0)|(1 << 1)|(1 << 2)));
+   serial_port_out(port, UART_MTK_DMA_EN,
+   (serial_port_in(port, UART_MTK_DMA_EN) |
+   ((1 << 0) | (1 << 2;
+   serial_port_out(port, UART_MTK_DMA_EN,
+   (serial_port

[PATCH 3/4] serial: 8250-mtk: add uart DMA support

2017-02-16 Thread Long Cheng
Modify uart register to support DMA function.

Signed-off-by: Long Cheng 
---
 drivers/tty/serial/8250/8250_mtk.c |  194 +++-
 1 file changed, 193 insertions(+), 1 deletion(-)

diff --git a/drivers/tty/serial/8250/8250_mtk.c 
b/drivers/tty/serial/8250/8250_mtk.c
index ce0cc47..7d7a864 100644
--- a/drivers/tty/serial/8250/8250_mtk.c
+++ b/drivers/tty/serial/8250/8250_mtk.c
@@ -23,6 +23,10 @@
 #include 
 #include 
 #include 
+#include 
+#include 
+#include 
+#include 
 
 #include "8250.h"
 
@@ -30,13 +34,165 @@
 #define UART_MTK_SAMPLE_COUNT  0x0a/* Sample count register */
 #define UART_MTK_SAMPLE_POINT  0x0b/* Sample point register */
 #define MTK_UART_RATE_FIX  0x0d/* UART Rate Fix Register */
-
+#define UART_MTK_DMA_EN0x13
+#define TX_TRIGGER 1
+#define RX_TRIGGER 8192
+
+#ifdef CONFIG_SERIAL_8250_DMA
+enum dma_rx_status {
+   DMA_RX_START = 0,
+   DMA_RX_RUNNING = 1,
+   DMA_RX_SHUTDOWN = 2,
+};
+#endif
 struct mtk8250_data {
int line;
+   int rxpos;
struct clk  *uart_clk;
struct clk  *bus_clk;
+   struct uart_8250_dma*dma;
+#ifdef CONFIG_SERIAL_8250_DMA
+   enum dma_rx_status  rxstatus;
+#endif
 };
 
+#ifdef CONFIG_SERIAL_8250_DMA
+static int mtk8250_rx_dma(struct uart_8250_port *up);
+
+static void __mtkdma_rx_complete(void *param)
+{
+   struct uart_8250_port *up = param;
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct tty_port *tty_port = >port.state->port;
+   struct dma_tx_state state;
+   unsigned char *ptr;
+   int copied;
+
+   dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
+   dma->rx_size, DMA_FROM_DEVICE);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   dmaengine_terminate_all(dma->rxchan);
+
+   if (data->rxstatus == DMA_RX_SHUTDOWN)
+   return;
+
+   if ((data->rxpos + state.residue) <= dma->rx_size) {
+   ptr = (unsigned char *)(data->rxpos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr, state.residue);
+   } else {
+   ptr = (unsigned char *)(data->rxpos + dma->rx_buf);
+   copied = tty_insert_flip_string(tty_port, ptr,
+   (dma->rx_size - data->rxpos));
+   ptr = (unsigned char *)(dma->rx_buf);
+   copied += tty_insert_flip_string(tty_port, ptr,
+   (data->rxpos + state.residue - dma->rx_size));
+   }
+   up->port.icount.rx += copied;
+
+   tty_flip_buffer_push(tty_port);
+
+   mtk8250_rx_dma(up);
+}
+
+static int mtk8250_rx_dma(struct uart_8250_port *up)
+{
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   struct dma_async_tx_descriptor  *desc;
+   struct dma_tx_state  state;
+
+   desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
+  dma->rx_size, DMA_DEV_TO_MEM,
+  DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+   if (!desc)
+   return -EBUSY;
+
+   desc->callback = __mtkdma_rx_complete;
+   desc->callback_param = up;
+
+   dma->rx_cookie = dmaengine_submit(desc);
+
+   dmaengine_tx_status(dma->rxchan, dma->rx_cookie, );
+   data->rxpos = state.residue;
+
+   dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
+  dma->rx_size, DMA_FROM_DEVICE);
+
+   dma_async_issue_pending(dma->rxchan);
+
+   return 0;
+}
+
+static void mtk_dma_enable(struct uart_8250_port *up)
+{
+   struct uart_port *port = >port;
+   struct uart_8250_dma *dma = up->dma;
+   struct mtk8250_data *data = up->port.private_data;
+   int tmp = 0;
+
+   if (data->rxstatus != DMA_RX_START)
+   return;
+
+   dma->rxconf.direction   = DMA_DEV_TO_MEM;
+   dma->rxconf.src_addr_width  = dma->rx_size/1024;
+   dma->rxconf.src_addr= dma->rx_addr;
+
+   dma->txconf.direction   = DMA_MEM_TO_DEV;
+   dma->txconf.dst_addr_width  = UART_XMIT_SIZE/1024;
+   dma->txconf.dst_addr= dma->tx_addr;
+
+   serial_port_out(port, UART_FCR, ((1 << 0)|(1 << 1)|(1 << 2)));
+   serial_port_out(port, UART_MTK_DMA_EN,
+   (serial_port_in(port, UART_MTK_DMA_EN) |
+   ((1 << 0) | (1 << 2;
+   serial_port_out(port, UART_MTK_DMA_EN,
+   (serial_port_in(port, UART_MTK_D

[PATCH 0/4] add uart DMA function

2017-02-16 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA 
function.

Long Cheng (4):
  dt-bindings: dma: uart: add uart dma bindings
  dmaengine: mtk_uart_dma: add Mediatek uart DMA support
  serial: 8250-mtk: add uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 .../devicetree/bindings/dma/mtk_uart_dma.txt   |   32 +
 arch/arm/boot/dts/mt2701-evb.dts   |   22 +
 arch/arm/boot/dts/mt2701.dtsi  |   29 +
 drivers/dma/Kconfig|9 +
 drivers/dma/Makefile   |1 +
 drivers/dma/mtk_uart_dma.c |  955 
 drivers/tty/serial/8250/8250_mtk.c |  194 +++-
 7 files changed, 1241 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mtk_uart_dma.txt
 create mode 100644 drivers/dma/mtk_uart_dma.c

-- 
1.7.9.5



[PATCH 0/4] add uart DMA function

2017-02-16 Thread Long Cheng
In Mediatek SOCs, the uart can support DMA function.
Base on DMA engine formwork, we add the DMA code to support uart. And put the 
code under drivers/dma.

This series contains document bindings, Kconfig to control the function enable 
or not,
device tree including interrupt and dma device node, the code of UART DMA 
function.

Long Cheng (4):
  dt-bindings: dma: uart: add uart dma bindings
  dmaengine: mtk_uart_dma: add Mediatek uart DMA support
  serial: 8250-mtk: add uart DMA support
  arm: dts: mt2701: add uart APDMA to device tree

 .../devicetree/bindings/dma/mtk_uart_dma.txt   |   32 +
 arch/arm/boot/dts/mt2701-evb.dts   |   22 +
 arch/arm/boot/dts/mt2701.dtsi  |   29 +
 drivers/dma/Kconfig|9 +
 drivers/dma/Makefile   |1 +
 drivers/dma/mtk_uart_dma.c |  955 
 drivers/tty/serial/8250/8250_mtk.c |  194 +++-
 7 files changed, 1241 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mtk_uart_dma.txt
 create mode 100644 drivers/dma/mtk_uart_dma.c

-- 
1.7.9.5



Re: [PATCH] serial: 8250_mtk: support big baud rate.

2016-08-24 Thread Long Cheng
On Fri, 2016-08-12 at 10:41 +0800, Long Cheng wrote:
> From: Eddie Huang <eddie.hu...@mediatek.com>
> 
> mediatek can support baud rate up to 4M.
> the 'uart_get_baud_rate' function will limit the max baud rate.
> Modify max baud to remove the limit.
> 
> Signed-off-by: Long Cheng <long.ch...@mediatek.com>
> ---
>  drivers/tty/serial/8250/8250_mtk.c  |6 +-
>  drivers/tty/serial/8250/8250_port.c |4 +---
>  2 files changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/8250_mtk.c 
> b/drivers/tty/serial/8250/8250_mtk.c
> index 3611ec9..ce0cc47 100644
> --- a/drivers/tty/serial/8250/8250_mtk.c
> +++ b/drivers/tty/serial/8250/8250_mtk.c
> @@ -62,7 +62,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios 
> *termios,
>*/
>   baud = uart_get_baud_rate(port, termios, old,
> port->uartclk / 16 / 0x,
> -   port->uartclk / 16);
> +   port->uartclk);
>  
>   if (baud <= 115200) {
>   serial_port_out(port, UART_MTK_HIGHS, 0x0);
> @@ -76,10 +76,6 @@ mtk8250_set_termios(struct uart_port *port, struct 
> ktermios *termios,
>   quot = DIV_ROUND_UP(port->uartclk, 4 * baud);
>   } else {
>   serial_port_out(port, UART_MTK_HIGHS, 0x3);
> -
> - /* Set to highest baudrate supported */
> - if (baud >= 1152000)
> - baud = 921600;
>   quot = DIV_ROUND_UP(port->uartclk, 256 * baud);
>   }
>  
> diff --git a/drivers/tty/serial/8250/8250_port.c 
> b/drivers/tty/serial/8250/8250_port.c
> index 7481b95..c45c1e3 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -2504,8 +2504,6 @@ static unsigned int serial8250_get_baud_rate(struct 
> uart_port *port,
>struct ktermios *termios,
>struct ktermios *old)
>  {
> - unsigned int tolerance = port->uartclk / 100;
> -
>   /*
>* Ask the core to calculate the divisor for us.
>* Allow 1% tolerance at the upper limit so uart clks marginally
> @@ -2514,7 +2512,7 @@ static unsigned int serial8250_get_baud_rate(struct 
> uart_port *port,
>*/
>   return uart_get_baud_rate(port, termios, old,
> port->uartclk / 16 / 0x,
> -   (port->uartclk + tolerance) / 16);
> +   port->uartclk);
>  }
>  
>  void

Ping? Any reaction to the above?

Regards, thanks.



Re: [PATCH] serial: 8250_mtk: support big baud rate.

2016-08-24 Thread Long Cheng
On Fri, 2016-08-12 at 10:41 +0800, Long Cheng wrote:
> From: Eddie Huang 
> 
> mediatek can support baud rate up to 4M.
> the 'uart_get_baud_rate' function will limit the max baud rate.
> Modify max baud to remove the limit.
> 
> Signed-off-by: Long Cheng 
> ---
>  drivers/tty/serial/8250/8250_mtk.c  |6 +-
>  drivers/tty/serial/8250/8250_port.c |4 +---
>  2 files changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/8250_mtk.c 
> b/drivers/tty/serial/8250/8250_mtk.c
> index 3611ec9..ce0cc47 100644
> --- a/drivers/tty/serial/8250/8250_mtk.c
> +++ b/drivers/tty/serial/8250/8250_mtk.c
> @@ -62,7 +62,7 @@ mtk8250_set_termios(struct uart_port *port, struct ktermios 
> *termios,
>*/
>   baud = uart_get_baud_rate(port, termios, old,
> port->uartclk / 16 / 0x,
> -   port->uartclk / 16);
> +   port->uartclk);
>  
>   if (baud <= 115200) {
>   serial_port_out(port, UART_MTK_HIGHS, 0x0);
> @@ -76,10 +76,6 @@ mtk8250_set_termios(struct uart_port *port, struct 
> ktermios *termios,
>   quot = DIV_ROUND_UP(port->uartclk, 4 * baud);
>   } else {
>   serial_port_out(port, UART_MTK_HIGHS, 0x3);
> -
> - /* Set to highest baudrate supported */
> - if (baud >= 1152000)
> - baud = 921600;
>   quot = DIV_ROUND_UP(port->uartclk, 256 * baud);
>   }
>  
> diff --git a/drivers/tty/serial/8250/8250_port.c 
> b/drivers/tty/serial/8250/8250_port.c
> index 7481b95..c45c1e3 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -2504,8 +2504,6 @@ static unsigned int serial8250_get_baud_rate(struct 
> uart_port *port,
>struct ktermios *termios,
>struct ktermios *old)
>  {
> - unsigned int tolerance = port->uartclk / 100;
> -
>   /*
>* Ask the core to calculate the divisor for us.
>* Allow 1% tolerance at the upper limit so uart clks marginally
> @@ -2514,7 +2512,7 @@ static unsigned int serial8250_get_baud_rate(struct 
> uart_port *port,
>*/
>   return uart_get_baud_rate(port, termios, old,
> port->uartclk / 16 / 0x,
> -   (port->uartclk + tolerance) / 16);
> +   port->uartclk);
>  }
>  
>  void

Ping? Any reaction to the above?

Regards, thanks.



  1   2   >