]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/spi/imx_ecspi.c
Unified codebase for TX28, TX48, TX51, TX53
[karo-tx-uboot.git] / drivers / spi / imx_ecspi.c
1 /*
2  * (C) Copyright 2008-2010 Freescale Semiconductor, Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <config.h>
24 #include <common.h>
25 #include <spi.h>
26 #include <asm/errno.h>
27 #include <linux/types.h>
28 #include <asm/io.h>
29 #include <malloc.h>
30
31 #include <imx_spi.h>
32
33 #ifdef  DEBUG
34
35 /* -----------------------------------------------
36  * Helper functions to peek into tx and rx buffers
37  * ----------------------------------------------- */
38 static const char * const hex_digit = "0123456789ABCDEF";
39
40 static char quickhex(int i)
41 {
42         return hex_digit[i];
43 }
44
45 static void memdump(const void *pv, int num)
46 {
47
48 }
49
50 #else /* !DEBUG */
51
52 #define memdump(p, n)
53
54 #endif /* DEBUG */
55
56 extern s32 spi_get_cfg(struct imx_spi_dev_t *dev);
57
58 static inline struct imx_spi_dev_t *to_imx_spi_slave(struct spi_slave *slave)
59 {
60         return container_of(slave, struct imx_spi_dev_t, slave);
61 }
62
63 static s32 spi_reset(struct spi_slave *slave)
64 {
65         u32 clk_src = mxc_get_clock(MXC_CSPI_CLK);
66         s32 pre_div = 0, post_div = 0, i, reg_ctrl, reg_config;
67         struct imx_spi_dev_t *dev = to_imx_spi_slave(slave);
68         struct spi_reg_t *reg = &(dev->reg);
69
70         if (dev->freq == 0) {
71                 printf("Error: desired clock is 0\n");
72                 return 1;
73         }
74
75         reg_ctrl = readl(dev->base + SPI_CON_REG);
76         /* Reset spi */
77         writel(0, dev->base + SPI_CON_REG);
78         writel((reg_ctrl | 0x1), dev->base + SPI_CON_REG);
79
80         /* Control register setup */
81         if (clk_src > dev->freq) {
82                 pre_div = clk_src / dev->freq;
83                 if (pre_div > 16) {
84                         post_div = pre_div / 16;
85                         pre_div = 15;
86                 }
87                 if (post_div != 0) {
88                         for (i = 0; i < 16; i++) {
89                                 if ((1 << i) >= post_div)
90                                         break;
91                         }
92                         if (i == 16) {
93                                 printf("Error: no divider can meet the freq: %d\n",
94                                         dev->freq);
95                                 return -1;
96                         }
97                         post_div = i;
98                 }
99         }
100
101         debug("pre_div = %d, post_div=%d\n", pre_div, post_div);
102         reg_ctrl = (reg_ctrl & ~(3 << 18)) | dev->ss << 18;
103         reg_ctrl = (reg_ctrl & ~(0xF << 12)) | pre_div << 12;
104         reg_ctrl = (reg_ctrl & ~(0xF << 8)) | post_div << 8;
105         reg_ctrl |= 1 << (dev->ss + 4); /* always set to master mode !!!! */
106         reg_ctrl &= ~0x1;               /* disable spi */
107
108         reg_config = readl(dev->base + SPI_CFG_REG);
109         /* configuration register setup */
110         reg_config = (reg_config & ~(1 << ((dev->ss + 12)))) |
111                 (dev->ss_pol << (dev->ss + 12));
112         reg_config = (reg_config & ~(1 << ((dev->ss + 20)))) |
113                 (dev->in_sctl << (dev->ss + 20));
114         reg_config = (reg_config & ~(1 << ((dev->ss + 16)))) |
115                 (dev->in_dctl << (dev->ss + 16));
116         reg_config = (reg_config & ~(1 << ((dev->ss + 8)))) |
117                 (dev->ssctl << (dev->ss + 8));
118         reg_config = (reg_config & ~(1 << ((dev->ss + 4)))) |
119                 (dev->sclkpol << (dev->ss + 4));
120         reg_config = (reg_config & ~(1 << ((dev->ss + 0)))) |
121                 (dev->sclkpha << (dev->ss + 0));
122
123         debug("reg_ctrl = 0x%x\n", reg_ctrl);
124         writel(reg_ctrl, dev->base + SPI_CON_REG);
125         debug("reg_config = 0x%x\n", reg_config);
126         writel(reg_config, dev->base + SPI_CFG_REG);
127
128         /* save config register and control register */
129         reg->cfg_reg  = reg_config;
130         reg->ctrl_reg = reg_ctrl;
131
132         /* clear interrupt reg */
133         writel(0, dev->base + SPI_INT_REG);
134         writel(3 << 6, dev->base + SPI_STAT_REG);
135
136         return 0;
137 }
138
139 void spi_init(void)
140 {
141 }
142
143 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
144                 unsigned int max_hz, unsigned int mode)
145 {
146         struct imx_spi_dev_t *imx_spi_slave = NULL;
147
148         if (!spi_cs_is_valid(bus, cs))
149                 return NULL;
150
151         imx_spi_slave = (struct imx_spi_dev_t *)malloc(sizeof(struct imx_spi_dev_t));
152         if (!imx_spi_slave)
153                 return NULL;
154
155         imx_spi_slave->slave.bus = bus;
156         imx_spi_slave->slave.cs = cs;
157
158         spi_get_cfg(imx_spi_slave);
159
160         spi_io_init(imx_spi_slave);
161
162         spi_reset(&(imx_spi_slave->slave));
163
164         return &(imx_spi_slave->slave);
165 }
166
167 void spi_free_slave(struct spi_slave *slave)
168 {
169         struct imx_spi_dev_t *imx_spi_slave;
170
171         if (slave) {
172                 imx_spi_slave = to_imx_spi_slave(slave);
173                 free(imx_spi_slave);
174         }
175 }
176
177 int spi_claim_bus(struct spi_slave *slave)
178 {
179         return 0;
180 }
181
182 void spi_release_bus(struct spi_slave *slave)
183 {
184
185 }
186
187 /*
188  * SPI transfer:
189  *
190  * See include/spi.h and http://www.altera.com/literature/ds/ds_nios_spi.pdf
191  * for more informations.
192  */
193 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
194                 void *din, unsigned long flags)
195 {
196         s32 val = SPI_RETRY_TIMES;
197         u32 *p_buf;
198         u32 reg;
199         s32 len = 0,
200                 ret_val = 0;
201         s32 burst_bytes = bitlen >> 3;
202         s32 tmp = 0;
203         struct imx_spi_dev_t *dev = to_imx_spi_slave(slave);
204         struct spi_reg_t *spi_reg = &(dev->reg);
205
206         if (!slave)
207                 return -1;
208
209         if (burst_bytes > (MAX_SPI_BYTES)) {
210                 printf("Error: maximum burst size is 0x%x bytes, asking 0x%x\n",
211                                 MAX_SPI_BYTES, burst_bytes);
212                 return -1;
213         }
214
215         if (flags & SPI_XFER_BEGIN) {
216                 spi_cs_activate(slave);
217
218                 if (spi_reg->ctrl_reg == 0) {
219                         printf("Error: spi(base=0x%x) has not been initialized yet\n",
220                                         dev->base);
221                         return -1;
222                 }
223                 spi_reg->ctrl_reg = (spi_reg->ctrl_reg & ~0xFFF00000) | \
224                                         ((burst_bytes * 8 - 1) << 20);
225
226                 writel(spi_reg->ctrl_reg | 0x1, dev->base + SPI_CON_REG);
227                 writel(spi_reg->cfg_reg, dev->base + SPI_CFG_REG);
228                 debug("ctrl_reg=0x%x, cfg_reg=0x%x\n",
229                                          readl(dev->base + SPI_CON_REG),
230                                          readl(dev->base + SPI_CFG_REG));
231
232                 /* move data to the tx fifo */
233                 if (dout) {
234                         for (p_buf = (u32 *)dout, len = burst_bytes; len > 0;
235                                 p_buf++, len -= 4)
236                                 writel(*p_buf, dev->base + SPI_TX_DATA);
237                 } else {
238                         for (len = burst_bytes; len > 0; len -= 4)
239                                 writel(tmp, dev->base + SPI_TX_DATA);
240                 }
241
242                 reg = readl(dev->base + SPI_CON_REG);
243                 reg |= (1 << 2); /* set xch bit */
244                 debug("control reg = 0x%08x\n", reg);
245                 writel(reg, dev->base + SPI_CON_REG);
246
247                 /* poll on the TC bit (transfer complete) */
248                 while ((val-- > 0) &&
249                         (readl(dev->base + SPI_STAT_REG) & (1 << 7)) == 0) {
250                         udelay(100);
251                 }
252
253                 /* clear the TC bit */
254                 writel(3 << 6, dev->base + SPI_STAT_REG);
255                 if (val <= 0) {
256                         printf("Error: re-tried %d times without response. Give up\n",
257                                         SPI_RETRY_TIMES);
258                         ret_val = -1;
259                         goto error;
260                 }
261         }
262
263         /* move data in the rx buf */
264         if (flags & SPI_XFER_END) {
265                 if (din) {
266                         for (p_buf = (u32 *)din, len = burst_bytes; len > 0;
267                                 ++p_buf, len -= 4)
268                                 *p_buf = readl(dev->base + SPI_RX_DATA);
269                 } else {
270                         for (len = burst_bytes; len > 0; len -= 4)
271                                 tmp = readl(dev->base + SPI_RX_DATA);
272                 }
273
274                 spi_cs_deactivate(slave);
275         }
276
277         return ret_val;
278
279 error:
280         spi_cs_deactivate(slave);
281         return ret_val;
282 }
283
284 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
285 {
286         return 1;
287 }
288
289 void spi_cs_activate(struct spi_slave *slave)
290 {
291         struct imx_spi_dev_t *dev = to_imx_spi_slave(slave);
292
293         spi_io_init(dev);
294 }
295
296 void spi_cs_deactivate(struct spi_slave *slave)
297 {
298         struct imx_spi_dev_t *dev = to_imx_spi_slave(slave);
299
300         writel(0, dev->base + SPI_CON_REG);
301 }
302