]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/spi/imx_cspi.c
applied patches from Freescale and Ka-Ro
[karo-tx-uboot.git] / drivers / spi / imx_cspi.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 extern s32 spi_get_cfg(struct imx_spi_dev_t *dev);
34
35 static inline struct imx_spi_dev_t *to_imx_spi_slave(struct spi_slave *slave)
36 {
37         return container_of(slave, struct imx_spi_dev_t, slave);
38 }
39
40 static s32 spi_reset(struct spi_slave *slave)
41 {
42         u32 clk_src = mxc_get_clock(MXC_CSPI_CLK);
43         s32 div = 0, i, reg_ctrl;
44         struct imx_spi_dev_t *dev = to_imx_spi_slave(slave);
45         struct spi_reg_t *reg = &(dev->reg);
46         int lim = 0;
47         unsigned int baud_rate_div[] = { 4, 8, 16, 32, 64, 128, 256, 512 };
48
49         if (dev->freq == 0) {
50                 printf("Error: desired clock is 0\n");
51                 return 1;
52         }
53
54         reg_ctrl = readl(dev->base + SPI_CON_REG);
55         /* Reset spi */
56         writel(0, dev->base + SPI_CON_REG);
57         writel((reg_ctrl | SPI_CTRL_EN), dev->base + SPI_CON_REG);
58
59         lim = sizeof(baud_rate_div) / sizeof(unsigned int);
60         if (clk_src > dev->freq) {
61                 div = clk_src / dev->freq;
62
63                 for (i = 0; i < lim; i++) {
64                         if (div <= baud_rate_div[i])
65                                 break;
66                 }
67         }
68         debug("div = %d\n", baud_rate_div[i]);
69
70         reg_ctrl =
71             (reg_ctrl & ~SPI_CTRL_SS_MASK) | (dev->ss << SPI_CTRL_SS_OFF);
72         reg_ctrl = (reg_ctrl & ~SPI_CTRL_DATA_MASK) | (i << SPI_CTRL_DATA_OFF);
73         reg_ctrl |= SPI_CTRL_MODE;      /* always set to master mode !!!! */
74         reg_ctrl &= ~SPI_CTRL_EN;       /* disable spi */
75
76         /* configuration register setup */
77         reg_ctrl =
78             (reg_ctrl & ~SPI_CTRL_SSPOL) | (dev->ss_pol << SPI_CTRL_SSPOL_OFF);
79         reg_ctrl =
80             (reg_ctrl & ~SPI_CTRL_SSCTL) | (dev->ssctl << SPI_CTRL_SSCTL_OFF);
81         reg_ctrl =
82             (reg_ctrl & ~SPI_CTRL_SCLK_POL) | (dev->
83                                                sclkpol <<
84                                                SPI_CTRL_SCLK_POL_OFF);
85         reg_ctrl =
86             (reg_ctrl & ~SPI_CTRL_SCLK_PHA) | (dev->
87                                                sclkpha <<
88                                                SPI_CTRL_SCLK_PHA_OFF);
89
90         debug("reg_ctrl = 0x%x\n", reg_ctrl);
91         writel(reg_ctrl, dev->base + SPI_CON_REG);
92         /* save control register */
93         reg->ctrl_reg = reg_ctrl;
94
95         /* clear interrupt reg */
96         writel(0, dev->base + SPI_INT_REG);
97         writel(SPI_INT_STAT_TC, dev->base + SPI_STAT_REG);
98
99         return 0;
100 }
101
102 void spi_init(void)
103 {
104 }
105
106 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
107                                   unsigned int max_hz, unsigned int mode)
108 {
109         struct imx_spi_dev_t *imx_spi_slave = NULL;
110
111         if (!spi_cs_is_valid(bus, cs))
112                 return NULL;
113
114         imx_spi_slave =
115             (struct imx_spi_dev_t *)malloc(sizeof(struct imx_spi_dev_t));
116         if (!imx_spi_slave)
117                 return NULL;
118
119         imx_spi_slave->slave.bus = bus;
120         imx_spi_slave->slave.cs = cs;
121
122         spi_get_cfg(imx_spi_slave);
123
124         spi_io_init(imx_spi_slave);
125
126         spi_reset(&(imx_spi_slave->slave));
127
128         return &(imx_spi_slave->slave);
129 }
130
131 void spi_free_slave(struct spi_slave *slave)
132 {
133         struct imx_spi_dev_t *imx_spi_slave;
134
135         if (slave) {
136                 imx_spi_slave = to_imx_spi_slave(slave);
137                 free(imx_spi_slave);
138         }
139 }
140
141 int spi_claim_bus(struct spi_slave *slave)
142 {
143         return 0;
144 }
145
146 void spi_release_bus(struct spi_slave *slave)
147 {
148
149 }
150
151 /*
152  * SPI transfer:
153  *
154  * See include/spi.h and http://www.altera.com/literature/ds/ds_nios_spi.pdf
155  * for more informations.
156  */
157 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
158              void *din, unsigned long flags)
159 {
160         s32 val = SPI_RETRY_TIMES;
161         u32 *p_buf;
162         u32 reg;
163         s32 len = 0, ret_val = 0;
164         s32 burst_bytes = bitlen >> 3;
165         struct imx_spi_dev_t *dev = to_imx_spi_slave(slave);
166         struct spi_reg_t *spi_reg = &(dev->reg);
167
168         if (!slave)
169                 return -1;
170
171         if ((bitlen % 8) != 0)
172                 burst_bytes++;
173
174         if (burst_bytes > (dev->fifo_sz)) {
175                 printf("Error: maximum burst size is 0x%x bytes, asking 0x%x\n",
176                        dev->fifo_sz, burst_bytes);
177                 return -1;
178         }
179
180         if (flags & SPI_XFER_BEGIN) {
181                 spi_cs_activate(slave);
182
183                 if (spi_reg->ctrl_reg == 0) {
184                         printf
185                             ("Error: spi(base=0x%x) has not been initialized\n",
186                              dev->base);
187                         return -1;
188                 }
189
190                 spi_reg->ctrl_reg = (spi_reg->ctrl_reg & ~SPI_CTRL_BURST_MASK) |
191                     ((bitlen - 1) << SPI_CTRL_BURST_OFF);
192                 writel(spi_reg->ctrl_reg | SPI_CTRL_EN,
193                        dev->base + SPI_CON_REG);
194                 debug("ctrl_reg=0x%x\n", readl(dev->base + SPI_CON_REG));
195
196                 /* move data to the tx fifo */
197                 if (dout) {
198                         for (p_buf = (u32 *) dout, len = burst_bytes; len > 0;
199                              p_buf++, len -= 4)
200                                 writel(*p_buf, dev->base + SPI_TX_DATA);
201                 }
202
203                 reg = readl(dev->base + SPI_CON_REG);
204                 reg |= SPI_CTRL_REG_XCH_BIT;    /* set xch bit */
205                 debug("control reg = 0x%08x\n", reg);
206                 writel(reg, dev->base + SPI_CON_REG);
207
208                 /* poll on the TC bit (transfer complete) */
209                 while ((val-- > 0) &&
210                        (((reg =
211                           readl(dev->base + SPI_STAT_REG)) & SPI_INT_STAT_TC) ==
212                         0));
213
214                 /* clear the TC bit */
215                 writel(reg | SPI_INT_STAT_TC, dev->base + SPI_STAT_REG);
216                 if (val <= 0) {
217                         printf
218                             ("Error: re-tried %d times without response. Give up\n",
219                              SPI_RETRY_TIMES);
220                         ret_val = -1;
221                         goto error;
222                 }
223         }
224
225         /* move data in the rx buf */
226         if (flags & SPI_XFER_END) {
227                 if (din) {
228                         for (p_buf = (u32 *) din, len = burst_bytes; len > 0;
229                              p_buf++, len -= 4)
230                                 *p_buf = readl(dev->base + SPI_RX_DATA);
231                 }
232         }
233 error:
234         spi_cs_deactivate(slave);
235         return ret_val;
236 }
237
238 int spi_cs_is_valid(unsigned int bus, unsigned int cs)
239 {
240         return 1;
241 }
242
243 void spi_cs_activate(struct spi_slave *slave)
244 {
245         struct imx_spi_dev_t *dev = to_imx_spi_slave(slave);
246
247         spi_io_init(dev);
248 }
249
250 void spi_cs_deactivate(struct spi_slave *slave)
251 {
252         struct imx_spi_dev_t *dev = to_imx_spi_slave(slave);
253
254         writel(0, dev->base + SPI_CON_REG);
255 }