Merge branch 'master' of git://git.denx.de/u-boot-usb
[platform/kernel/u-boot.git] / 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 /*
23  * This driver desperately needs rework:
24  *
25  * - use structure SoC access
26  * - get rid of including asm/arch/at91_spi.h
27  * - remove asm/arch/at91_spi.h
28  * - get rid of all CONFIG_ATMEL_LEGACY defines and uses
29  *
30  * 02-Aug-2010 Reinhard Meyer <uboot@emk-elektronik.de>
31  */
32
33 #include <common.h>
34 #ifndef CONFIG_ATMEL_LEGACY
35 # define CONFIG_ATMEL_LEGACY
36 #endif
37 #include <spi.h>
38 #include <malloc.h>
39
40 #include <asm/io.h>
41
42 #include <asm/arch/clk.h>
43 #include <asm/arch/hardware.h>
44
45 #include "atmel_spi.h"
46
47 #include <asm/arch/gpio.h>
48 #include <asm/arch/at91_pio.h>
49 #include <asm/arch/at91_spi.h>
50
51 #include <dataflash.h>
52
53 #define AT91_SPI_PCS0_DATAFLASH_CARD    0xE     /* Chip Select 0: NPCS0%1110 */
54 #define AT91_SPI_PCS1_DATAFLASH_CARD    0xD     /* Chip Select 1: NPCS1%1101 */
55 #define AT91_SPI_PCS2_DATAFLASH_CARD    0xB     /* Chip Select 2: NPCS2%1011 */
56 #define AT91_SPI_PCS3_DATAFLASH_CARD    0x7     /* Chip Select 3: NPCS3%0111 */
57
58 void AT91F_SpiInit(void)
59 {
60         /* Reset the SPI */
61         writel(AT91_SPI_SWRST, ATMEL_BASE_SPI0 + AT91_SPI_CR);
62
63         /* Configure SPI in Master Mode with No CS selected !!! */
64         writel(AT91_SPI_MSTR | AT91_SPI_MODFDIS | AT91_SPI_PCS,
65                ATMEL_BASE_SPI0 + AT91_SPI_MR);
66
67         /* Configure CS0 */
68         writel(AT91_SPI_NCPHA |
69                (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
70                (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
71                ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
72                ATMEL_BASE_SPI0 + AT91_SPI_CSR(0));
73
74 #ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS1
75         /* Configure CS1 */
76         writel(AT91_SPI_NCPHA |
77                (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
78                (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
79                ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
80                ATMEL_BASE_SPI0 + AT91_SPI_CSR(1));
81 #endif
82 #ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS2
83         /* Configure CS2 */
84         writel(AT91_SPI_NCPHA |
85                (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
86                (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
87                ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
88                ATMEL_BASE_SPI0 + AT91_SPI_CSR(2));
89 #endif
90 #ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS3
91         /* Configure CS3 */
92         writel(AT91_SPI_NCPHA |
93                (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
94                (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
95                ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
96                ATMEL_BASE_SPI0 + AT91_SPI_CSR(3));
97 #endif
98
99         /* SPI_Enable */
100         writel(AT91_SPI_SPIEN, ATMEL_BASE_SPI0 + AT91_SPI_CR);
101
102         while (!(readl(ATMEL_BASE_SPI0 + AT91_SPI_SR) & AT91_SPI_SPIENS))
103                 ;
104
105         /*
106          * Add tempo to get SPI in a safe state.
107          * Should not be needed for new silicon (Rev B)
108          */
109         udelay(500000);
110         readl(ATMEL_BASE_SPI0 + AT91_SPI_SR);
111         readl(ATMEL_BASE_SPI0 + AT91_SPI_RDR);
112
113 }
114
115 void AT91F_SpiEnable(int cs)
116 {
117         unsigned long mode;
118
119         switch (cs) {
120         case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
121                 mode = readl(ATMEL_BASE_SPI0 + AT91_SPI_MR);
122                 mode &= 0xFFF0FFFF;
123                 writel(mode | ((AT91_SPI_PCS0_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
124                        ATMEL_BASE_SPI0 + AT91_SPI_MR);
125                 break;
126         case 1: /* Configure SPI CS1 for Serial DataFlash AT45DBxx */
127                 mode = readl(ATMEL_BASE_SPI0 + AT91_SPI_MR);
128                 mode &= 0xFFF0FFFF;
129                 writel(mode | ((AT91_SPI_PCS1_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
130                        ATMEL_BASE_SPI0 + AT91_SPI_MR);
131                 break;
132         case 2: /* Configure SPI CS2 for Serial DataFlash AT45DBxx */
133                 mode = readl(ATMEL_BASE_SPI0 + AT91_SPI_MR);
134                 mode &= 0xFFF0FFFF;
135                 writel(mode | ((AT91_SPI_PCS2_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
136                        ATMEL_BASE_SPI0 + AT91_SPI_MR);
137                 break;
138         case 3:
139                 mode = readl(ATMEL_BASE_SPI0 + AT91_SPI_MR);
140                 mode &= 0xFFF0FFFF;
141                 writel(mode | ((AT91_SPI_PCS3_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
142                        ATMEL_BASE_SPI0 + AT91_SPI_MR);
143                 break;
144         }
145
146         /* SPI_Enable */
147         writel(AT91_SPI_SPIEN, ATMEL_BASE_SPI0 + AT91_SPI_CR);
148 }
149
150 unsigned int AT91F_SpiWrite1(AT91PS_DataflashDesc pDesc);
151
152 unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc)
153 {
154         unsigned int timeout;
155         unsigned int timebase;
156
157         pDesc->state = BUSY;
158
159         writel(AT91_SPI_TXTDIS + AT91_SPI_RXTDIS,
160                 ATMEL_BASE_SPI0 + AT91_SPI_PTCR);
161
162         /* Initialize the Transmit and Receive Pointer */
163         writel((unsigned int)pDesc->rx_cmd_pt,
164                 ATMEL_BASE_SPI0 + AT91_SPI_RPR);
165         writel((unsigned int)pDesc->tx_cmd_pt,
166                 ATMEL_BASE_SPI0 + AT91_SPI_TPR);
167
168         /* Intialize the Transmit and Receive Counters */
169         writel(pDesc->rx_cmd_size, ATMEL_BASE_SPI0 + AT91_SPI_RCR);
170         writel(pDesc->tx_cmd_size, ATMEL_BASE_SPI0 + AT91_SPI_TCR);
171
172         if (pDesc->tx_data_size != 0) {
173                 /* Initialize the Next Transmit and Next Receive Pointer */
174                 writel((unsigned int)pDesc->rx_data_pt,
175                         ATMEL_BASE_SPI0 + AT91_SPI_RNPR);
176                 writel((unsigned int)pDesc->tx_data_pt,
177                         ATMEL_BASE_SPI0 + AT91_SPI_TNPR);
178
179                 /* Intialize the Next Transmit and Next Receive Counters */
180                 writel(pDesc->rx_data_size,
181                         ATMEL_BASE_SPI0 + AT91_SPI_RNCR);
182                 writel(pDesc->tx_data_size,
183                         ATMEL_BASE_SPI0 + AT91_SPI_TNCR);
184         }
185
186         /* arm simple, non interrupt dependent timer */
187         timebase = get_timer(0);
188         timeout = 0;
189
190         writel(AT91_SPI_TXTEN + AT91_SPI_RXTEN,
191                 ATMEL_BASE_SPI0 + AT91_SPI_PTCR);
192         while (!(readl(ATMEL_BASE_SPI0 + AT91_SPI_SR) & AT91_SPI_RXBUFF) &&
193                 ((timeout = get_timer(timebase)) < CONFIG_SYS_SPI_WRITE_TOUT))
194                 ;
195         writel(AT91_SPI_TXTDIS + AT91_SPI_RXTDIS,
196                 ATMEL_BASE_SPI0 + AT91_SPI_PTCR);
197         pDesc->state = IDLE;
198
199         if (timeout >= CONFIG_SYS_SPI_WRITE_TOUT) {
200                 printf("Error Timeout\n\r");
201                 return DATAFLASH_ERROR;
202         }
203
204         return DATAFLASH_OK;
205 }