]>
Commit | Line | Data |
---|---|---|
83d290c5 | 1 | // SPDX-License-Identifier: GPL-2.0+ |
eaf8c986 HS |
2 | /* |
3 | * (C) Copyright 2013 | |
4 | * Heiko Schocher, DENX Software Engineering, [email protected]. | |
5 | * | |
6 | * Based on: | |
7 | * Copyright (c) 2011 IDS GmbH, Germany | |
8 | * ids8313.c - ids8313 board support. | |
9 | * | |
10 | * Sergej Stepanov <[email protected]> | |
11 | * Based on board/freescale/mpc8313erdb/mpc8313erdb.c | |
eaf8c986 HS |
12 | */ |
13 | ||
14 | #include <common.h> | |
807765b0 | 15 | #include <fdt_support.h> |
9b4a205f | 16 | #include <init.h> |
eaf8c986 HS |
17 | #include <mpc83xx.h> |
18 | #include <spi.h> | |
c05ed00a | 19 | #include <linux/delay.h> |
b08c8c48 | 20 | #include <linux/libfdt.h> |
eaf8c986 HS |
21 | |
22 | DECLARE_GLOBAL_DATA_PTR; | |
23 | /** CPLD contains the info about: | |
24 | * - board type: *pCpld & 0xF0 | |
25 | * - hw-revision: *pCpld & 0x0F | |
26 | * - cpld-revision: *pCpld+1 | |
27 | */ | |
28 | int checkboard(void) | |
29 | { | |
30 | char *pcpld = (char *)CONFIG_SYS_CPLD_BASE; | |
31 | u8 u8Vers = readb(pcpld); | |
32 | u8 u8Revs = readb(pcpld + 1); | |
33 | ||
34 | printf("Board: "); | |
35 | switch (u8Vers & 0xF0) { | |
36 | case '\x40': | |
37 | printf("CU73X"); | |
38 | break; | |
39 | case '\x50': | |
40 | printf("CC73X"); | |
41 | break; | |
42 | default: | |
43 | printf("unknown(0x%02X, 0x%02X)\n", u8Vers, u8Revs); | |
44 | return 0; | |
45 | } | |
46 | printf("\nInfo: HW-Rev: %i, CPLD-Rev: %i\n", | |
47 | u8Vers & 0x0F, u8Revs & 0xFF); | |
48 | return 0; | |
49 | } | |
50 | ||
51 | /* | |
52 | * fixed sdram init | |
53 | */ | |
54 | int fixed_sdram(unsigned long config) | |
55 | { | |
56 | immap_t *im = (immap_t *)CONFIG_SYS_IMMR; | |
57 | u32 msize = CONFIG_SYS_DDR_SIZE << 20; | |
58 | ||
59 | #ifndef CONFIG_SYS_RAMBOOT | |
60 | u32 msize_log2 = __ilog2(msize); | |
61 | ||
62 | out_be32(&im->sysconf.ddrlaw[0].bar, | |
133ec602 | 63 | (CONFIG_SYS_SDRAM_BASE & 0xfffff000)); |
eaf8c986 HS |
64 | out_be32(&im->sysconf.ddrlaw[0].ar, LBLAWAR_EN | (msize_log2 - 1)); |
65 | out_be32(&im->sysconf.ddrcdr, CONFIG_SYS_DDRCDR_VALUE); | |
66 | sync(); | |
67 | ||
68 | /* | |
69 | * Erratum DDR3 requires a 50ms delay after clearing DDRCDR[DDR_cfg], | |
70 | * or the DDR2 controller may fail to initialize correctly. | |
71 | */ | |
72 | udelay(50000); | |
73 | ||
74 | out_be32(&im->ddr.csbnds[0].csbnds, (msize - 1) >> 24); | |
75 | out_be32(&im->ddr.cs_config[0], config); | |
76 | ||
77 | /* currently we use only one CS, so disable the other banks */ | |
78 | out_be32(&im->ddr.cs_config[1], 0); | |
79 | out_be32(&im->ddr.cs_config[2], 0); | |
80 | out_be32(&im->ddr.cs_config[3], 0); | |
81 | ||
82 | out_be32(&im->ddr.timing_cfg_3, CONFIG_SYS_DDR_TIMING_3); | |
83 | out_be32(&im->ddr.timing_cfg_1, CONFIG_SYS_DDR_TIMING_1); | |
84 | out_be32(&im->ddr.timing_cfg_2, CONFIG_SYS_DDR_TIMING_2); | |
85 | out_be32(&im->ddr.timing_cfg_0, CONFIG_SYS_DDR_TIMING_0); | |
86 | ||
87 | out_be32(&im->ddr.sdram_cfg, CONFIG_SYS_SDRAM_CFG); | |
88 | out_be32(&im->ddr.sdram_cfg2, CONFIG_SYS_SDRAM_CFG2); | |
89 | ||
90 | out_be32(&im->ddr.sdram_mode, CONFIG_SYS_DDR_MODE); | |
91 | out_be32(&im->ddr.sdram_mode2, CONFIG_SYS_DDR_MODE_2); | |
92 | ||
93 | out_be32(&im->ddr.sdram_interval, CONFIG_SYS_DDR_INTERVAL); | |
94 | out_be32(&im->ddr.sdram_clk_cntl, CONFIG_SYS_DDR_CLK_CNTL); | |
95 | sync(); | |
96 | udelay(300); | |
97 | ||
98 | /* enable DDR controller */ | |
99 | setbits_be32(&im->ddr.sdram_cfg, SDRAM_CFG_MEM_EN); | |
100 | /* now check the real size */ | |
101 | disable_addr_trans(); | |
8a81bfd2 | 102 | msize = get_ram_size(CONFIG_SYS_SDRAM_BASE, msize); |
eaf8c986 HS |
103 | enable_addr_trans(); |
104 | #endif | |
105 | return msize; | |
106 | } | |
107 | ||
108 | static int setup_sdram(void) | |
109 | { | |
110 | u32 msize = CONFIG_SYS_DDR_SIZE << 20; | |
111 | long int size_01, size_02; | |
112 | ||
113 | size_01 = fixed_sdram(CONFIG_SYS_DDR_CONFIG); | |
114 | size_02 = fixed_sdram(CONFIG_SYS_DDR_CONFIG_256); | |
115 | ||
116 | if (size_01 > size_02) | |
117 | msize = fixed_sdram(CONFIG_SYS_DDR_CONFIG); | |
118 | else | |
119 | msize = size_02; | |
120 | ||
121 | return msize; | |
122 | } | |
123 | ||
f1683aa7 | 124 | int dram_init(void) |
eaf8c986 HS |
125 | { |
126 | immap_t *im = (immap_t *)CONFIG_SYS_IMMR; | |
127 | fsl_lbc_t *lbc = &im->im_lbc; | |
128 | u32 msize = 0; | |
129 | ||
130 | if ((in_be32(&im->sysconf.immrbar) & IMMRBAR_BASE_ADDR) != (u32)im) | |
088454cd | 131 | return -ENXIO; |
eaf8c986 HS |
132 | |
133 | msize = setup_sdram(); | |
134 | ||
42c9a494 MS |
135 | out_be32(&lbc->lbcr, (0x00040000 | (0xFF << LBCR_BMT_SHIFT) | 0xF)); |
136 | out_be32(&lbc->mrtpr, 0x20000000); | |
eaf8c986 HS |
137 | sync(); |
138 | ||
088454cd SG |
139 | gd->ram_size = msize; |
140 | ||
141 | return 0; | |
eaf8c986 HS |
142 | } |
143 | ||
144 | #if defined(CONFIG_OF_BOARD_SETUP) | |
e895a4b0 | 145 | int ft_board_setup(void *blob, bd_t *bd) |
eaf8c986 HS |
146 | { |
147 | ft_cpu_setup(blob, bd); | |
e895a4b0 SG |
148 | |
149 | return 0; | |
eaf8c986 HS |
150 | } |
151 | #endif | |
152 | ||
153 | /* gpio mask for spi_cs */ | |
154 | #define IDSCPLD_SPI_CS_MASK 0x00000001 | |
155 | /* spi_cs multiplexed through cpld */ | |
156 | #define IDSCPLD_SPI_CS_BASE (CONFIG_SYS_CPLD_BASE + 0xf) | |
157 | ||
158 | #if defined(CONFIG_MISC_INIT_R) | |
159 | /* srp umcr mask for rts */ | |
160 | #define IDSUMCR_RTS_MASK 0x04 | |
161 | int misc_init_r(void) | |
162 | { | |
163 | /*srp*/ | |
164 | duart83xx_t *uart1 = &((immap_t *)CONFIG_SYS_IMMR)->duart[0]; | |
165 | duart83xx_t *uart2 = &((immap_t *)CONFIG_SYS_IMMR)->duart[1]; | |
166 | ||
167 | gpio83xx_t *iopd = &((immap_t *)CONFIG_SYS_IMMR)->gpio[0]; | |
168 | u8 *spi_base = (u8 *)IDSCPLD_SPI_CS_BASE; | |
169 | ||
170 | /* deactivate spi_cs channels */ | |
171 | out_8(spi_base, 0); | |
172 | /* deactivate the spi_cs */ | |
173 | setbits_be32(&iopd->dir, IDSCPLD_SPI_CS_MASK); | |
174 | /*srp - deactivate rts*/ | |
175 | out_8(&uart1->umcr, IDSUMCR_RTS_MASK); | |
176 | out_8(&uart2->umcr, IDSUMCR_RTS_MASK); | |
177 | ||
178 | ||
179 | gd->fdt_blob = (void *)CONFIG_SYS_FLASH_BASE; | |
180 | return 0; | |
181 | } | |
182 | #endif | |
183 | ||
184 | #ifdef CONFIG_MPC8XXX_SPI | |
185 | /* | |
186 | * The following are used to control the SPI chip selects | |
187 | */ | |
188 | int spi_cs_is_valid(unsigned int bus, unsigned int cs) | |
189 | { | |
190 | return bus == 0 && ((cs >= 0) && (cs <= 2)); | |
191 | } | |
192 | ||
193 | void spi_cs_activate(struct spi_slave *slave) | |
194 | { | |
195 | gpio83xx_t *iopd = &((immap_t *)CONFIG_SYS_IMMR)->gpio[0]; | |
196 | u8 *spi_base = (u8 *)IDSCPLD_SPI_CS_BASE; | |
197 | ||
198 | /* select the spi_cs channel */ | |
199 | out_8(spi_base, 1 << slave->cs); | |
200 | /* activate the spi_cs */ | |
201 | clrbits_be32(&iopd->dat, IDSCPLD_SPI_CS_MASK); | |
202 | } | |
203 | ||
204 | void spi_cs_deactivate(struct spi_slave *slave) | |
205 | { | |
206 | gpio83xx_t *iopd = &((immap_t *)CONFIG_SYS_IMMR)->gpio[0]; | |
207 | u8 *spi_base = (u8 *)IDSCPLD_SPI_CS_BASE; | |
208 | ||
209 | /* select the spi_cs channel */ | |
210 | out_8(spi_base, 1 << slave->cs); | |
211 | /* deactivate the spi_cs */ | |
212 | setbits_be32(&iopd->dat, IDSCPLD_SPI_CS_MASK); | |
213 | } | |
35f9d9bd | 214 | #endif |