1
/* Driver for ATMEL DataFlash support
2
* Author : Hamid Ikdoumi (Atmel)
4
* This program is free software; you can redistribute it and/or
5
* modify it under the terms of the GNU General Public License as
6
* published by the Free Software Foundation; either version 2 of
7
* the License, or (at your option) any later version.
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
23
#include <asm/hardware.h>
25
#ifdef CONFIG_HAS_DATAFLASH
26
#include <dataflash.h>
28
#define AT91C_SPI_CLK 10000000 /* Max Value = 10MHz to be compliant to
29
the Continuous Array Read function */
31
/* AC Characteristics */
32
/* DLYBS = tCSS = 250ns min and DLYBCT = tCSH = 250ns */
33
#define DATAFLASH_TCSS (0xC << 16)
34
#define DATAFLASH_TCHS (0x1 << 24)
36
#define AT91C_TIMEOUT_WRDY 200000
37
#define AT91C_SPI_PCS0_SERIAL_DATAFLASH 0xE /* Chip Select 0: NPCS0%1110 */
38
#define AT91C_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3: NPCS3%0111 */
40
/*-------------------------------------------------------------------*/
41
/* SPI DataFlash Init */
42
/*-------------------------------------------------------------------*/
43
void AT91F_SpiInit(void)
46
AT91C_BASE_PIOA->PIO_ASR =
47
AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI |
48
AT91C_PA5_NPCS2 | AT91C_PA6_NPCS3 | AT91C_PA0_MISO |
50
AT91C_BASE_PIOA->PIO_PDR =
51
AT91C_PA3_NPCS0 | AT91C_PA4_NPCS1 | AT91C_PA1_MOSI |
52
AT91C_PA5_NPCS2 | AT91C_PA6_NPCS3 | AT91C_PA0_MISO |
55
AT91C_BASE_PMC->PMC_PCER = 1 << AT91C_ID_SPI;
58
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SWRST;
60
/* Configure SPI in Master Mode with No CS selected !!! */
61
AT91C_BASE_SPI->SPI_MR =
62
AT91C_SPI_MSTR | AT91C_SPI_MODFDIS | AT91C_SPI_PCS;
64
/* Configure CS0 and CS3 */
65
*(AT91C_SPI_CSR + 0) =
66
AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) |
67
(AT91C_SPI_DLYBCT & DATAFLASH_TCHS) |
68
((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
70
*(AT91C_SPI_CSR + 3) =
71
AT91C_SPI_CPOL | (AT91C_SPI_DLYBS & DATAFLASH_TCSS) |
72
(AT91C_SPI_DLYBCT & DATAFLASH_TCHS) |
73
((AT91C_MASTER_CLOCK / (2*AT91C_SPI_CLK)) << 8);
76
void AT91F_SpiEnable(int cs)
79
case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
80
AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
81
AT91C_BASE_SPI->SPI_MR |=
82
((AT91C_SPI_PCS0_SERIAL_DATAFLASH<<16) &
85
case 3: /* Configure SPI CS3 for Serial DataFlash Card */
86
/* Set up PIO SDC_TYPE to switch on DataFlash Card */
87
/* and not MMC/SDCard */
88
AT91C_BASE_PIOB->PIO_PER =
89
AT91C_PIO_PB7; /* Set in PIO mode */
90
AT91C_BASE_PIOB->PIO_OER =
91
AT91C_PIO_PB7; /* Configure in output */
93
AT91C_BASE_PIOB->PIO_CODR = AT91C_PIO_PB7;
95
AT91C_BASE_SPI->SPI_MR &= 0xFFF0FFFF;
96
AT91C_BASE_SPI->SPI_MR |=
97
((AT91C_SPI_PCS3_DATAFLASH_CARD<<16) & AT91C_SPI_PCS);
102
AT91C_BASE_SPI->SPI_CR = AT91C_SPI_SPIEN; }
104
/*---------------------------------------------------------------------------*/
105
/* \fn AT91F_SpiWrite */
106
/* \brief Set the PDC registers for a transfert */
107
/*---------------------------------------------------------------------------*/
108
unsigned int AT91F_SpiWrite ( AT91PS_DataflashDesc pDesc )
110
unsigned int timeout;
114
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
116
/* Initialize the Transmit and Receive Pointer */
117
AT91C_BASE_SPI->SPI_RPR = (unsigned int)pDesc->rx_cmd_pt ;
118
AT91C_BASE_SPI->SPI_TPR = (unsigned int)pDesc->tx_cmd_pt ;
120
/* Intialize the Transmit and Receive Counters */
121
AT91C_BASE_SPI->SPI_RCR = pDesc->rx_cmd_size;
122
AT91C_BASE_SPI->SPI_TCR = pDesc->tx_cmd_size;
124
if ( pDesc->tx_data_size != 0 ) {
125
/* Initialize the Next Transmit and Next Receive Pointer */
126
AT91C_BASE_SPI->SPI_RNPR = (unsigned int)pDesc->rx_data_pt ;
127
AT91C_BASE_SPI->SPI_TNPR = (unsigned int)pDesc->tx_data_pt ;
129
/* Intialize the Next Transmit and Next Receive Counters */
130
AT91C_BASE_SPI->SPI_RNCR = pDesc->rx_data_size ;
131
AT91C_BASE_SPI->SPI_TNCR = pDesc->tx_data_size ;
134
/* arm simple, non interrupt dependent timer */
135
reset_timer_masked();
138
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTEN + AT91C_PDC_RXTEN;
139
while(!(AT91C_BASE_SPI->SPI_SR & AT91C_SPI_RXBUFF) &&
140
((timeout = get_timer_masked() ) < CONFIG_SYS_SPI_WRITE_TOUT));
141
AT91C_BASE_SPI->SPI_PTCR = AT91C_PDC_TXTDIS + AT91C_PDC_RXTDIS;
144
if (timeout >= CONFIG_SYS_SPI_WRITE_TOUT){
145
printf("Error Timeout\n\r");
146
return DATAFLASH_ERROR;