Commit c0eaffa03959a97e6c139ea023e4041170e105e6

Authored by Hannes Schmelzer
Committed by Jagan Teki
1 parent 51dce7d2bf

spi: omap3: fix claim/release bus within DM

The claim/release bus function must not reset the whole SPI core because
settings regarding wordlen, clock-frequency and so on made by
set_wordlen, set_mode, set_speed get lost with this action. Resulting in
a non-functional SPI.

Without DM the failure didn't came up since after the spi_reset within
claim bus all the setup (wordlen, mode, ...) was called, in DM they are
called by the spi uclass.

We change now the things as following for having a working SPI instance
in DM:

- move the spi_reset(...) to the probe call in DM for having a known
hardware state after probe. Without DM we don't have a probe call, so we
issue the reset as before during the claim_bus call.

- in release bus we just reset the modulctrl to the reset-value (spi-
slave)

Signed-off-by: Hannes Schmelzer <oe5hpm@oevsv.at>
Reviewed-by: Jagan Teki <jagan@openedev.com>

Showing 1 changed file with 7 additions and 7 deletions Inline Diff

drivers/spi/omap3_spi.c
1 // SPDX-License-Identifier: GPL-2.0+ 1 // SPDX-License-Identifier: GPL-2.0+
2 /* 2 /*
3 * Copyright (C) 2016 Jagan Teki <jteki@openedev.com> 3 * Copyright (C) 2016 Jagan Teki <jteki@openedev.com>
4 * Christophe Ricard <christophe.ricard@gmail.com> 4 * Christophe Ricard <christophe.ricard@gmail.com>
5 * 5 *
6 * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com> 6 * Copyright (C) 2010 Dirk Behme <dirk.behme@googlemail.com>
7 * 7 *
8 * Driver for McSPI controller on OMAP3. Based on davinci_spi.c 8 * Driver for McSPI controller on OMAP3. Based on davinci_spi.c
9 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/ 9 * Copyright (C) 2009 Texas Instruments Incorporated - http://www.ti.com/
10 * 10 *
11 * Copyright (C) 2007 Atmel Corporation 11 * Copyright (C) 2007 Atmel Corporation
12 * 12 *
13 * Parts taken from linux/drivers/spi/omap2_mcspi.c 13 * Parts taken from linux/drivers/spi/omap2_mcspi.c
14 * Copyright (C) 2005, 2006 Nokia Corporation 14 * Copyright (C) 2005, 2006 Nokia Corporation
15 * 15 *
16 * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com> 16 * Modified by Ruslan Araslanov <ruslan.araslanov@vitecmm.com>
17 */ 17 */
18 18
19 #include <common.h> 19 #include <common.h>
20 #include <dm.h> 20 #include <dm.h>
21 #include <spi.h> 21 #include <spi.h>
22 #include <malloc.h> 22 #include <malloc.h>
23 #include <asm/io.h> 23 #include <asm/io.h>
24 24
25 DECLARE_GLOBAL_DATA_PTR; 25 DECLARE_GLOBAL_DATA_PTR;
26 26
27 #if defined(CONFIG_AM33XX) || defined(CONFIG_AM43XX) 27 #if defined(CONFIG_AM33XX) || defined(CONFIG_AM43XX)
28 #define OMAP3_MCSPI1_BASE 0x48030100 28 #define OMAP3_MCSPI1_BASE 0x48030100
29 #define OMAP3_MCSPI2_BASE 0x481A0100 29 #define OMAP3_MCSPI2_BASE 0x481A0100
30 #else 30 #else
31 #define OMAP3_MCSPI1_BASE 0x48098000 31 #define OMAP3_MCSPI1_BASE 0x48098000
32 #define OMAP3_MCSPI2_BASE 0x4809A000 32 #define OMAP3_MCSPI2_BASE 0x4809A000
33 #define OMAP3_MCSPI3_BASE 0x480B8000 33 #define OMAP3_MCSPI3_BASE 0x480B8000
34 #define OMAP3_MCSPI4_BASE 0x480BA000 34 #define OMAP3_MCSPI4_BASE 0x480BA000
35 #endif 35 #endif
36 36
37 #define OMAP4_MCSPI_REG_OFFSET 0x100 37 #define OMAP4_MCSPI_REG_OFFSET 0x100
38 38
39 struct omap2_mcspi_platform_config { 39 struct omap2_mcspi_platform_config {
40 unsigned int regs_offset; 40 unsigned int regs_offset;
41 }; 41 };
42 42
43 /* per-register bitmasks */ 43 /* per-register bitmasks */
44 #define OMAP3_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3) 44 #define OMAP3_MCSPI_SYSCONFIG_SMARTIDLE (2 << 3)
45 #define OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2) 45 #define OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP BIT(2)
46 #define OMAP3_MCSPI_SYSCONFIG_AUTOIDLE BIT(0) 46 #define OMAP3_MCSPI_SYSCONFIG_AUTOIDLE BIT(0)
47 #define OMAP3_MCSPI_SYSCONFIG_SOFTRESET BIT(1) 47 #define OMAP3_MCSPI_SYSCONFIG_SOFTRESET BIT(1)
48 48
49 #define OMAP3_MCSPI_SYSSTATUS_RESETDONE BIT(0) 49 #define OMAP3_MCSPI_SYSSTATUS_RESETDONE BIT(0)
50 50
51 #define OMAP3_MCSPI_MODULCTRL_SINGLE BIT(0) 51 #define OMAP3_MCSPI_MODULCTRL_SINGLE BIT(0)
52 #define OMAP3_MCSPI_MODULCTRL_MS BIT(2) 52 #define OMAP3_MCSPI_MODULCTRL_MS BIT(2)
53 #define OMAP3_MCSPI_MODULCTRL_STEST BIT(3) 53 #define OMAP3_MCSPI_MODULCTRL_STEST BIT(3)
54 54
55 #define OMAP3_MCSPI_CHCONF_PHA BIT(0) 55 #define OMAP3_MCSPI_CHCONF_PHA BIT(0)
56 #define OMAP3_MCSPI_CHCONF_POL BIT(1) 56 #define OMAP3_MCSPI_CHCONF_POL BIT(1)
57 #define OMAP3_MCSPI_CHCONF_CLKD_MASK GENMASK(5, 2) 57 #define OMAP3_MCSPI_CHCONF_CLKD_MASK GENMASK(5, 2)
58 #define OMAP3_MCSPI_CHCONF_EPOL BIT(6) 58 #define OMAP3_MCSPI_CHCONF_EPOL BIT(6)
59 #define OMAP3_MCSPI_CHCONF_WL_MASK GENMASK(11, 7) 59 #define OMAP3_MCSPI_CHCONF_WL_MASK GENMASK(11, 7)
60 #define OMAP3_MCSPI_CHCONF_TRM_RX_ONLY BIT(12) 60 #define OMAP3_MCSPI_CHCONF_TRM_RX_ONLY BIT(12)
61 #define OMAP3_MCSPI_CHCONF_TRM_TX_ONLY BIT(13) 61 #define OMAP3_MCSPI_CHCONF_TRM_TX_ONLY BIT(13)
62 #define OMAP3_MCSPI_CHCONF_TRM_MASK GENMASK(13, 12) 62 #define OMAP3_MCSPI_CHCONF_TRM_MASK GENMASK(13, 12)
63 #define OMAP3_MCSPI_CHCONF_DMAW BIT(14) 63 #define OMAP3_MCSPI_CHCONF_DMAW BIT(14)
64 #define OMAP3_MCSPI_CHCONF_DMAR BIT(15) 64 #define OMAP3_MCSPI_CHCONF_DMAR BIT(15)
65 #define OMAP3_MCSPI_CHCONF_DPE0 BIT(16) 65 #define OMAP3_MCSPI_CHCONF_DPE0 BIT(16)
66 #define OMAP3_MCSPI_CHCONF_DPE1 BIT(17) 66 #define OMAP3_MCSPI_CHCONF_DPE1 BIT(17)
67 #define OMAP3_MCSPI_CHCONF_IS BIT(18) 67 #define OMAP3_MCSPI_CHCONF_IS BIT(18)
68 #define OMAP3_MCSPI_CHCONF_TURBO BIT(19) 68 #define OMAP3_MCSPI_CHCONF_TURBO BIT(19)
69 #define OMAP3_MCSPI_CHCONF_FORCE BIT(20) 69 #define OMAP3_MCSPI_CHCONF_FORCE BIT(20)
70 70
71 #define OMAP3_MCSPI_CHSTAT_RXS BIT(0) 71 #define OMAP3_MCSPI_CHSTAT_RXS BIT(0)
72 #define OMAP3_MCSPI_CHSTAT_TXS BIT(1) 72 #define OMAP3_MCSPI_CHSTAT_TXS BIT(1)
73 #define OMAP3_MCSPI_CHSTAT_EOT BIT(2) 73 #define OMAP3_MCSPI_CHSTAT_EOT BIT(2)
74 74
75 #define OMAP3_MCSPI_CHCTRL_EN BIT(0) 75 #define OMAP3_MCSPI_CHCTRL_EN BIT(0)
76 #define OMAP3_MCSPI_CHCTRL_DIS (0 << 0) 76 #define OMAP3_MCSPI_CHCTRL_DIS (0 << 0)
77 77
78 #define OMAP3_MCSPI_WAKEUPENABLE_WKEN BIT(0) 78 #define OMAP3_MCSPI_WAKEUPENABLE_WKEN BIT(0)
79 #define MCSPI_PINDIR_D0_IN_D1_OUT 0 79 #define MCSPI_PINDIR_D0_IN_D1_OUT 0
80 #define MCSPI_PINDIR_D0_OUT_D1_IN 1 80 #define MCSPI_PINDIR_D0_OUT_D1_IN 1
81 81
82 #define OMAP3_MCSPI_MAX_FREQ 48000000 82 #define OMAP3_MCSPI_MAX_FREQ 48000000
83 #define SPI_WAIT_TIMEOUT 10 83 #define SPI_WAIT_TIMEOUT 10
84 84
85 /* OMAP3 McSPI registers */ 85 /* OMAP3 McSPI registers */
86 struct mcspi_channel { 86 struct mcspi_channel {
87 unsigned int chconf; /* 0x2C, 0x40, 0x54, 0x68 */ 87 unsigned int chconf; /* 0x2C, 0x40, 0x54, 0x68 */
88 unsigned int chstat; /* 0x30, 0x44, 0x58, 0x6C */ 88 unsigned int chstat; /* 0x30, 0x44, 0x58, 0x6C */
89 unsigned int chctrl; /* 0x34, 0x48, 0x5C, 0x70 */ 89 unsigned int chctrl; /* 0x34, 0x48, 0x5C, 0x70 */
90 unsigned int tx; /* 0x38, 0x4C, 0x60, 0x74 */ 90 unsigned int tx; /* 0x38, 0x4C, 0x60, 0x74 */
91 unsigned int rx; /* 0x3C, 0x50, 0x64, 0x78 */ 91 unsigned int rx; /* 0x3C, 0x50, 0x64, 0x78 */
92 }; 92 };
93 93
94 struct mcspi { 94 struct mcspi {
95 unsigned char res1[0x10]; 95 unsigned char res1[0x10];
96 unsigned int sysconfig; /* 0x10 */ 96 unsigned int sysconfig; /* 0x10 */
97 unsigned int sysstatus; /* 0x14 */ 97 unsigned int sysstatus; /* 0x14 */
98 unsigned int irqstatus; /* 0x18 */ 98 unsigned int irqstatus; /* 0x18 */
99 unsigned int irqenable; /* 0x1C */ 99 unsigned int irqenable; /* 0x1C */
100 unsigned int wakeupenable; /* 0x20 */ 100 unsigned int wakeupenable; /* 0x20 */
101 unsigned int syst; /* 0x24 */ 101 unsigned int syst; /* 0x24 */
102 unsigned int modulctrl; /* 0x28 */ 102 unsigned int modulctrl; /* 0x28 */
103 struct mcspi_channel channel[4]; 103 struct mcspi_channel channel[4];
104 /* channel0: 0x2C - 0x3C, bus 0 & 1 & 2 & 3 */ 104 /* channel0: 0x2C - 0x3C, bus 0 & 1 & 2 & 3 */
105 /* channel1: 0x40 - 0x50, bus 0 & 1 */ 105 /* channel1: 0x40 - 0x50, bus 0 & 1 */
106 /* channel2: 0x54 - 0x64, bus 0 & 1 */ 106 /* channel2: 0x54 - 0x64, bus 0 & 1 */
107 /* channel3: 0x68 - 0x78, bus 0 */ 107 /* channel3: 0x68 - 0x78, bus 0 */
108 }; 108 };
109 109
110 struct omap3_spi_priv { 110 struct omap3_spi_priv {
111 #ifndef CONFIG_DM_SPI 111 #ifndef CONFIG_DM_SPI
112 struct spi_slave slave; 112 struct spi_slave slave;
113 #endif 113 #endif
114 struct mcspi *regs; 114 struct mcspi *regs;
115 unsigned int cs; 115 unsigned int cs;
116 unsigned int freq; 116 unsigned int freq;
117 unsigned int mode; 117 unsigned int mode;
118 unsigned int wordlen; 118 unsigned int wordlen;
119 unsigned int pin_dir:1; 119 unsigned int pin_dir:1;
120 }; 120 };
121 121
122 static void omap3_spi_write_chconf(struct omap3_spi_priv *priv, int val) 122 static void omap3_spi_write_chconf(struct omap3_spi_priv *priv, int val)
123 { 123 {
124 writel(val, &priv->regs->channel[priv->cs].chconf); 124 writel(val, &priv->regs->channel[priv->cs].chconf);
125 /* Flash post writes to make immediate effect */ 125 /* Flash post writes to make immediate effect */
126 readl(&priv->regs->channel[priv->cs].chconf); 126 readl(&priv->regs->channel[priv->cs].chconf);
127 } 127 }
128 128
129 static void omap3_spi_set_enable(struct omap3_spi_priv *priv, int enable) 129 static void omap3_spi_set_enable(struct omap3_spi_priv *priv, int enable)
130 { 130 {
131 writel(enable, &priv->regs->channel[priv->cs].chctrl); 131 writel(enable, &priv->regs->channel[priv->cs].chctrl);
132 /* Flash post writes to make immediate effect */ 132 /* Flash post writes to make immediate effect */
133 readl(&priv->regs->channel[priv->cs].chctrl); 133 readl(&priv->regs->channel[priv->cs].chctrl);
134 } 134 }
135 135
136 static int omap3_spi_write(struct omap3_spi_priv *priv, unsigned int len, 136 static int omap3_spi_write(struct omap3_spi_priv *priv, unsigned int len,
137 const void *txp, unsigned long flags) 137 const void *txp, unsigned long flags)
138 { 138 {
139 ulong start; 139 ulong start;
140 int i, chconf; 140 int i, chconf;
141 141
142 chconf = readl(&priv->regs->channel[priv->cs].chconf); 142 chconf = readl(&priv->regs->channel[priv->cs].chconf);
143 143
144 /* Enable the channel */ 144 /* Enable the channel */
145 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 145 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
146 146
147 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 147 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
148 chconf |= (priv->wordlen - 1) << 7; 148 chconf |= (priv->wordlen - 1) << 7;
149 chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY; 149 chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
150 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 150 chconf |= OMAP3_MCSPI_CHCONF_FORCE;
151 omap3_spi_write_chconf(priv, chconf); 151 omap3_spi_write_chconf(priv, chconf);
152 152
153 for (i = 0; i < len; i++) { 153 for (i = 0; i < len; i++) {
154 /* wait till TX register is empty (TXS == 1) */ 154 /* wait till TX register is empty (TXS == 1) */
155 start = get_timer(0); 155 start = get_timer(0);
156 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 156 while (!(readl(&priv->regs->channel[priv->cs].chstat) &
157 OMAP3_MCSPI_CHSTAT_TXS)) { 157 OMAP3_MCSPI_CHSTAT_TXS)) {
158 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 158 if (get_timer(start) > SPI_WAIT_TIMEOUT) {
159 printf("SPI TXS timed out, status=0x%08x\n", 159 printf("SPI TXS timed out, status=0x%08x\n",
160 readl(&priv->regs->channel[priv->cs].chstat)); 160 readl(&priv->regs->channel[priv->cs].chstat));
161 return -1; 161 return -1;
162 } 162 }
163 } 163 }
164 /* Write the data */ 164 /* Write the data */
165 unsigned int *tx = &priv->regs->channel[priv->cs].tx; 165 unsigned int *tx = &priv->regs->channel[priv->cs].tx;
166 if (priv->wordlen > 16) 166 if (priv->wordlen > 16)
167 writel(((u32 *)txp)[i], tx); 167 writel(((u32 *)txp)[i], tx);
168 else if (priv->wordlen > 8) 168 else if (priv->wordlen > 8)
169 writel(((u16 *)txp)[i], tx); 169 writel(((u16 *)txp)[i], tx);
170 else 170 else
171 writel(((u8 *)txp)[i], tx); 171 writel(((u8 *)txp)[i], tx);
172 } 172 }
173 173
174 /* wait to finish of transfer */ 174 /* wait to finish of transfer */
175 while ((readl(&priv->regs->channel[priv->cs].chstat) & 175 while ((readl(&priv->regs->channel[priv->cs].chstat) &
176 (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) != 176 (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) !=
177 (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS)) 177 (OMAP3_MCSPI_CHSTAT_EOT | OMAP3_MCSPI_CHSTAT_TXS))
178 ; 178 ;
179 179
180 /* Disable the channel otherwise the next immediate RX will get affected */ 180 /* Disable the channel otherwise the next immediate RX will get affected */
181 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 181 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
182 182
183 if (flags & SPI_XFER_END) { 183 if (flags & SPI_XFER_END) {
184 184
185 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 185 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
186 omap3_spi_write_chconf(priv, chconf); 186 omap3_spi_write_chconf(priv, chconf);
187 } 187 }
188 return 0; 188 return 0;
189 } 189 }
190 190
191 static int omap3_spi_read(struct omap3_spi_priv *priv, unsigned int len, 191 static int omap3_spi_read(struct omap3_spi_priv *priv, unsigned int len,
192 void *rxp, unsigned long flags) 192 void *rxp, unsigned long flags)
193 { 193 {
194 int i, chconf; 194 int i, chconf;
195 ulong start; 195 ulong start;
196 196
197 chconf = readl(&priv->regs->channel[priv->cs].chconf); 197 chconf = readl(&priv->regs->channel[priv->cs].chconf);
198 198
199 /* Enable the channel */ 199 /* Enable the channel */
200 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 200 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
201 201
202 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 202 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
203 chconf |= (priv->wordlen - 1) << 7; 203 chconf |= (priv->wordlen - 1) << 7;
204 chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY; 204 chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
205 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 205 chconf |= OMAP3_MCSPI_CHCONF_FORCE;
206 omap3_spi_write_chconf(priv, chconf); 206 omap3_spi_write_chconf(priv, chconf);
207 207
208 writel(0, &priv->regs->channel[priv->cs].tx); 208 writel(0, &priv->regs->channel[priv->cs].tx);
209 209
210 for (i = 0; i < len; i++) { 210 for (i = 0; i < len; i++) {
211 start = get_timer(0); 211 start = get_timer(0);
212 /* Wait till RX register contains data (RXS == 1) */ 212 /* Wait till RX register contains data (RXS == 1) */
213 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 213 while (!(readl(&priv->regs->channel[priv->cs].chstat) &
214 OMAP3_MCSPI_CHSTAT_RXS)) { 214 OMAP3_MCSPI_CHSTAT_RXS)) {
215 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 215 if (get_timer(start) > SPI_WAIT_TIMEOUT) {
216 printf("SPI RXS timed out, status=0x%08x\n", 216 printf("SPI RXS timed out, status=0x%08x\n",
217 readl(&priv->regs->channel[priv->cs].chstat)); 217 readl(&priv->regs->channel[priv->cs].chstat));
218 return -1; 218 return -1;
219 } 219 }
220 } 220 }
221 221
222 /* Disable the channel to prevent furher receiving */ 222 /* Disable the channel to prevent furher receiving */
223 if (i == (len - 1)) 223 if (i == (len - 1))
224 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 224 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
225 225
226 /* Read the data */ 226 /* Read the data */
227 unsigned int *rx = &priv->regs->channel[priv->cs].rx; 227 unsigned int *rx = &priv->regs->channel[priv->cs].rx;
228 if (priv->wordlen > 16) 228 if (priv->wordlen > 16)
229 ((u32 *)rxp)[i] = readl(rx); 229 ((u32 *)rxp)[i] = readl(rx);
230 else if (priv->wordlen > 8) 230 else if (priv->wordlen > 8)
231 ((u16 *)rxp)[i] = (u16)readl(rx); 231 ((u16 *)rxp)[i] = (u16)readl(rx);
232 else 232 else
233 ((u8 *)rxp)[i] = (u8)readl(rx); 233 ((u8 *)rxp)[i] = (u8)readl(rx);
234 } 234 }
235 235
236 if (flags & SPI_XFER_END) { 236 if (flags & SPI_XFER_END) {
237 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 237 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
238 omap3_spi_write_chconf(priv, chconf); 238 omap3_spi_write_chconf(priv, chconf);
239 } 239 }
240 240
241 return 0; 241 return 0;
242 } 242 }
243 243
244 /*McSPI Transmit Receive Mode*/ 244 /*McSPI Transmit Receive Mode*/
245 static int omap3_spi_txrx(struct omap3_spi_priv *priv, unsigned int len, 245 static int omap3_spi_txrx(struct omap3_spi_priv *priv, unsigned int len,
246 const void *txp, void *rxp, unsigned long flags) 246 const void *txp, void *rxp, unsigned long flags)
247 { 247 {
248 ulong start; 248 ulong start;
249 int chconf, i = 0; 249 int chconf, i = 0;
250 250
251 chconf = readl(&priv->regs->channel[priv->cs].chconf); 251 chconf = readl(&priv->regs->channel[priv->cs].chconf);
252 252
253 /*Enable SPI channel*/ 253 /*Enable SPI channel*/
254 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 254 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
255 255
256 /*set TRANSMIT-RECEIVE Mode*/ 256 /*set TRANSMIT-RECEIVE Mode*/
257 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK); 257 chconf &= ~(OMAP3_MCSPI_CHCONF_TRM_MASK | OMAP3_MCSPI_CHCONF_WL_MASK);
258 chconf |= (priv->wordlen - 1) << 7; 258 chconf |= (priv->wordlen - 1) << 7;
259 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 259 chconf |= OMAP3_MCSPI_CHCONF_FORCE;
260 omap3_spi_write_chconf(priv, chconf); 260 omap3_spi_write_chconf(priv, chconf);
261 261
262 /*Shift in and out 1 byte at time*/ 262 /*Shift in and out 1 byte at time*/
263 for (i=0; i < len; i++){ 263 for (i=0; i < len; i++){
264 /* Write: wait for TX empty (TXS == 1)*/ 264 /* Write: wait for TX empty (TXS == 1)*/
265 start = get_timer(0); 265 start = get_timer(0);
266 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 266 while (!(readl(&priv->regs->channel[priv->cs].chstat) &
267 OMAP3_MCSPI_CHSTAT_TXS)) { 267 OMAP3_MCSPI_CHSTAT_TXS)) {
268 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 268 if (get_timer(start) > SPI_WAIT_TIMEOUT) {
269 printf("SPI TXS timed out, status=0x%08x\n", 269 printf("SPI TXS timed out, status=0x%08x\n",
270 readl(&priv->regs->channel[priv->cs].chstat)); 270 readl(&priv->regs->channel[priv->cs].chstat));
271 return -1; 271 return -1;
272 } 272 }
273 } 273 }
274 /* Write the data */ 274 /* Write the data */
275 unsigned int *tx = &priv->regs->channel[priv->cs].tx; 275 unsigned int *tx = &priv->regs->channel[priv->cs].tx;
276 if (priv->wordlen > 16) 276 if (priv->wordlen > 16)
277 writel(((u32 *)txp)[i], tx); 277 writel(((u32 *)txp)[i], tx);
278 else if (priv->wordlen > 8) 278 else if (priv->wordlen > 8)
279 writel(((u16 *)txp)[i], tx); 279 writel(((u16 *)txp)[i], tx);
280 else 280 else
281 writel(((u8 *)txp)[i], tx); 281 writel(((u8 *)txp)[i], tx);
282 282
283 /*Read: wait for RX containing data (RXS == 1)*/ 283 /*Read: wait for RX containing data (RXS == 1)*/
284 start = get_timer(0); 284 start = get_timer(0);
285 while (!(readl(&priv->regs->channel[priv->cs].chstat) & 285 while (!(readl(&priv->regs->channel[priv->cs].chstat) &
286 OMAP3_MCSPI_CHSTAT_RXS)) { 286 OMAP3_MCSPI_CHSTAT_RXS)) {
287 if (get_timer(start) > SPI_WAIT_TIMEOUT) { 287 if (get_timer(start) > SPI_WAIT_TIMEOUT) {
288 printf("SPI RXS timed out, status=0x%08x\n", 288 printf("SPI RXS timed out, status=0x%08x\n",
289 readl(&priv->regs->channel[priv->cs].chstat)); 289 readl(&priv->regs->channel[priv->cs].chstat));
290 return -1; 290 return -1;
291 } 291 }
292 } 292 }
293 /* Read the data */ 293 /* Read the data */
294 unsigned int *rx = &priv->regs->channel[priv->cs].rx; 294 unsigned int *rx = &priv->regs->channel[priv->cs].rx;
295 if (priv->wordlen > 16) 295 if (priv->wordlen > 16)
296 ((u32 *)rxp)[i] = readl(rx); 296 ((u32 *)rxp)[i] = readl(rx);
297 else if (priv->wordlen > 8) 297 else if (priv->wordlen > 8)
298 ((u16 *)rxp)[i] = (u16)readl(rx); 298 ((u16 *)rxp)[i] = (u16)readl(rx);
299 else 299 else
300 ((u8 *)rxp)[i] = (u8)readl(rx); 300 ((u8 *)rxp)[i] = (u8)readl(rx);
301 } 301 }
302 /* Disable the channel */ 302 /* Disable the channel */
303 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 303 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
304 304
305 /*if transfer must be terminated disable the channel*/ 305 /*if transfer must be terminated disable the channel*/
306 if (flags & SPI_XFER_END) { 306 if (flags & SPI_XFER_END) {
307 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 307 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
308 omap3_spi_write_chconf(priv, chconf); 308 omap3_spi_write_chconf(priv, chconf);
309 } 309 }
310 310
311 return 0; 311 return 0;
312 } 312 }
313 313
314 static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen, 314 static int _spi_xfer(struct omap3_spi_priv *priv, unsigned int bitlen,
315 const void *dout, void *din, unsigned long flags) 315 const void *dout, void *din, unsigned long flags)
316 { 316 {
317 unsigned int len; 317 unsigned int len;
318 int ret = -1; 318 int ret = -1;
319 319
320 if (priv->wordlen < 4 || priv->wordlen > 32) { 320 if (priv->wordlen < 4 || priv->wordlen > 32) {
321 printf("omap3_spi: invalid wordlen %d\n", priv->wordlen); 321 printf("omap3_spi: invalid wordlen %d\n", priv->wordlen);
322 return -1; 322 return -1;
323 } 323 }
324 324
325 if (bitlen % priv->wordlen) 325 if (bitlen % priv->wordlen)
326 return -1; 326 return -1;
327 327
328 len = bitlen / priv->wordlen; 328 len = bitlen / priv->wordlen;
329 329
330 if (bitlen == 0) { /* only change CS */ 330 if (bitlen == 0) { /* only change CS */
331 int chconf = readl(&priv->regs->channel[priv->cs].chconf); 331 int chconf = readl(&priv->regs->channel[priv->cs].chconf);
332 332
333 if (flags & SPI_XFER_BEGIN) { 333 if (flags & SPI_XFER_BEGIN) {
334 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN); 334 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_EN);
335 chconf |= OMAP3_MCSPI_CHCONF_FORCE; 335 chconf |= OMAP3_MCSPI_CHCONF_FORCE;
336 omap3_spi_write_chconf(priv, chconf); 336 omap3_spi_write_chconf(priv, chconf);
337 } 337 }
338 if (flags & SPI_XFER_END) { 338 if (flags & SPI_XFER_END) {
339 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE; 339 chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
340 omap3_spi_write_chconf(priv, chconf); 340 omap3_spi_write_chconf(priv, chconf);
341 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS); 341 omap3_spi_set_enable(priv, OMAP3_MCSPI_CHCTRL_DIS);
342 } 342 }
343 ret = 0; 343 ret = 0;
344 } else { 344 } else {
345 if (dout != NULL && din != NULL) 345 if (dout != NULL && din != NULL)
346 ret = omap3_spi_txrx(priv, len, dout, din, flags); 346 ret = omap3_spi_txrx(priv, len, dout, din, flags);
347 else if (dout != NULL) 347 else if (dout != NULL)
348 ret = omap3_spi_write(priv, len, dout, flags); 348 ret = omap3_spi_write(priv, len, dout, flags);
349 else if (din != NULL) 349 else if (din != NULL)
350 ret = omap3_spi_read(priv, len, din, flags); 350 ret = omap3_spi_read(priv, len, din, flags);
351 } 351 }
352 return ret; 352 return ret;
353 } 353 }
354 354
355 static void _omap3_spi_set_speed(struct omap3_spi_priv *priv) 355 static void _omap3_spi_set_speed(struct omap3_spi_priv *priv)
356 { 356 {
357 uint32_t confr, div = 0; 357 uint32_t confr, div = 0;
358 358
359 confr = readl(&priv->regs->channel[priv->cs].chconf); 359 confr = readl(&priv->regs->channel[priv->cs].chconf);
360 360
361 /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */ 361 /* Calculate clock divisor. Valid range: 0x0 - 0xC ( /1 - /4096 ) */
362 if (priv->freq) { 362 if (priv->freq) {
363 while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div)) 363 while (div <= 0xC && (OMAP3_MCSPI_MAX_FREQ / (1 << div))
364 > priv->freq) 364 > priv->freq)
365 div++; 365 div++;
366 } else { 366 } else {
367 div = 0xC; 367 div = 0xC;
368 } 368 }
369 369
370 /* set clock divisor */ 370 /* set clock divisor */
371 confr &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK; 371 confr &= ~OMAP3_MCSPI_CHCONF_CLKD_MASK;
372 confr |= div << 2; 372 confr |= div << 2;
373 373
374 omap3_spi_write_chconf(priv, confr); 374 omap3_spi_write_chconf(priv, confr);
375 } 375 }
376 376
377 static void _omap3_spi_set_mode(struct omap3_spi_priv *priv) 377 static void _omap3_spi_set_mode(struct omap3_spi_priv *priv)
378 { 378 {
379 uint32_t confr; 379 uint32_t confr;
380 380
381 confr = readl(&priv->regs->channel[priv->cs].chconf); 381 confr = readl(&priv->regs->channel[priv->cs].chconf);
382 382
383 /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS 383 /* standard 4-wire master mode: SCK, MOSI/out, MISO/in, nCS
384 * REVISIT: this controller could support SPI_3WIRE mode. 384 * REVISIT: this controller could support SPI_3WIRE mode.
385 */ 385 */
386 if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) { 386 if (priv->pin_dir == MCSPI_PINDIR_D0_IN_D1_OUT) {
387 confr &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1); 387 confr &= ~(OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1);
388 confr |= OMAP3_MCSPI_CHCONF_DPE0; 388 confr |= OMAP3_MCSPI_CHCONF_DPE0;
389 } else { 389 } else {
390 confr &= ~OMAP3_MCSPI_CHCONF_DPE0; 390 confr &= ~OMAP3_MCSPI_CHCONF_DPE0;
391 confr |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1; 391 confr |= OMAP3_MCSPI_CHCONF_IS|OMAP3_MCSPI_CHCONF_DPE1;
392 } 392 }
393 393
394 /* set SPI mode 0..3 */ 394 /* set SPI mode 0..3 */
395 confr &= ~(OMAP3_MCSPI_CHCONF_POL | OMAP3_MCSPI_CHCONF_PHA); 395 confr &= ~(OMAP3_MCSPI_CHCONF_POL | OMAP3_MCSPI_CHCONF_PHA);
396 if (priv->mode & SPI_CPHA) 396 if (priv->mode & SPI_CPHA)
397 confr |= OMAP3_MCSPI_CHCONF_PHA; 397 confr |= OMAP3_MCSPI_CHCONF_PHA;
398 if (priv->mode & SPI_CPOL) 398 if (priv->mode & SPI_CPOL)
399 confr |= OMAP3_MCSPI_CHCONF_POL; 399 confr |= OMAP3_MCSPI_CHCONF_POL;
400 400
401 /* set chipselect polarity; manage with FORCE */ 401 /* set chipselect polarity; manage with FORCE */
402 if (!(priv->mode & SPI_CS_HIGH)) 402 if (!(priv->mode & SPI_CS_HIGH))
403 confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */ 403 confr |= OMAP3_MCSPI_CHCONF_EPOL; /* active-low; normal */
404 else 404 else
405 confr &= ~OMAP3_MCSPI_CHCONF_EPOL; 405 confr &= ~OMAP3_MCSPI_CHCONF_EPOL;
406 406
407 /* Transmit & receive mode */ 407 /* Transmit & receive mode */
408 confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK; 408 confr &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
409 409
410 omap3_spi_write_chconf(priv, confr); 410 omap3_spi_write_chconf(priv, confr);
411 } 411 }
412 412
413 static void _omap3_spi_set_wordlen(struct omap3_spi_priv *priv) 413 static void _omap3_spi_set_wordlen(struct omap3_spi_priv *priv)
414 { 414 {
415 unsigned int confr; 415 unsigned int confr;
416 416
417 /* McSPI individual channel configuration */ 417 /* McSPI individual channel configuration */
418 confr = readl(&priv->regs->channel[priv->wordlen].chconf); 418 confr = readl(&priv->regs->channel[priv->wordlen].chconf);
419 419
420 /* wordlength */ 420 /* wordlength */
421 confr &= ~OMAP3_MCSPI_CHCONF_WL_MASK; 421 confr &= ~OMAP3_MCSPI_CHCONF_WL_MASK;
422 confr |= (priv->wordlen - 1) << 7; 422 confr |= (priv->wordlen - 1) << 7;
423 423
424 omap3_spi_write_chconf(priv, confr); 424 omap3_spi_write_chconf(priv, confr);
425 } 425 }
426 426
427 static void spi_reset(struct mcspi *regs) 427 static void spi_reset(struct mcspi *regs)
428 { 428 {
429 unsigned int tmp; 429 unsigned int tmp;
430 430
431 writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &regs->sysconfig); 431 writel(OMAP3_MCSPI_SYSCONFIG_SOFTRESET, &regs->sysconfig);
432 do { 432 do {
433 tmp = readl(&regs->sysstatus); 433 tmp = readl(&regs->sysstatus);
434 } while (!(tmp & OMAP3_MCSPI_SYSSTATUS_RESETDONE)); 434 } while (!(tmp & OMAP3_MCSPI_SYSSTATUS_RESETDONE));
435 435
436 writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE | 436 writel(OMAP3_MCSPI_SYSCONFIG_AUTOIDLE |
437 OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP | 437 OMAP3_MCSPI_SYSCONFIG_ENAWAKEUP |
438 OMAP3_MCSPI_SYSCONFIG_SMARTIDLE, &regs->sysconfig); 438 OMAP3_MCSPI_SYSCONFIG_SMARTIDLE, &regs->sysconfig);
439 439
440 writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &regs->wakeupenable); 440 writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &regs->wakeupenable);
441 } 441 }
442 442
443 static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv) 443 static void _omap3_spi_claim_bus(struct omap3_spi_priv *priv)
444 { 444 {
445 unsigned int conf; 445 unsigned int conf;
446
447 spi_reset(priv->regs);
448
449 /* 446 /*
450 * setup when switching from (reset default) slave mode 447 * setup when switching from (reset default) slave mode
451 * to single-channel master mode 448 * to single-channel master mode
452 */ 449 */
453 conf = readl(&priv->regs->modulctrl); 450 conf = readl(&priv->regs->modulctrl);
454 conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS); 451 conf &= ~(OMAP3_MCSPI_MODULCTRL_STEST | OMAP3_MCSPI_MODULCTRL_MS);
455 conf |= OMAP3_MCSPI_MODULCTRL_SINGLE; 452 conf |= OMAP3_MCSPI_MODULCTRL_SINGLE;
456 453
457 writel(conf, &priv->regs->modulctrl); 454 writel(conf, &priv->regs->modulctrl);
458 } 455 }
459 456
460 #ifndef CONFIG_DM_SPI 457 #ifndef CONFIG_DM_SPI
461 458
462 static inline struct omap3_spi_priv *to_omap3_spi(struct spi_slave *slave) 459 static inline struct omap3_spi_priv *to_omap3_spi(struct spi_slave *slave)
463 { 460 {
464 return container_of(slave, struct omap3_spi_priv, slave); 461 return container_of(slave, struct omap3_spi_priv, slave);
465 } 462 }
466 463
467 void spi_init(void) 464 void spi_init(void)
468 { 465 {
469 /* do nothing */ 466 /* do nothing */
470 } 467 }
471 468
472 void spi_free_slave(struct spi_slave *slave) 469 void spi_free_slave(struct spi_slave *slave)
473 { 470 {
474 struct omap3_spi_priv *priv = to_omap3_spi(slave); 471 struct omap3_spi_priv *priv = to_omap3_spi(slave);
475 472
476 free(priv); 473 free(priv);
477 } 474 }
478 475
479 int spi_claim_bus(struct spi_slave *slave) 476 int spi_claim_bus(struct spi_slave *slave)
480 { 477 {
481 struct omap3_spi_priv *priv = to_omap3_spi(slave); 478 struct omap3_spi_priv *priv = to_omap3_spi(slave);
482 479
480 spi_reset(priv->regs);
481
483 _omap3_spi_claim_bus(priv); 482 _omap3_spi_claim_bus(priv);
484 _omap3_spi_set_wordlen(priv); 483 _omap3_spi_set_wordlen(priv);
485 _omap3_spi_set_mode(priv); 484 _omap3_spi_set_mode(priv);
486 _omap3_spi_set_speed(priv); 485 _omap3_spi_set_speed(priv);
487 486
488 return 0; 487 return 0;
489 } 488 }
490 489
491 void spi_release_bus(struct spi_slave *slave) 490 void spi_release_bus(struct spi_slave *slave)
492 { 491 {
493 struct omap3_spi_priv *priv = to_omap3_spi(slave); 492 struct omap3_spi_priv *priv = to_omap3_spi(slave);
494 493
495 /* Reset the SPI hardware */ 494 writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl);
496 spi_reset(priv->regs);
497 } 495 }
498 496
499 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, 497 struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
500 unsigned int max_hz, unsigned int mode) 498 unsigned int max_hz, unsigned int mode)
501 { 499 {
502 struct omap3_spi_priv *priv; 500 struct omap3_spi_priv *priv;
503 struct mcspi *regs; 501 struct mcspi *regs;
504 502
505 /* 503 /*
506 * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules) 504 * OMAP3 McSPI (MultiChannel SPI) has 4 busses (modules)
507 * with different number of chip selects (CS, channels): 505 * with different number of chip selects (CS, channels):
508 * McSPI1 has 4 CS (bus 0, cs 0 - 3) 506 * McSPI1 has 4 CS (bus 0, cs 0 - 3)
509 * McSPI2 has 2 CS (bus 1, cs 0 - 1) 507 * McSPI2 has 2 CS (bus 1, cs 0 - 1)
510 * McSPI3 has 2 CS (bus 2, cs 0 - 1) 508 * McSPI3 has 2 CS (bus 2, cs 0 - 1)
511 * McSPI4 has 1 CS (bus 3, cs 0) 509 * McSPI4 has 1 CS (bus 3, cs 0)
512 */ 510 */
513 511
514 switch (bus) { 512 switch (bus) {
515 case 0: 513 case 0:
516 regs = (struct mcspi *)OMAP3_MCSPI1_BASE; 514 regs = (struct mcspi *)OMAP3_MCSPI1_BASE;
517 break; 515 break;
518 #ifdef OMAP3_MCSPI2_BASE 516 #ifdef OMAP3_MCSPI2_BASE
519 case 1: 517 case 1:
520 regs = (struct mcspi *)OMAP3_MCSPI2_BASE; 518 regs = (struct mcspi *)OMAP3_MCSPI2_BASE;
521 break; 519 break;
522 #endif 520 #endif
523 #ifdef OMAP3_MCSPI3_BASE 521 #ifdef OMAP3_MCSPI3_BASE
524 case 2: 522 case 2:
525 regs = (struct mcspi *)OMAP3_MCSPI3_BASE; 523 regs = (struct mcspi *)OMAP3_MCSPI3_BASE;
526 break; 524 break;
527 #endif 525 #endif
528 #ifdef OMAP3_MCSPI4_BASE 526 #ifdef OMAP3_MCSPI4_BASE
529 case 3: 527 case 3:
530 regs = (struct mcspi *)OMAP3_MCSPI4_BASE; 528 regs = (struct mcspi *)OMAP3_MCSPI4_BASE;
531 break; 529 break;
532 #endif 530 #endif
533 default: 531 default:
534 printf("SPI error: unsupported bus %i. Supported busses 0 - 3\n", bus); 532 printf("SPI error: unsupported bus %i. Supported busses 0 - 3\n", bus);
535 return NULL; 533 return NULL;
536 } 534 }
537 535
538 if (((bus == 0) && (cs > 3)) || 536 if (((bus == 0) && (cs > 3)) ||
539 ((bus == 1) && (cs > 1)) || 537 ((bus == 1) && (cs > 1)) ||
540 ((bus == 2) && (cs > 1)) || 538 ((bus == 2) && (cs > 1)) ||
541 ((bus == 3) && (cs > 0))) { 539 ((bus == 3) && (cs > 0))) {
542 printf("SPI error: unsupported chip select %i on bus %i\n", cs, bus); 540 printf("SPI error: unsupported chip select %i on bus %i\n", cs, bus);
543 return NULL; 541 return NULL;
544 } 542 }
545 543
546 if (max_hz > OMAP3_MCSPI_MAX_FREQ) { 544 if (max_hz > OMAP3_MCSPI_MAX_FREQ) {
547 printf("SPI error: unsupported frequency %i Hz. Max frequency is 48 MHz\n", 545 printf("SPI error: unsupported frequency %i Hz. Max frequency is 48 MHz\n",
548 max_hz); 546 max_hz);
549 return NULL; 547 return NULL;
550 } 548 }
551 549
552 if (mode > SPI_MODE_3) { 550 if (mode > SPI_MODE_3) {
553 printf("SPI error: unsupported SPI mode %i\n", mode); 551 printf("SPI error: unsupported SPI mode %i\n", mode);
554 return NULL; 552 return NULL;
555 } 553 }
556 554
557 priv = spi_alloc_slave(struct omap3_spi_priv, bus, cs); 555 priv = spi_alloc_slave(struct omap3_spi_priv, bus, cs);
558 if (!priv) { 556 if (!priv) {
559 printf("SPI error: malloc of SPI structure failed\n"); 557 printf("SPI error: malloc of SPI structure failed\n");
560 return NULL; 558 return NULL;
561 } 559 }
562 560
563 priv->regs = regs; 561 priv->regs = regs;
564 priv->cs = cs; 562 priv->cs = cs;
565 priv->freq = max_hz; 563 priv->freq = max_hz;
566 priv->mode = mode; 564 priv->mode = mode;
567 priv->wordlen = priv->slave.wordlen; 565 priv->wordlen = priv->slave.wordlen;
568 #if 0 566 #if 0
569 /* Please migrate to DM_SPI support for this feature. */ 567 /* Please migrate to DM_SPI support for this feature. */
570 priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; 568 priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
571 #endif 569 #endif
572 570
573 return &priv->slave; 571 return &priv->slave;
574 } 572 }
575 573
576 int spi_xfer(struct spi_slave *slave, unsigned int bitlen, 574 int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
577 const void *dout, void *din, unsigned long flags) 575 const void *dout, void *din, unsigned long flags)
578 { 576 {
579 struct omap3_spi_priv *priv = to_omap3_spi(slave); 577 struct omap3_spi_priv *priv = to_omap3_spi(slave);
580 578
581 return _spi_xfer(priv, bitlen, dout, din, flags); 579 return _spi_xfer(priv, bitlen, dout, din, flags);
582 } 580 }
583 581
584 #else 582 #else
585 583
586 static int omap3_spi_claim_bus(struct udevice *dev) 584 static int omap3_spi_claim_bus(struct udevice *dev)
587 { 585 {
588 struct udevice *bus = dev->parent; 586 struct udevice *bus = dev->parent;
589 struct omap3_spi_priv *priv = dev_get_priv(bus); 587 struct omap3_spi_priv *priv = dev_get_priv(bus);
590 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); 588 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
591 589
592 priv->cs = slave_plat->cs; 590 priv->cs = slave_plat->cs;
593 priv->freq = slave_plat->max_hz; 591 priv->freq = slave_plat->max_hz;
594 592
595 _omap3_spi_claim_bus(priv); 593 _omap3_spi_claim_bus(priv);
596 594
597 return 0; 595 return 0;
598 } 596 }
599 597
600 static int omap3_spi_release_bus(struct udevice *dev) 598 static int omap3_spi_release_bus(struct udevice *dev)
601 { 599 {
602 struct udevice *bus = dev->parent; 600 struct udevice *bus = dev->parent;
603 struct omap3_spi_priv *priv = dev_get_priv(bus); 601 struct omap3_spi_priv *priv = dev_get_priv(bus);
604 602
605 /* Reset the SPI hardware */ 603 writel(OMAP3_MCSPI_MODULCTRL_MS, &priv->regs->modulctrl);
606 spi_reset(priv->regs);
607 604
608 return 0; 605 return 0;
609 } 606 }
610 607
611 static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen) 608 static int omap3_spi_set_wordlen(struct udevice *dev, unsigned int wordlen)
612 { 609 {
613 struct udevice *bus = dev->parent; 610 struct udevice *bus = dev->parent;
614 struct omap3_spi_priv *priv = dev_get_priv(bus); 611 struct omap3_spi_priv *priv = dev_get_priv(bus);
615 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev); 612 struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
616 613
617 priv->cs = slave_plat->cs; 614 priv->cs = slave_plat->cs;
618 priv->wordlen = wordlen; 615 priv->wordlen = wordlen;
619 _omap3_spi_set_wordlen(priv); 616 _omap3_spi_set_wordlen(priv);
620 617
621 return 0; 618 return 0;
622 } 619 }
623 620
624 static int omap3_spi_probe(struct udevice *dev) 621 static int omap3_spi_probe(struct udevice *dev)
625 { 622 {
626 struct omap3_spi_priv *priv = dev_get_priv(dev); 623 struct omap3_spi_priv *priv = dev_get_priv(dev);
627 const void *blob = gd->fdt_blob; 624 const void *blob = gd->fdt_blob;
628 int node = dev_of_offset(dev); 625 int node = dev_of_offset(dev);
629 626
630 struct omap2_mcspi_platform_config* data = 627 struct omap2_mcspi_platform_config* data =
631 (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev); 628 (struct omap2_mcspi_platform_config*)dev_get_driver_data(dev);
632 629
633 priv->regs = (struct mcspi *)(devfdt_get_addr(dev) + data->regs_offset); 630 priv->regs = (struct mcspi *)(devfdt_get_addr(dev) + data->regs_offset);
634 if (fdtdec_get_bool(blob, node, "ti,pindir-d0-out-d1-in")) 631 if (fdtdec_get_bool(blob, node, "ti,pindir-d0-out-d1-in"))
635 priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN; 632 priv->pin_dir = MCSPI_PINDIR_D0_OUT_D1_IN;
636 else 633 else
637 priv->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT; 634 priv->pin_dir = MCSPI_PINDIR_D0_IN_D1_OUT;
638 priv->wordlen = SPI_DEFAULT_WORDLEN; 635 priv->wordlen = SPI_DEFAULT_WORDLEN;
636
637 spi_reset(priv->regs);
638
639 return 0; 639 return 0;
640 } 640 }
641 641
642 static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen, 642 static int omap3_spi_xfer(struct udevice *dev, unsigned int bitlen,
643 const void *dout, void *din, unsigned long flags) 643 const void *dout, void *din, unsigned long flags)
644 { 644 {
645 struct udevice *bus = dev->parent; 645 struct udevice *bus = dev->parent;
646 struct omap3_spi_priv *priv = dev_get_priv(bus); 646 struct omap3_spi_priv *priv = dev_get_priv(bus);
647 647
648 return _spi_xfer(priv, bitlen, dout, din, flags); 648 return _spi_xfer(priv, bitlen, dout, din, flags);
649 } 649 }
650 650
651 static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed) 651 static int omap3_spi_set_speed(struct udevice *dev, unsigned int speed)
652 { 652 {
653 653
654 struct omap3_spi_priv *priv = dev_get_priv(dev); 654 struct omap3_spi_priv *priv = dev_get_priv(dev);
655 655
656 priv->freq = speed; 656 priv->freq = speed;
657 _omap3_spi_set_speed(priv); 657 _omap3_spi_set_speed(priv);
658 658
659 return 0; 659 return 0;
660 } 660 }
661 661
662 static int omap3_spi_set_mode(struct udevice *dev, uint mode) 662 static int omap3_spi_set_mode(struct udevice *dev, uint mode)
663 { 663 {
664 struct omap3_spi_priv *priv = dev_get_priv(dev); 664 struct omap3_spi_priv *priv = dev_get_priv(dev);
665 665
666 priv->mode = mode; 666 priv->mode = mode;
667 667
668 _omap3_spi_set_mode(priv); 668 _omap3_spi_set_mode(priv);
669 669
670 return 0; 670 return 0;
671 } 671 }
672 672
673 static const struct dm_spi_ops omap3_spi_ops = { 673 static const struct dm_spi_ops omap3_spi_ops = {
674 .claim_bus = omap3_spi_claim_bus, 674 .claim_bus = omap3_spi_claim_bus,
675 .release_bus = omap3_spi_release_bus, 675 .release_bus = omap3_spi_release_bus,
676 .set_wordlen = omap3_spi_set_wordlen, 676 .set_wordlen = omap3_spi_set_wordlen,
677 .xfer = omap3_spi_xfer, 677 .xfer = omap3_spi_xfer,
678 .set_speed = omap3_spi_set_speed, 678 .set_speed = omap3_spi_set_speed,
679 .set_mode = omap3_spi_set_mode, 679 .set_mode = omap3_spi_set_mode,
680 /* 680 /*
681 * cs_info is not needed, since we require all chip selects to be 681 * cs_info is not needed, since we require all chip selects to be
682 * in the device tree explicitly 682 * in the device tree explicitly
683 */ 683 */
684 }; 684 };
685 685
686 static struct omap2_mcspi_platform_config omap2_pdata = { 686 static struct omap2_mcspi_platform_config omap2_pdata = {
687 .regs_offset = 0, 687 .regs_offset = 0,
688 }; 688 };
689 689
690 static struct omap2_mcspi_platform_config omap4_pdata = { 690 static struct omap2_mcspi_platform_config omap4_pdata = {
691 .regs_offset = OMAP4_MCSPI_REG_OFFSET, 691 .regs_offset = OMAP4_MCSPI_REG_OFFSET,
692 }; 692 };
693 693
694 static const struct udevice_id omap3_spi_ids[] = { 694 static const struct udevice_id omap3_spi_ids[] = {
695 { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata }, 695 { .compatible = "ti,omap2-mcspi", .data = (ulong)&omap2_pdata },
696 { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata }, 696 { .compatible = "ti,omap4-mcspi", .data = (ulong)&omap4_pdata },
697 { } 697 { }
698 }; 698 };
699 699
700 U_BOOT_DRIVER(omap3_spi) = { 700 U_BOOT_DRIVER(omap3_spi) = {
701 .name = "omap3_spi", 701 .name = "omap3_spi",
702 .id = UCLASS_SPI, 702 .id = UCLASS_SPI,
703 .of_match = omap3_spi_ids, 703 .of_match = omap3_spi_ids,
704 .probe = omap3_spi_probe, 704 .probe = omap3_spi_probe,