1 From a950701d418e2e103cdfcd2f5880816dc1c6e6ec Mon Sep 17 00:00:00 2001
2 From: Marek Vasut <marex@denx.de>
3 Date: Tue, 1 May 2012 11:09:45 +0000
4 Subject: [PATCH 47/56] i.MX28: Implement boot pads sampling and reporting
6 This patch implements code that samples i.MX28 boot pads and reports boot mode
9 Signed-off-by: Marek Vasut <marex@denx.de>
10 Cc: Detlev Zundel <dzu@denx.de>
11 Cc: Fabio Estevam <fabio.estevam@freescale.com>
12 Cc: Stefano Babic <sbabic@denx.de>
13 Cc: Wolfgang Denk <wd@denx.de>
15 arch/arm/cpu/arm926ejs/mx28/mx28.c | 4 +++
16 arch/arm/cpu/arm926ejs/mx28/spl_boot.c | 48 ++++++++++++++++++++++++++++
17 arch/arm/include/asm/arch-mx28/sys_proto.h | 26 +++++++++++++++
18 include/configs/m28evk.h | 1 +
19 include/configs/mx28evk.h | 1 +
20 5 files changed, 80 insertions(+)
22 diff --git a/arch/arm/cpu/arm926ejs/mx28/mx28.c b/arch/arm/cpu/arm926ejs/mx28/mx28.c
23 index 54a68e1..865dbb3 100644
24 --- a/arch/arm/cpu/arm926ejs/mx28/mx28.c
25 +++ b/arch/arm/cpu/arm926ejs/mx28/mx28.c
26 @@ -185,8 +185,12 @@ int arch_cpu_init(void)
27 #if defined(CONFIG_DISPLAY_CPUINFO)
28 int print_cpuinfo(void)
30 + struct mx28_spl_data *data = (struct mx28_spl_data *)
31 + ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
33 printf("Freescale i.MX28 family at %d MHz\n",
34 mxc_get_clock(MXC_ARM_CLK) / 1000000);
35 + printf("BOOT: %s\n", mx28_boot_modes[data->boot_mode_idx].mode);
39 diff --git a/arch/arm/cpu/arm926ejs/mx28/spl_boot.c b/arch/arm/cpu/arm926ejs/mx28/spl_boot.c
40 index 37e1eb7..c9b4566 100644
41 --- a/arch/arm/cpu/arm926ejs/mx28/spl_boot.c
42 +++ b/arch/arm/cpu/arm926ejs/mx28/spl_boot.c
44 #include <asm/arch/iomux-mx28.h>
45 #include <asm/arch/imx-regs.h>
46 #include <asm/arch/sys_proto.h>
47 +#include <asm/gpio.h>
49 #include "mx28_init.h"
51 @@ -47,11 +48,56 @@ void early_delay(int delay)
55 +#define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
56 +const iomux_cfg_t iomux_boot[] = {
57 + MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD,
58 + MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD,
59 + MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD,
60 + MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD,
61 + MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD,
62 + MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD,
65 +uint8_t mx28_get_bootmode_index(void)
67 + uint8_t bootmode = 0;
71 + /* Setup IOMUX of bootmode pads to GPIO */
72 + mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot));
74 + /* Setup bootmode pins as GPIO input */
75 + gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0);
76 + gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1);
77 + gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2);
78 + gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3);
79 + gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4);
80 + gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5);
82 + /* Read bootmode pads */
83 + bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0;
84 + bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1;
85 + bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2;
86 + bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3;
87 + bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4;
88 + bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5;
90 + for (i = 0; i < ARRAY_SIZE(mx28_boot_modes); i++) {
91 + masked = bootmode & mx28_boot_modes[i].boot_mask;
92 + if (masked == mx28_boot_modes[i].boot_pads)
99 void mx28_common_spl_init(const iomux_cfg_t *iomux_setup,
100 const unsigned int iomux_size)
102 struct mx28_spl_data *data = (struct mx28_spl_data *)
103 ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
104 + uint8_t bootmode = mx28_get_bootmode_index();
106 mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
108 @@ -59,6 +105,8 @@ void mx28_common_spl_init(const iomux_cfg_t *iomux_setup,
110 data->mem_dram_size = mx28_mem_get_size();
112 + data->boot_mode_idx = bootmode;
114 mx28_power_wait_pswitch();
117 diff --git a/arch/arm/include/asm/arch-mx28/sys_proto.h b/arch/arm/include/asm/arch-mx28/sys_proto.h
118 index 04f2e4d..e701c64 100644
119 --- a/arch/arm/include/asm/arch-mx28/sys_proto.h
120 +++ b/arch/arm/include/asm/arch-mx28/sys_proto.h
121 @@ -39,7 +39,33 @@ void mx28_common_spl_init(const iomux_cfg_t *iomux_setup,
122 const unsigned int iomux_size);
131 +static const struct mx28_pair mx28_boot_modes[] = {
132 + { 0x00, 0x0f, "USB #0" },
133 + { 0x01, 0x1f, "I2C #0, master, 3V3" },
134 + { 0x11, 0x1f, "I2C #0, master, 1V8" },
135 + { 0x02, 0x1f, "SSP SPI #2, master, 3V3 NOR" },
136 + { 0x12, 0x1f, "SSP SPI #2, master, 1V8 NOR" },
137 + { 0x03, 0x1f, "SSP SPI #3, master, 3V3 NOR" },
138 + { 0x13, 0x1f, "SSP SPI #3, master, 1V8 NOR" },
139 + { 0x04, 0x1f, "NAND, 3V3" },
140 + { 0x14, 0x1f, "NAND, 1V8" },
141 + { 0x08, 0x1f, "SSP SPI #3, master, 3V3 EEPROM" },
142 + { 0x18, 0x1f, "SSP SPI #3, master, 1V8 EEPROM" },
143 + { 0x09, 0x1f, "SSP SD/MMC #0, 3V3" },
144 + { 0x19, 0x1f, "SSP SD/MMC #0, 1V8" },
145 + { 0x0a, 0x1f, "SSP SD/MMC #1, 3V3" },
146 + { 0x1a, 0x1f, "SSP SD/MMC #1, 1V8" },
147 + { 0x00, 0x00, "Reserved/Unknown/Wrong" },
150 struct mx28_spl_data {
151 + uint8_t boot_mode_idx;
152 uint32_t mem_dram_size;
155 diff --git a/include/configs/m28evk.h b/include/configs/m28evk.h
156 index 60f8a6c..c62f4d0 100644
157 --- a/include/configs/m28evk.h
158 +++ b/include/configs/m28evk.h
160 #define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds"
161 #define CONFIG_SPL_LIBCOMMON_SUPPORT
162 #define CONFIG_SPL_LIBGENERIC_SUPPORT
163 +#define CONFIG_SPL_GPIO_SUPPORT
167 diff --git a/include/configs/mx28evk.h b/include/configs/mx28evk.h
168 index 5cd9730..0c18e50 100644
169 --- a/include/configs/mx28evk.h
170 +++ b/include/configs/mx28evk.h
172 #define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/arm926ejs/mx28/u-boot-spl.lds"
173 #define CONFIG_SPL_LIBCOMMON_SUPPORT
174 #define CONFIG_SPL_LIBGENERIC_SUPPORT
175 +#define CONFIG_SPL_GPIO_SUPPORT