From addb32866d99068307f8eddb282ebb325d18446f Mon Sep 17 00:00:00 2001 From: Clark Wang Date: Wed, 6 Mar 2019 06:30:36 +0000 Subject: doc: lpspi: Document DT bindings for LPSPI clocks Add introductions of clocks and clock-names strings. Signed-off-by: Clark Wang Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt index 6cc3c6fe25a3..e71b81a41ac0 100644 --- a/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt +++ b/Documentation/devicetree/bindings/spi/spi-fsl-lpspi.txt @@ -7,7 +7,11 @@ Required properties: - reg : address and length of the lpspi master registers - interrupt-parent : core interrupt controller - interrupts : lpspi interrupt -- clocks : lpspi clock specifier +- clocks : lpspi clock specifier. Its number and order need to correspond to the + value in clock-names. +- clock-names : Corresponding to per clock and ipg clock in "clocks" + respectively. In i.MX7ULP, it only has per clk, so use CLK_DUMMY + to fill the "ipg" blank. - spi-slave : spi slave mode support. In slave mode, add this attribute without value. In master mode, remove it. @@ -18,6 +22,8 @@ lpspi2: lpspi@40290000 { reg = <0x40290000 0x10000>; interrupt-parent = <&intc>; interrupts = ; - clocks = <&clks IMX7ULP_CLK_LPSPI2>; + clocks = <&clks IMX7ULP_CLK_LPSPI2>, + <&clks IMX7ULP_CLK_DUMMY>; + clock-names = "per", "ipg"; spi-slave; }; -- cgit v1.2.3 From 69b921acae8a5b7feef03921d9b42c3634f3b9d1 Mon Sep 17 00:00:00 2001 From: Rasmus Villemoes Date: Wed, 6 Mar 2019 10:32:05 +0000 Subject: spi: spi-fsl-spi: support use of the SPISEL_BOOT signal on MPC8309 The MPC8309 has a dedicated signal, SPISEL_BOOT, usually used as chip select for the flash device from which the bootloader is loaded. It is not an ordinary gpio, but is simply controlled via the SPI_CS register in the system configuration. To allow accessing such a spi slave, we need to teach fsl_spi_cs_control() how to control the SPISEL_BOOT signal. To distinguish the gpio-controlled slaves, continue to have those use chip_select values of 0..ngpios-1, and use chip_select == ngpios for the boot flash. I'm not too happy with all the ifdeffery, but it seems to be necessary for guarding the sysdev/fsl_soc.h and use of get_immrbase() (spi-fsl-lib.c already contains similar ifdeffery). Googling suggests that the MPC8306 is similar, with the SPI_CS register at the same offset. Signed-off-by: Rasmus Villemoes Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/fsl-spi.txt | 4 +++ drivers/spi/spi-fsl-lib.h | 2 ++ drivers/spi/spi-fsl-spi.c | 40 ++++++++++++++++++++--- 3 files changed, 41 insertions(+), 5 deletions(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/fsl-spi.txt b/Documentation/devicetree/bindings/spi/fsl-spi.txt index 8854004a1d3a..411375eac54d 100644 --- a/Documentation/devicetree/bindings/spi/fsl-spi.txt +++ b/Documentation/devicetree/bindings/spi/fsl-spi.txt @@ -18,6 +18,10 @@ Optional properties: - gpios : specifies the gpio pins to be used for chipselects. The gpios will be referred to as reg = in the SPI child nodes. If unspecified, a single SPI device without a chip select can be used. +- fsl,spisel_boot : for the MPC8306 and MPC8309, specifies that the + SPISEL_BOOT signal is used as chip select for a slave device. Use + reg = in the corresponding child node, i.e. 0 if + the gpios property is not present. Example: spi@4c0 { diff --git a/drivers/spi/spi-fsl-lib.h b/drivers/spi/spi-fsl-lib.h index f303f306b38e..483734bc1b1e 100644 --- a/drivers/spi/spi-fsl-lib.h +++ b/drivers/spi/spi-fsl-lib.h @@ -95,8 +95,10 @@ static inline u32 mpc8xxx_spi_read_reg(__be32 __iomem *reg) struct mpc8xxx_spi_probe_info { struct fsl_spi_platform_data pdata; + int ngpios; int *gpios; bool *alow_flags; + __be32 __iomem *immr_spi_cs; }; extern u32 mpc8xxx_spi_tx_buf_u8(struct mpc8xxx_spi *mpc8xxx_spi); diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index 8f2e97857e8b..3d7b50c65f36 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c @@ -39,6 +39,14 @@ #include #include +#ifdef CONFIG_FSL_SOC +#include +#endif + +/* Specific to the MPC8306/MPC8309 */ +#define IMMR_SPI_CS_OFFSET 0x14c +#define SPI_BOOT_SEL_BIT 0x80000000 + #include "spi-fsl-lib.h" #include "spi-fsl-cpm.h" #include "spi-fsl-spi.h" @@ -701,10 +709,17 @@ static void fsl_spi_cs_control(struct spi_device *spi, bool on) struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); u16 cs = spi->chip_select; - int gpio = pinfo->gpios[cs]; - bool alow = pinfo->alow_flags[cs]; - gpio_set_value(gpio, on ^ alow); + if (cs < pinfo->ngpios) { + int gpio = pinfo->gpios[cs]; + bool alow = pinfo->alow_flags[cs]; + + gpio_set_value(gpio, on ^ alow); + } else { + if (WARN_ON_ONCE(cs > pinfo->ngpios || !pinfo->immr_spi_cs)) + return; + iowrite32be(on ? SPI_BOOT_SEL_BIT : 0, pinfo->immr_spi_cs); + } } static int of_fsl_spi_get_chipselects(struct device *dev) @@ -712,12 +727,15 @@ static int of_fsl_spi_get_chipselects(struct device *dev) struct device_node *np = dev->of_node; struct fsl_spi_platform_data *pdata = dev_get_platdata(dev); struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); + bool spisel_boot = IS_ENABLED(CONFIG_FSL_SOC) && + of_property_read_bool(np, "fsl,spisel_boot"); int ngpios; int i = 0; int ret; ngpios = of_gpio_count(np); - if (ngpios <= 0) { + ngpios = max(ngpios, 0); + if (ngpios == 0 && !spisel_boot) { /* * SPI w/o chip-select line. One SPI device is still permitted * though. @@ -726,6 +744,7 @@ static int of_fsl_spi_get_chipselects(struct device *dev) return 0; } + pinfo->ngpios = ngpios; pinfo->gpios = kmalloc_array(ngpios, sizeof(*pinfo->gpios), GFP_KERNEL); if (!pinfo->gpios) @@ -769,7 +788,18 @@ static int of_fsl_spi_get_chipselects(struct device *dev) } } - pdata->max_chipselect = ngpios; +#if IS_ENABLED(CONFIG_FSL_SOC) + if (spisel_boot) { + pinfo->immr_spi_cs = ioremap(get_immrbase() + IMMR_SPI_CS_OFFSET, 4); + if (!pinfo->immr_spi_cs) { + ret = -ENOMEM; + i = ngpios - 1; + goto err_loop; + } + } +#endif + + pdata->max_chipselect = ngpios + spisel_boot; pdata->cs_control = fsl_spi_cs_control; return 0; -- cgit v1.2.3 From 57a9f6e7eefa697349ff4823f178fd56abe27345 Mon Sep 17 00:00:00 2001 From: Phil Edworthy Date: Tue, 19 Mar 2019 15:52:05 +0000 Subject: dt-bindings: snps,dw-apb-ssi: Add mandatory clock bindings documentation The Synopsys SSI driver uses a mandatory clock that is not documented, so detail it in the device tree bindings. Also correct the spelling of "pins" in the "Optional Properties" section for the driver. Signed-off-by: Phil Edworthy Signed-off-by: Gareth Williams Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt index 2864bc6b659c..bcd8f960afb9 100644 --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt @@ -8,9 +8,10 @@ Required properties: - interrupts : One interrupt, used by the controller. - #address-cells : <1>, as required by generic SPI binding. - #size-cells : <0>, also as required by generic SPI binding. +- clocks : phandle for the core clock used to generate the external SPI clock. Optional properties: -- cs-gpios : Specifies the gpio pis to be used for chipselects. +- 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). @@ -25,6 +26,7 @@ Example: 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>; -- cgit v1.2.3 From 2f324ac7cf8c50aa079cf30445b99a1b98ea2728 Mon Sep 17 00:00:00 2001 From: Gareth Williams Date: Tue, 19 Mar 2019 15:52:06 +0000 Subject: dt-bindings: snps,dw-apb-ssi: Add optional clock bindings documentation Add documentation to the Synopsys SPI dt-bindings to support an optional interface clock that may be used for register access. Signed-off-by: Phil Edworthy Signed-off-by: Gareth Williams Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt index bcd8f960afb9..f54c8c36395e 100644 --- a/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt +++ b/Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.txt @@ -8,9 +8,15 @@ Required properties: - interrupts : One interrupt, used by the controller. - #address-cells : <1>, as required by generic SPI binding. - #size-cells : <0>, also as required by generic SPI binding. -- clocks : phandle for the core clock used to generate the external SPI clock. +- 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 -- cgit v1.2.3 From cbd66c626e16743b05af807ad48012c0a097b9fb Mon Sep 17 00:00:00 2001 From: Stefan Roese Date: Mon, 25 Mar 2019 09:29:25 +0100 Subject: spi: mt7621: Move SPI driver out of staging This patch moves the MT7621 SPI driver, which is used on some Ralink / MediaTek MT76xx MIPS SoC's, out of the staging directory. No changes to the source code are done in this patch. This driver version was tested successfully on an MT7688 based platform with an SPI NOR on CS0 and an SPI NAND on CS1 without any issues (so far). This patch also documents the devicetree bindings for the MT7621 SPI device driver. Signed-off-by: Stefan Roese Cc: Rob Herring Cc: Mark Brown Cc: Greg Kroah-Hartman Cc: NeilBrown Cc: Sankalp Negi Cc: Chuanhong Guo Cc: John Crispin Cc: Armando Miraglia Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-mt7621.txt | 26 ++ drivers/spi/Kconfig | 6 + drivers/spi/Makefile | 1 + drivers/spi/spi-mt7621.c | 421 ++++++++++++++++++++ drivers/staging/Kconfig | 2 - drivers/staging/Makefile | 1 - drivers/staging/mt7621-spi/Kconfig | 6 - drivers/staging/mt7621-spi/Makefile | 1 - drivers/staging/mt7621-spi/TODO | 5 - drivers/staging/mt7621-spi/spi-mt7621.c | 422 --------------------- 10 files changed, 454 insertions(+), 437 deletions(-) create mode 100644 Documentation/devicetree/bindings/spi/spi-mt7621.txt create mode 100644 drivers/spi/spi-mt7621.c delete mode 100644 drivers/staging/mt7621-spi/Kconfig delete mode 100644 drivers/staging/mt7621-spi/Makefile delete mode 100644 drivers/staging/mt7621-spi/TODO delete mode 100644 drivers/staging/mt7621-spi/spi-mt7621.c (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-mt7621.txt b/Documentation/devicetree/bindings/spi/spi-mt7621.txt new file mode 100644 index 000000000000..d5baec0fa56e --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-mt7621.txt @@ -0,0 +1,26 @@ +Binding for MTK SPI controller (MT7621 MIPS) + +Required properties: +- compatible: Should be one of the following: + - "ralink,mt7621-spi": for mt7621/mt7628/mt7688 platforms +- #address-cells: should be 1. +- #size-cells: should be 0. +- reg: Address and length of the register set for the device +- resets: phandle to the reset controller asserting this device in + reset + See ../reset/reset.txt for details. + +Optional properties: +- cs-gpios: see spi-bus.txt. + +Example: + +- SoC Specific Portion: +spi0: spi@b00 { + compatible = "ralink,mt7621-spi"; + reg = <0xb00 0x100>; + #address-cells = <1>; + #size-cells = <0>; + resets = <&rstctrl 18>; + reset-names = "spi"; +}; diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index f761655e2a36..8ce4f7df0ef2 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -426,6 +426,12 @@ config SPI_MT65XX say Y or M here.If you are not sure, say N. SPI drivers for Mediatek MT65XX and MT81XX series ARM SoCs. +config SPI_MT7621 + tristate "MediaTek MT7621 SPI Controller" + depends on RALINK || COMPILE_TEST + help + This selects a driver for the MediaTek MT7621 SPI Controller. + config SPI_NPCM_PSPI tristate "Nuvoton NPCM PSPI Controller" depends on ARCH_NPCM || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index d8fc03c9faa2..369f29a8a6af 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -60,6 +60,7 @@ obj-$(CONFIG_SPI_MPC512x_PSC) += spi-mpc512x-psc.o obj-$(CONFIG_SPI_MPC52xx_PSC) += spi-mpc52xx-psc.o obj-$(CONFIG_SPI_MPC52xx) += spi-mpc52xx.o obj-$(CONFIG_SPI_MT65XX) += spi-mt65xx.o +obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o obj-$(CONFIG_SPI_MXIC) += spi-mxic.o obj-$(CONFIG_SPI_MXS) += spi-mxs.o obj-$(CONFIG_SPI_NPCM_PSPI) += spi-npcm-pspi.o diff --git a/drivers/spi/spi-mt7621.c b/drivers/spi/spi-mt7621.c new file mode 100644 index 000000000000..ae836114ee3d --- /dev/null +++ b/drivers/spi/spi-mt7621.c @@ -0,0 +1,421 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// spi-mt7621.c -- MediaTek MT7621 SPI controller driver +// +// Copyright (C) 2011 Sergiy +// Copyright (C) 2011-2013 Gabor Juhos +// Copyright (C) 2014-2015 Felix Fietkau +// +// Some parts are based on spi-orion.c: +// Author: Shadi Ammouri +// Copyright (C) 2007-2008 Marvell Ltd. + +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "spi-mt7621" + +/* in usec */ +#define RALINK_SPI_WAIT_MAX_LOOP 2000 + +/* SPISTAT register bit field */ +#define SPISTAT_BUSY BIT(0) + +#define MT7621_SPI_TRANS 0x00 +#define SPITRANS_BUSY BIT(16) + +#define MT7621_SPI_OPCODE 0x04 +#define MT7621_SPI_DATA0 0x08 +#define MT7621_SPI_DATA4 0x18 +#define SPI_CTL_TX_RX_CNT_MASK 0xff +#define SPI_CTL_START BIT(8) + +#define MT7621_SPI_MASTER 0x28 +#define MASTER_MORE_BUFMODE BIT(2) +#define MASTER_FULL_DUPLEX BIT(10) +#define MASTER_RS_CLK_SEL GENMASK(27, 16) +#define MASTER_RS_CLK_SEL_SHIFT 16 +#define MASTER_RS_SLAVE_SEL GENMASK(31, 29) + +#define MT7621_SPI_MOREBUF 0x2c +#define MT7621_SPI_POLAR 0x38 +#define MT7621_SPI_SPACE 0x3c + +#define MT7621_CPHA BIT(5) +#define MT7621_CPOL BIT(4) +#define MT7621_LSB_FIRST BIT(3) + +struct mt7621_spi { + struct spi_controller *master; + void __iomem *base; + unsigned int sys_freq; + unsigned int speed; + struct clk *clk; + int pending_write; + + struct mt7621_spi_ops *ops; +}; + +static inline struct mt7621_spi *spidev_to_mt7621_spi(struct spi_device *spi) +{ + return spi_controller_get_devdata(spi->master); +} + +static inline u32 mt7621_spi_read(struct mt7621_spi *rs, u32 reg) +{ + return ioread32(rs->base + reg); +} + +static inline void mt7621_spi_write(struct mt7621_spi *rs, u32 reg, u32 val) +{ + iowrite32(val, rs->base + reg); +} + +static void mt7621_spi_set_cs(struct spi_device *spi, int enable) +{ + struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); + int cs = spi->chip_select; + u32 polar = 0; + u32 master; + + /* + * Select SPI device 7, enable "more buffer mode" and disable + * full-duplex (only half-duplex really works on this chip + * reliably) + */ + master = mt7621_spi_read(rs, MT7621_SPI_MASTER); + master |= MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE; + master &= ~MASTER_FULL_DUPLEX; + mt7621_spi_write(rs, MT7621_SPI_MASTER, master); + + rs->pending_write = 0; + + if (enable) + polar = BIT(cs); + mt7621_spi_write(rs, MT7621_SPI_POLAR, polar); +} + +static int mt7621_spi_prepare(struct spi_device *spi, unsigned int speed) +{ + struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); + u32 rate; + u32 reg; + + dev_dbg(&spi->dev, "speed:%u\n", speed); + + rate = DIV_ROUND_UP(rs->sys_freq, speed); + dev_dbg(&spi->dev, "rate-1:%u\n", rate); + + if (rate > 4097) + return -EINVAL; + + if (rate < 2) + rate = 2; + + reg = mt7621_spi_read(rs, MT7621_SPI_MASTER); + reg &= ~MASTER_RS_CLK_SEL; + reg |= (rate - 2) << MASTER_RS_CLK_SEL_SHIFT; + rs->speed = speed; + + reg &= ~MT7621_LSB_FIRST; + if (spi->mode & SPI_LSB_FIRST) + reg |= MT7621_LSB_FIRST; + + /* + * This SPI controller seems to be tested on SPI flash only and some + * bits are swizzled under other SPI modes probably due to incorrect + * wiring inside the silicon. Only mode 0 works correctly. + */ + reg &= ~(MT7621_CPHA | MT7621_CPOL); + + mt7621_spi_write(rs, MT7621_SPI_MASTER, reg); + + return 0; +} + +static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs) +{ + int i; + + for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) { + u32 status; + + status = mt7621_spi_read(rs, MT7621_SPI_TRANS); + if ((status & SPITRANS_BUSY) == 0) + return 0; + cpu_relax(); + udelay(1); + } + + return -ETIMEDOUT; +} + +static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs, + int rx_len, u8 *buf) +{ + int tx_len; + + /* + * Combine with any pending write, and perform one or more half-duplex + * transactions reading 'len' bytes. Data to be written is already in + * MT7621_SPI_DATA. + */ + tx_len = rs->pending_write; + rs->pending_write = 0; + + while (rx_len || tx_len) { + int i; + u32 val = (min(tx_len, 4) * 8) << 24; + int rx = min(rx_len, 32); + + if (tx_len > 4) + val |= (tx_len - 4) * 8; + val |= (rx * 8) << 12; + mt7621_spi_write(rs, MT7621_SPI_MOREBUF, val); + + tx_len = 0; + + val = mt7621_spi_read(rs, MT7621_SPI_TRANS); + val |= SPI_CTL_START; + mt7621_spi_write(rs, MT7621_SPI_TRANS, val); + + mt7621_spi_wait_till_ready(rs); + + for (i = 0; i < rx; i++) { + if ((i % 4) == 0) + val = mt7621_spi_read(rs, MT7621_SPI_DATA0 + i); + *buf++ = val & 0xff; + val >>= 8; + } + + rx_len -= i; + } +} + +static inline void mt7621_spi_flush(struct mt7621_spi *rs) +{ + mt7621_spi_read_half_duplex(rs, 0, NULL); +} + +static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs, + int tx_len, const u8 *buf) +{ + int len = rs->pending_write; + int val = 0; + + if (len & 3) { + val = mt7621_spi_read(rs, MT7621_SPI_OPCODE + (len & ~3)); + if (len < 4) { + val <<= (4 - len) * 8; + val = swab32(val); + } + } + + while (tx_len > 0) { + if (len >= 36) { + rs->pending_write = len; + mt7621_spi_flush(rs); + len = 0; + } + + val |= *buf++ << (8 * (len & 3)); + len++; + if ((len & 3) == 0) { + if (len == 4) + /* The byte-order of the opcode is weird! */ + val = swab32(val); + mt7621_spi_write(rs, MT7621_SPI_OPCODE + len - 4, val); + val = 0; + } + tx_len -= 1; + } + + if (len & 3) { + if (len < 4) { + val = swab32(val); + val >>= (4 - len) * 8; + } + mt7621_spi_write(rs, MT7621_SPI_OPCODE + (len & ~3), val); + } + + rs->pending_write = len; +} + +static int mt7621_spi_transfer_one_message(struct spi_controller *master, + struct spi_message *m) +{ + struct mt7621_spi *rs = spi_controller_get_devdata(master); + struct spi_device *spi = m->spi; + unsigned int speed = spi->max_speed_hz; + struct spi_transfer *t = NULL; + int status = 0; + + mt7621_spi_wait_till_ready(rs); + + list_for_each_entry(t, &m->transfers, transfer_list) + if (t->speed_hz < speed) + speed = t->speed_hz; + + if (mt7621_spi_prepare(spi, speed)) { + status = -EIO; + goto msg_done; + } + + /* Assert CS */ + mt7621_spi_set_cs(spi, 1); + + m->actual_length = 0; + list_for_each_entry(t, &m->transfers, transfer_list) { + if ((t->rx_buf) && (t->tx_buf)) { + /* + * This controller will shift some extra data out + * of spi_opcode if (mosi_bit_cnt > 0) && + * (cmd_bit_cnt == 0). So the claimed full-duplex + * support is broken since we have no way to read + * the MISO value during that bit. + */ + status = -EIO; + goto msg_done; + } else if (t->rx_buf) { + mt7621_spi_read_half_duplex(rs, t->len, t->rx_buf); + } else if (t->tx_buf) { + mt7621_spi_write_half_duplex(rs, t->len, t->tx_buf); + } + m->actual_length += t->len; + } + + /* Flush data and deassert CS */ + mt7621_spi_flush(rs); + mt7621_spi_set_cs(spi, 0); + +msg_done: + m->status = status; + spi_finalize_current_message(master); + + return 0; +} + +static int mt7621_spi_setup(struct spi_device *spi) +{ + struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); + + if ((spi->max_speed_hz == 0) || + (spi->max_speed_hz > (rs->sys_freq / 2))) + spi->max_speed_hz = (rs->sys_freq / 2); + + if (spi->max_speed_hz < (rs->sys_freq / 4097)) { + dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n", + spi->max_speed_hz); + return -EINVAL; + } + + return 0; +} + +static const struct of_device_id mt7621_spi_match[] = { + { .compatible = "ralink,mt7621-spi" }, + {}, +}; +MODULE_DEVICE_TABLE(of, mt7621_spi_match); + +static int mt7621_spi_probe(struct platform_device *pdev) +{ + const struct of_device_id *match; + struct spi_controller *master; + struct mt7621_spi *rs; + void __iomem *base; + struct resource *r; + int status = 0; + struct clk *clk; + struct mt7621_spi_ops *ops; + int ret; + + match = of_match_device(mt7621_spi_match, &pdev->dev); + if (!match) + return -EINVAL; + ops = (struct mt7621_spi_ops *)match->data; + + r = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, r); + if (IS_ERR(base)) + return PTR_ERR(base); + + clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(clk)) { + dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n", + status); + return PTR_ERR(clk); + } + + status = clk_prepare_enable(clk); + if (status) + return status; + + master = spi_alloc_master(&pdev->dev, sizeof(*rs)); + if (!master) { + dev_info(&pdev->dev, "master allocation failed\n"); + return -ENOMEM; + } + + master->mode_bits = SPI_LSB_FIRST; + master->flags = SPI_CONTROLLER_HALF_DUPLEX; + master->setup = mt7621_spi_setup; + master->transfer_one_message = mt7621_spi_transfer_one_message; + master->bits_per_word_mask = SPI_BPW_MASK(8); + master->dev.of_node = pdev->dev.of_node; + master->num_chipselect = 2; + + dev_set_drvdata(&pdev->dev, master); + + rs = spi_controller_get_devdata(master); + rs->base = base; + rs->clk = clk; + rs->master = master; + rs->sys_freq = clk_get_rate(rs->clk); + rs->ops = ops; + rs->pending_write = 0; + dev_info(&pdev->dev, "sys_freq: %u\n", rs->sys_freq); + + ret = device_reset(&pdev->dev); + if (ret) { + dev_err(&pdev->dev, "SPI reset failed!\n"); + return ret; + } + + return devm_spi_register_controller(&pdev->dev, master); +} + +static int mt7621_spi_remove(struct platform_device *pdev) +{ + struct spi_controller *master; + struct mt7621_spi *rs; + + master = dev_get_drvdata(&pdev->dev); + rs = spi_controller_get_devdata(master); + + clk_disable_unprepare(rs->clk); + + return 0; +} + +MODULE_ALIAS("platform:" DRIVER_NAME); + +static struct platform_driver mt7621_spi_driver = { + .driver = { + .name = DRIVER_NAME, + .of_match_table = mt7621_spi_match, + }, + .probe = mt7621_spi_probe, + .remove = mt7621_spi_remove, +}; + +module_platform_driver(mt7621_spi_driver); + +MODULE_DESCRIPTION("MT7621 SPI driver"); +MODULE_AUTHOR("Felix Fietkau "); +MODULE_LICENSE("GPL"); diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index c0901b96cfe4..3241bd50d139 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig @@ -106,8 +106,6 @@ source "drivers/staging/mt7621-pci-phy/Kconfig" source "drivers/staging/mt7621-pinctrl/Kconfig" -source "drivers/staging/mt7621-spi/Kconfig" - source "drivers/staging/mt7621-dma/Kconfig" source "drivers/staging/ralink-gdma/Kconfig" diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 57c6bce13ff4..296ff11ecfae 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile @@ -43,7 +43,6 @@ obj-$(CONFIG_PI433) += pi433/ obj-$(CONFIG_PCI_MT7621) += mt7621-pci/ obj-$(CONFIG_PCI_MT7621_PHY) += mt7621-pci-phy/ obj-$(CONFIG_PINCTRL_RT2880) += mt7621-pinctrl/ -obj-$(CONFIG_SPI_MT7621) += mt7621-spi/ obj-$(CONFIG_SOC_MT7621) += mt7621-dma/ obj-$(CONFIG_DMA_RALINK) += ralink-gdma/ obj-$(CONFIG_MTK_MMC) += mt7621-mmc/ diff --git a/drivers/staging/mt7621-spi/Kconfig b/drivers/staging/mt7621-spi/Kconfig deleted file mode 100644 index 0b90f4cfa426..000000000000 --- a/drivers/staging/mt7621-spi/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -config SPI_MT7621 - tristate "MediaTek MT7621 SPI Controller" - depends on RALINK - help - This selects a driver for the MediaTek MT7621 SPI Controller. - diff --git a/drivers/staging/mt7621-spi/Makefile b/drivers/staging/mt7621-spi/Makefile deleted file mode 100644 index 3be508f63bac..000000000000 --- a/drivers/staging/mt7621-spi/Makefile +++ /dev/null @@ -1 +0,0 @@ -obj-$(CONFIG_SPI_MT7621) += spi-mt7621.o diff --git a/drivers/staging/mt7621-spi/TODO b/drivers/staging/mt7621-spi/TODO deleted file mode 100644 index fdbc5002c32a..000000000000 --- a/drivers/staging/mt7621-spi/TODO +++ /dev/null @@ -1,5 +0,0 @@ - -- general code review and clean up -- ensure device-tree requirements are documented - -Cc: NeilBrown diff --git a/drivers/staging/mt7621-spi/spi-mt7621.c b/drivers/staging/mt7621-spi/spi-mt7621.c deleted file mode 100644 index b509f9fe3346..000000000000 --- a/drivers/staging/mt7621-spi/spi-mt7621.c +++ /dev/null @@ -1,422 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * spi-mt7621.c -- MediaTek MT7621 SPI controller driver - * - * Copyright (C) 2011 Sergiy - * Copyright (C) 2011-2013 Gabor Juhos - * Copyright (C) 2014-2015 Felix Fietkau - * - * Some parts are based on spi-orion.c: - * Author: Shadi Ammouri - * Copyright (C) 2007-2008 Marvell Ltd. - */ - -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "spi-mt7621" - -/* in usec */ -#define RALINK_SPI_WAIT_MAX_LOOP 2000 - -/* SPISTAT register bit field */ -#define SPISTAT_BUSY BIT(0) - -#define MT7621_SPI_TRANS 0x00 -#define SPITRANS_BUSY BIT(16) - -#define MT7621_SPI_OPCODE 0x04 -#define MT7621_SPI_DATA0 0x08 -#define MT7621_SPI_DATA4 0x18 -#define SPI_CTL_TX_RX_CNT_MASK 0xff -#define SPI_CTL_START BIT(8) - -#define MT7621_SPI_MASTER 0x28 -#define MASTER_MORE_BUFMODE BIT(2) -#define MASTER_FULL_DUPLEX BIT(10) -#define MASTER_RS_CLK_SEL GENMASK(27, 16) -#define MASTER_RS_CLK_SEL_SHIFT 16 -#define MASTER_RS_SLAVE_SEL GENMASK(31, 29) - -#define MT7621_SPI_MOREBUF 0x2c -#define MT7621_SPI_POLAR 0x38 -#define MT7621_SPI_SPACE 0x3c - -#define MT7621_CPHA BIT(5) -#define MT7621_CPOL BIT(4) -#define MT7621_LSB_FIRST BIT(3) - -struct mt7621_spi { - struct spi_master *master; - void __iomem *base; - unsigned int sys_freq; - unsigned int speed; - struct clk *clk; - int pending_write; - - struct mt7621_spi_ops *ops; -}; - -static inline struct mt7621_spi *spidev_to_mt7621_spi(struct spi_device *spi) -{ - return spi_master_get_devdata(spi->master); -} - -static inline u32 mt7621_spi_read(struct mt7621_spi *rs, u32 reg) -{ - return ioread32(rs->base + reg); -} - -static inline void mt7621_spi_write(struct mt7621_spi *rs, u32 reg, u32 val) -{ - iowrite32(val, rs->base + reg); -} - -static void mt7621_spi_reset(struct mt7621_spi *rs) -{ - u32 master = mt7621_spi_read(rs, MT7621_SPI_MASTER); - - /* - * Select SPI device 7, enable "more buffer mode" and disable - * full-duplex (only half-duplex really works on this chip - * reliably) - */ - master |= MASTER_RS_SLAVE_SEL | MASTER_MORE_BUFMODE; - master &= ~MASTER_FULL_DUPLEX; - - mt7621_spi_write(rs, MT7621_SPI_MASTER, master); - rs->pending_write = 0; -} - -static void mt7621_spi_set_cs(struct spi_device *spi, int enable) -{ - struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); - int cs = spi->chip_select; - u32 polar = 0; - - mt7621_spi_reset(rs); - if (enable) - polar = BIT(cs); - mt7621_spi_write(rs, MT7621_SPI_POLAR, polar); -} - -static int mt7621_spi_prepare(struct spi_device *spi, unsigned int speed) -{ - struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); - u32 rate; - u32 reg; - - dev_dbg(&spi->dev, "speed:%u\n", speed); - - rate = DIV_ROUND_UP(rs->sys_freq, speed); - dev_dbg(&spi->dev, "rate-1:%u\n", rate); - - if (rate > 4097) - return -EINVAL; - - if (rate < 2) - rate = 2; - - reg = mt7621_spi_read(rs, MT7621_SPI_MASTER); - reg &= ~MASTER_RS_CLK_SEL; - reg |= (rate - 2) << MASTER_RS_CLK_SEL_SHIFT; - rs->speed = speed; - - reg &= ~MT7621_LSB_FIRST; - if (spi->mode & SPI_LSB_FIRST) - reg |= MT7621_LSB_FIRST; - - /* - * This SPI controller seems to be tested on SPI flash only and some - * bits are swizzled under other SPI modes probably due to incorrect - * wiring inside the silicon. Only mode 0 works correctly. - */ - reg &= ~(MT7621_CPHA | MT7621_CPOL); - - mt7621_spi_write(rs, MT7621_SPI_MASTER, reg); - - return 0; -} - -static inline int mt7621_spi_wait_till_ready(struct mt7621_spi *rs) -{ - int i; - - for (i = 0; i < RALINK_SPI_WAIT_MAX_LOOP; i++) { - u32 status; - - status = mt7621_spi_read(rs, MT7621_SPI_TRANS); - if ((status & SPITRANS_BUSY) == 0) - return 0; - cpu_relax(); - udelay(1); - } - - return -ETIMEDOUT; -} - -static void mt7621_spi_read_half_duplex(struct mt7621_spi *rs, - int rx_len, u8 *buf) -{ - /* - * Combine with any pending write, and perform one or more half-duplex - * transactions reading 'len' bytes. Data to be written is already in - * MT7621_SPI_DATA. - */ - int tx_len = rs->pending_write; - - rs->pending_write = 0; - - while (rx_len || tx_len) { - int i; - u32 val = (min(tx_len, 4) * 8) << 24; - int rx = min(rx_len, 32); - - if (tx_len > 4) - val |= (tx_len - 4) * 8; - val |= (rx * 8) << 12; - mt7621_spi_write(rs, MT7621_SPI_MOREBUF, val); - - tx_len = 0; - - val = mt7621_spi_read(rs, MT7621_SPI_TRANS); - val |= SPI_CTL_START; - mt7621_spi_write(rs, MT7621_SPI_TRANS, val); - - mt7621_spi_wait_till_ready(rs); - - for (i = 0; i < rx; i++) { - if ((i % 4) == 0) - val = mt7621_spi_read(rs, MT7621_SPI_DATA0 + i); - *buf++ = val & 0xff; - val >>= 8; - } - - rx_len -= i; - } -} - -static inline void mt7621_spi_flush(struct mt7621_spi *rs) -{ - mt7621_spi_read_half_duplex(rs, 0, NULL); -} - -static void mt7621_spi_write_half_duplex(struct mt7621_spi *rs, - int tx_len, const u8 *buf) -{ - int val = 0; - int len = rs->pending_write; - - if (len & 3) { - val = mt7621_spi_read(rs, MT7621_SPI_OPCODE + (len & ~3)); - if (len < 4) { - val <<= (4 - len) * 8; - val = swab32(val); - } - } - - while (tx_len > 0) { - if (len >= 36) { - rs->pending_write = len; - mt7621_spi_flush(rs); - len = 0; - } - - val |= *buf++ << (8 * (len & 3)); - len++; - if ((len & 3) == 0) { - if (len == 4) - /* The byte-order of the opcode is weird! */ - val = swab32(val); - mt7621_spi_write(rs, MT7621_SPI_OPCODE + len - 4, val); - val = 0; - } - tx_len -= 1; - } - if (len & 3) { - if (len < 4) { - val = swab32(val); - val >>= (4 - len) * 8; - } - mt7621_spi_write(rs, MT7621_SPI_OPCODE + (len & ~3), val); - } - rs->pending_write = len; -} - -static int mt7621_spi_transfer_one_message(struct spi_master *master, - struct spi_message *m) -{ - struct mt7621_spi *rs = spi_master_get_devdata(master); - struct spi_device *spi = m->spi; - unsigned int speed = spi->max_speed_hz; - struct spi_transfer *t = NULL; - int status = 0; - - mt7621_spi_wait_till_ready(rs); - - list_for_each_entry(t, &m->transfers, transfer_list) - if (t->speed_hz < speed) - speed = t->speed_hz; - - if (mt7621_spi_prepare(spi, speed)) { - status = -EIO; - goto msg_done; - } - - mt7621_spi_set_cs(spi, 1); - m->actual_length = 0; - list_for_each_entry(t, &m->transfers, transfer_list) { - if ((t->rx_buf) && (t->tx_buf)) { - /* This controller will shift some extra data out - * of spi_opcode if (mosi_bit_cnt > 0) && - * (cmd_bit_cnt == 0). So the claimed full-duplex - * support is broken since we have no way to read - * the MISO value during that bit. - */ - status = -EIO; - goto msg_done; - } else if (t->rx_buf) { - mt7621_spi_read_half_duplex(rs, t->len, t->rx_buf); - } else if (t->tx_buf) { - mt7621_spi_write_half_duplex(rs, t->len, t->tx_buf); - } - m->actual_length += t->len; - } - mt7621_spi_flush(rs); - - mt7621_spi_set_cs(spi, 0); - -msg_done: - m->status = status; - spi_finalize_current_message(master); - - return 0; -} - -static int mt7621_spi_setup(struct spi_device *spi) -{ - struct mt7621_spi *rs = spidev_to_mt7621_spi(spi); - - if ((spi->max_speed_hz == 0) || - (spi->max_speed_hz > (rs->sys_freq / 2))) - spi->max_speed_hz = (rs->sys_freq / 2); - - if (spi->max_speed_hz < (rs->sys_freq / 4097)) { - dev_err(&spi->dev, "setup: requested speed is too low %d Hz\n", - spi->max_speed_hz); - return -EINVAL; - } - - return 0; -} - -static const struct of_device_id mt7621_spi_match[] = { - { .compatible = "ralink,mt7621-spi" }, - {}, -}; -MODULE_DEVICE_TABLE(of, mt7621_spi_match); - -static int mt7621_spi_probe(struct platform_device *pdev) -{ - const struct of_device_id *match; - struct spi_master *master; - struct mt7621_spi *rs; - void __iomem *base; - struct resource *r; - int status = 0; - struct clk *clk; - struct mt7621_spi_ops *ops; - int ret; - - match = of_match_device(mt7621_spi_match, &pdev->dev); - if (!match) - return -EINVAL; - ops = (struct mt7621_spi_ops *)match->data; - - r = platform_get_resource(pdev, IORESOURCE_MEM, 0); - base = devm_ioremap_resource(&pdev->dev, r); - if (IS_ERR(base)) - return PTR_ERR(base); - - clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(clk)) { - dev_err(&pdev->dev, "unable to get SYS clock, err=%d\n", - status); - return PTR_ERR(clk); - } - - status = clk_prepare_enable(clk); - if (status) - return status; - - master = spi_alloc_master(&pdev->dev, sizeof(*rs)); - if (!master) { - dev_info(&pdev->dev, "master allocation failed\n"); - return -ENOMEM; - } - - master->mode_bits = SPI_LSB_FIRST; - - master->setup = mt7621_spi_setup; - master->transfer_one_message = mt7621_spi_transfer_one_message; - master->bits_per_word_mask = SPI_BPW_MASK(8); - master->dev.of_node = pdev->dev.of_node; - master->num_chipselect = 2; - - dev_set_drvdata(&pdev->dev, master); - - rs = spi_master_get_devdata(master); - rs->base = base; - rs->clk = clk; - rs->master = master; - rs->sys_freq = clk_get_rate(rs->clk); - rs->ops = ops; - rs->pending_write = 0; - dev_info(&pdev->dev, "sys_freq: %u\n", rs->sys_freq); - - ret = device_reset(&pdev->dev); - if (ret) { - dev_err(&pdev->dev, "SPI reset failed!\n"); - return ret; - } - - mt7621_spi_reset(rs); - - return spi_register_master(master); -} - -static int mt7621_spi_remove(struct platform_device *pdev) -{ - struct spi_master *master; - struct mt7621_spi *rs; - - master = dev_get_drvdata(&pdev->dev); - rs = spi_master_get_devdata(master); - - clk_disable(rs->clk); - spi_unregister_master(master); - - return 0; -} - -MODULE_ALIAS("platform:" DRIVER_NAME); - -static struct platform_driver mt7621_spi_driver = { - .driver = { - .name = DRIVER_NAME, - .of_match_table = mt7621_spi_match, - }, - .probe = mt7621_spi_probe, - .remove = mt7621_spi_remove, -}; - -module_platform_driver(mt7621_spi_driver); - -MODULE_DESCRIPTION("MT7621 SPI driver"); -MODULE_AUTHOR("Felix Fietkau "); -MODULE_LICENSE("GPL"); -- cgit v1.2.3 From d2920ef5d094b59254bedfccb1fab984d101c332 Mon Sep 17 00:00:00 2001 From: Naga Sureshkumar Relli Date: Mon, 1 Apr 2019 13:28:32 +0530 Subject: dt-bindings: spi: Add device tree binding documentation for Zynq QSPI controller This patch adds the dts binding document for Zynq SOC QSPI controller. Reviewed-by: Rob Herring Signed-off-by: Naga Sureshkumar Relli Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/spi-zynq-qspi.txt | 25 ++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 Documentation/devicetree/bindings/spi/spi-zynq-qspi.txt (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-zynq-qspi.txt b/Documentation/devicetree/bindings/spi/spi-zynq-qspi.txt new file mode 100644 index 000000000000..16b734ad3102 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/spi-zynq-qspi.txt @@ -0,0 +1,25 @@ +Xilinx Zynq QSPI controller Device Tree Bindings +------------------------------------------------------------------- + +Required properties: +- compatible : Should be "xlnx,zynq-qspi-1.0". +- reg : Physical base address and size of QSPI registers map. +- interrupts : Property with a value describing the interrupt + number. +- clock-names : List of input clock names - "ref_clk", "pclk" + (See clock bindings for details). +- clocks : Clock phandles (see clock bindings for details). + +Optional properties: +- num-cs : Number of chip selects used. + +Example: + qspi: spi@e000d000 { + compatible = "xlnx,zynq-qspi-1.0"; + reg = <0xe000d000 0x1000>; + interrupt-parent = <&intc>; + interrupts = <0 19 4>; + clock-names = "ref_clk", "pclk"; + clocks = <&clkc 10>, <&clkc 43>; + num-cs = <1>; + }; -- cgit v1.2.3 From 24496da6927fa7399f7f60ab31b4cea27ec3ed00 Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Thu, 4 Apr 2019 17:14:15 -0700 Subject: spi-summary: document set_cs_timing This patch documents set_cs_timing SPI master method. Signed-off-by: Sowjanya Komatineni Signed-off-by: Mark Brown --- Documentation/spi/spi-summary | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'Documentation') diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary index 1721c1b570c3..1a63194b74d7 100644 --- a/Documentation/spi/spi-summary +++ b/Documentation/spi/spi-summary @@ -572,6 +572,12 @@ SPI MASTER METHODS 0: transfer is finished 1: transfer is still in progress + master->set_cs_timing(struct spi_device *spi, u8 setup_clk_cycles, + u8 hold_clk_cycles, u8 inactive_clk_cycles) + This method allows SPI client drivers to request SPI master controller + for configuring device specific CS setup, hold and inactive timing + requirements. + DEPRECATED METHODS master->transfer(struct spi_device *spi, struct spi_message *message) -- cgit v1.2.3 From 7558f978f9b66a2bc284a0e8c0764b88305bc29f Mon Sep 17 00:00:00 2001 From: Sowjanya Komatineni Date: Thu, 4 Apr 2019 17:14:18 -0700 Subject: spi: document tx/rx clock delay properties Tegra SPI controller has TX and RX trimmers to tuning the delay of SPI master clock with respect to the data. TX and RX tap values are based on the platform validation across the PVT and the trimmer values vary based on the trace lengths to the corresponding SPI devices. Signed-off-by: Sowjanya Komatineni Signed-off-by: Mark Brown --- .../devicetree/bindings/spi/nvidia,tegra114-spi.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt index 9ba7c5a273b4..db8e0d71c5bc 100644 --- a/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt +++ b/Documentation/devicetree/bindings/spi/nvidia,tegra114-spi.txt @@ -23,6 +23,18 @@ Required properties: Recommended properties: - spi-max-frequency: Definition as per Documentation/devicetree/bindings/spi/spi-bus.txt +Optional properties: +- nvidia,tx-clk-tap-delay: Delays the clock going out to the external device + with this tap value. This property is used to tune the outgoing data from + Tegra SPI master with respect to outgoing Tegra SPI master clock. + Tap values vary based on the platform design trace lengths from Tegra SPI + to corresponding slave devices. Valid tap values are from 0 thru 63. +- nvidia,rx-clk-tap-delay: Delays the clock coming in from the external device + with this tap value. This property is used to adjust the Tegra SPI master + clock with respect to the data from the SPI slave device. + Tap values vary based on the platform design trace lengths from Tegra SPI + to corresponding slave devices. Valid tap values are from 0 thru 63. + Example: spi@7000d600 { @@ -38,4 +50,12 @@ spi@7000d600 { reset-names = "spi"; dmas = <&apbdma 16>, <&apbdma 16>; dma-names = "rx", "tx"; + @ { + ... + ... + nvidia,rx-clk-tap-delay = <0>; + nvidia,tx-clk-tap-delay = <16>; + ... + }; + }; -- cgit v1.2.3 From 9231b4603ef266cdf242d44c3164d6ee69447a1b Mon Sep 17 00:00:00 2001 From: Cao Van Dong Date: Thu, 11 Apr 2019 16:54:21 +0900 Subject: spi: sh-msiof: Document r8a77470 bindings Document SoC specific bindings for R-Car RZ/G1C(r8a77470) SoC. Signed-off-by: Cao Van Dong Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/sh-msiof.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/sh-msiof.txt b/Documentation/devicetree/bindings/spi/sh-msiof.txt index 37cf69586d10..18e14ee257b2 100644 --- a/Documentation/devicetree/bindings/spi/sh-msiof.txt +++ b/Documentation/devicetree/bindings/spi/sh-msiof.txt @@ -4,6 +4,7 @@ Required properties: - compatible : "renesas,msiof-r8a7743" (RZ/G1M) "renesas,msiof-r8a7744" (RZ/G1N) "renesas,msiof-r8a7745" (RZ/G1E) + "renesas,msiof-r8a77470" (RZ/G1C) "renesas,msiof-r8a774a1" (RZ/G2M) "renesas,msiof-r8a774c0" (RZ/G2E) "renesas,msiof-r8a7790" (R-Car H2) -- cgit v1.2.3 From bf6e839657598b77e40eb18225f8660c4778cb19 Mon Sep 17 00:00:00 2001 From: Leilk Liu Date: Wed, 17 Apr 2019 16:47:16 +0800 Subject: dt-bindings: spi: spi-mt65xx: add support for MT8516 Add binding documentation of spi-mt65xx for MT8516 SOC. Signed-off-by: Leilk Liu Reviewed-by: Matthias Brugger Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/spi/spi-mt65xx.txt | 1 + 1 file changed, 1 insertion(+) (limited to 'Documentation') diff --git a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt index 69c356767cf8..c0f6c8ecfa2e 100644 --- a/Documentation/devicetree/bindings/spi/spi-mt65xx.txt +++ b/Documentation/devicetree/bindings/spi/spi-mt65xx.txt @@ -10,6 +10,7 @@ Required properties: - mediatek,mt8135-spi: for mt8135 platforms - mediatek,mt8173-spi: for mt8173 platforms - mediatek,mt8183-spi: for mt8183 platforms + - "mediatek,mt8516-spi", "mediatek,mt2712-spi": for mt8516 platforms - #address-cells: should be 1. -- cgit v1.2.3