mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 14:41:31 +00:00
spi: omap3: Fix timeout handling
The timeout value is never reset during the transfer. This means that when transferring more data we eventually trigger the timeout. This was reported on the mailing list: "Spansion SPI flash read timeout with AM335x" Signed-off-by: David Dueck <davidcdueck@googlemail.com> CC: Tom Rini <trini@konsulko.com> CC: Stefan Roese <sr@denx.de> CC: Andy Pont <andy.pont@sdcsystems.com> Tested-by: David Dueck <davidcdueck@googlemail.com> Reviewed-by: Jagannadha Sutradharudu Teki <jagannadh.teki@gmail.com>
This commit is contained in:
parent
122d805fd4
commit
611c9ba2b8
1 changed files with 12 additions and 8 deletions
|
@ -20,7 +20,7 @@
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
#include "omap3_spi.h"
|
#include "omap3_spi.h"
|
||||||
|
|
||||||
#define SPI_WAIT_TIMEOUT 3000000
|
#define SPI_WAIT_TIMEOUT 10
|
||||||
|
|
||||||
static void spi_reset(struct omap3_spi_slave *ds)
|
static void spi_reset(struct omap3_spi_slave *ds)
|
||||||
{
|
{
|
||||||
|
@ -227,7 +227,7 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp,
|
||||||
{
|
{
|
||||||
struct omap3_spi_slave *ds = to_omap3_spi(slave);
|
struct omap3_spi_slave *ds = to_omap3_spi(slave);
|
||||||
int i;
|
int i;
|
||||||
int timeout = SPI_WAIT_TIMEOUT;
|
ulong start;
|
||||||
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
||||||
|
|
||||||
/* Enable the channel */
|
/* Enable the channel */
|
||||||
|
@ -241,9 +241,10 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const void *txp,
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
/* wait till TX register is empty (TXS == 1) */
|
/* wait till TX register is empty (TXS == 1) */
|
||||||
|
start = get_timer(0);
|
||||||
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
||||||
OMAP3_MCSPI_CHSTAT_TXS)) {
|
OMAP3_MCSPI_CHSTAT_TXS)) {
|
||||||
if (--timeout <= 0) {
|
if (get_timer(start) > SPI_WAIT_TIMEOUT) {
|
||||||
printf("SPI TXS timed out, status=0x%08x\n",
|
printf("SPI TXS timed out, status=0x%08x\n",
|
||||||
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -280,7 +281,7 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
|
||||||
{
|
{
|
||||||
struct omap3_spi_slave *ds = to_omap3_spi(slave);
|
struct omap3_spi_slave *ds = to_omap3_spi(slave);
|
||||||
int i;
|
int i;
|
||||||
int timeout = SPI_WAIT_TIMEOUT;
|
ulong start;
|
||||||
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
||||||
|
|
||||||
/* Enable the channel */
|
/* Enable the channel */
|
||||||
|
@ -295,10 +296,11 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, void *rxp,
|
||||||
writel(0, &ds->regs->channel[ds->slave.cs].tx);
|
writel(0, &ds->regs->channel[ds->slave.cs].tx);
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
|
start = get_timer(0);
|
||||||
/* Wait till RX register contains data (RXS == 1) */
|
/* Wait till RX register contains data (RXS == 1) */
|
||||||
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
||||||
OMAP3_MCSPI_CHSTAT_RXS)) {
|
OMAP3_MCSPI_CHSTAT_RXS)) {
|
||||||
if (--timeout <= 0) {
|
if (get_timer(start) > SPI_WAIT_TIMEOUT) {
|
||||||
printf("SPI RXS timed out, status=0x%08x\n",
|
printf("SPI RXS timed out, status=0x%08x\n",
|
||||||
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -332,7 +334,7 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
|
||||||
const void *txp, void *rxp, unsigned long flags)
|
const void *txp, void *rxp, unsigned long flags)
|
||||||
{
|
{
|
||||||
struct omap3_spi_slave *ds = to_omap3_spi(slave);
|
struct omap3_spi_slave *ds = to_omap3_spi(slave);
|
||||||
int timeout = SPI_WAIT_TIMEOUT;
|
ulong start;
|
||||||
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
|
||||||
int irqstatus = readl(&ds->regs->irqstatus);
|
int irqstatus = readl(&ds->regs->irqstatus);
|
||||||
int i=0;
|
int i=0;
|
||||||
|
@ -350,9 +352,10 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
|
||||||
for (i=0; i < len; i++){
|
for (i=0; i < len; i++){
|
||||||
/* Write: wait for TX empty (TXS == 1)*/
|
/* Write: wait for TX empty (TXS == 1)*/
|
||||||
irqstatus |= (1<< (4*(ds->slave.bus)));
|
irqstatus |= (1<< (4*(ds->slave.bus)));
|
||||||
|
start = get_timer(0);
|
||||||
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
||||||
OMAP3_MCSPI_CHSTAT_TXS)) {
|
OMAP3_MCSPI_CHSTAT_TXS)) {
|
||||||
if (--timeout <= 0) {
|
if (get_timer(start) > SPI_WAIT_TIMEOUT) {
|
||||||
printf("SPI TXS timed out, status=0x%08x\n",
|
printf("SPI TXS timed out, status=0x%08x\n",
|
||||||
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -368,9 +371,10 @@ int omap3_spi_txrx(struct spi_slave *slave, unsigned int len,
|
||||||
writel(((u8 *)txp)[i], tx);
|
writel(((u8 *)txp)[i], tx);
|
||||||
|
|
||||||
/*Read: wait for RX containing data (RXS == 1)*/
|
/*Read: wait for RX containing data (RXS == 1)*/
|
||||||
|
start = get_timer(0);
|
||||||
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
|
||||||
OMAP3_MCSPI_CHSTAT_RXS)) {
|
OMAP3_MCSPI_CHSTAT_RXS)) {
|
||||||
if (--timeout <= 0) {
|
if (get_timer(start) > SPI_WAIT_TIMEOUT) {
|
||||||
printf("SPI RXS timed out, status=0x%08x\n",
|
printf("SPI RXS timed out, status=0x%08x\n",
|
||||||
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
readl(&ds->regs->channel[ds->slave.cs].chstat));
|
||||||
return -1;
|
return -1;
|
||||||
|
|
Loading…
Add table
Reference in a new issue