RE: [PATCH 1/2] spi: spi-fsl-dspi: replace regmap R/W with internal implementation

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

 




On Wed, May 04, 2016 at 5:33 AM, pku.leo@xxxxxxxxx wrote:
> On Wed, Apr 27, 2016 at 3:12 AM, Yuan Yao <yao.yuan@xxxxxxxxxxxxx> wrote:
> > From: Yuan Yao <yao.yuan@xxxxxxx>
> >
> > The qSPI controller's endian is independent of the CPU core's endian.
> 
> DSPI?

Thanks for your review.
Sorry for the typo, I will update in the next version.
 
> >
> > For eg, Core on NXP LS1043A SoC is little endian but DSPI is big
> > endian whereas Core on LS2080A SoC is little endian and DSPI also is
> > little endian on the same core.
> 
> It's not correct to say the SoC is little endian for LS1043 or LS2080.
> Not all devices on the SoC are sharing the same endianness and the core
> endianness is configurable.

Ok, I will update it.
 

> 
> >
> > At first we use regmap to cover this issue.
> > But the regmap is designed too large and complex.
> > The issue for regmap often effect the DSPI's stability.
> 
> This is not stability issue but functional issue.

Ok, I will update it.

> 
> >
> > DSPI driver just only need a effective way to R/W the controller
> > register with BE or LE mode.
> >
> > So it's better to packaging a sample function.
> > This will make the DSPI driver more stability and high effective.
> >
> > Signed-off-by: Yuan Yao <yao.yuan@xxxxxxx>
> > ---
> >  drivers/spi/spi-fsl-dspi.c | 99
> > +++++++++++++++++++++++++++-------------------
> >  1 file changed, 59 insertions(+), 40 deletions(-)
> >
> > diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
> > index 9e9dadb..9a61572 100644
> > --- a/drivers/spi/spi-fsl-dspi.c
> > +++ b/drivers/spi/spi-fsl-dspi.c
> > @@ -27,7 +27,6 @@
> >  #include <linux/pinctrl/consumer.h>
> >  #include <linux/platform_device.h>
> >  #include <linux/pm_runtime.h>
> > -#include <linux/regmap.h>
> >  #include <linux/sched.h>
> >  #include <linux/spi/spi.h>
> >  #include <linux/spi/spi_bitbang.h>
> > @@ -143,7 +142,7 @@ struct fsl_dspi {
> >         struct spi_master       *master;
> >         struct platform_device  *pdev;
> >
> > -       struct regmap           *regmap;
> > +       void __iomem            *iobase;
> >         int                     irq;
> >         struct clk              *clk;
> >
> > @@ -165,13 +164,46 @@ struct fsl_dspi {
> >         u32                     waitflags;
> >
> >         u32                     spi_tcnt;
> > +       bool                    big_endian;
> >  };
> >
> > +/*
> > + * R/W functions for big- or little-endian registers:
> > + * The qSPI controller's endian is independent of the CPU core's endian.
> 
> DSPI?

Yes, DSPI, I will update it.
> 
> > + */
> > +static void dspi_writel(struct fsl_dspi *d, u32 val, u32 offset) {
> > +       if (d->big_endian)
> > +               iowrite32be(val, d->iobase + offset);
> > +       else
> > +               iowrite32(val, d->iobase + offset); }
> > +
> > +static u32 dspi_readl(struct fsl_dspi *d, u32 offset) {
> > +       if (d->big_endian)
> > +               return ioread32be(d->iobase + offset);
> > +       else
> > +               return ioread32(d->iobase + offset); }
> > +
> > +static void dspi_updatel(struct fsl_dspi *d, u32 mask, u32 val, u32
> > +offset) {
> > +       u32 tmp, orig;
> > +
> > +       orig = dspi_readl(d, offset);
> > +
> > +       tmp = orig & ~mask;
> > +       tmp |= val & mask;
> > +
> > +       dspi_writel(d, tmp, offset);
> > +}
> > +
> >  static inline int is_double_byte_mode(struct fsl_dspi *dspi)  {
> >         unsigned int val;
> >
> > -       regmap_read(dspi->regmap, SPI_CTAR(0), &val);
> > +       val = dspi_readl(dspi, SPI_CTAR(0));
> >
> >         return ((val & SPI_FRAME_BITS_MASK) == SPI_FRAME_BITS(8)) ? 0
> > : 1;  } @@ -270,7 +302,7 @@ static void dspi_data_from_popr(struct
> > fsl_dspi *dspi, int rx_word)
> >         u16 d;
> >         unsigned int val;
> >
> > -       regmap_read(dspi->regmap, SPI_POPR, &val);
> > +       val = dspi_readl(dspi, SPI_POPR);
> >         d = SPI_POPR_RXDATA(val);
> >
> >         if (!(dspi->dataflags & TRAN_STATE_RX_VOID)) @@ -294,8 +326,8
> > @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
> >                  */
> >                 if (tx_word && (dspi->len == 1)) {
> >                         dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
> > -                       regmap_update_bits(dspi->regmap, SPI_CTAR(0),
> > -                                       SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
> > +                       dspi_updatel(dspi, SPI_FRAME_BITS_MASK,
> > +                                       SPI_FRAME_BITS(8),
> > + SPI_CTAR(0));
> >                         tx_word = 0;
> >                 }
> >
> > @@ -309,7 +341,7 @@ static int dspi_eoq_write(struct fsl_dspi *dspi)
> >                 } else if (tx_word && (dspi->len == 1))
> >                         dspi_pushr |= SPI_PUSHR_EOQ;
> >
> > -               regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
> > +               dspi_writel(dspi, dspi_pushr, SPI_PUSHR);
> >
> >                 tx_count++;
> >         }
> > @@ -343,8 +375,8 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi)
> >
> >         if (tx_word && (dspi->len == 1)) {
> >                 dspi->dataflags |= TRAN_STATE_WORD_ODD_NUM;
> > -               regmap_update_bits(dspi->regmap, SPI_CTAR(0),
> > -                               SPI_FRAME_BITS_MASK, SPI_FRAME_BITS(8));
> > +               dspi_updatel(dspi, SPI_FRAME_BITS_MASK,
> > +                               SPI_FRAME_BITS(8), SPI_CTAR(0));
> >                 tx_word = 0;
> >         }
> >
> > @@ -353,7 +385,7 @@ static int dspi_tcfq_write(struct fsl_dspi *dspi)
> >         if ((dspi->cs_change) && (!dspi->len))
> >                 dspi_pushr &= ~SPI_PUSHR_CONT;
> >
> > -       regmap_write(dspi->regmap, SPI_PUSHR, dspi_pushr);
> > +       dspi_writel(dspi, dspi_pushr, SPI_PUSHR);
> >
> >         return tx_word + 1;
> >  }
> > @@ -378,7 +410,7 @@ static int dspi_transfer_one_message(struct
> spi_master *master,
> >         enum dspi_trans_mode trans_mode;
> >         u32 spi_tcr;
> >
> > -       regmap_read(dspi->regmap, SPI_TCR, &spi_tcr);
> > +       spi_tcr = dspi_readl(dspi, SPI_TCR);
> >         dspi->spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr);
> >
> >         message->actual_length = 0;
> > @@ -407,21 +439,19 @@ static int dspi_transfer_one_message(struct
> spi_master *master,
> >                 if (!dspi->tx)
> >                         dspi->dataflags |= TRAN_STATE_TX_VOID;
> >
> > -               regmap_write(dspi->regmap, SPI_MCR, dspi->cur_chip->mcr_val);
> > -               regmap_update_bits(dspi->regmap, SPI_MCR,
> > -                               SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
> > -                               SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF);
> > -               regmap_write(dspi->regmap, SPI_CTAR(0),
> > -                               dspi->cur_chip->ctar_val);
> > +               dspi_writel(dspi, dspi->cur_chip->mcr_val, SPI_MCR);
> > +               dspi_updatel(dspi, SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF,
> > +                                  SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF, SPI_MCR);
> > +               dspi_writel(dspi, dspi->cur_chip->ctar_val,
> > + SPI_CTAR(0));
> >
> >                 trans_mode = dspi->devtype_data->trans_mode;
> >                 switch (trans_mode) {
> >                 case DSPI_EOQ_MODE:
> > -                       regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_EOQFE);
> > +                       dspi_writel(dspi, SPI_RSER_EOQFE, SPI_RSER);
> >                         dspi_eoq_write(dspi);
> >                         break;
> >                 case DSPI_TCFQ_MODE:
> > -                       regmap_write(dspi->regmap, SPI_RSER, SPI_RSER_TCFQE);
> > +                       dspi_writel(dspi, SPI_RSER_TCFQE, SPI_RSER);
> >                         dspi_tcfq_write(dspi);
> >                         break;
> >                 default:
> > @@ -525,14 +555,14 @@ static irqreturn_t dspi_interrupt(int irq, void
> *dev_id)
> >         u32 spi_tcnt, tcnt_diff;
> >         int tx_word;
> >
> > -       regmap_read(dspi->regmap, SPI_SR, &spi_sr);
> > -       regmap_write(dspi->regmap, SPI_SR, spi_sr);
> > +       spi_sr = dspi_readl(dspi, SPI_SR);
> > +       dspi_writel(dspi, spi_sr, SPI_SR);
> >
> >
> >         if (spi_sr & (SPI_SR_EOQF | SPI_SR_TCFQF)) {
> >                 tx_word = is_double_byte_mode(dspi);
> >
> > -               regmap_read(dspi->regmap, SPI_TCR, &spi_tcr);
> > +               spi_tcr = dspi_readl(dspi, SPI_TCR);
> >                 spi_tcnt = SPI_TCR_GET_TCNT(spi_tcr);
> >                 /*
> >                  * The width of SPI Transfer Counter in SPI_TCR is
> > 16bits, @@ -569,10 +599,10 @@ static irqreturn_t dspi_interrupt(int
> > irq, void *dev_id)
> >
> >                 if (!dspi->len) {
> >                         if (dspi->dataflags & TRAN_STATE_WORD_ODD_NUM) {
> > -                               regmap_update_bits(dspi->regmap,
> > -                                                  SPI_CTAR(0),
> > -                                                  SPI_FRAME_BITS_MASK,
> > -                                                  SPI_FRAME_BITS(16));
> > +                               dspi_updatel(dspi,
> > +                                            SPI_FRAME_BITS_MASK,
> > +                                            SPI_FRAME_BITS(16),
> > +                                            SPI_CTAR(0));
> >                                 dspi->dataflags &= ~TRAN_STATE_WORD_ODD_NUM;
> >                         }
> >
> > @@ -636,13 +666,6 @@ static int dspi_resume(struct device *dev)
> >
> >  static SIMPLE_DEV_PM_OPS(dspi_pm, dspi_suspend, dspi_resume);
> >
> > -static const struct regmap_config dspi_regmap_config = {
> > -       .reg_bits = 32,
> > -       .val_bits = 32,
> > -       .reg_stride = 4,
> > -       .max_register = 0x88,
> > -};
> > -
> >  static int dspi_probe(struct platform_device *pdev)  {
> >         struct device_node *np = pdev->dev.of_node; @@ -700,13 +723,7
> > @@ static int dspi_probe(struct platform_device *pdev)
> >                 goto out_master_put;
> >         }
> >
> > -       dspi->regmap = devm_regmap_init_mmio_clk(&pdev->dev, NULL, base,
> > -                                               &dspi_regmap_config);
> > -       if (IS_ERR(dspi->regmap)) {
> > -               dev_err(&pdev->dev, "failed to init regmap: %ld\n",
> > -                               PTR_ERR(dspi->regmap));
> > -               return PTR_ERR(dspi->regmap);
> > -       }
> > +       dspi->iobase = base;
> >
> >         dspi->irq = platform_get_irq(pdev, 0);
> >         if (dspi->irq < 0) {
> > @@ -730,6 +747,8 @@ static int dspi_probe(struct platform_device *pdev)
> >         }
> >         clk_prepare_enable(dspi->clk);
> >
> > +       dspi->big_endian = of_property_read_bool(np, "big-endian");
> > +
> >         master->max_speed_hz =
> >                 clk_get_rate(dspi->clk) /
> > dspi->devtype_data->max_clock_factor;
> >
> > --
> > 2.1.0.27.g96db324
> >
> > --
> > To unsubscribe from this list: send the line "unsubscribe devicetree"
> > in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo
> > info at  http://vger.kernel.org/majordomo-info.html
��.n��������+%������w��{.n����z�{��ܨ}���Ơz�j:+v�����w����ޙ��&�)ߡ�a����z�ޗ���ݢj��w�f




[Index of Archives]     [Device Tree Compilter]     [Device Tree Spec]     [Linux Driver Backports]     [Video for Linux]     [Linux USB Devel]     [Linux PCI Devel]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Yosemite Backpacking]
  Powered by Linux