Hi, čt 27. 8. 2020 v 14:10 odesílatel Michal Simek <michal.si...@xilinx.com> napsal: > > From: T Karthik Reddy <t.karthik.re...@xilinx.com> > > This endinness changes are taken from linux uartlite driver. > Reset TX fifo in control register and check TX fifo empty > flag in lower byte of the status register to detect if it > is a little endian system. Based on this check, program the > registers with le32 or be32 through out the driver. > > Signed-off-by: T Karthik Reddy <t.karthik.re...@xilinx.com> > Signed-off-by: Ashok Reddy Soma <ashok.reddy.s...@xilinx.com> > Signed-off-by: Michal Simek <michal.si...@xilinx.com> > --- > > drivers/serial/serial_xuartlite.c | 74 ++++++++++++++++++++++++++----- > 1 file changed, 64 insertions(+), 10 deletions(-) > > diff --git a/drivers/serial/serial_xuartlite.c > b/drivers/serial/serial_xuartlite.c > index 5116d13751de..e16642504b16 100644 > --- a/drivers/serial/serial_xuartlite.c > +++ b/drivers/serial/serial_xuartlite.c > @@ -32,17 +32,64 @@ struct uartlite { > > struct uartlite_platdata { > struct uartlite *regs; > + const struct uartlite_reg_ops *reg_ops; > }; > > +struct uartlite_reg_ops { > + u32 (*in)(void __iomem *addr); > + void (*out)(u32 val, void __iomem *addr); > +}; > + > +static u32 uartlite_inle32(void __iomem *addr) > +{ > + return in_le32(addr); > +} > + > +static void uartlite_outle32(u32 val, void __iomem *addr) > +{ > + out_le32(addr, val); > +} > + > +static const struct uartlite_reg_ops uartlite_le = { > + .in = uartlite_inle32, > + .out = uartlite_outle32, > +}; > + > +static u32 uartlite_inbe32(void __iomem *addr) > +{ > + return in_be32(addr); > +} > + > +static void uartlite_outbe32(u32 val, void __iomem *addr) > +{ > + out_be32(addr, val); > +} > + > +static const struct uartlite_reg_ops uartlite_be = { > + .in = uartlite_inbe32, > + .out = uartlite_outbe32, > +}; > + > +static u32 uart_in32(void __iomem *addr, struct uartlite_platdata *plat) > +{ > + return plat->reg_ops->in(addr); > +} > + > +static void uart_out32(void __iomem *addr, u32 val, > + struct uartlite_platdata *plat) > +{ > + plat->reg_ops->out(val, addr); > +} > + > static int uartlite_serial_putc(struct udevice *dev, const char ch) > { > struct uartlite_platdata *plat = dev_get_platdata(dev); > struct uartlite *regs = plat->regs; > > - if (in_be32(®s->status) & SR_TX_FIFO_FULL) > + if (uart_in32(®s->status, plat) & SR_TX_FIFO_FULL) > return -EAGAIN; > > - out_be32(®s->tx_fifo, ch & 0xff); > + uart_out32(®s->tx_fifo, ch & 0xff, plat); > > return 0; > } > @@ -52,10 +99,10 @@ static int uartlite_serial_getc(struct udevice *dev) > struct uartlite_platdata *plat = dev_get_platdata(dev); > struct uartlite *regs = plat->regs; > > - if (!(in_be32(®s->status) & SR_RX_FIFO_VALID_DATA)) > + if (!(uart_in32(®s->status, plat) & SR_RX_FIFO_VALID_DATA)) > return -EAGAIN; > > - return in_be32(®s->rx_fifo) & 0xff; > + return uart_in32(®s->rx_fifo, plat) & 0xff; > } > > static int uartlite_serial_pending(struct udevice *dev, bool input) > @@ -64,19 +111,26 @@ static int uartlite_serial_pending(struct udevice *dev, > bool input) > struct uartlite *regs = plat->regs; > > if (input) > - return in_be32(®s->status) & SR_RX_FIFO_VALID_DATA; > + return uart_in32(®s->status, plat) & SR_RX_FIFO_VALID_DATA; > > - return !(in_be32(®s->status) & SR_TX_FIFO_EMPTY); > + return !(uart_in32(®s->status, plat) & SR_TX_FIFO_EMPTY); > } > > static int uartlite_serial_probe(struct udevice *dev) > { > struct uartlite_platdata *plat = dev_get_platdata(dev); > struct uartlite *regs = plat->regs; > - > - out_be32(®s->control, 0); > - out_be32(®s->control, ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX); > - in_be32(®s->control); > + int ret; > + > + plat->reg_ops = &uartlite_be; > + ret = uart_in32(®s->control, plat); > + uart_out32(®s->control, 0, plat); > + uart_out32(®s->control, > + ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX, plat); > + ret = uart_in32(®s->status, plat); > + /* Endianness detection */ > + if ((ret & SR_TX_FIFO_EMPTY) != SR_TX_FIFO_EMPTY) > + plat->reg_ops = &uartlite_le; > > return 0; > } > -- > 2.28.0 >
We found some issues with this patch that's why please ignore it - v2 will be sent. Thanks, Michal -- Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91 w: www.monstr.eu p: +42-0-721842854 Maintainer of Linux kernel - Xilinx Microblaze Maintainer of Linux kernel - Xilinx Zynq ARM and ZynqMP ARM64 SoCs U-Boot custodian - Xilinx Microblaze/Zynq/ZynqMP/Versal SoCs