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