]> git.ipfire.org Git - people/ms/u-boot.git/blame - board/beckhoff/mx53cx9020/mx53cx9020.c
arm: imx: cx9020: remove usage of mx53_dram_size
[people/ms/u-boot.git] / board / beckhoff / mx53cx9020 / mx53cx9020.c
CommitLineData
98d62e61
PB
1/*
2 * Copyright (C) 2015 Beckhoff Automation GmbH & Co. KG
3 * Patrick Bruenn <p.bruenn@beckhoff.com>
4 *
5 * Based on <u-boot>/board/freescale/mx53loco/mx53loco.c
6 * Copyright (C) 2011 Freescale Semiconductor, Inc.
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 */
10
11#include <common.h>
9d922450 12#include <dm.h>
98d62e61
PB
13#include <asm/io.h>
14#include <asm/arch/imx-regs.h>
15#include <asm/arch/sys_proto.h>
16#include <asm/arch/crm_regs.h>
17#include <asm/arch/clock.h>
18#include <asm/arch/iomux-mx53.h>
19#include <asm/arch/clock.h>
552a848e 20#include <asm/mach-imx/mx5_video.h>
98d62e61
PB
21#include <ACEX1K.h>
22#include <netdev.h>
23#include <i2c.h>
24#include <mmc.h>
25#include <fsl_esdhc.h>
26#include <asm/gpio.h>
27#include <linux/fb.h>
28#include <ipu_pixfmt.h>
7594c51a 29#include <input.h>
98d62e61 30#include <fs.h>
98d62e61
PB
31#include <dm/platform_data/serial_mxc.h>
32
33enum LED_GPIOS {
34 GPIO_SD1_CD = IMX_GPIO_NR(1, 1),
35 GPIO_SD2_CD = IMX_GPIO_NR(1, 4),
36 GPIO_LED_SD2_R = IMX_GPIO_NR(3, 16),
37 GPIO_LED_SD2_B = IMX_GPIO_NR(3, 17),
38 GPIO_LED_SD2_G = IMX_GPIO_NR(3, 18),
39 GPIO_LED_SD1_R = IMX_GPIO_NR(3, 19),
40 GPIO_LED_SD1_B = IMX_GPIO_NR(3, 20),
41 GPIO_LED_SD1_G = IMX_GPIO_NR(3, 21),
42 GPIO_LED_PWR_R = IMX_GPIO_NR(3, 22),
43 GPIO_LED_PWR_B = IMX_GPIO_NR(3, 23),
44 GPIO_LED_PWR_G = IMX_GPIO_NR(3, 24),
45 GPIO_SUPS_INT = IMX_GPIO_NR(3, 31),
46 GPIO_C3_CONFIG = IMX_GPIO_NR(6, 8),
47 GPIO_C3_STATUS = IMX_GPIO_NR(6, 7),
48 GPIO_C3_DONE = IMX_GPIO_NR(6, 9),
49};
50
51#define CCAT_BASE_ADDR ((void *)0xf0000000)
52#define CCAT_END_ADDR (CCAT_BASE_ADDR + (1024 * 1024 * 32))
53#define CCAT_SIZE 1191788
54#define CCAT_SIGN_ADDR (CCAT_BASE_ADDR + 12)
55static const char CCAT_SIGNATURE[] = "CCAT";
56
57static const u32 CCAT_MODE_CONFIG = 0x0024DC81;
58static const u32 CCAT_MODE_RUN = 0x0033DC8F;
59
60DECLARE_GLOBAL_DATA_PTR;
61
98d62e61
PB
62phys_size_t get_effective_memsize(void)
63{
64 /*
65 * WARNING: We must override get_effective_memsize() function here
66 * to report only the size of the first DRAM bank. This is to make
67 * U-Boot relocator place U-Boot into valid memory, that is, at the
68 * end of the first DRAM bank. If we did not override this function
69 * like so, U-Boot would be placed at the address of the first DRAM
70 * bank + total DRAM size - sizeof(uboot), which in the setup where
71 * each DRAM bank contains 512MiB of DRAM would result in placing
72 * U-Boot into invalid memory area close to the end of the first
73 * DRAM bank.
74 */
a75a3ef3 75 return get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
98d62e61
PB
76}
77
78int dram_init(void)
79{
a75a3ef3
PB
80 gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
81 gd->ram_size += get_ram_size((void *)PHYS_SDRAM_2, 1 << 30);
98d62e61
PB
82
83 return 0;
84}
85
76b00aca 86int dram_init_banksize(void)
98d62e61
PB
87{
88 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
a75a3ef3 89 gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
98d62e61
PB
90
91 gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
a75a3ef3 92 gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2, 1 << 30);
76b00aca
SG
93
94 return 0;
98d62e61
PB
95}
96
97u32 get_board_rev(void)
98{
99 struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
100 struct fuse_bank *bank = &iim->bank[0];
101 struct fuse_bank0_regs *fuse =
102 (struct fuse_bank0_regs *)bank->fuse_regs;
103
104 int rev = readl(&fuse->gp[6]);
105
106 return (get_cpu_rev() & ~(0xF << 8)) | (rev & 0xF) << 8;
107}
108
109/*
110 * Set CCAT mode
111 * @mode: use CCAT_MODE_CONFIG or CCAT_MODE_RUN
112 */
113void weim_cs0_settings(u32 mode)
114{
115 struct weim *weim_regs = (struct weim *)WEIM_BASE_ADDR;
116
117 writel(0x0, &weim_regs->cs0gcr1);
118 writel(mode, &weim_regs->cs0gcr1);
119 writel(0x00001002, &weim_regs->cs0gcr2);
120
121 writel(0x04000000, &weim_regs->cs0rcr1);
122 writel(0x00000000, &weim_regs->cs0rcr2);
123
124 writel(0x04000000, &weim_regs->cs0wcr1);
125 writel(0x00000000, &weim_regs->cs0wcr2);
126}
127
128static void setup_gpio_eim(void)
129{
130 gpio_direction_input(GPIO_C3_STATUS);
131 gpio_direction_input(GPIO_C3_DONE);
132 gpio_direction_output(GPIO_C3_CONFIG, 1);
133
134 weim_cs0_settings(CCAT_MODE_RUN);
135}
136
137static void setup_gpio_sups(void)
138{
139 gpio_direction_input(GPIO_SUPS_INT);
140
141 static const int BLINK_INTERVALL = 50000;
142 int status = 1;
143 while (gpio_get_value(GPIO_SUPS_INT)) {
144 /* signal "CX SUPS power fail" */
145 gpio_set_value(GPIO_LED_PWR_R,
146 (++status / BLINK_INTERVALL) % 2);
147 }
148
149 /* signal "CX power up" */
150 gpio_set_value(GPIO_LED_PWR_R, 1);
151}
152
153static void setup_gpio_leds(void)
154{
155 gpio_direction_output(GPIO_LED_SD2_R, 0);
156 gpio_direction_output(GPIO_LED_SD2_B, 0);
157 gpio_direction_output(GPIO_LED_SD2_G, 0);
158 gpio_direction_output(GPIO_LED_SD1_R, 0);
159 gpio_direction_output(GPIO_LED_SD1_B, 0);
160 gpio_direction_output(GPIO_LED_SD1_G, 0);
161 gpio_direction_output(GPIO_LED_PWR_R, 0);
162 gpio_direction_output(GPIO_LED_PWR_B, 0);
163 gpio_direction_output(GPIO_LED_PWR_G, 0);
164}
165
166#ifdef CONFIG_USB_EHCI_MX5
167int board_ehci_hcd_init(int port)
168{
169 /* request VBUS power enable pin, GPIO7_8 */
170 gpio_direction_output(IMX_GPIO_NR(7, 8), 1);
171 return 0;
172}
173#endif
174
175#ifdef CONFIG_FSL_ESDHC
176struct fsl_esdhc_cfg esdhc_cfg[2] = {
177 {MMC_SDHC1_BASE_ADDR},
178 {MMC_SDHC2_BASE_ADDR},
179};
180
181int board_mmc_getcd(struct mmc *mmc)
182{
183 struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
184 int ret;
185
186 gpio_direction_input(GPIO_SD1_CD);
187 gpio_direction_input(GPIO_SD2_CD);
188
189 if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
190 ret = !gpio_get_value(GPIO_SD1_CD);
191 else
192 ret = !gpio_get_value(GPIO_SD2_CD);
193
194 return ret;
195}
196
197int board_mmc_init(bd_t *bis)
198{
199 u32 index;
200 int ret;
201
202 esdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK);
203 esdhc_cfg[1].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
204
205 for (index = 0; index < CONFIG_SYS_FSL_ESDHC_NUM; index++) {
206 switch (index) {
207 case 0:
208 break;
209 case 1:
210 break;
211 default:
212 printf("Warning: you configured more ESDHC controller(%d) as supported by the board(2)\n",
213 CONFIG_SYS_FSL_ESDHC_NUM);
214 return -EINVAL;
215 }
216 ret = fsl_esdhc_initialize(bis, &esdhc_cfg[index]);
217 if (ret)
218 return ret;
219 }
220
221 return 0;
222}
223#endif
224
225static int power_init(void)
226{
227 /* nothing to do on CX9020 */
228 return 0;
229}
230
231static void clock_1GHz(void)
232{
233 int ret;
234 u32 ref_clk = MXC_HCLK;
235 /*
236 * After increasing voltage to 1.25V, we can switch
237 * CPU clock to 1GHz and DDR to 400MHz safely
238 */
239 ret = mxc_set_clock(ref_clk, 1000, MXC_ARM_CLK);
240 if (ret)
241 printf("CPU: Switch CPU clock to 1GHZ failed\n");
242
243 ret = mxc_set_clock(ref_clk, 400, MXC_PERIPH_CLK);
244 ret |= mxc_set_clock(ref_clk, 400, MXC_DDR_CLK);
245 if (ret)
246 printf("CPU: Switch DDR clock to 400MHz failed\n");
247}
248
249int board_early_init_f(void)
250{
251 setup_gpio_leds();
252 setup_gpio_sups();
253 setup_gpio_eim();
254 setup_iomux_lcd();
255
256 return 0;
257}
258
259/*
260 * Do not overwrite the console
261 * Use always serial for U-Boot console
262 */
263int overwrite_console(void)
264{
265 return 1;
266}
267
268int board_init(void)
269{
270 gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
271
272 mxc_set_sata_internal_clock();
273
274 return 0;
275}
276
277int checkboard(void)
278{
279 puts("Board: Beckhoff CX9020\n");
280
281 return 0;
282}
283
284static int ccat_config_fn(int assert_config, int flush, int cookie)
285{
286 /* prepare FPGA for programming */
287 weim_cs0_settings(CCAT_MODE_CONFIG);
288 gpio_set_value(GPIO_C3_CONFIG, 0);
289 udelay(1);
290 gpio_set_value(GPIO_C3_CONFIG, 1);
291 udelay(230);
292
293 return FPGA_SUCCESS;
294}
295
296static int ccat_status_fn(int cookie)
297{
298 return FPGA_FAIL;
299}
300
301static int ccat_write_fn(const void *buf, size_t buf_len, int flush, int cookie)
302{
303 const uint8_t *const buffer = buf;
304
305 /* program CCAT */
306 int i;
307 for (i = 0; i < buf_len; ++i)
308 writeb(buffer[i], CCAT_BASE_ADDR);
309
310 writeb(0xff, CCAT_BASE_ADDR);
311 writeb(0xff, CCAT_BASE_ADDR);
312
313 return FPGA_SUCCESS;
314}
315
316static int ccat_done_fn(int cookie)
317{
318 /* programming complete? */
319 return gpio_get_value(GPIO_C3_DONE);
320}
321
322static int ccat_post_fn(int cookie)
323{
324 /* switch to FPGA run mode */
325 weim_cs0_settings(CCAT_MODE_RUN);
326 invalidate_dcache_range((ulong) CCAT_BASE_ADDR, (ulong) CCAT_END_ADDR);
327
328 if (memcmp(CCAT_SIGN_ADDR, CCAT_SIGNATURE, sizeof(CCAT_SIGNATURE))) {
329 printf("Verifing CCAT firmware failed, signature not found\n");
330 return FPGA_FAIL;
331 }
332
333 /* signal "CX booting OS" */
334 gpio_set_value(GPIO_LED_PWR_R, 1);
335 gpio_set_value(GPIO_LED_PWR_G, 1);
336 gpio_set_value(GPIO_LED_PWR_B, 0);
337 return FPGA_SUCCESS;
338}
339
340static Altera_CYC2_Passive_Serial_fns ccat_fns = {
341 .config = ccat_config_fn,
342 .status = ccat_status_fn,
343 .done = ccat_done_fn,
344 .write = ccat_write_fn,
345 .abort = ccat_post_fn,
346 .post = ccat_post_fn,
347};
348
349static Altera_desc ccat_fpga = {
350 .family = Altera_CYC2,
351 .iface = passive_serial,
352 .size = CCAT_SIZE,
353 .iface_fns = &ccat_fns,
354 .base = CCAT_BASE_ADDR,
355};
356
357int board_late_init(void)
358{
359 if (!power_init())
360 clock_1GHz();
361
362 fpga_init();
363 fpga_add(fpga_altera, &ccat_fpga);
364
365 return 0;
366}