1 /*
2  * Copyright (C) 2011  Renesas Solutions Corp.
3  *
4  * This file is subject to the terms and conditions of the GNU Lesser
5  * General Public License.  See the file "COPYING.LIB" in the main
6  * directory of this archive for more details.
7  */
8 
9 #include <common.h>
10 
11 #define CONFIG_RAM_BOOT_PHYS	0x4ef80000
12 #if defined(CONFIG_SH7757_OFFSET_SPI)
13 #define CONFIG_SPI_ADDR		0x00010000
14 #else
15 #define CONFIG_SPI_ADDR		0x00000000
16 #endif
17 #define CONFIG_SPI_LENGTH	0x00030000
18 #define CONFIG_RAM_BOOT		0x8ef80000
19 
20 #define SPIWDMADR	0xFE001018
21 #define SPIWDMCNTR	0xFE001020
22 #define SPIDMCOR	0xFE001028
23 #define SPIDMINTSR	0xFE001188
24 #define SPIDMINTMR	0xFE001190
25 
26 #define SPIDMINTSR_DMEND	0x00000004
27 
28 #define TBR	0xFE002000
29 #define RBR	0xFE002000
30 
31 #define CR1	0xFE002008
32 #define CR2	0xFE002010
33 #define CR3	0xFE002018
34 #define CR4	0xFE002020
35 
36 /* CR1 */
37 #define SPI_TBE		0x80
38 #define SPI_TBF		0x40
39 #define SPI_RBE		0x20
40 #define SPI_RBF		0x10
41 #define SPI_PFONRD	0x08
42 #define SPI_SSDB	0x04
43 #define SPI_SSD		0x02
44 #define SPI_SSA		0x01
45 
46 /* CR2 */
47 #define SPI_RSTF	0x80
48 #define SPI_LOOPBK	0x40
49 #define SPI_CPOL	0x20
50 #define SPI_CPHA	0x10
51 #define SPI_L1M0	0x08
52 
53 /* CR4 */
54 #define SPI_TBEI	0x80
55 #define SPI_TBFI	0x40
56 #define SPI_RBEI	0x20
57 #define SPI_RBFI	0x10
58 #define SPI_SSS		0x01
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 
66 #define __uses_spiboot2	__attribute__((section(".spiboot2.text")))
67 static void __uses_spiboot2 spi_reset(void)
68 {
69 	spi_write(0xfe, CR1);
70 
71 	spi_write(0, SPIDMCOR);
72 	spi_write(0x00, CR1);
73 
74 	spi_write(spi_read(CR2) | SPI_RSTF, CR2);	/* fifo reset */
75 	spi_write(spi_read(CR2) & ~SPI_RSTF, CR2);
76 }
77 
78 static void __uses_spiboot2 spi_read_flash(void *buf, unsigned long addr,
79 					   unsigned long len)
80 {
81 	spi_write(M25_READ, TBR);
82 	spi_write((addr >> 16) & 0xFF, TBR);
83 	spi_write((addr >> 8) & 0xFF, TBR);
84 	spi_write(addr & 0xFF, TBR);
85 
86 	spi_write(SPIDMINTSR_DMEND, SPIDMINTSR);
87 	spi_write((unsigned long)buf, SPIWDMADR);
88 	spi_write(len & 0xFFFFFFE0, SPIWDMCNTR);
89 	spi_write(1, SPIDMCOR);
90 
91 	spi_write(0xff, CR3);
92 	spi_write(spi_read(CR1) | SPI_SSDB, CR1);
93 	spi_write(spi_read(CR1) | SPI_SSA, CR1);
94 
95 	while (!(spi_read(SPIDMINTSR) & SPIDMINTSR_DMEND))
96 		;
97 }
98 
99 void __uses_spiboot2 spiboot_main(void)
100 {
101 	void (*_start)(void) = (void *)CONFIG_SYS_TEXT_BASE;
102 
103 	spi_reset();
104 	spi_read_flash((void *)CONFIG_RAM_BOOT_PHYS, CONFIG_SPI_ADDR,
105 			CONFIG_SPI_LENGTH);
106 
107 	_start();
108 }
109