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