]> git.ipfire.org Git - people/ms/u-boot.git/blob - board/udoo/neo/neo.c
ad7452cd91bfbba8e90459d7b313a563d4eb9f39
[people/ms/u-boot.git] / board / udoo / neo / neo.c
1 /*
2 * Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
3 * Copyright (C) Jasbir Matharu
4 * Copyright (C) UDOO Team
5 *
6 * Author: Breno Lima <breno.lima@nxp.com>
7 * Author: Francesco Montefoschi <francesco.monte@gmail.com>
8 *
9 * SPDX-License-Identifier: GPL-2.0+
10 */
11
12 #include <asm/arch/clock.h>
13 #include <asm/arch/imx-regs.h>
14 #include <asm/arch/iomux.h>
15 #include <asm/arch/mx6-pins.h>
16 #include <asm/gpio.h>
17 #include <asm/imx-common/iomux-v3.h>
18 #include <mmc.h>
19 #include <fsl_esdhc.h>
20 #include <asm/arch/crm_regs.h>
21 #include <asm/io.h>
22 #include <asm/imx-common/mxc_i2c.h>
23 #include <asm/arch/sys_proto.h>
24 #include <spl.h>
25 #include <linux/sizes.h>
26 #include <common.h>
27 #include <i2c.h>
28 #include <power/pmic.h>
29 #include <power/pfuze3000_pmic.h>
30
31 DECLARE_GLOBAL_DATA_PTR;
32
33 enum {
34 UDOO_NEO_TYPE_BASIC,
35 UDOO_NEO_TYPE_BASIC_KS,
36 UDOO_NEO_TYPE_FULL,
37 UDOO_NEO_TYPE_EXTENDED,
38 };
39
40 #define UART_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
41 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
42 PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
43
44 #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
45 PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \
46 PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS)
47
48 #define I2C_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
49 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
50 PAD_CTL_DSE_40ohm | PAD_CTL_HYS | \
51 PAD_CTL_ODE)
52
53 #define WDOG_PAD_CTRL (PAD_CTL_PUE | PAD_CTL_PKE | PAD_CTL_SPEED_MED | \
54 PAD_CTL_DSE_40ohm)
55
56 #define BOARD_DETECT_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \
57 PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \
58 PAD_CTL_DSE_34ohm | PAD_CTL_HYS | PAD_CTL_SRE_FAST)
59 #define BOARD_DETECT_PAD_CFG (MUX_PAD_CTRL(BOARD_DETECT_PAD_CTRL) | \
60 MUX_MODE_SION)
61
62 int dram_init(void)
63 {
64 gd->ram_size = imx_ddr_size();
65 return 0;
66 }
67
68 #ifdef CONFIG_SYS_I2C_MXC
69 #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
70 /* I2C1 for PMIC */
71 static struct i2c_pads_info i2c_pad_info1 = {
72 .scl = {
73 .i2c_mode = MX6_PAD_GPIO1_IO00__I2C1_SCL | PC,
74 .gpio_mode = MX6_PAD_GPIO1_IO00__GPIO1_IO_0 | PC,
75 .gp = IMX_GPIO_NR(1, 0),
76 },
77 .sda = {
78 .i2c_mode = MX6_PAD_GPIO1_IO01__I2C1_SDA | PC,
79 .gpio_mode = MX6_PAD_GPIO1_IO01__GPIO1_IO_1 | PC,
80 .gp = IMX_GPIO_NR(1, 1),
81 },
82 };
83 #endif
84
85 #ifdef CONFIG_POWER
86 int power_init_board(void)
87 {
88 struct pmic *p;
89 int ret;
90 unsigned int reg, rev_id;
91
92 ret = power_pfuze3000_init(PFUZE3000_I2C_BUS);
93 if (ret)
94 return ret;
95
96 p = pmic_get("PFUZE3000");
97 ret = pmic_probe(p);
98 if (ret)
99 return ret;
100
101 pmic_reg_read(p, PFUZE3000_DEVICEID, &reg);
102 pmic_reg_read(p, PFUZE3000_REVID, &rev_id);
103 printf("PMIC: PFUZE3000 DEV_ID=0x%x REV_ID=0x%x\n", reg, rev_id);
104
105 /* disable Low Power Mode during standby mode */
106 pmic_reg_read(p, PFUZE3000_LDOGCTL, &reg);
107 reg |= 0x1;
108 ret = pmic_reg_write(p, PFUZE3000_LDOGCTL, reg);
109 if (ret)
110 return ret;
111
112 ret = pmic_reg_write(p, PFUZE3000_SW1AMODE, 0xc);
113 if (ret)
114 return ret;
115
116 ret = pmic_reg_write(p, PFUZE3000_SW1BMODE, 0xc);
117 if (ret)
118 return ret;
119
120 ret = pmic_reg_write(p, PFUZE3000_SW2MODE, 0xc);
121 if (ret)
122 return ret;
123
124 ret = pmic_reg_write(p, PFUZE3000_SW3MODE, 0xc);
125 if (ret)
126 return ret;
127
128 /* set SW1A standby voltage 0.975V */
129 pmic_reg_read(p, PFUZE3000_SW1ASTBY, &reg);
130 reg &= ~0x3f;
131 reg |= PFUZE3000_SW1AB_SETP(9750);
132 ret = pmic_reg_write(p, PFUZE3000_SW1ASTBY, reg);
133 if (ret)
134 return ret;
135
136 /* set SW1B standby voltage 0.975V */
137 pmic_reg_read(p, PFUZE3000_SW1BSTBY, &reg);
138 reg &= ~0x3f;
139 reg |= PFUZE3000_SW1AB_SETP(9750);
140 ret = pmic_reg_write(p, PFUZE3000_SW1BSTBY, reg);
141 if (ret)
142 return ret;
143
144 /* set SW1A/VDD_ARM_IN step ramp up time from 16us to 4us/25mV */
145 pmic_reg_read(p, PFUZE3000_SW1ACONF, &reg);
146 reg &= ~0xc0;
147 reg |= 0x40;
148 ret = pmic_reg_write(p, PFUZE3000_SW1ACONF, reg);
149 if (ret)
150 return ret;
151
152 /* set SW1B/VDD_SOC_IN step ramp up time from 16us to 4us/25mV */
153 pmic_reg_read(p, PFUZE3000_SW1BCONF, &reg);
154 reg &= ~0xc0;
155 reg |= 0x40;
156 ret = pmic_reg_write(p, PFUZE3000_SW1BCONF, reg);
157 if (ret)
158 return ret;
159
160 /* set VDD_ARM_IN to 1.350V */
161 pmic_reg_read(p, PFUZE3000_SW1AVOLT, &reg);
162 reg &= ~0x3f;
163 reg |= PFUZE3000_SW1AB_SETP(13500);
164 ret = pmic_reg_write(p, PFUZE3000_SW1AVOLT, reg);
165 if (ret)
166 return ret;
167
168 /* set VDD_SOC_IN to 1.350V */
169 pmic_reg_read(p, PFUZE3000_SW1BVOLT, &reg);
170 reg &= ~0x3f;
171 reg |= PFUZE3000_SW1AB_SETP(13500);
172 ret = pmic_reg_write(p, PFUZE3000_SW1BVOLT, reg);
173 if (ret)
174 return ret;
175
176 /* set DDR_1_5V to 1.350V */
177 pmic_reg_read(p, PFUZE3000_SW3VOLT, &reg);
178 reg &= ~0x0f;
179 reg |= PFUZE3000_SW3_SETP(13500);
180 ret = pmic_reg_write(p, PFUZE3000_SW3VOLT, reg);
181 if (ret)
182 return ret;
183
184 /* set VGEN2_1V5 to 1.5V */
185 pmic_reg_read(p, PFUZE3000_VLDO2CTL, &reg);
186 reg &= ~0x0f;
187 reg |= PFUZE3000_VLDO_SETP(15000);
188 /* enable */
189 reg |= 0x10;
190 ret = pmic_reg_write(p, PFUZE3000_VLDO2CTL, reg);
191 if (ret)
192 return ret;
193
194 return 0;
195 }
196 #endif
197
198 static iomux_v3_cfg_t const uart1_pads[] = {
199 MX6_PAD_GPIO1_IO04__UART1_TX | MUX_PAD_CTRL(UART_PAD_CTRL),
200 MX6_PAD_GPIO1_IO05__UART1_RX | MUX_PAD_CTRL(UART_PAD_CTRL),
201 };
202
203 static iomux_v3_cfg_t const usdhc2_pads[] = {
204 MX6_PAD_SD2_CLK__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL),
205 MX6_PAD_SD2_CMD__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL),
206 MX6_PAD_SD2_DATA0__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
207 MX6_PAD_SD2_DATA1__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
208 MX6_PAD_SD2_DATA2__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
209 MX6_PAD_SD2_DATA3__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
210 /* CD pin */
211 MX6_PAD_SD1_DATA0__GPIO6_IO_2 | MUX_PAD_CTRL(NO_PAD_CTRL),
212 /* Power */
213 MX6_PAD_SD1_CMD__GPIO6_IO_1 | MUX_PAD_CTRL(NO_PAD_CTRL),
214 };
215
216 static iomux_v3_cfg_t const board_recognition_pads[] = {
217 /*Connected to R184*/
218 MX6_PAD_NAND_READY_B__GPIO4_IO_13 | BOARD_DETECT_PAD_CFG,
219 /*Connected to R185*/
220 MX6_PAD_NAND_ALE__GPIO4_IO_0 | BOARD_DETECT_PAD_CFG,
221 };
222
223 static iomux_v3_cfg_t const wdog_b_pad = {
224 MX6_PAD_GPIO1_IO13__GPIO1_IO_13 | MUX_PAD_CTRL(WDOG_PAD_CTRL),
225 };
226
227 static iomux_v3_cfg_t const peri_3v3_pads[] = {
228 MX6_PAD_QSPI1A_DATA0__GPIO4_IO_16 | MUX_PAD_CTRL(NO_PAD_CTRL),
229 };
230
231 static void setup_iomux_uart(void)
232 {
233 imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
234 }
235
236 int board_init(void)
237 {
238 /* Address of boot parameters */
239 gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
240
241 /*
242 * Because kernel set WDOG_B mux before pad with the commone pinctrl
243 * framwork now and wdog reset will be triggered once set WDOG_B mux
244 * with default pad setting, we set pad setting here to workaround this.
245 * Since imx_iomux_v3_setup_pad also set mux before pad setting, we set
246 * as GPIO mux firstly here to workaround it.
247 */
248 imx_iomux_v3_setup_pad(wdog_b_pad);
249
250 /* Enable PERI_3V3, which is used by SD2, ENET, LVDS, BT */
251 imx_iomux_v3_setup_multiple_pads(peri_3v3_pads,
252 ARRAY_SIZE(peri_3v3_pads));
253
254 /* Active high for ncp692 */
255 gpio_direction_output(IMX_GPIO_NR(4, 16) , 1);
256
257 #ifdef CONFIG_SYS_I2C_MXC
258 setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
259 #endif
260
261 return 0;
262 }
263
264 static int get_board_value(void)
265 {
266 int r184, r185;
267
268 imx_iomux_v3_setup_multiple_pads(board_recognition_pads,
269 ARRAY_SIZE(board_recognition_pads));
270
271 gpio_direction_input(IMX_GPIO_NR(4, 13));
272 gpio_direction_input(IMX_GPIO_NR(4, 0));
273
274 r184 = gpio_get_value(IMX_GPIO_NR(4, 13));
275 r185 = gpio_get_value(IMX_GPIO_NR(4, 0));
276
277 /*
278 * Machine selection -
279 * Machine r184, r185
280 * ---------------------------------
281 * Basic 0 0
282 * Basic Ks 0 1
283 * Full 1 0
284 * Extended 1 1
285 */
286
287 return (r184 << 1) + r185;
288 }
289
290 int board_early_init_f(void)
291 {
292 setup_iomux_uart();
293
294 return 0;
295 }
296
297 static struct fsl_esdhc_cfg usdhc_cfg[2] = {
298 {USDHC2_BASE_ADDR, 0, 4},
299 {USDHC3_BASE_ADDR, 0, 4},
300 };
301
302 #define USDHC2_PWR_GPIO IMX_GPIO_NR(6, 1)
303 #define USDHC2_CD_GPIO IMX_GPIO_NR(6, 2)
304
305 int board_mmc_getcd(struct mmc *mmc)
306 {
307 return !gpio_get_value(USDHC2_CD_GPIO);
308 }
309
310 int board_mmc_init(bd_t *bis)
311 {
312 imx_iomux_v3_setup_multiple_pads(usdhc2_pads, ARRAY_SIZE(usdhc2_pads));
313 usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK);
314 usdhc_cfg[0].esdhc_base = USDHC2_BASE_ADDR;
315 gpio_direction_input(USDHC2_CD_GPIO);
316 gpio_direction_output(USDHC2_PWR_GPIO, 1);
317
318 gd->arch.sdhc_clk = usdhc_cfg[0].sdhc_clk;
319 return fsl_esdhc_initialize(bis, &usdhc_cfg[0]);
320 }
321
322 static char *board_string(void)
323 {
324 switch (get_board_value()) {
325 case UDOO_NEO_TYPE_BASIC:
326 return "BASIC";
327 case UDOO_NEO_TYPE_BASIC_KS:
328 return "BASICKS";
329 case UDOO_NEO_TYPE_FULL:
330 return "FULL";
331 case UDOO_NEO_TYPE_EXTENDED:
332 return "EXTENDED";
333 }
334 return "UNDEFINED";
335 }
336
337 int checkboard(void)
338 {
339 printf("Board: UDOO Neo %s\n", board_string());
340 return 0;
341 }
342
343 int board_late_init(void)
344 {
345 #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
346 setenv("board_name", board_string());
347 #endif
348
349 return 0;
350 }
351
352 #ifdef CONFIG_SPL_BUILD
353
354 #include <libfdt.h>
355 #include <asm/arch/mx6-ddr.h>
356
357 static const struct mx6sx_iomux_ddr_regs mx6_ddr_ioregs = {
358 .dram_dqm0 = 0x00000028,
359 .dram_dqm1 = 0x00000028,
360 .dram_dqm2 = 0x00000028,
361 .dram_dqm3 = 0x00000028,
362 .dram_ras = 0x00000020,
363 .dram_cas = 0x00000020,
364 .dram_odt0 = 0x00000020,
365 .dram_odt1 = 0x00000020,
366 .dram_sdba2 = 0x00000000,
367 .dram_sdcke0 = 0x00003000,
368 .dram_sdcke1 = 0x00003000,
369 .dram_sdclk_0 = 0x00000030,
370 .dram_sdqs0 = 0x00000028,
371 .dram_sdqs1 = 0x00000028,
372 .dram_sdqs2 = 0x00000028,
373 .dram_sdqs3 = 0x00000028,
374 .dram_reset = 0x00000020,
375 };
376
377 static const struct mx6sx_iomux_grp_regs mx6_grp_ioregs = {
378 .grp_addds = 0x00000020,
379 .grp_ddrmode_ctl = 0x00020000,
380 .grp_ddrpke = 0x00000000,
381 .grp_ddrmode = 0x00020000,
382 .grp_b0ds = 0x00000028,
383 .grp_b1ds = 0x00000028,
384 .grp_ctlds = 0x00000020,
385 .grp_ddr_type = 0x000c0000,
386 .grp_b2ds = 0x00000028,
387 .grp_b3ds = 0x00000028,
388 };
389
390 static const struct mx6_mmdc_calibration neo_mmcd_calib = {
391 .p0_mpwldectrl0 = 0x000E000B,
392 .p0_mpwldectrl1 = 0x000E0010,
393 .p0_mpdgctrl0 = 0x41600158,
394 .p0_mpdgctrl1 = 0x01500140,
395 .p0_mprddlctl = 0x3A383E3E,
396 .p0_mpwrdlctl = 0x3A383C38,
397 };
398
399 static const struct mx6_mmdc_calibration neo_basic_mmcd_calib = {
400 .p0_mpwldectrl0 = 0x001E0022,
401 .p0_mpwldectrl1 = 0x001C0019,
402 .p0_mpdgctrl0 = 0x41540150,
403 .p0_mpdgctrl1 = 0x01440138,
404 .p0_mprddlctl = 0x403E4644,
405 .p0_mpwrdlctl = 0x3C3A4038,
406 };
407
408 /* MT41K256M16 */
409 static struct mx6_ddr3_cfg neo_mem_ddr = {
410 .mem_speed = 1600,
411 .density = 4,
412 .width = 16,
413 .banks = 8,
414 .rowaddr = 15,
415 .coladdr = 10,
416 .pagesz = 2,
417 .trcd = 1375,
418 .trcmin = 4875,
419 .trasmin = 3500,
420 };
421
422 /* MT41K128M16 */
423 static struct mx6_ddr3_cfg neo_basic_mem_ddr = {
424 .mem_speed = 1600,
425 .density = 2,
426 .width = 16,
427 .banks = 8,
428 .rowaddr = 14,
429 .coladdr = 10,
430 .pagesz = 2,
431 .trcd = 1375,
432 .trcmin = 4875,
433 .trasmin = 3500,
434 };
435
436 static void ccgr_init(void)
437 {
438 struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
439
440 writel(0xFFFFFFFF, &ccm->CCGR0);
441 writel(0xFFFFFFFF, &ccm->CCGR1);
442 writel(0xFFFFFFFF, &ccm->CCGR2);
443 writel(0xFFFFFFFF, &ccm->CCGR3);
444 writel(0xFFFFFFFF, &ccm->CCGR4);
445 writel(0xFFFFFFFF, &ccm->CCGR5);
446 writel(0xFFFFFFFF, &ccm->CCGR6);
447 writel(0xFFFFFFFF, &ccm->CCGR7);
448 }
449
450 static void spl_dram_init(void)
451 {
452 int board = get_board_value();
453
454 struct mx6_ddr_sysinfo sysinfo = {
455 .dsize = 1, /* width of data bus: 1 = 32 bits */
456 .cs_density = 24,
457 .ncs = 1,
458 .cs1_mirror = 0,
459 .rtt_wr = 2,
460 .rtt_nom = 2, /* RTT_Nom = RZQ/2 */
461 .walat = 1, /* Write additional latency */
462 .ralat = 5, /* Read additional latency */
463 .mif3_mode = 3, /* Command prediction working mode */
464 .bi_on = 1, /* Bank interleaving enabled */
465 .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */
466 .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */
467 };
468
469 mx6sx_dram_iocfg(32, &mx6_ddr_ioregs, &mx6_grp_ioregs);
470 if (board == UDOO_NEO_TYPE_BASIC || board == UDOO_NEO_TYPE_BASIC_KS)
471 mx6_dram_cfg(&sysinfo, &neo_basic_mmcd_calib,
472 &neo_basic_mem_ddr);
473 else
474 mx6_dram_cfg(&sysinfo, &neo_mmcd_calib, &neo_mem_ddr);
475 }
476
477 void board_init_f(ulong dummy)
478 {
479 ccgr_init();
480
481 /* setup AIPS and disable watchdog */
482 arch_cpu_init();
483
484 board_early_init_f();
485
486 /* setup GP timer */
487 timer_init();
488
489 /* UART clocks enabled and gd valid - init serial console */
490 preloader_console_init();
491
492 /* DDR initialization */
493 spl_dram_init();
494
495 /* Clear the BSS. */
496 memset(__bss_start, 0, __bss_end - __bss_start);
497
498 /* load/boot image from boot device */
499 board_init_r(NULL, 0);
500 }
501
502 #endif