+// SPDX-License-Identifier: GPL-2.0
/*
* NVIDIA Tegra SPI controller (T114 and later)
*
* 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
*/
#include <common.h>
#include <dm.h>
+#include <log.h>
+#include <time.h>
#include <asm/io.h>
#include <asm/arch/clock.h>
#include <asm/arch-tegra/clk_rst.h>
#include <spi.h>
-#include <fdtdec.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
#include "tegra_spi.h"
-DECLARE_GLOBAL_DATA_PTR;
-
/* COMMAND1 */
#define SPI_CMD1_GO BIT(31)
#define SPI_CMD1_M_S BIT(30)
-#define SPI_CMD1_MODE_MASK 0x3
+#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 BIT(25)
#define SPI_CMD1_CS_POL_INACTIVE2 BIT(24)
#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 0x3
+#define SPI_CMD1_IDLE_SDA_MASK GENMASK(1, 0)
#define SPI_CMD1_IDLE_SDA_SHIFT 18
#define SPI_CMD1_BIDIR BIT(17)
#define SPI_CMD1_LSBI_FE BIT(16)
#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 0x1F
+#define SPI_CMD1_BIT_LEN_MASK GENMASK(4, 0)
#define SPI_CMD1_BIT_LEN_SHIFT 0
/* COMMAND2 */
#define SPI_CMD2_TX_CLK_TAP_DELAY BIT(6)
-#define SPI_CMD2_TX_CLK_TAP_DELAY_MASK (0x3F << 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 (0x3F << 0)
+#define SPI_CMD2_RX_CLK_TAP_DELAY_MASK GENMASK(5, 0)
/* TRANSFER STATUS */
#define SPI_XFER_STS_RDY BIT(30)
int last_transaction_us;
};
-static int tegra114_spi_ofdata_to_platdata(struct udevice *bus)
+static int tegra114_spi_of_to_plat(struct udevice *bus)
{
- struct tegra_spi_platdata *plat = bus->platdata;
- const void *blob = gd->fdt_blob;
- int node = bus->of_offset;
+ struct tegra_spi_plat *plat = dev_get_plat(bus);
- plat->base = dev_get_addr(bus);
- 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__,
}
/* 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);
static int tegra114_spi_probe(struct udevice *bus)
{
- struct tegra_spi_platdata *plat = dev_get_platdata(bus);
+ struct tegra_spi_plat *plat = dev_get_plat(bus);
struct tegra114_spi_priv *priv = dev_get_priv(bus);
struct spi_regs *regs;
ulong rate;
bus->name, priv->freq, rate);
}
}
+ udelay(plat->deactivate_delay_us);
/* Clear stale status here */
setbits_le32(®s->fifo_status,
static void spi_cs_activate(struct udevice *dev)
{
struct udevice *bus = dev->parent;
- struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+ struct tegra_spi_plat *pdata = dev_get_plat(bus);
struct tegra114_spi_priv *priv = dev_get_priv(bus);
/* If it's too soon to do another transaction, wait */
static void spi_cs_deactivate(struct udevice *dev)
{
struct udevice *bus = dev->parent;
- struct tegra_spi_platdata *pdata = dev_get_platdata(bus);
+ struct tegra_spi_plat *pdata = dev_get_plat(bus);
struct tegra114_spi_priv *priv = dev_get_priv(bus);
setbits_le32(&priv->regs->command1, SPI_CMD1_CS_SW_VAL);
int ret;
debug("%s: slave %u:%u dout %p din %p bitlen %u\n",
- __func__, bus->seq, spi_chip_select(dev), dout, din, bitlen);
+ __func__, dev_seq(bus), spi_chip_select(dev), dout, din, bitlen);
if (bitlen % 8)
return -1;
num_bytes = bitlen / 8;
static int tegra114_spi_set_speed(struct udevice *bus, uint speed)
{
- struct tegra_spi_platdata *plat = bus->platdata;
+ struct tegra_spi_plat *plat = dev_get_plat(bus);
struct tegra114_spi_priv *priv = dev_get_priv(bus);
if (speed > plat->frequency)
.id = UCLASS_SPI,
.of_match = tegra114_spi_ids,
.ops = &tegra114_spi_ops,
- .ofdata_to_platdata = tegra114_spi_ofdata_to_platdata,
- .platdata_auto_alloc_size = sizeof(struct tegra_spi_platdata),
- .priv_auto_alloc_size = sizeof(struct tegra114_spi_priv),
+ .of_to_plat = tegra114_spi_of_to_plat,
+ .plat_auto = sizeof(struct tegra_spi_plat),
+ .priv_auto = sizeof(struct tegra114_spi_priv),
.probe = tegra114_spi_probe,
};