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 Biju,

On Tue, Mar 28, 2023 at 5:36 PM Biju Das <biju.das.jz@xxxxxxxxxxxxxx> wrote:
> > Subject: Re: [PATCH v2 3/3] tty: serial: sh-sci: Add RZ/G2L SCIF DMA rx
> > support
> > 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) {

Please reverse order, and use "==", to match the flow in
sci_dma_rx_reenable_irq() above.

> +                               disable_irq_nosync(irq);

I think that can be s->irqs[SCIx_RXI_IRQ] unconditionally, i.e. outside
the if/else?

> +                               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;

Gr{oetje,eeting}s,

                        Geert

-- 
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@xxxxxxxxxxxxxx

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