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