spi: designware_spi: Some fixes / changes

As suggested by Pavel, here some fixes to the designware SPI driver:

- Spelling fixes
- Comment for timeout added
- Removed n_bytes completely (bits_per_word is enough for this)
- Unput clock now not defined via macro. The function to
  get the clock value is now called directly from within the driver

Signed-off-by: Stefan Roese <sr@denx.de>
Cc: Chin Liang See <clsee@altera.com>
Cc: Dinh Nguyen <dinguyen@altera.com>
Cc: Vince Bridgers <vbridger@altera.com>
Cc: Marek Vasut <marex@denx.de>
Acked-by: Pavel Machek <pavel@denx.de>
Cc: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
This commit is contained in:
Stefan Roese 2014-11-16 12:47:01 +01:00 committed by Marek Vasut
parent 481549f8c1
commit a72f80208d
1 changed files with 20 additions and 19 deletions

View File

@ -3,7 +3,8 @@
* *
* Copyright (C) 2014 Stefan Roese <sr@denx.de> * 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. * Copyright (c) 2009, Intel Corporation.
* *
* SPDX-License-Identifier: GPL-2.0 * SPDX-License-Identifier: GPL-2.0
@ -17,6 +18,7 @@
#include <fdtdec.h> #include <fdtdec.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <asm/io.h> #include <asm/io.h>
#include <asm/arch/clock_manager.h>
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
@ -81,7 +83,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define SR_TX_ERR (1 << 5) #define SR_TX_ERR (1 << 5)
#define SR_DCOL (1 << 6) #define SR_DCOL (1 << 6)
#define RX_TIMEOUT 1000 #define RX_TIMEOUT 1000 /* timeout in ms */
struct dw_spi_platdata { struct dw_spi_platdata {
s32 frequency; /* Default clock frequency, -1 for none */ s32 frequency; /* Default clock frequency, -1 for none */
@ -95,7 +97,6 @@ struct dw_spi_priv {
int bits_per_word; int bits_per_word;
u8 cs; /* chip select pin */ u8 cs; /* chip select pin */
u8 n_bytes; /* current is a 1/2/4 byte op */
u8 tmode; /* TR/TO/RO/EEPROM */ u8 tmode; /* TR/TO/RO/EEPROM */
u8 type; /* SPI/SSP/MicroWire */ u8 type; /* SPI/SSP/MicroWire */
int len; int len;
@ -185,7 +186,6 @@ static int dw_spi_probe(struct udevice *bus)
/* Currently only bits_per_word == 8 supported */ /* Currently only bits_per_word == 8 supported */
priv->bits_per_word = 8; priv->bits_per_word = 8;
priv->n_bytes = 1;
priv->tmode = 0; /* Tx & Rx */ 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; 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); tx_room = priv->fifo_len - dw_readw(priv, DW_SPI_TXFLR);
/* /*
* Another concern is about the tx/rx mismatch, we * 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 * one maximum value for tx, but it doesn't cover the
* data which is out of tx/rx fifo and inside the * data which is out of tx/rx fifo and inside the
* shift registers. So a control from sw point of * shift registers. So a control from sw point of
* view is taken. * view is taken.
*/ */
rxtx_gap = ((priv->rx_end - priv->rx) - (priv->tx_end - priv->tx)) / 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)); 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 */ /* Return the max entries we should read out of rx fifo */
static inline u32 rx_max(struct dw_spi_priv *priv) 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)); 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--) { while (max--) {
/* Set the tx word if the transfer's original "tx" is not null */ /* Set the tx word if the transfer's original "tx" is not null */
if (priv->tx_end - priv->len) { if (priv->tx_end - priv->len) {
if (priv->n_bytes == 1) if (priv->bits_per_word == 8)
txw = *(u8 *)(priv->tx); txw = *(u8 *)(priv->tx);
else else
txw = *(u16 *)(priv->tx); txw = *(u16 *)(priv->tx);
} }
dw_writew(priv, DW_SPI_DR, txw); dw_writew(priv, DW_SPI_DR, txw);
debug("%s: tx=0x%02x\n", __func__, 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--) { while (max--) {
rxw = dw_readw(priv, DW_SPI_DR); rxw = dw_readw(priv, DW_SPI_DR);
debug("%s: rx=0x%02x\n", __func__, rxw); 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->rx_end - priv->len) {
if (priv->n_bytes == 1) if (priv->bits_per_word == 8)
*(u8 *)(priv->rx) = rxw; *(u8 *)(priv->rx) = rxw;
else else
*(u16 *)(priv->rx) = rxw; *(u16 *)(priv->rx) = rxw;
} }
priv->rx += priv->n_bytes; priv->rx += priv->bits_per_word >> 3;
} }
return 0; return 0;
@ -297,7 +301,6 @@ static int dw_spi_xfer(struct udevice *dev, unsigned int bitlen,
u8 *rx = din; u8 *rx = din;
int ret = 0; int ret = 0;
u32 cr0 = 0; u32 cr0 = 0;
u8 bits = 0;
u32 cs; u32 cs;
/* spi core configured to do 8 bit transfers */ /* 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; return -1;
} }
bits = priv->bits_per_word; cr0 = (priv->bits_per_word - 1) | (priv->type << SPI_FRF_OFFSET) |
priv->n_bytes = bits >> 3;
cr0 = (bits - 1) | (priv->type << SPI_FRF_OFFSET) |
(priv->mode << SPI_MODE_OFFSET) | (priv->mode << SPI_MODE_OFFSET) |
(priv->tmode << SPI_TMOD_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 &= ~SPI_TMOD_MASK;
cr0 |= (priv->tmode << SPI_TMOD_OFFSET); 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); debug("%s: rx=%p tx=%p len=%d [bytes]\n", __func__, rx, tx, priv->len);
priv->tx = (void *)tx; priv->tx = (void *)tx;
@ -368,7 +369,7 @@ static int dw_spi_set_speed(struct udevice *bus, uint speed)
spi_enable_chip(priv, 0); spi_enable_chip(priv, 0);
/* clk_div doesn't support odd number */ /* 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; clk_div = (clk_div + 1) & 0xfffe;
dw_writel(priv, DW_SPI_BAUDR, clk_div); dw_writel(priv, DW_SPI_BAUDR, clk_div);