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