arm: imx: cx9020: remove usage of mx53_dram_size
[oweals/u-boot.git] / board / beckhoff / mx53cx9020 / mx53cx9020.c
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>
12 #include <dm.h>
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>
20 #include <asm/mach-imx/mx5_video.h>
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>
29 #include <input.h>
30 #include <fs.h>
31 #include <dm/platform_data/serial_mxc.h>
32
33 enum 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)
55 static const char CCAT_SIGNATURE[] = "CCAT";
56
57 static const u32 CCAT_MODE_CONFIG = 0x0024DC81;
58 static const u32 CCAT_MODE_RUN = 0x0033DC8F;
59
60 DECLARE_GLOBAL_DATA_PTR;
61
62 phys_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          */
75         return get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
76 }
77
78 int dram_init(void)
79 {
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);
82
83         return 0;
84 }
85
86 int dram_init_banksize(void)
87 {
88         gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
89         gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30);
90
91         gd->bd->bi_dram[1].start = PHYS_SDRAM_2;
92         gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2, 1 << 30);
93
94         return 0;
95 }
96
97 u32 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  */
113 void 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
128 static 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
137 static 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
153 static 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
167 int 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
176 struct fsl_esdhc_cfg esdhc_cfg[2] = {
177         {MMC_SDHC1_BASE_ADDR},
178         {MMC_SDHC2_BASE_ADDR},
179 };
180
181 int 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
197 int 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
225 static int power_init(void)
226 {
227         /* nothing to do on CX9020 */
228         return 0;
229 }
230
231 static 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
249 int 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  */
263 int overwrite_console(void)
264 {
265         return 1;
266 }
267
268 int 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
277 int checkboard(void)
278 {
279         puts("Board: Beckhoff CX9020\n");
280
281         return 0;
282 }
283
284 static 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
296 static int ccat_status_fn(int cookie)
297 {
298         return FPGA_FAIL;
299 }
300
301 static 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
316 static int ccat_done_fn(int cookie)
317 {
318         /* programming complete? */
319         return gpio_get_value(GPIO_C3_DONE);
320 }
321
322 static 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
340 static 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
349 static 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
357 int 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 }