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