RE: [PATCH v2 3/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA rx support

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Geert,

Thanks for the feedback.


> Subject: Re: [PATCH v2 3/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA rx
> support
> 
> Hi Biju,
> 
> On Fri, Mar 24, 2023 at 11:02 AM Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
> wrote:
> > Add SCIF DMA rx support for RZ/G2L alike SoCs.
> >
> > RZ/G2L alike SoCs use the same signal for both interrupt and DMA
> > transfer requests, so we must disable line interrupt while transferring
> DMA.
> >
> > We must set FIFO trigger to 1 so that SCIF will request DMA when there
> > is a character as SCIF DMA request is based on FIFO data full RDF.
> >
> > Based on a patch in the BSP by Long Luu <long.luu.ur@xxxxxxxxxxx>
> >
> > Signed-off-by: Biju Das <biju.das.jz@xxxxxxxxxxxxxx>
> 
> Thanks for your patch!
> 
> > --- a/drivers/tty/serial/sh-sci.c
> > +++ b/drivers/tty/serial/sh-sci.c
> > @@ -1312,9 +1312,13 @@ static void sci_dma_rx_reenable_irq(struct
> > sci_port *s)
> >
> >         /* Direct new serial port interrupts back to CPU */
> >         scr = serial_port_in(port, SCSCR);
> > -       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
> > -               scr &= ~SCSCR_RDRQE;
> > +       if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
> > +           is_rz_scif_port(port, s)) {
> >                 enable_irq(s->irqs[SCIx_RXI_IRQ]);
> > +               if (port->type == PORT_SCIF)
> > +                       scif_set_rtrg(port, s->rx_trigger);
> > +               else
> > +                       scr &= ~SCSCR_RDRQE;
> >         }
> >         serial_port_out(port, SCSCR, scr | SCSCR_RIE);  } @@ -1735,7
> > +1739,15 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
> >                         if (sci_dma_rx_submit(s, false) < 0)
> >                                 goto handle_pio;
> >
> > -                       scr &= ~SCSCR_RIE;
> > +                       if (is_rz_scif_port(port, s)) {
> > +                               /* Switch irq from SCIF to DMA */
> > +
> > + disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
> 
> Perhaps this can be combined with the disable_irq_nosync() above?

OK, will do, As per Table 22.19 SCIFA Interrupt Sources, DMAC activation
Only possible with RXI interrupt.

So we need to use "s->irqs[SCIx_RXI_IRQ]" instead of "irq" for RZ/G2L SCIFA.


> 
> > +                               scif_set_rtrg(port, 1);
> > +                               /* DMA need RIE enable */
> > +                               scr |= SCSCR_RIE;
> > +                       } else {
> > +                               scr &= ~SCSCR_RIE;
> > +                       }
> 
> ... and this with some other SCIFA code path?

OK.

> 
> Looks like RZ/A2 and RZ/G2L "SCIFA" does have some resemblance with SCIFA,
> contrary to earlier statements?
> Perhaps the code can be simplified by treating it even more like a SCIFA?

Yes, new patch looks like

diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c
index 367bdb913d4a..146409e44556 100644
--- a/drivers/tty/serial/sh-sci.c
+++ b/drivers/tty/serial/sh-sci.c
@@ -1299,9 +1299,13 @@ static void sci_dma_rx_reenable_irq(struct sci_port *s)
 
 	/* Direct new serial port interrupts back to CPU */
 	scr = serial_port_in(port, SCSCR);
-	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-		scr &= ~SCSCR_RDRQE;
+	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+	    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
 		enable_irq(s->irqs[SCIx_RXI_IRQ]);
+		if (s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
+			scif_set_rtrg(port, s->rx_trigger);
+		else
+			scr &= ~SCSCR_RDRQE;
 	}
 	serial_port_out(port, SCSCR, scr | SCSCR_RIE);
 }
@@ -1538,7 +1542,8 @@ static enum hrtimer_restart sci_dma_rx_timer_fn(struct hrtimer *t)
 			tty_flip_buffer_push(&port->state->port);
 	}
 
-	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+	if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+	    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
 		sci_dma_rx_submit(s, true);
 
 	sci_dma_rx_reenable_irq(s);
@@ -1662,7 +1667,8 @@ static void sci_request_dma(struct uart_port *port)
 
 		s->chan_rx_saved = s->chan_rx = chan;
 
-		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB)
+		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+		    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE)
 			sci_dma_rx_submit(s, false);
 	}
 }
@@ -1715,9 +1721,16 @@ static irqreturn_t sci_rx_interrupt(int irq, void *ptr)
 		u16 ssr = serial_port_in(port, SCxSR);
 
 		/* Disable future Rx interrupts */
-		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB) {
-			disable_irq_nosync(irq);
-			scr |= SCSCR_RDRQE;
+		if (port->type == PORT_SCIFA || port->type == PORT_SCIFB ||
+		    s->cfg->regtype == SCIx_RZ_SCIFA_REGTYPE) {
+			if (s->cfg->regtype != SCIx_RZ_SCIFA_REGTYPE) {
+				disable_irq_nosync(irq);
+				scr |= SCSCR_RDRQE;
+			} else {
+				disable_irq_nosync(s->irqs[SCIx_RXI_IRQ]);
+				scif_set_rtrg(port, 1);
+				scr |= SCSCR_RIE;
+			}
		} else {
 			if (sci_dma_rx_submit(s, false) < 0)
 				goto handle_pio;

Cheers,
Biju
> 
> >                 }
> >                 serial_port_out(port, SCSCR, scr);
> >                 /* Clear current interrupt */
> 
> Gr{oetje,eeting}s,
> 
>                         Geert
> 
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-
> m68k.org
> 
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like
> that.
>                                 -- Linus Torvalds




[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux