uboot/board/renesas/sh7753evb/spi-boot.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013  Renesas Solutions Corp.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8
   9#define CONFIG_SPI_ADDR         0x00000000
  10#define PHYADDR(_addr)          ((_addr & 0x1fffffff) | 0x40000000)
  11#define CONFIG_RAM_BOOT_PHYS    PHYADDR(CONFIG_SYS_TEXT_BASE)
  12
  13#define SPIWDMADR       0xFE001018
  14#define SPIWDMCNTR      0xFE001020
  15#define SPIDMCOR        0xFE001028
  16#define SPIDMINTSR      0xFE001188
  17#define SPIDMINTMR      0xFE001190
  18
  19#define SPIDMINTSR_DMEND        0x00000004
  20
  21#define TBR     0xFE002000
  22#define RBR     0xFE002000
  23
  24#define CR1     0xFE002008
  25#define CR2     0xFE002010
  26#define CR3     0xFE002018
  27#define CR4     0xFE002020
  28#define CR7     0xFE002038
  29#define CR8     0xFE002040
  30
  31/* CR1 */
  32#define SPI_TBE         0x80
  33#define SPI_TBF         0x40
  34#define SPI_RBE         0x20
  35#define SPI_RBF         0x10
  36#define SPI_PFONRD      0x08
  37#define SPI_SSDB        0x04
  38#define SPI_SSD         0x02
  39#define SPI_SSA         0x01
  40
  41/* CR2 */
  42#define SPI_RSTF        0x80
  43#define SPI_LOOPBK      0x40
  44#define SPI_CPOL        0x20
  45#define SPI_CPHA        0x10
  46#define SPI_L1M0        0x08
  47
  48/* CR4 */
  49#define SPI_TBEI        0x80
  50#define SPI_TBFI        0x40
  51#define SPI_RBEI        0x20
  52#define SPI_RBFI        0x10
  53#define SPI_SpiS0       0x02
  54#define SPI_SSS         0x01
  55
  56/* CR7 */
  57#define CR7_IDX_OR12    0x12
  58#define OR12_ADDR32     0x00000001
  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#define M25_READ_4BYTE  0x13
  66
  67extern void bss_start(void);
  68
  69#define __uses_spiboot2 __attribute__((section(".spiboot2.text")))
  70static void __uses_spiboot2 spi_reset(void)
  71{
  72        int timeout = 0x00100000;
  73
  74        /* Make sure the last transaction is finalized */
  75        spi_write(0x00, CR3);
  76        spi_write(0x02, CR1);
  77        while (!(spi_read(CR4) & SPI_SpiS0)) {
  78                if (timeout-- < 0)
  79                        break;
  80        }
  81        spi_write(0x00, CR1);
  82
  83        spi_write(spi_read(CR2) | SPI_RSTF, CR2);       /* fifo reset */
  84        spi_write(spi_read(CR2) & ~SPI_RSTF, CR2);
  85
  86        spi_write(0, SPIDMCOR);
  87}
  88
  89static void __uses_spiboot2 spi_read_flash(void *buf, unsigned long addr,
  90                                           unsigned long len)
  91{
  92        spi_write(CR7_IDX_OR12, CR7);
  93        if (spi_read(CR8) & OR12_ADDR32) {
  94                /* 4-bytes address mode */
  95                spi_write(M25_READ_4BYTE, TBR);
  96                spi_write((addr >> 24) & 0xFF, TBR);    /* ADDR31-24 */
  97        } else {
  98                /* 3-bytes address mode */
  99                spi_write(M25_READ, TBR);
 100        }
 101        spi_write((addr >> 16) & 0xFF, TBR);    /* ADDR23-16 */
 102        spi_write((addr >> 8) & 0xFF, TBR);     /* ADDR15-8 */
 103        spi_write(addr & 0xFF, TBR);            /* ADDR7-0 */
 104
 105        spi_write(SPIDMINTSR_DMEND, SPIDMINTSR);
 106        spi_write((unsigned long)buf, SPIWDMADR);
 107        spi_write(len & 0xFFFFFFE0, SPIWDMCNTR);
 108        spi_write(1, SPIDMCOR);
 109
 110        spi_write(0xff, CR3);
 111        spi_write(spi_read(CR1) | SPI_SSDB, CR1);
 112        spi_write(spi_read(CR1) | SPI_SSA, CR1);
 113
 114        while (!(spi_read(SPIDMINTSR) & SPIDMINTSR_DMEND))
 115                ;
 116
 117        /* Nagate SP0-SS0 */
 118        spi_write(0, CR1);
 119}
 120
 121void __uses_spiboot2 spiboot_main(void)
 122{
 123        /*
 124         * This code rounds len up for SPIWDMCNTR. We should set it to 0 in
 125         * lower 5-bits.
 126         */
 127        void (*_start)(void) = (void *)CONFIG_SYS_TEXT_BASE;
 128        volatile unsigned long len = (bss_start - _start + 31) & 0xffffffe0;
 129
 130        spi_reset();
 131        spi_read_flash((void *)CONFIG_RAM_BOOT_PHYS, CONFIG_SPI_ADDR, len);
 132
 133        _start();
 134}
 135