diff options
-rw-r--r-- | drivers/spi/designware_spi.c | 39 |
1 files changed, 20 insertions, 19 deletions
diff --git a/drivers/spi/designware_spi.c b/drivers/spi/designware_spi.c index 1bc0d04..98c9f03 100644 --- a/drivers/spi/designware_spi.c +++ b/drivers/spi/designware_spi.c @@ -3,7 +3,8 @@ * * Copyright (C) 2014 Stefan Roese <sr@denx.de> * - * 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 <fdtdec.h> #include <linux/compat.h> #include <asm/io.h> +#include <asm/arch/clock_manager.h> DECLARE_GLOBAL_DATA_PTR; @@ -81,7 +83,7 @@ DECLARE_GLOBAL_DATA_PTR; #define SR_TX_ERR (1 << 5) #define SR_DCOL (1 << 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; @@ -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); |