2 * Freescale i.MX28 Boot setup
4 * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
5 * on behalf of DENX Software Engineering GmbH
7 * SPDX-License-Identifier: GPL-2.0+
13 #include <asm/arch/imx-regs.h>
14 #include <asm/arch/sys_proto.h>
20 * This delay function is intended to be used only in early stage of boot, where
21 * clock are not set up yet. The timer used here is reset on every boot and
22 * takes a few seconds to roll. The boot doesn't take that long, so to keep the
23 * code simple, it doesn't take rolling into consideration.
25 void early_delay(int delay
)
27 struct mxs_digctl_regs
*digctl_regs
=
28 (struct mxs_digctl_regs
*)MXS_DIGCTL_BASE
;
30 uint32_t st
= readl(&digctl_regs
->hw_digctl_microseconds
);
32 while (st
> readl(&digctl_regs
->hw_digctl_microseconds
))
36 #define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
37 static const iomux_cfg_t iomux_boot
[] = {
38 #if defined(CONFIG_MX23)
39 MX23_PAD_LCD_D00__GPIO_1_0
| MUX_CONFIG_BOOTMODE_PAD
,
40 MX23_PAD_LCD_D01__GPIO_1_1
| MUX_CONFIG_BOOTMODE_PAD
,
41 MX23_PAD_LCD_D02__GPIO_1_2
| MUX_CONFIG_BOOTMODE_PAD
,
42 MX23_PAD_LCD_D03__GPIO_1_3
| MUX_CONFIG_BOOTMODE_PAD
,
43 MX23_PAD_LCD_D04__GPIO_1_4
| MUX_CONFIG_BOOTMODE_PAD
,
44 MX23_PAD_LCD_D05__GPIO_1_5
| MUX_CONFIG_BOOTMODE_PAD
,
45 #elif defined(CONFIG_MX28)
46 MX28_PAD_LCD_D00__GPIO_1_0
| MUX_CONFIG_BOOTMODE_PAD
,
47 MX28_PAD_LCD_D01__GPIO_1_1
| MUX_CONFIG_BOOTMODE_PAD
,
48 MX28_PAD_LCD_D02__GPIO_1_2
| MUX_CONFIG_BOOTMODE_PAD
,
49 MX28_PAD_LCD_D03__GPIO_1_3
| MUX_CONFIG_BOOTMODE_PAD
,
50 MX28_PAD_LCD_D04__GPIO_1_4
| MUX_CONFIG_BOOTMODE_PAD
,
51 MX28_PAD_LCD_D05__GPIO_1_5
| MUX_CONFIG_BOOTMODE_PAD
,
55 static uint8_t mxs_get_bootmode_index(void)
61 /* Setup IOMUX of bootmode pads to GPIO */
62 mxs_iomux_setup_multiple_pads(iomux_boot
, ARRAY_SIZE(iomux_boot
));
64 #if defined(CONFIG_MX23)
65 /* Setup bootmode pins as GPIO input */
66 gpio_direction_input(MX23_PAD_LCD_D00__GPIO_1_0
);
67 gpio_direction_input(MX23_PAD_LCD_D01__GPIO_1_1
);
68 gpio_direction_input(MX23_PAD_LCD_D02__GPIO_1_2
);
69 gpio_direction_input(MX23_PAD_LCD_D03__GPIO_1_3
);
70 gpio_direction_input(MX23_PAD_LCD_D05__GPIO_1_5
);
72 /* Read bootmode pads */
73 bootmode
|= (gpio_get_value(MX23_PAD_LCD_D00__GPIO_1_0
) ? 1 : 0) << 0;
74 bootmode
|= (gpio_get_value(MX23_PAD_LCD_D01__GPIO_1_1
) ? 1 : 0) << 1;
75 bootmode
|= (gpio_get_value(MX23_PAD_LCD_D02__GPIO_1_2
) ? 1 : 0) << 2;
76 bootmode
|= (gpio_get_value(MX23_PAD_LCD_D03__GPIO_1_3
) ? 1 : 0) << 3;
77 bootmode
|= (gpio_get_value(MX23_PAD_LCD_D05__GPIO_1_5
) ? 1 : 0) << 5;
78 #elif defined(CONFIG_MX28)
79 /* Setup bootmode pins as GPIO input */
80 gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0
);
81 gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1
);
82 gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2
);
83 gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3
);
84 gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4
);
85 gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5
);
87 /* Read bootmode pads */
88 bootmode
|= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0
) ? 1 : 0) << 0;
89 bootmode
|= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1
) ? 1 : 0) << 1;
90 bootmode
|= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2
) ? 1 : 0) << 2;
91 bootmode
|= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3
) ? 1 : 0) << 3;
92 bootmode
|= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4
) ? 1 : 0) << 4;
93 bootmode
|= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5
) ? 1 : 0) << 5;
96 for (i
= 0; i
< ARRAY_SIZE(mxs_boot_modes
); i
++) {
97 masked
= bootmode
& mxs_boot_modes
[i
].boot_mask
;
98 if (masked
== mxs_boot_modes
[i
].boot_pads
)
105 void mxs_common_spl_init(const iomux_cfg_t
*iomux_setup
,
106 const unsigned int iomux_size
)
108 struct mxs_spl_data
*data
= (struct mxs_spl_data
*)
109 ((CONFIG_SYS_TEXT_BASE
- sizeof(struct mxs_spl_data
)) & ~0xf);
110 uint8_t bootmode
= mxs_get_bootmode_index();
112 mxs_iomux_setup_multiple_pads(iomux_setup
, iomux_size
);
116 data
->mem_dram_size
= mxs_mem_get_size();
118 data
->boot_mode_idx
= bootmode
;
120 mxs_power_wait_pswitch();
123 /* Support aparatus */
124 inline void board_init_f(unsigned long bootflag
)
130 inline void board_init_r(gd_t
*id
, ulong dest_addr
)