X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fspi%2Ftegra114_spi.c;h=04b4fce0612bbd14221f595ae3e65d73beb22e0f;hb=3b4cab15acd83aa468e809a300797253d8f66818;hp=53ff9ea22105353180159203def640905b5fecf8;hpb=307367eaffc8638e10ba1784fc66bfe623ae79e2;p=u-boot diff --git a/drivers/spi/tegra114_spi.c b/drivers/spi/tegra114_spi.c index 53ff9ea221..04b4fce061 100644 --- a/drivers/spi/tegra114_spi.c +++ b/drivers/spi/tegra114_spi.c @@ -3,22 +3,7 @@ * * Copyright (c) 2010-2013 NVIDIA Corporation * - * See file CREDITS for list of people who contributed to this - * project. - * - * This software is licensed under the terms of the GNU General Public - * License version 2, as published by the Free Software Foundation, and - * may be copied, distributed, and modified under those terms. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0 */ #include @@ -27,60 +12,59 @@ #include #include #include -#include #include "tegra_spi.h" DECLARE_GLOBAL_DATA_PTR; /* COMMAND1 */ -#define SPI_CMD1_GO (1 << 31) -#define SPI_CMD1_M_S (1 << 30) -#define SPI_CMD1_MODE_MASK 0x3 +#define SPI_CMD1_GO BIT(31) +#define SPI_CMD1_M_S BIT(30) +#define SPI_CMD1_MODE_MASK GENMASK(1, 0) #define SPI_CMD1_MODE_SHIFT 28 -#define SPI_CMD1_CS_SEL_MASK 0x3 +#define SPI_CMD1_CS_SEL_MASK GENMASK(1, 0) #define SPI_CMD1_CS_SEL_SHIFT 26 -#define SPI_CMD1_CS_POL_INACTIVE3 (1 << 25) -#define SPI_CMD1_CS_POL_INACTIVE2 (1 << 24) -#define SPI_CMD1_CS_POL_INACTIVE1 (1 << 23) -#define SPI_CMD1_CS_POL_INACTIVE0 (1 << 22) -#define SPI_CMD1_CS_SW_HW (1 << 21) -#define SPI_CMD1_CS_SW_VAL (1 << 20) -#define SPI_CMD1_IDLE_SDA_MASK 0x3 +#define SPI_CMD1_CS_POL_INACTIVE3 BIT(25) +#define SPI_CMD1_CS_POL_INACTIVE2 BIT(24) +#define SPI_CMD1_CS_POL_INACTIVE1 BIT(23) +#define SPI_CMD1_CS_POL_INACTIVE0 BIT(22) +#define SPI_CMD1_CS_SW_HW BIT(21) +#define SPI_CMD1_CS_SW_VAL BIT(20) +#define SPI_CMD1_IDLE_SDA_MASK GENMASK(1, 0) #define SPI_CMD1_IDLE_SDA_SHIFT 18 -#define SPI_CMD1_BIDIR (1 << 17) -#define SPI_CMD1_LSBI_FE (1 << 16) -#define SPI_CMD1_LSBY_FE (1 << 15) -#define SPI_CMD1_BOTH_EN_BIT (1 << 14) -#define SPI_CMD1_BOTH_EN_BYTE (1 << 13) -#define SPI_CMD1_RX_EN (1 << 12) -#define SPI_CMD1_TX_EN (1 << 11) -#define SPI_CMD1_PACKED (1 << 5) -#define SPI_CMD1_BIT_LEN_MASK 0x1F +#define SPI_CMD1_BIDIR BIT(17) +#define SPI_CMD1_LSBI_FE BIT(16) +#define SPI_CMD1_LSBY_FE BIT(15) +#define SPI_CMD1_BOTH_EN_BIT BIT(14) +#define SPI_CMD1_BOTH_EN_BYTE BIT(13) +#define SPI_CMD1_RX_EN BIT(12) +#define SPI_CMD1_TX_EN BIT(11) +#define SPI_CMD1_PACKED BIT(5) +#define SPI_CMD1_BIT_LEN_MASK GENMASK(4, 0) #define SPI_CMD1_BIT_LEN_SHIFT 0 /* COMMAND2 */ -#define SPI_CMD2_TX_CLK_TAP_DELAY (1 << 6) -#define SPI_CMD2_TX_CLK_TAP_DELAY_MASK (0x3F << 6) -#define SPI_CMD2_RX_CLK_TAP_DELAY (1 << 0) -#define SPI_CMD2_RX_CLK_TAP_DELAY_MASK (0x3F << 0) +#define SPI_CMD2_TX_CLK_TAP_DELAY BIT(6) +#define SPI_CMD2_TX_CLK_TAP_DELAY_MASK GENMASK(11, 6) +#define SPI_CMD2_RX_CLK_TAP_DELAY BIT(0) +#define SPI_CMD2_RX_CLK_TAP_DELAY_MASK GENMASK(5, 0) /* TRANSFER STATUS */ -#define SPI_XFER_STS_RDY (1 << 30) +#define SPI_XFER_STS_RDY BIT(30) /* FIFO STATUS */ -#define SPI_FIFO_STS_CS_INACTIVE (1 << 31) -#define SPI_FIFO_STS_FRAME_END (1 << 30) -#define SPI_FIFO_STS_RX_FIFO_FLUSH (1 << 15) -#define SPI_FIFO_STS_TX_FIFO_FLUSH (1 << 14) -#define SPI_FIFO_STS_ERR (1 << 8) -#define SPI_FIFO_STS_TX_FIFO_OVF (1 << 7) -#define SPI_FIFO_STS_TX_FIFO_UNR (1 << 6) -#define SPI_FIFO_STS_RX_FIFO_OVF (1 << 5) -#define SPI_FIFO_STS_RX_FIFO_UNR (1 << 4) -#define SPI_FIFO_STS_TX_FIFO_FULL (1 << 3) -#define SPI_FIFO_STS_TX_FIFO_EMPTY (1 << 2) -#define SPI_FIFO_STS_RX_FIFO_FULL (1 << 1) -#define SPI_FIFO_STS_RX_FIFO_EMPTY (1 << 0) +#define SPI_FIFO_STS_CS_INACTIVE BIT(31) +#define SPI_FIFO_STS_FRAME_END BIT(30) +#define SPI_FIFO_STS_RX_FIFO_FLUSH BIT(15) +#define SPI_FIFO_STS_TX_FIFO_FLUSH BIT(14) +#define SPI_FIFO_STS_ERR BIT(8) +#define SPI_FIFO_STS_TX_FIFO_OVF BIT(7) +#define SPI_FIFO_STS_TX_FIFO_UNR BIT(6) +#define SPI_FIFO_STS_RX_FIFO_OVF BIT(5) +#define SPI_FIFO_STS_RX_FIFO_UNR BIT(4) +#define SPI_FIFO_STS_TX_FIFO_FULL BIT(3) +#define SPI_FIFO_STS_TX_FIFO_EMPTY BIT(2) +#define SPI_FIFO_STS_RX_FIFO_FULL BIT(1) +#define SPI_FIFO_STS_RX_FIFO_EMPTY BIT(0) #define SPI_TIMEOUT 1000 #define TEGRA_SPI_MAX_FREQ 52000000 @@ -115,11 +99,9 @@ struct tegra114_spi_priv { static int tegra114_spi_ofdata_to_platdata(struct udevice *bus) { struct tegra_spi_platdata *plat = bus->platdata; - const void *blob = gd->fdt_blob; - int node = bus->of_offset; - plat->base = fdtdec_get_addr(blob, node, "reg"); - plat->periph_id = clock_decode_periph_id(blob, node); + plat->base = dev_read_addr(bus); + plat->periph_id = clock_decode_periph_id(bus); if (plat->periph_id == PERIPH_ID_NONE) { debug("%s: could not decode periph id %d\n", __func__, @@ -128,10 +110,10 @@ static int tegra114_spi_ofdata_to_platdata(struct udevice *bus) } /* Use 500KHz as a suitable default */ - plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", - 500000); - plat->deactivate_delay_us = fdtdec_get_int(blob, node, - "spi-deactivate-delay", 0); + plat->frequency = dev_read_u32_default(bus, "spi-max-frequency", + 500000); + plat->deactivate_delay_us = dev_read_u32_default(bus, + "spi-deactivate-delay", 0); debug("%s: base=%#08lx, periph_id=%d, max-frequency=%d, deactivate_delay=%d\n", __func__, plat->base, plat->periph_id, plat->frequency, plat->deactivate_delay_us); @@ -143,23 +125,31 @@ static int tegra114_spi_probe(struct udevice *bus) { struct tegra_spi_platdata *plat = dev_get_platdata(bus); struct tegra114_spi_priv *priv = dev_get_priv(bus); + struct spi_regs *regs; + ulong rate; priv->regs = (struct spi_regs *)plat->base; + regs = priv->regs; priv->last_transaction_us = timer_get_us(); priv->freq = plat->frequency; priv->periph_id = plat->periph_id; - return 0; -} - -static int tegra114_spi_claim_bus(struct udevice *bus) -{ - struct tegra114_spi_priv *priv = dev_get_priv(bus); - struct spi_regs *regs = priv->regs; - - /* Change SPI clock to correct frequency, PLLP_OUT0 source */ - clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, priv->freq); + /* + * Change SPI clock to correct frequency, PLLP_OUT0 source, falling + * back to the oscillator if that is too fast. + */ + rate = clock_start_periph_pll(priv->periph_id, CLOCK_ID_PERIPH, + priv->freq); + if (rate > priv->freq + 100000) { + rate = clock_start_periph_pll(priv->periph_id, CLOCK_ID_OSC, + priv->freq); + if (rate != priv->freq) { + printf("Warning: SPI '%s' requested clock %u, actual clock %lu\n", + bus->name, priv->freq, rate); + } + } + udelay(plat->deactivate_delay_us); /* Clear stale status here */ setbits_le32(®s->fifo_status, @@ -174,9 +164,8 @@ static int tegra114_spi_claim_bus(struct udevice *bus) SPI_FIFO_STS_RX_FIFO_EMPTY); debug("%s: FIFO STATUS = %08x\n", __func__, readl(®s->fifo_status)); - /* Set master mode and sw controlled CS */ - setbits_le32(®s->command1, SPI_CMD1_M_S | SPI_CMD1_CS_SW_HW | - (priv->mode << SPI_CMD1_MODE_SHIFT)); + setbits_le32(&priv->regs->command1, SPI_CMD1_M_S | SPI_CMD1_CS_SW_HW | + (priv->mode << SPI_CMD1_MODE_SHIFT) | SPI_CMD1_CS_SW_VAL); debug("%s: COMMAND1 = %08x\n", __func__, readl(®s->command1)); return 0; @@ -248,6 +237,9 @@ static int tegra114_spi_xfer(struct udevice *dev, unsigned int bitlen, ret = 0; + if (flags & SPI_XFER_BEGIN) + spi_cs_activate(dev); + /* clear all error status bits */ reg = readl(®s->fifo_status); writel(reg, ®s->fifo_status); @@ -259,9 +251,6 @@ static int tegra114_spi_xfer(struct udevice *dev, unsigned int bitlen, /* set xfer size to 1 block (32 bits) */ writel(0, ®s->dma_blk); - if (flags & SPI_XFER_BEGIN) - spi_cs_activate(dev); - /* handle data in 32-bit chunks */ while (num_bytes > 0) { int bytes; @@ -384,7 +373,6 @@ static int tegra114_spi_set_mode(struct udevice *bus, uint mode) } static const struct dm_spi_ops tegra114_spi_ops = { - .claim_bus = tegra114_spi_claim_bus, .xfer = tegra114_spi_xfer, .set_speed = tegra114_spi_set_speed, .set_mode = tegra114_spi_set_mode,