]> git.sur5r.net Git - u-boot/blob - drivers/spi/atmel_dataflash_spi.c
EfikaMX: Enable EXT2 booting
[u-boot] / drivers / spi / atmel_dataflash_spi.c
1 /*
2  * Driver for ATMEL DataFlash support
3  * Author : Hamid Ikdoumi (Atmel)
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of
8  * the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18  * MA 02111-1307 USA
19  *
20  */
21
22 #include <common.h>
23 #ifndef CONFIG_AT91_LEGACY
24 # define CONFIG_AT91_LEGACY
25 # warning Please update to use C structure SoC access !
26 #endif
27 #include <spi.h>
28 #include <malloc.h>
29
30 #include <asm/io.h>
31
32 #include <asm/arch/clk.h>
33 #include <asm/arch/hardware.h>
34
35 #include "atmel_spi.h"
36
37 #include <asm/arch/gpio.h>
38 #include <asm/arch/at91_pio.h>
39 #include <asm/arch/at91_spi.h>
40
41 #include <dataflash.h>
42
43 #define AT91_SPI_PCS0_DATAFLASH_CARD    0xE     /* Chip Select 0: NPCS0%1110 */
44 #define AT91_SPI_PCS1_DATAFLASH_CARD    0xD     /* Chip Select 1: NPCS1%1101 */
45 #define AT91_SPI_PCS2_DATAFLASH_CARD    0xB     /* Chip Select 2: NPCS2%1011 */
46 #define AT91_SPI_PCS3_DATAFLASH_CARD    0x7     /* Chip Select 3: NPCS3%0111 */
47
48 void AT91F_SpiInit(void)
49 {
50         /* Reset the SPI */
51         writel(AT91_SPI_SWRST, ATMEL_BASE_SPI0 + AT91_SPI_CR);
52
53         /* Configure SPI in Master Mode with No CS selected !!! */
54         writel(AT91_SPI_MSTR | AT91_SPI_MODFDIS | AT91_SPI_PCS,
55                ATMEL_BASE_SPI0 + AT91_SPI_MR);
56
57         /* Configure CS0 */
58         writel(AT91_SPI_NCPHA |
59                (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
60                (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
61                ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
62                ATMEL_BASE_SPI0 + AT91_SPI_CSR(0));
63
64 #ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS1
65         /* Configure CS1 */
66         writel(AT91_SPI_NCPHA |
67                (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
68                (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
69                ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
70                ATMEL_BASE_SPI0 + AT91_SPI_CSR(1));
71 #endif
72 #ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS2
73         /* Configure CS2 */
74         writel(AT91_SPI_NCPHA |
75                (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
76                (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
77                ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
78                ATMEL_BASE_SPI0 + AT91_SPI_CSR(2));
79 #endif
80 #ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS3
81         /* Configure CS3 */
82         writel(AT91_SPI_NCPHA |
83                (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
84                (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
85                ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
86                ATMEL_BASE_SPI0 + AT91_SPI_CSR(3));
87 #endif
88
89         /* SPI_Enable */
90         writel(AT91_SPI_SPIEN, ATMEL_BASE_SPI0 + AT91_SPI_CR);
91
92         while (!(readl(ATMEL_BASE_SPI0 + AT91_SPI_SR) & AT91_SPI_SPIENS))
93                 ;
94
95         /*
96          * Add tempo to get SPI in a safe state.
97          * Should not be needed for new silicon (Rev B)
98          */
99         udelay(500000);
100         readl(ATMEL_BASE_SPI0 + AT91_SPI_SR);
101         readl(ATMEL_BASE_SPI0 + AT91_SPI_RDR);
102
103 }
104
105 void AT91F_SpiEnable(int cs)
106 {
107         unsigned long mode;
108
109         switch (cs) {
110         case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
111                 mode = readl(ATMEL_BASE_SPI0 + AT91_SPI_MR);
112                 mode &= 0xFFF0FFFF;
113                 writel(mode | ((AT91_SPI_PCS0_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
114                        ATMEL_BASE_SPI0 + AT91_SPI_MR);
115                 break;
116         case 1: /* Configure SPI CS1 for Serial DataFlash AT45DBxx */
117                 mode = readl(ATMEL_BASE_SPI0 + AT91_SPI_MR);
118                 mode &= 0xFFF0FFFF;
119                 writel(mode | ((AT91_SPI_PCS1_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
120                        ATMEL_BASE_SPI0 + AT91_SPI_MR);
121                 break;
122         case 2: /* Configure SPI CS2 for Serial DataFlash AT45DBxx */
123                 mode = readl(ATMEL_BASE_SPI0 + AT91_SPI_MR);
124                 mode &= 0xFFF0FFFF;
125                 writel(mode | ((AT91_SPI_PCS2_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
126                        ATMEL_BASE_SPI0 + AT91_SPI_MR);
127                 break;
128         case 3:
129                 mode = readl(ATMEL_BASE_SPI0 + AT91_SPI_MR);
130                 mode &= 0xFFF0FFFF;
131                 writel(mode | ((AT91_SPI_PCS3_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
132                        ATMEL_BASE_SPI0 + AT91_SPI_MR);
133                 break;
134         }
135
136         /* SPI_Enable */
137         writel(AT91_SPI_SPIEN, ATMEL_BASE_SPI0 + AT91_SPI_CR);
138 }
139
140 unsigned int AT91F_SpiWrite1(AT91PS_DataflashDesc pDesc);
141
142 unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc)
143 {
144         unsigned int timeout;
145         unsigned int timebase;
146
147         pDesc->state = BUSY;
148
149         writel(AT91_SPI_TXTDIS + AT91_SPI_RXTDIS,
150                 ATMEL_BASE_SPI0 + AT91_SPI_PTCR);
151
152         /* Initialize the Transmit and Receive Pointer */
153         writel((unsigned int)pDesc->rx_cmd_pt,
154                 ATMEL_BASE_SPI0 + AT91_SPI_RPR);
155         writel((unsigned int)pDesc->tx_cmd_pt,
156                 ATMEL_BASE_SPI0 + AT91_SPI_TPR);
157
158         /* Intialize the Transmit and Receive Counters */
159         writel(pDesc->rx_cmd_size, ATMEL_BASE_SPI0 + AT91_SPI_RCR);
160         writel(pDesc->tx_cmd_size, ATMEL_BASE_SPI0 + AT91_SPI_TCR);
161
162         if (pDesc->tx_data_size != 0) {
163                 /* Initialize the Next Transmit and Next Receive Pointer */
164                 writel((unsigned int)pDesc->rx_data_pt,
165                         ATMEL_BASE_SPI0 + AT91_SPI_RNPR);
166                 writel((unsigned int)pDesc->tx_data_pt,
167                         ATMEL_BASE_SPI0 + AT91_SPI_TNPR);
168
169                 /* Intialize the Next Transmit and Next Receive Counters */
170                 writel(pDesc->rx_data_size,
171                         ATMEL_BASE_SPI0 + AT91_SPI_RNCR);
172                 writel(pDesc->tx_data_size,
173                         ATMEL_BASE_SPI0 + AT91_SPI_TNCR);
174         }
175
176         /* arm simple, non interrupt dependent timer */
177         timebase = get_timer(0);
178         timeout = 0;
179
180         writel(AT91_SPI_TXTEN + AT91_SPI_RXTEN,
181                 ATMEL_BASE_SPI0 + AT91_SPI_PTCR);
182         while (!(readl(ATMEL_BASE_SPI0 + AT91_SPI_SR) & AT91_SPI_RXBUFF) &&
183                 ((timeout = get_timer(timebase)) < CONFIG_SYS_SPI_WRITE_TOUT))
184                 ;
185         writel(AT91_SPI_TXTDIS + AT91_SPI_RXTDIS,
186                 ATMEL_BASE_SPI0 + AT91_SPI_PTCR);
187         pDesc->state = IDLE;
188
189         if (timeout >= CONFIG_SYS_SPI_WRITE_TOUT) {
190                 printf("Error Timeout\n\r");
191                 return DATAFLASH_ERROR;
192         }
193
194         return DATAFLASH_OK;
195 }