blob: 3a648e619027f7fb0399f54078f9fc6e00756e26 [file] [log] [blame]
Stelian Popfefb6c12008-01-30 21:15:54 +00001/*
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
Stelian Popfefb6c12008-01-30 21:15:54 +000022#include <common.h>
Stelian Pop983c1db2008-03-26 20:52:32 +010023#include <asm/arch/hardware.h>
Jean-Christophe PLAGNIOL-VILLARDdc39ae92009-04-16 21:30:44 +020024#include <asm/arch/clk.h>
Stelian Pop983c1db2008-03-26 20:52:32 +010025#include <asm/arch/gpio.h>
26#include <asm/arch/io.h>
27#include <asm/arch/at91_pio.h>
28#include <asm/arch/at91_spi.h>
Stelian Popfefb6c12008-01-30 21:15:54 +000029
Stelian Popfefb6c12008-01-30 21:15:54 +000030#include <dataflash.h>
31
Stelian Pop983c1db2008-03-26 20:52:32 +010032#define AT91_SPI_PCS0_DATAFLASH_CARD 0xE /* Chip Select 0: NPCS0%1110 */
Remy Bohmer41dfd8a2009-10-28 22:13:37 +010033#define AT91_SPI_PCS1_DATAFLASH_CARD 0xD /* Chip Select 1: NPCS1%1101 */
34#define AT91_SPI_PCS2_DATAFLASH_CARD 0xB /* Chip Select 2: NPCS2%1011 */
Stelian Pop983c1db2008-03-26 20:52:32 +010035#define AT91_SPI_PCS3_DATAFLASH_CARD 0x7 /* Chip Select 3: NPCS3%0111 */
Stelian Popfefb6c12008-01-30 21:15:54 +000036
37void AT91F_SpiInit(void)
38{
39 /* Reset the SPI */
Stelian Pop983c1db2008-03-26 20:52:32 +010040 writel(AT91_SPI_SWRST, AT91_BASE_SPI + AT91_SPI_CR);
Stelian Popfefb6c12008-01-30 21:15:54 +000041
42 /* Configure SPI in Master Mode with No CS selected !!! */
Stelian Pop983c1db2008-03-26 20:52:32 +010043 writel(AT91_SPI_MSTR | AT91_SPI_MODFDIS | AT91_SPI_PCS,
44 AT91_BASE_SPI + AT91_SPI_MR);
Stelian Popfefb6c12008-01-30 21:15:54 +000045
46 /* Configure CS0 */
Stelian Pop983c1db2008-03-26 20:52:32 +010047 writel(AT91_SPI_NCPHA |
48 (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
49 (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
Jean-Christophe PLAGNIOL-VILLARDdc39ae92009-04-16 21:30:44 +020050 ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
Stelian Pop983c1db2008-03-26 20:52:32 +010051 AT91_BASE_SPI + AT91_SPI_CSR(0));
52
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020053#ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS1
Stelian Pop983c1db2008-03-26 20:52:32 +010054 /* Configure CS1 */
55 writel(AT91_SPI_NCPHA |
56 (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
57 (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
Jean-Christophe PLAGNIOL-VILLARDdc39ae92009-04-16 21:30:44 +020058 ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
Stelian Pop983c1db2008-03-26 20:52:32 +010059 AT91_BASE_SPI + AT91_SPI_CSR(1));
60#endif
Remy Bohmer41dfd8a2009-10-28 22:13:37 +010061#ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS2
62 /* Configure CS2 */
63 writel(AT91_SPI_NCPHA |
64 (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
65 (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
66 ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
67 AT91_BASE_SPI + AT91_SPI_CSR(2));
68#endif
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +020069#ifdef CONFIG_SYS_DATAFLASH_LOGIC_ADDR_CS3
Stelian Pop983c1db2008-03-26 20:52:32 +010070 /* Configure CS3 */
71 writel(AT91_SPI_NCPHA |
72 (AT91_SPI_DLYBS & DATAFLASH_TCSS) |
73 (AT91_SPI_DLYBCT & DATAFLASH_TCHS) |
Jean-Christophe PLAGNIOL-VILLARDdc39ae92009-04-16 21:30:44 +020074 ((get_mck_clk_rate() / AT91_SPI_CLK) << 8),
Stelian Pop983c1db2008-03-26 20:52:32 +010075 AT91_BASE_SPI + AT91_SPI_CSR(3));
76#endif
77
78 /* SPI_Enable */
79 writel(AT91_SPI_SPIEN, AT91_BASE_SPI + AT91_SPI_CR);
80
81 while (!(readl(AT91_BASE_SPI + AT91_SPI_SR) & AT91_SPI_SPIENS));
82
83 /*
84 * Add tempo to get SPI in a safe state.
85 * Should not be needed for new silicon (Rev B)
86 */
87 udelay(500000);
88 readl(AT91_BASE_SPI + AT91_SPI_SR);
89 readl(AT91_BASE_SPI + AT91_SPI_RDR);
90
Stelian Popfefb6c12008-01-30 21:15:54 +000091}
92
93void AT91F_SpiEnable(int cs)
94{
Stelian Pop983c1db2008-03-26 20:52:32 +010095 unsigned long mode;
Jean-Christophe PLAGNIOL-VILLARD1762f132008-03-31 21:20:49 +020096
Stelian Popfefb6c12008-01-30 21:15:54 +000097 switch (cs) {
98 case 0: /* Configure SPI CS0 for Serial DataFlash AT45DBxx */
Stelian Pop983c1db2008-03-26 20:52:32 +010099 mode = readl(AT91_BASE_SPI + AT91_SPI_MR);
100 mode &= 0xFFF0FFFF;
101 writel(mode | ((AT91_SPI_PCS0_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
102 AT91_BASE_SPI + AT91_SPI_MR);
103 break;
104 case 1: /* Configure SPI CS1 for Serial DataFlash AT45DBxx */
105 mode = readl(AT91_BASE_SPI + AT91_SPI_MR);
106 mode &= 0xFFF0FFFF;
107 writel(mode | ((AT91_SPI_PCS1_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
108 AT91_BASE_SPI + AT91_SPI_MR);
Stelian Popfefb6c12008-01-30 21:15:54 +0000109 break;
Remy Bohmer41dfd8a2009-10-28 22:13:37 +0100110 case 2: /* Configure SPI CS2 for Serial DataFlash AT45DBxx */
111 mode = readl(AT91_BASE_SPI + AT91_SPI_MR);
112 mode &= 0xFFF0FFFF;
113 writel(mode | ((AT91_SPI_PCS2_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
114 AT91_BASE_SPI + AT91_SPI_MR);
115 break;
Stelian Popfefb6c12008-01-30 21:15:54 +0000116 case 3:
Stelian Pop983c1db2008-03-26 20:52:32 +0100117 mode = readl(AT91_BASE_SPI + AT91_SPI_MR);
118 mode &= 0xFFF0FFFF;
119 writel(mode | ((AT91_SPI_PCS3_DATAFLASH_CARD<<16) & AT91_SPI_PCS),
120 AT91_BASE_SPI + AT91_SPI_MR);
Stelian Popfefb6c12008-01-30 21:15:54 +0000121 break;
122 }
123
124 /* SPI_Enable */
Stelian Pop983c1db2008-03-26 20:52:32 +0100125 writel(AT91_SPI_SPIEN, AT91_BASE_SPI + AT91_SPI_CR);
Stelian Popfefb6c12008-01-30 21:15:54 +0000126}
127
Stelian Pop983c1db2008-03-26 20:52:32 +0100128unsigned int AT91F_SpiWrite1(AT91PS_DataflashDesc pDesc);
129
Stelian Popfefb6c12008-01-30 21:15:54 +0000130unsigned int AT91F_SpiWrite(AT91PS_DataflashDesc pDesc)
131{
132 unsigned int timeout;
133
134 pDesc->state = BUSY;
135
Stelian Pop983c1db2008-03-26 20:52:32 +0100136 writel(AT91_SPI_TXTDIS + AT91_SPI_RXTDIS, AT91_BASE_SPI + AT91_SPI_PTCR);
137
Stelian Popfefb6c12008-01-30 21:15:54 +0000138 /* Initialize the Transmit and Receive Pointer */
Stelian Pop983c1db2008-03-26 20:52:32 +0100139 writel((unsigned int)pDesc->rx_cmd_pt, AT91_BASE_SPI + AT91_SPI_RPR);
140 writel((unsigned int)pDesc->tx_cmd_pt, AT91_BASE_SPI + AT91_SPI_TPR);
Stelian Popfefb6c12008-01-30 21:15:54 +0000141
142 /* Intialize the Transmit and Receive Counters */
Stelian Pop983c1db2008-03-26 20:52:32 +0100143 writel(pDesc->rx_cmd_size, AT91_BASE_SPI + AT91_SPI_RCR);
144 writel(pDesc->tx_cmd_size, AT91_BASE_SPI + AT91_SPI_TCR);
Stelian Popfefb6c12008-01-30 21:15:54 +0000145
146 if (pDesc->tx_data_size != 0) {
147 /* Initialize the Next Transmit and Next Receive Pointer */
Stelian Pop983c1db2008-03-26 20:52:32 +0100148 writel((unsigned int)pDesc->rx_data_pt, AT91_BASE_SPI + AT91_SPI_RNPR);
149 writel((unsigned int)pDesc->tx_data_pt, AT91_BASE_SPI + AT91_SPI_TNPR);
Stelian Popfefb6c12008-01-30 21:15:54 +0000150
151 /* Intialize the Next Transmit and Next Receive Counters */
Stelian Pop983c1db2008-03-26 20:52:32 +0100152 writel(pDesc->rx_data_size, AT91_BASE_SPI + AT91_SPI_RNCR);
153 writel(pDesc->tx_data_size, AT91_BASE_SPI + AT91_SPI_TNCR);
Stelian Popfefb6c12008-01-30 21:15:54 +0000154 }
155
156 /* arm simple, non interrupt dependent timer */
157 reset_timer_masked();
158 timeout = 0;
159
Stelian Pop983c1db2008-03-26 20:52:32 +0100160 writel(AT91_SPI_TXTEN + AT91_SPI_RXTEN, AT91_BASE_SPI + AT91_SPI_PTCR);
161 while (!(readl(AT91_BASE_SPI + AT91_SPI_SR) & AT91_SPI_RXBUFF) &&
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200162 ((timeout = get_timer_masked()) < CONFIG_SYS_SPI_WRITE_TOUT));
Stelian Pop983c1db2008-03-26 20:52:32 +0100163 writel(AT91_SPI_TXTDIS + AT91_SPI_RXTDIS, AT91_BASE_SPI + AT91_SPI_PTCR);
Stelian Popfefb6c12008-01-30 21:15:54 +0000164 pDesc->state = IDLE;
165
Jean-Christophe PLAGNIOL-VILLARD6d0f6bc2008-10-16 15:01:15 +0200166 if (timeout >= CONFIG_SYS_SPI_WRITE_TOUT) {
Stelian Popfefb6c12008-01-30 21:15:54 +0000167 printf("Error Timeout\n\r");
168 return DATAFLASH_ERROR;
169 }
170
171 return DATAFLASH_OK;
172}