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"))) 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 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 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*8e9c897bSYoshihiro Shimoda 110