X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fspi%2Fdesignware_spi.c;h=24a6e982054c5ce67893c81b85a1f74397b8ff56;hb=4ca0c3c993436cca743ed521e7f3d784d7fe31c8;hp=1bc0d04cca6f28b9b3bd1a5ec29536b3a3d890db;hpb=5bef6fd79f9442269c6a0d3778cb65c7a71e4d9a;p=u-boot diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c index 1bc0d04cca..24a6e98205 100644 --- a/drivers/spi/designware_spi.c +++ b/drivers/spi/designware_spi.c @@ -3,7 +3,8 @@ * * Copyright (C) 2014 Stefan Roese * - * Very loosly based on the Linux driver version which is: + * Very loosely based on the Linux driver: + * drivers/spi/spi-dw.c, which is: * Copyright (c) 2009, Intel Corporation. * * SPDX-License-Identifier: GPL-2.0 @@ -17,6 +18,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -72,16 +74,16 @@ DECLARE_GLOBAL_DATA_PTR; #define SPI_CFS_OFFSET 12 /* Bit fields in SR, 7 bits */ -#define SR_MASK 0x7f /* cover 7 bits */ -#define SR_BUSY (1 << 0) -#define SR_TF_NOT_FULL (1 << 1) -#define SR_TF_EMPT (1 << 2) -#define SR_RF_NOT_EMPT (1 << 3) -#define SR_RF_FULL (1 << 4) -#define SR_TX_ERR (1 << 5) -#define SR_DCOL (1 << 6) +#define SR_MASK GENMASK(6, 0) /* cover 7 bits */ +#define SR_BUSY BIT(0) +#define SR_TF_NOT_FULL BIT(1) +#define SR_TF_EMPT BIT(2) +#define SR_RF_NOT_EMPT BIT(3) +#define SR_RF_FULL BIT(4) +#define SR_TX_ERR BIT(5) +#define SR_DCOL BIT(6) -#define RX_TIMEOUT 1000 +#define RX_TIMEOUT 1000 /* timeout in ms */ struct dw_spi_platdata { s32 frequency; /* Default clock frequency, -1 for none */ @@ -95,7 +97,6 @@ struct dw_spi_priv { int bits_per_word; u8 cs; /* chip select pin */ - u8 n_bytes; /* current is a 1/2/4 byte op */ u8 tmode; /* TR/TO/RO/EEPROM */ u8 type; /* SPI/SSP/MicroWire */ int len; @@ -133,7 +134,7 @@ static int dw_spi_ofdata_to_platdata(struct udevice *bus) const void *blob = gd->fdt_blob; int node = bus->of_offset; - plat->regs = (struct dw_spi *)fdtdec_get_addr(blob, node, "reg"); + plat->regs = (struct dw_spi *)dev_get_addr(bus); /* Use 500KHz as a suitable default */ plat->frequency = fdtdec_get_int(blob, node, "spi-max-frequency", @@ -163,13 +164,13 @@ static void spi_hw_init(struct dw_spi_priv *priv) if (!priv->fifo_len) { u32 fifo; - for (fifo = 2; fifo <= 257; fifo++) { + for (fifo = 1; fifo < 256; fifo++) { dw_writew(priv, DW_SPI_TXFLTR, fifo); if (fifo != dw_readw(priv, DW_SPI_TXFLTR)) break; } - priv->fifo_len = (fifo == 257) ? 0 : fifo; + priv->fifo_len = (fifo == 1) ? 0 : fifo; dw_writew(priv, DW_SPI_TXFLTR, 0); } debug("%s: fifo_len=%d\n", __func__, priv->fifo_len); @@ -185,7 +186,6 @@ static int dw_spi_probe(struct udevice *bus) /* Currently only bits_per_word == 8 supported */ priv->bits_per_word = 8; - priv->n_bytes = 1; priv->tmode = 0; /* Tx & Rx */ @@ -200,19 +200,19 @@ static inline u32 tx_max(struct dw_spi_priv *priv) { u32 tx_left, tx_room, rxtx_gap; - tx_left = (priv->tx_end - priv->tx) / priv->n_bytes; + tx_left = (priv->tx_end - priv->tx) / (priv->bits_per_word >> 3); tx_room = priv->fifo_len - dw_readw(priv, DW_SPI_TXFLR); /* * Another concern is about the tx/rx mismatch, we - * though to use (priv->fifo_len - rxflr - txflr) as + * thought about using (priv->fifo_len - rxflr - txflr) as * one maximum value for tx, but it doesn't cover the * data which is out of tx/rx fifo and inside the * shift registers. So a control from sw point of * view is taken. */ rxtx_gap = ((priv->rx_end - priv->rx) - (priv->tx_end - priv->tx)) / - priv->n_bytes; + (priv->bits_per_word >> 3); return min3(tx_left, tx_room, (u32)(priv->fifo_len - rxtx_gap)); } @@ -220,7 +220,7 @@ static inline u32 tx_max(struct dw_spi_priv *priv) /* Return the max entries we should read out of rx fifo */ static inline u32 rx_max(struct dw_spi_priv *priv) { - u32 rx_left = (priv->rx_end - priv->rx) / priv->n_bytes; + u32 rx_left = (priv->rx_end - priv->rx) / (priv->bits_per_word >> 3); return min_t(u32, rx_left, dw_readw(priv, DW_SPI_RXFLR)); } @@ -233,14 +233,14 @@ static void dw_writer(struct dw_spi_priv *priv) while (max--) { /* Set the tx word if the transfer's original "tx" is not null */ if (priv->tx_end - priv->len) { - if (priv->n_bytes == 1) + if (priv->bits_per_word == 8) txw = *(u8 *)(priv->tx); else txw = *(u16 *)(priv->tx); } dw_writew(priv, DW_SPI_DR, txw); debug("%s: tx=0x%02x\n", __func__, txw); - priv->tx += priv->n_bytes; + priv->tx += priv->bits_per_word >> 3; } } @@ -261,14 +261,18 @@ static int dw_reader(struct dw_spi_priv *priv) while (max--) { rxw = dw_readw(priv, DW_SPI_DR); debug("%s: rx=0x%02x\n", __func__, rxw); - /* Care rx only if the transfer's original "rx" is not null */ + + /* + * Care about rx only if the transfer's original "rx" is + * not null + */ if (priv->rx_end - priv->len) { - if (priv->n_bytes == 1) + if (priv->bits_per_word == 8) *(u8 *)(priv->rx) = rxw; else *(u16 *)(priv->rx) = rxw; } - priv->rx += priv->n_bytes; + priv->rx += priv->bits_per_word >> 3; } return 0; @@ -297,7 +301,6 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int bitlen, u8 *rx = din; int ret = 0; u32 cr0 = 0; - u8 bits = 0; u32 cs; /* spi core configured to do 8 bit transfers */ @@ -306,9 +309,7 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int bitlen, return -1; } - bits = priv->bits_per_word; - priv->n_bytes = bits >> 3; - cr0 = (bits - 1) | (priv->type << SPI_FRF_OFFSET) | + cr0 = (priv->bits_per_word - 1) | (priv->type << SPI_FRF_OFFSET) | (priv->mode << SPI_MODE_OFFSET) | (priv->tmode << SPI_TMOD_OFFSET); @@ -322,7 +323,7 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int bitlen, cr0 &= ~SPI_TMOD_MASK; cr0 |= (priv->tmode << SPI_TMOD_OFFSET); - priv->len = bitlen / 8; + priv->len = bitlen >> 3; debug("%s: rx=%p tx=%p len=%d [bytes]\n", __func__, rx, tx, priv->len); priv->tx = (void *)tx; @@ -368,7 +369,7 @@ static int dw_spi_set_speed(struct udevice *bus, uint speed) spi_enable_chip(priv, 0); /* clk_div doesn't support odd number */ - clk_div = CONFIG_DW_SPI_REF_CLK / speed; + clk_div = cm_get_spi_controller_clk_hz() / speed; clk_div = (clk_div + 1) & 0xfffe; dw_writel(priv, DW_SPI_BAUDR, clk_div); @@ -408,7 +409,7 @@ static const struct dm_spi_ops dw_spi_ops = { }; static const struct udevice_id dw_spi_ids[] = { - { .compatible = "snps,dw-spi-mmio" }, + { .compatible = "snps,dw-apb-ssi" }, { } }; @@ -420,6 +421,5 @@ U_BOOT_DRIVER(dw_spi) = { .ofdata_to_platdata = dw_spi_ofdata_to_platdata, .platdata_auto_alloc_size = sizeof(struct dw_spi_platdata), .priv_auto_alloc_size = sizeof(struct dw_spi_priv), - .per_child_auto_alloc_size = sizeof(struct spi_slave), .probe = dw_spi_probe, };