]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/renesas/sh7753evb/spi-boot.c
Merge branch 'master' of git://www.denx.de/git/u-boot-imx
[karo-tx-uboot.git] / board / renesas / sh7753evb / spi-boot.c
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
67 extern void bss_start(void);
68
69 #define __uses_spiboot2 __attribute__((section(".spiboot2.text")))
70 static 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
89 static 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
121 void __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 }