1 /*
2  * Copyright (C) 2013  Renesas Solutions Corp.
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 
7 #include <common.h>
8 
9 #define CONFIG_SPI_ADDR		0x00000000
10 #define PHYADDR(_addr)		((_addr & 0x1fffffff) | 0x40000000)
11 #define CONFIG_RAM_BOOT_PHYS	PHYADDR(CONFIG_SYS_TEXT_BASE)
12 
13 #define SPIWDMADR	0xFE001018
14 #define SPIWDMCNTR	0xFE001020
15 #define SPIDMCOR	0xFE001028
16 #define SPIDMINTSR	0xFE001188
17 #define SPIDMINTMR	0xFE001190
18 
19 #define SPIDMINTSR_DMEND	0x00000004
20 
21 #define TBR	0xFE002000
22 #define RBR	0xFE002000
23 
24 #define CR1	0xFE002008
25 #define CR2	0xFE002010
26 #define CR3	0xFE002018
27 #define CR4	0xFE002020
28 #define CR7	0xFE002038
29 #define CR8	0xFE002040
30 
31 /* CR1 */
32 #define SPI_TBE		0x80
33 #define SPI_TBF		0x40
34 #define SPI_RBE		0x20
35 #define SPI_RBF		0x10
36 #define SPI_PFONRD	0x08
37 #define SPI_SSDB	0x04
38 #define SPI_SSD		0x02
39 #define SPI_SSA		0x01
40 
41 /* CR2 */
42 #define SPI_RSTF	0x80
43 #define SPI_LOOPBK	0x40
44 #define SPI_CPOL	0x20
45 #define SPI_CPHA	0x10
46 #define SPI_L1M0	0x08
47 
48 /* CR4 */
49 #define SPI_TBEI	0x80
50 #define SPI_TBFI	0x40
51 #define SPI_RBEI	0x20
52 #define SPI_RBFI	0x10
53 #define SPI_SpiS0	0x02
54 #define SPI_SSS		0x01
55 
56 /* CR7 */
57 #define CR7_IDX_OR12	0x12
58 #define OR12_ADDR32	0x00000001
59 
60 #define spi_write(val, addr)	(*(volatile unsigned long *)(addr)) = val
61 #define spi_read(addr)		(*(volatile unsigned long *)(addr))
62 
63 /* M25P80 */
64 #define M25_READ	0x03
65 #define M25_READ_4BYTE	0x13
66 
67 extern void bss_start(void);
68 
69 #define __uses_spiboot2	__attribute__((section(".spiboot2.text")))
70 static void __uses_spiboot2 spi_reset(void)
71 {
72 	int timeout = 0x00100000;
73 
74 	/* Make sure the last transaction is finalized */
75 	spi_write(0x00, CR3);
76 	spi_write(0x02, CR1);
77 	while (!(spi_read(CR4) & SPI_SpiS0)) {
78 		if (timeout-- < 0)
79 			break;
80 	}
81 	spi_write(0x00, CR1);
82 
83 	spi_write(spi_read(CR2) | SPI_RSTF, CR2);	/* fifo reset */
84 	spi_write(spi_read(CR2) & ~SPI_RSTF, CR2);
85 
86 	spi_write(0, SPIDMCOR);
87 }
88 
89 static void __uses_spiboot2 spi_read_flash(void *buf, unsigned long addr,
90 					   unsigned long len)
91 {
92 	spi_write(CR7_IDX_OR12, CR7);
93 	if (spi_read(CR8) & OR12_ADDR32) {
94 		/* 4-bytes address mode */
95 		spi_write(M25_READ_4BYTE, TBR);
96 		spi_write((addr >> 24) & 0xFF, TBR);	/* ADDR31-24 */
97 	} else {
98 		/* 3-bytes address mode */
99 		spi_write(M25_READ, TBR);
100 	}
101 	spi_write((addr >> 16) & 0xFF, TBR);	/* ADDR23-16 */
102 	spi_write((addr >> 8) & 0xFF, TBR);	/* ADDR15-8 */
103 	spi_write(addr & 0xFF, TBR);		/* ADDR7-0 */
104 
105 	spi_write(SPIDMINTSR_DMEND, SPIDMINTSR);
106 	spi_write((unsigned long)buf, SPIWDMADR);
107 	spi_write(len & 0xFFFFFFE0, SPIWDMCNTR);
108 	spi_write(1, SPIDMCOR);
109 
110 	spi_write(0xff, CR3);
111 	spi_write(spi_read(CR1) | SPI_SSDB, CR1);
112 	spi_write(spi_read(CR1) | SPI_SSA, CR1);
113 
114 	while (!(spi_read(SPIDMINTSR) & SPIDMINTSR_DMEND))
115 		;
116 
117 	/* Nagate SP0-SS0 */
118 	spi_write(0, CR1);
119 }
120 
121 void __uses_spiboot2 spiboot_main(void)
122 {
123 	/*
124 	 * This code rounds len up for SPIWDMCNTR. We should set it to 0 in
125 	 * lower 5-bits.
126 	 */
127 	void (*_start)(void) = (void *)CONFIG_SYS_TEXT_BASE;
128 	volatile unsigned long len = (bss_start - _start + 31) & 0xffffffe0;
129 
130 	spi_reset();
131 	spi_read_flash((void *)CONFIG_RAM_BOOT_PHYS, CONFIG_SPI_ADDR, len);
132 
133 	_start();
134 }
135