uboot/board/renesas/sh7757lcr/spi-boot.c
<<
>>
Prefs
   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")))
  67static 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
  78static 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
  99void __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