Hi Sean

> From: U-Boot [mailto:u-boot-boun...@lists.denx.de] On Behalf Of Sean Anderson
> Sent: Tuesday, February 11, 2020 2:04 PM
> To: u-boot@lists.denx.de
> Cc: Rick Chen; Eugeniy Paltsev
> Subject: [PATCH v4 06/17] spi: dw: Add device tree properties for fields in 
> CTRL1
>
> Some devices have different layouts for the fields in CTRL1 (e.g. the 
> Kendryte K210). Allow this layout to be configurable from the device tree.

The description of CTRL1 here don't match with the below content of CTRL0.
Is it a typo ?

Thanks
Rick

> The documentation has been taken from Linux.
>
> Signed-off-by: Sean Anderson <sean...@gmail.com>
> ---
>
> Changes in v4:
> - New
>
>  .../spi/snps,dw-apb-ssi.txt                   | 43 +++++++++++++++++++
>  drivers/spi/designware_spi.c                  | 40 ++++++++++-------
>  2 files changed, 68 insertions(+), 15 deletions(-)  create mode 100644 
> doc/device-tree-bindings/spi/snps,dw-apb-ssi.txt
>
> diff --git a/doc/device-tree-bindings/spi/snps,dw-apb-ssi.txt 
> b/doc/device-tree-bindings/spi/snps,dw-apb-ssi.txt
> new file mode 100644
> index 0000000000..4b6152f6b7
> --- /dev/null
> +++ b/doc/device-tree-bindings/spi/snps,dw-apb-ssi.txt
> @@ -0,0 +1,43 @@
> +Synopsys DesignWare AMBA 2.0 Synchronous Serial Interface.
> +
> +Required properties:
> +- compatible : "snps,dw-apb-ssi"
> +- reg : The register base for the controller. For "mscc,<soc>-spi", a
> +second
> +  register set is required (named ICPU_CFG:SPI_MST)
> +- #address-cells : <1>, as required by generic SPI binding.
> +- #size-cells : <0>, also as required by generic SPI binding.
> +- clocks : phandles for the clocks, see the description of clock-names below.
> +   The phandle for the "ssi_clk" is required. The phandle for the "pclk" 
> clock
> +   is optional. If a single clock is specified but no clock-name, it is the
> +   "ssi_clk" clock. If both clocks are listed, the "ssi_clk" must be first.
> +
> +Optional properties:
> +- clock-names : Contains the names of the clocks:
> +    "ssi_clk", for the core clock used to generate the external SPI clock.
> +    "pclk", the interface clock, required for register access.
> +- cs-gpios : Specifies the gpio pins to be used for chipselects.
> +- num-cs : The number of chipselects. If omitted, this will default to 4.
> +- reg-io-width : The I/O register width (in bytes) implemented by this
> +  device.  Supported values are 2 or 4 (the default).
> +- snps,dfs-offset The offset in bits of the DFS field in CTRL0,
> +defaulting to 0
> +- snps,frf-offset The offset in bits of the FRF field in CTRL0,
> +defaulting to 4
> +- snps,tmod-offset The offset in bits of the tmode field in CTRL0,
> +defaulting
> +  to 6
> +- snps,mode-offset The offset in bits of the work mode field in CTRL0,
> +  defaulting to 8
> +
> +Child nodes as per the generic SPI binding.
> +
> +Example:
> +
> +       spi@fff00000 {
> +               compatible = "snps,dw-apb-ssi";
> +               reg = <0xfff00000 0x1000>;
> +               interrupts = <0 154 4>;
> +               #address-cells = <1>;
> +               #size-cells = <0>;
> +               clocks = <&spi_m_clk>;
> +               num-cs = <2>;
> +               cs-gpios = <&gpio0 13 0>,
> +                          <&gpio0 14 0>;
> +       };
> diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c 
> index 66ff8eeccd..04cc873754 100644
> --- a/drivers/spi/designware_spi.c
> +++ b/drivers/spi/designware_spi.c
> @@ -3,6 +3,7 @@
>   * Designware master SPI core controller driver
>   *
>   * Copyright (C) 2014 Stefan Roese <s...@denx.de>
> + * Copyright (C) 2020 Sean Anderson <sean...@gmail.com>
>   *
>   * Very loosely based on the Linux driver:
>   * drivers/spi/spi-dw.c, which is:
> @@ -50,20 +51,14 @@
>  #define DW_SPI_DR                      0x60
>
>  /* Bit fields in CTRLR0 */
> -#define SPI_DFS_OFFSET                 0
> -
> -#define SPI_FRF_OFFSET                 4
>  #define SPI_FRF_SPI                    0x0
>  #define SPI_FRF_SSP                    0x1
>  #define SPI_FRF_MICROWIRE              0x2
>  #define SPI_FRF_RESV                   0x3
>
> -#define SPI_MODE_OFFSET                        6
> -#define SPI_SCPH_OFFSET                        6
> -#define SPI_SCOL_OFFSET                        7
> +#define SPI_MODE_SCPH                  0x1
> +#define SPI_MODE_SCOL                  0x2
>
> -#define SPI_TMOD_OFFSET                        8
> -#define SPI_TMOD_MASK                  (0x3 << SPI_TMOD_OFFSET)
>  #define        SPI_TMOD_TR                     0x0             /* xmit & 
> recv */
>  #define SPI_TMOD_TO                    0x1             /* xmit only */
>  #define SPI_TMOD_RO                    0x2             /* recv only */
> @@ -88,6 +83,12 @@
>  struct dw_spi_platdata {
>         s32 frequency;          /* Default clock frequency, -1 for none */
>         void __iomem *regs;
> +
> +       /* Offsets in CTRL0 */
> +       u8 dfs_off;
> +       u8 frf_off;
> +       u8 tmod_off;
> +       u8 mode_off;
>  };
>
>  struct dw_spi_priv {
> @@ -114,6 +115,15 @@ struct dw_spi_priv {
>         struct reset_ctl_bulk   resets;
>  };
>
> +static inline u32 GEN_CTRL0(struct dw_spi_priv *priv,
> +                           struct dw_spi_platdata *plat)
> +{
> +       return ((priv->bits_per_word - 1) << plat->dfs_off |
> +             (priv->type << plat->frf_off) |
> +             (priv->mode << plat->mode_off) |
> +             (priv->tmode << plat->tmod_off)); }
> +
>  static inline u32 dw_read(struct dw_spi_priv *priv, u32 offset)  {
>         return __raw_readl(priv->regs + offset); @@ -159,6 +169,10 @@ static 
> int dw_spi_ofdata_to_platdata(struct udevice *bus)
>         /* Use 500KHz as a suitable default */
>         plat->frequency = dev_read_u32_default(bus, "spi-max-frequency",
>                                                500000);
> +       plat->dfs_off = dev_read_u32_default(bus, "snps,dfs-offset", 0);
> +       plat->frf_off = dev_read_u32_default(bus, "snps,frf-offset", 4);
> +       plat->mode_off = dev_read_u32_default(bus, "snps,mode-offset", 6);
> +       plat->tmod_off = dev_read_u32_default(bus, "snps,tmod-offset", 8);
>         debug("%s: regs=%p max-frequency=%d\n", __func__, plat->regs,
>               plat->frequency);
>
> @@ -387,6 +401,7 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int 
> bitlen,
>                        const void *dout, void *din, unsigned long flags)  {
>         struct udevice *bus = dev->parent;
> +       struct dw_spi_platdata *plat = dev_get_platdata(bus);
>         struct dw_spi_priv *priv = dev_get_priv(bus);
>         const u8 *tx = dout;
>         u8 *rx = din;
> @@ -405,10 +420,6 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int 
> bitlen,
>         if (flags & SPI_XFER_BEGIN)
>                 external_cs_manage(dev, false);
>
> -       cr0 = (priv->bits_per_word - 1) | (priv->type << SPI_FRF_OFFSET) |
> -               (priv->mode << SPI_MODE_OFFSET) |
> -               (priv->tmode << SPI_TMOD_OFFSET);
> -
>         if (rx && tx)
>                 priv->tmode = SPI_TMOD_TR;
>         else if (rx)
> @@ -420,8 +431,7 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int 
> bitlen,
>                  */
>                 priv->tmode = SPI_TMOD_TR;
>
> -       cr0 &= ~SPI_TMOD_MASK;
> -       cr0 |= (priv->tmode << SPI_TMOD_OFFSET);
> +       cr0 = GEN_CTRL0(priv, plat);
>
>         priv->len = bitlen >> 3;
>         debug("%s: rx=%p tx=%p len=%d [bytes]\n", __func__, rx, tx, 
> priv->len); @@ -475,7 +485,7 @@ static int dw_spi_xfer(struct udevice *dev, 
> unsigned int bitlen,
>
>  static int dw_spi_set_speed(struct udevice *bus, uint speed)  {
> -       struct dw_spi_platdata *plat = bus->platdata;
> +       struct dw_spi_platdata *plat = dev_get_platdata(bus);
>         struct dw_spi_priv *priv = dev_get_priv(bus);
>         u16 clk_div;
>
> --
> 2.25.0
>

Reply via email to