1 // SPDX-License-Identifier: GPL-2.0+
3 * Andestech ATCSPI200 SPI controller driver.
5 * Copyright 2017 Andes Technology, Inc.
6 * Author: Rick Chen (rick@andestech.com)
16 DECLARE_GLOBAL_DATA_PTR
;
18 #define MAX_TRANSFER_LEN 512
20 #define SPI_TIMEOUT 0x100000
23 #define SPI0_BASE 0xf0b00000
24 #define SPI1_BASE 0xf0f00000
25 #define NSPI_MAX_CS_NUM 1
27 struct atcspi200_spi_regs
{
30 u32 format
; /* 0x10 */
31 #define DATA_LENGTH(x) ((x-1)<<8)
35 #define TRAMODE_OFFSET 24
36 #define TRAMODE_MASK (0x0F<<TRAMODE_OFFSET)
37 #define TRAMODE_WR_SYNC (0<<TRAMODE_OFFSET)
38 #define TRAMODE_WO (1<<TRAMODE_OFFSET)
39 #define TRAMODE_RO (2<<TRAMODE_OFFSET)
40 #define TRAMODE_WR (3<<TRAMODE_OFFSET)
41 #define TRAMODE_RW (4<<TRAMODE_OFFSET)
42 #define TRAMODE_WDR (5<<TRAMODE_OFFSET)
43 #define TRAMODE_RDW (6<<TRAMODE_OFFSET)
44 #define TRAMODE_NONE (7<<TRAMODE_OFFSET)
45 #define TRAMODE_DW (8<<TRAMODE_OFFSET)
46 #define TRAMODE_DR (9<<TRAMODE_OFFSET)
47 #define WCNT_OFFSET 12
48 #define WCNT_MASK (0x1FF<<WCNT_OFFSET)
50 #define RCNT_MASK (0x1FF<<RCNT_OFFSET)
55 #define TXFTH_OFFSET 16
56 #define RXFTH_OFFSET 8
57 #define TXDMAEN (1<<4)
58 #define RXDMAEN (1<<3)
64 #define TXEPTY (1<<22)
65 #define TXFVE_MASK (0x1F<<16)
67 #define RXFVE_OFFSET (8)
68 #define RXFVE_MASK (0x1F<<RXFVE_OFFSET)
72 u32 timing
; /* 0x40 */
73 #define SCLK_DIV_MASK 0xFF
76 struct nds_spi_slave
{
77 volatile struct atcspi200_spi_regs
*regs
;
90 unsigned int max_transfer_length
;
93 static int __atcspi200_spi_set_speed(struct nds_spi_slave
*ns
)
97 tm
= ns
->regs
->timing
;
100 if(ns
->freq
>= ns
->clock
)
103 for (div
= 0; div
< 0xff; div
++) {
104 if (ns
->freq
>= ns
->clock
/ (2 * (div
+ 1)))
110 ns
->regs
->timing
= tm
;
116 static int __atcspi200_spi_claim_bus(struct nds_spi_slave
*ns
)
118 unsigned int format
=0;
119 ns
->regs
->ctrl
|= (TXFRST
|RXFRST
|SPIRST
);
120 while((ns
->regs
->ctrl
&(TXFRST
|RXFRST
|SPIRST
))&&(ns
->to
--))
125 format
= ns
->mode
|DATA_LENGTH(8);
126 ns
->regs
->format
= format
;
127 __atcspi200_spi_set_speed(ns
);
132 static int __atcspi200_spi_release_bus(struct nds_spi_slave
*ns
)
138 static int __atcspi200_spi_start(struct nds_spi_slave
*ns
)
141 int tc
= ns
->regs
->tctrl
;
143 tc
&= ~(WCNT_MASK
|RCNT_MASK
|TRAMODE_MASK
);
144 if ((ns
->din
)&&(ns
->cmd_len
))
153 tc
|= (ns
->cmd_len
+olen
-1) << WCNT_OFFSET
;
156 tc
|= (ns
->tran_len
-1) << RCNT_OFFSET
;
158 ns
->regs
->tctrl
= tc
;
161 for (i
=0;i
<ns
->cmd_len
;i
++)
162 ns
->regs
->data
= ns
->cmd_buf
[i
];
167 static int __atcspi200_spi_stop(struct nds_spi_slave
*ns
)
169 ns
->regs
->timing
= ns
->mtiming
;
170 while ((ns
->regs
->status
& SPIBSY
)&&(ns
->to
--))
177 static void __nspi_espi_tx(struct nds_spi_slave
*ns
, const void *dout
)
179 ns
->regs
->data
= *(u8
*)dout
;
182 static int __nspi_espi_rx(struct nds_spi_slave
*ns
, void *din
, unsigned int bytes
)
184 *(u8
*)din
= ns
->regs
->data
;
189 static int __atcspi200_spi_xfer(struct nds_spi_slave
*ns
,
190 unsigned int bitlen
, const void *data_out
, void *data_in
,
193 unsigned int event
, rx_bytes
;
194 const void *dout
= NULL
;
196 int num_blks
, num_chunks
, max_tran_len
, tran_len
;
198 u8
*cmd_buf
= ns
->cmd_buf
;
199 size_t cmd_len
= ns
->cmd_len
;
200 size_t data_len
= bitlen
/ 8;
204 max_tran_len
= ns
->max_transfer_length
;
207 cmd_len
= ns
->cmd_len
= data_len
;
208 memcpy(cmd_buf
, data_out
, cmd_len
);
216 ns
->data_len
= data_len
;
217 ns
->din
= (u8
*)data_in
;
218 ns
->dout
= (u8
*)data_out
;
221 case SPI_XFER_BEGIN
| SPI_XFER_END
:
225 cmd_len
= ns
->cmd_len
= data_len
;
226 memcpy(cmd_buf
, data_out
, cmd_len
);
229 __atcspi200_spi_start(ns
);
233 debug("spi_xfer: data_out %08X(%p) data_in %08X(%p) data_len %u\n",
234 *(uint
*)data_out
, data_out
, *(uint
*)data_in
,
236 num_chunks
= DIV_ROUND_UP(data_len
, max_tran_len
);
239 while (num_chunks
--) {
240 tran_len
= min(data_len
, (size_t)max_tran_len
);
241 ns
->tran_len
= tran_len
;
242 num_blks
= DIV_ROUND_UP(tran_len
, CHUNK_SIZE
);
243 num_bytes
= (tran_len
) % CHUNK_SIZE
;
245 num_bytes
= CHUNK_SIZE
;
246 __atcspi200_spi_start(ns
);
249 event
= in_le32(&ns
->regs
->status
);
250 if ((event
& TXEPTY
) && (data_out
)) {
251 __nspi_espi_tx(ns
, dout
);
252 num_blks
-= CHUNK_SIZE
;
256 if ((event
& RXFVE_MASK
) && (data_in
)) {
257 rf_cnt
= ((event
& RXFVE_MASK
)>> RXFVE_OFFSET
);
258 if (rf_cnt
>= CHUNK_SIZE
)
259 rx_bytes
= CHUNK_SIZE
;
260 else if (num_blks
== 1 && rf_cnt
== num_bytes
)
261 rx_bytes
= num_bytes
;
265 if (__nspi_espi_rx(ns
, din
, rx_bytes
) == rx_bytes
) {
266 num_blks
-= CHUNK_SIZE
;
267 din
= (unsigned char *)din
+ rx_bytes
;
272 data_len
-= tran_len
;
275 ns
->cmd_buf
[1] += ((tran_len
>>16)&0xff);
276 ns
->cmd_buf
[2] += ((tran_len
>>8)&0xff);
277 ns
->cmd_buf
[3] += ((tran_len
)&0xff);
278 ns
->data_len
= data_len
;
280 ret
= __atcspi200_spi_stop(ns
);
282 ret
= __atcspi200_spi_stop(ns
);
287 static int atcspi200_spi_set_speed(struct udevice
*bus
, uint max_hz
)
289 struct nds_spi_slave
*ns
= dev_get_priv(bus
);
291 debug("%s speed %u\n", __func__
, max_hz
);
294 __atcspi200_spi_set_speed(ns
);
299 static int atcspi200_spi_set_mode(struct udevice
*bus
, uint mode
)
301 struct nds_spi_slave
*ns
= dev_get_priv(bus
);
303 debug("%s mode %u\n", __func__
, mode
);
309 static int atcspi200_spi_claim_bus(struct udevice
*dev
)
311 struct dm_spi_slave_platdata
*slave_plat
=
312 dev_get_parent_platdata(dev
);
313 struct udevice
*bus
= dev
->parent
;
314 struct nds_spi_slave
*ns
= dev_get_priv(bus
);
316 if (slave_plat
->cs
>= ns
->num_cs
) {
317 printf("Invalid SPI chipselect\n");
321 return __atcspi200_spi_claim_bus(ns
);
324 static int atcspi200_spi_release_bus(struct udevice
*dev
)
326 struct nds_spi_slave
*ns
= dev_get_priv(dev
->parent
);
328 return __atcspi200_spi_release_bus(ns
);
331 static int atcspi200_spi_xfer(struct udevice
*dev
, unsigned int bitlen
,
332 const void *dout
, void *din
,
335 struct udevice
*bus
= dev
->parent
;
336 struct nds_spi_slave
*ns
= dev_get_priv(bus
);
338 return __atcspi200_spi_xfer(ns
, bitlen
, dout
, din
, flags
);
341 static int atcspi200_spi_get_clk(struct udevice
*bus
)
343 struct nds_spi_slave
*ns
= dev_get_priv(bus
);
348 ret
= clk_get_by_index(bus
, 0, &clk
);
352 clk_rate
= clk_get_rate(&clk
);
356 ns
->clock
= clk_rate
;
362 static int atcspi200_spi_probe(struct udevice
*bus
)
364 struct nds_spi_slave
*ns
= dev_get_priv(bus
);
366 ns
->to
= SPI_TIMEOUT
;
367 ns
->max_transfer_length
= MAX_TRANSFER_LEN
;
368 ns
->mtiming
= ns
->regs
->timing
;
369 atcspi200_spi_get_clk(bus
);
374 static int atcspi200_ofdata_to_platadata(struct udevice
*bus
)
376 struct nds_spi_slave
*ns
= dev_get_priv(bus
);
377 const void *blob
= gd
->fdt_blob
;
378 int node
= dev_of_offset(bus
);
380 ns
->regs
= map_physmem(devfdt_get_addr(bus
),
381 sizeof(struct atcspi200_spi_regs
),
384 printf("%s: could not map device address\n", __func__
);
387 ns
->num_cs
= fdtdec_get_int(blob
, node
, "num-cs", 4);
392 static const struct dm_spi_ops atcspi200_spi_ops
= {
393 .claim_bus
= atcspi200_spi_claim_bus
,
394 .release_bus
= atcspi200_spi_release_bus
,
395 .xfer
= atcspi200_spi_xfer
,
396 .set_speed
= atcspi200_spi_set_speed
,
397 .set_mode
= atcspi200_spi_set_mode
,
400 static const struct udevice_id atcspi200_spi_ids
[] = {
401 { .compatible
= "andestech,atcspi200" },
405 U_BOOT_DRIVER(atcspi200_spi
) = {
406 .name
= "atcspi200_spi",
408 .of_match
= atcspi200_spi_ids
,
409 .ops
= &atcspi200_spi_ops
,
410 .ofdata_to_platdata
= atcspi200_ofdata_to_platadata
,
411 .priv_auto_alloc_size
= sizeof(struct nds_spi_slave
),
412 .probe
= atcspi200_spi_probe
,