]> git.sur5r.net Git - u-boot/blob - board/freescale/mx6qsabrelite/mx6qsabrelite.c
Merge branch 'master' of git://git.denx.de/u-boot-i2c
[u-boot] / board / freescale / mx6qsabrelite / mx6qsabrelite.c
1 /*
2  * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License as
9  * published by the Free Software Foundation; either version 2 of
10  * the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20  * MA 02111-1307 USA
21  */
22
23 #include <common.h>
24 #include <asm/io.h>
25 #include <asm/arch/clock.h>
26 #include <asm/arch/imx-regs.h>
27 #include <asm/arch/mx6x_pins.h>
28 #include <asm/errno.h>
29 #include <asm/gpio.h>
30 #include <asm/imx-common/iomux-v3.h>
31 #include <asm/imx-common/mxc_i2c.h>
32 #include <mmc.h>
33 #include <fsl_esdhc.h>
34 #include <micrel.h>
35 #include <miiphy.h>
36 #include <netdev.h>
37 DECLARE_GLOBAL_DATA_PTR;
38
39 #define UART_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |            \
40        PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
41        PAD_CTL_DSE_40ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
42
43 #define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |            \
44        PAD_CTL_PUS_47K_UP  | PAD_CTL_SPEED_LOW |               \
45        PAD_CTL_DSE_80ohm   | PAD_CTL_SRE_FAST  | PAD_CTL_HYS)
46
47 #define ENET_PAD_CTRL  (PAD_CTL_PKE | PAD_CTL_PUE |             \
48         PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |             \
49         PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
50
51 #define SPI_PAD_CTRL (PAD_CTL_HYS |                             \
52         PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED |             \
53         PAD_CTL_DSE_40ohm     | PAD_CTL_SRE_FAST)
54
55 #define BUTTON_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE |            \
56         PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED   |             \
57         PAD_CTL_DSE_40ohm   | PAD_CTL_HYS)
58
59 #define I2C_PAD_CTRL    (PAD_CTL_PKE | PAD_CTL_PUE |            \
60         PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED |               \
61         PAD_CTL_DSE_40ohm | PAD_CTL_HYS |                       \
62         PAD_CTL_ODE | PAD_CTL_SRE_FAST)
63
64 int dram_init(void)
65 {
66        gd->ram_size = get_ram_size((void *)PHYS_SDRAM, PHYS_SDRAM_SIZE);
67
68        return 0;
69 }
70
71 iomux_v3_cfg_t uart1_pads[] = {
72         MX6Q_PAD_SD3_DAT6__UART1_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
73         MX6Q_PAD_SD3_DAT7__UART1_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
74 };
75
76 iomux_v3_cfg_t uart2_pads[] = {
77        MX6Q_PAD_EIM_D26__UART2_TXD | MUX_PAD_CTRL(UART_PAD_CTRL),
78        MX6Q_PAD_EIM_D27__UART2_RXD | MUX_PAD_CTRL(UART_PAD_CTRL),
79 };
80
81 #define PC MUX_PAD_CTRL(I2C_PAD_CTRL)
82
83 /* I2C1, SGTL5000 */
84 struct i2c_pads_info i2c_pad_info0 = {
85         .scl = {
86                 .i2c_mode = MX6Q_PAD_EIM_D21__I2C1_SCL | PC,
87                 .gpio_mode = MX6Q_PAD_EIM_D21__GPIO_3_21 | PC,
88                 .gp = GPIO_NUMBER(3, 21)
89         },
90         .sda = {
91                 .i2c_mode = MX6Q_PAD_EIM_D28__I2C1_SDA | PC,
92                 .gpio_mode = MX6Q_PAD_EIM_D28__GPIO_3_28 | PC,
93                 .gp = GPIO_NUMBER(3, 28)
94         }
95 };
96
97 /* I2C2 Camera, MIPI */
98 struct i2c_pads_info i2c_pad_info1 = {
99         .scl = {
100                 .i2c_mode = MX6Q_PAD_KEY_COL3__I2C2_SCL | PC,
101                 .gpio_mode = MX6Q_PAD_KEY_COL3__GPIO_4_12 | PC,
102                 .gp = GPIO_NUMBER(4, 12)
103         },
104         .sda = {
105                 .i2c_mode = MX6Q_PAD_KEY_ROW3__I2C2_SDA | PC,
106                 .gpio_mode = MX6Q_PAD_KEY_ROW3__GPIO_4_13 | PC,
107                 .gp = GPIO_NUMBER(4, 13)
108         }
109 };
110
111 /* I2C3, J15 - RGB connector */
112 struct i2c_pads_info i2c_pad_info2 = {
113         .scl = {
114                 .i2c_mode = MX6Q_PAD_GPIO_5__I2C3_SCL | PC,
115                 .gpio_mode = MX6Q_PAD_GPIO_5__GPIO_1_5 | PC,
116                 .gp = GPIO_NUMBER(1, 5)
117         },
118         .sda = {
119                 .i2c_mode = MX6Q_PAD_GPIO_16__I2C3_SDA | PC,
120                 .gpio_mode = MX6Q_PAD_GPIO_16__GPIO_7_11 | PC,
121                 .gp = GPIO_NUMBER(7, 11)
122         }
123 };
124
125 iomux_v3_cfg_t usdhc3_pads[] = {
126        MX6Q_PAD_SD3_CLK__USDHC3_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
127        MX6Q_PAD_SD3_CMD__USDHC3_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
128        MX6Q_PAD_SD3_DAT0__USDHC3_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
129        MX6Q_PAD_SD3_DAT1__USDHC3_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
130        MX6Q_PAD_SD3_DAT2__USDHC3_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
131        MX6Q_PAD_SD3_DAT3__USDHC3_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
132        MX6Q_PAD_SD3_DAT5__GPIO_7_0    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
133 };
134
135 iomux_v3_cfg_t usdhc4_pads[] = {
136        MX6Q_PAD_SD4_CLK__USDHC4_CLK   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
137        MX6Q_PAD_SD4_CMD__USDHC4_CMD   | MUX_PAD_CTRL(USDHC_PAD_CTRL),
138        MX6Q_PAD_SD4_DAT0__USDHC4_DAT0 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
139        MX6Q_PAD_SD4_DAT1__USDHC4_DAT1 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
140        MX6Q_PAD_SD4_DAT2__USDHC4_DAT2 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
141        MX6Q_PAD_SD4_DAT3__USDHC4_DAT3 | MUX_PAD_CTRL(USDHC_PAD_CTRL),
142        MX6Q_PAD_NANDF_D6__GPIO_2_6    | MUX_PAD_CTRL(NO_PAD_CTRL), /* CD */
143 };
144
145 iomux_v3_cfg_t enet_pads1[] = {
146         MX6Q_PAD_ENET_MDIO__ENET_MDIO           | MUX_PAD_CTRL(ENET_PAD_CTRL),
147         MX6Q_PAD_ENET_MDC__ENET_MDC             | MUX_PAD_CTRL(ENET_PAD_CTRL),
148         MX6Q_PAD_RGMII_TXC__ENET_RGMII_TXC      | MUX_PAD_CTRL(ENET_PAD_CTRL),
149         MX6Q_PAD_RGMII_TD0__ENET_RGMII_TD0      | MUX_PAD_CTRL(ENET_PAD_CTRL),
150         MX6Q_PAD_RGMII_TD1__ENET_RGMII_TD1      | MUX_PAD_CTRL(ENET_PAD_CTRL),
151         MX6Q_PAD_RGMII_TD2__ENET_RGMII_TD2      | MUX_PAD_CTRL(ENET_PAD_CTRL),
152         MX6Q_PAD_RGMII_TD3__ENET_RGMII_TD3      | MUX_PAD_CTRL(ENET_PAD_CTRL),
153         MX6Q_PAD_RGMII_TX_CTL__RGMII_TX_CTL     | MUX_PAD_CTRL(ENET_PAD_CTRL),
154         MX6Q_PAD_ENET_REF_CLK__ENET_TX_CLK      | MUX_PAD_CTRL(ENET_PAD_CTRL),
155         /* pin 35 - 1 (PHY_AD2) on reset */
156         MX6Q_PAD_RGMII_RXC__GPIO_6_30           | MUX_PAD_CTRL(NO_PAD_CTRL),
157         /* pin 32 - 1 - (MODE0) all */
158         MX6Q_PAD_RGMII_RD0__GPIO_6_25           | MUX_PAD_CTRL(NO_PAD_CTRL),
159         /* pin 31 - 1 - (MODE1) all */
160         MX6Q_PAD_RGMII_RD1__GPIO_6_27           | MUX_PAD_CTRL(NO_PAD_CTRL),
161         /* pin 28 - 1 - (MODE2) all */
162         MX6Q_PAD_RGMII_RD2__GPIO_6_28           | MUX_PAD_CTRL(NO_PAD_CTRL),
163         /* pin 27 - 1 - (MODE3) all */
164         MX6Q_PAD_RGMII_RD3__GPIO_6_29           | MUX_PAD_CTRL(NO_PAD_CTRL),
165         /* pin 33 - 1 - (CLK125_EN) 125Mhz clockout enabled */
166         MX6Q_PAD_RGMII_RX_CTL__GPIO_6_24        | MUX_PAD_CTRL(NO_PAD_CTRL),
167         /* pin 42 PHY nRST */
168         MX6Q_PAD_EIM_D23__GPIO_3_23             | MUX_PAD_CTRL(NO_PAD_CTRL),
169 };
170
171 iomux_v3_cfg_t enet_pads2[] = {
172         MX6Q_PAD_RGMII_RXC__ENET_RGMII_RXC      | MUX_PAD_CTRL(ENET_PAD_CTRL),
173         MX6Q_PAD_RGMII_RD0__ENET_RGMII_RD0      | MUX_PAD_CTRL(ENET_PAD_CTRL),
174         MX6Q_PAD_RGMII_RD1__ENET_RGMII_RD1      | MUX_PAD_CTRL(ENET_PAD_CTRL),
175         MX6Q_PAD_RGMII_RD2__ENET_RGMII_RD2      | MUX_PAD_CTRL(ENET_PAD_CTRL),
176         MX6Q_PAD_RGMII_RD3__ENET_RGMII_RD3      | MUX_PAD_CTRL(ENET_PAD_CTRL),
177         MX6Q_PAD_RGMII_RX_CTL__RGMII_RX_CTL     | MUX_PAD_CTRL(ENET_PAD_CTRL),
178 };
179
180 /* Button assignments for J14 */
181 static iomux_v3_cfg_t button_pads[] = {
182         /* Menu */
183         MX6Q_PAD_NANDF_D1__GPIO_2_1     | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
184         /* Back */
185         MX6Q_PAD_NANDF_D2__GPIO_2_2     | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
186         /* Labelled Search (mapped to Power under Android) */
187         MX6Q_PAD_NANDF_D3__GPIO_2_3     | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
188         /* Home */
189         MX6Q_PAD_NANDF_D4__GPIO_2_4     | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
190         /* Volume Down */
191         MX6Q_PAD_GPIO_19__GPIO_4_5      | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
192         /* Volume Up */
193         MX6Q_PAD_GPIO_18__GPIO_7_13     | MUX_PAD_CTRL(BUTTON_PAD_CTRL),
194 };
195
196 static void setup_iomux_enet(void)
197 {
198         gpio_direction_output(87, 0);  /* GPIO 3-23 */
199         gpio_direction_output(190, 1); /* GPIO 6-30 */
200         gpio_direction_output(185, 1); /* GPIO 6-25 */
201         gpio_direction_output(187, 1); /* GPIO 6-27 */
202         gpio_direction_output(188, 1); /* GPIO 6-28*/
203         gpio_direction_output(189, 1); /* GPIO 6-29 */
204         imx_iomux_v3_setup_multiple_pads(enet_pads1, ARRAY_SIZE(enet_pads1));
205         gpio_direction_output(184, 1); /* GPIO 6-24 */
206
207         /* Need delay 10ms according to KSZ9021 spec */
208         udelay(1000 * 10);
209         gpio_set_value(87, 1);  /* GPIO 3-23 */
210
211         imx_iomux_v3_setup_multiple_pads(enet_pads2, ARRAY_SIZE(enet_pads2));
212 }
213
214 iomux_v3_cfg_t usb_pads[] = {
215         MX6Q_PAD_GPIO_17__GPIO_7_12 | MUX_PAD_CTRL(NO_PAD_CTRL),
216 };
217
218 static void setup_iomux_uart(void)
219 {
220         imx_iomux_v3_setup_multiple_pads(uart1_pads, ARRAY_SIZE(uart1_pads));
221        imx_iomux_v3_setup_multiple_pads(uart2_pads, ARRAY_SIZE(uart2_pads));
222 }
223
224 #ifdef CONFIG_USB_EHCI_MX6
225 int board_ehci_hcd_init(int port)
226 {
227         imx_iomux_v3_setup_multiple_pads(usb_pads, ARRAY_SIZE(usb_pads));
228
229         /* Reset USB hub */
230         gpio_direction_output(GPIO_NUMBER(7, 12), 0);
231         mdelay(2);
232         gpio_set_value(GPIO_NUMBER(7, 12), 1);
233
234         return 0;
235 }
236 #endif
237
238 #ifdef CONFIG_FSL_ESDHC
239 struct fsl_esdhc_cfg usdhc_cfg[2] = {
240        {USDHC3_BASE_ADDR, 1},
241        {USDHC4_BASE_ADDR, 1},
242 };
243
244 int board_mmc_getcd(struct mmc *mmc)
245 {
246        struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
247        int ret;
248
249        if (cfg->esdhc_base == USDHC3_BASE_ADDR) {
250                gpio_direction_input(192); /*GPIO7_0*/
251                ret = !gpio_get_value(192);
252        } else {
253                gpio_direction_input(38); /*GPIO2_6*/
254                ret = !gpio_get_value(38);
255        }
256
257        return ret;
258 }
259
260 int board_mmc_init(bd_t *bis)
261 {
262        s32 status = 0;
263        u32 index = 0;
264
265        for (index = 0; index < CONFIG_SYS_FSL_USDHC_NUM; ++index) {
266                switch (index) {
267                case 0:
268                        imx_iomux_v3_setup_multiple_pads(
269                                usdhc3_pads, ARRAY_SIZE(usdhc3_pads));
270                        break;
271                case 1:
272                        imx_iomux_v3_setup_multiple_pads(
273                                usdhc4_pads, ARRAY_SIZE(usdhc4_pads));
274                        break;
275                default:
276                        printf("Warning: you configured more USDHC controllers"
277                                "(%d) then supported by the board (%d)\n",
278                                index + 1, CONFIG_SYS_FSL_USDHC_NUM);
279                        return status;
280                }
281
282                status |= fsl_esdhc_initialize(bis, &usdhc_cfg[index]);
283        }
284
285        return status;
286 }
287 #endif
288
289 u32 get_board_rev(void)
290 {
291         return 0x63000 ;
292 }
293
294 #ifdef CONFIG_MXC_SPI
295 iomux_v3_cfg_t ecspi1_pads[] = {
296         /* SS1 */
297         MX6Q_PAD_EIM_D19__GPIO_3_19   | MUX_PAD_CTRL(SPI_PAD_CTRL),
298         MX6Q_PAD_EIM_D17__ECSPI1_MISO | MUX_PAD_CTRL(SPI_PAD_CTRL),
299         MX6Q_PAD_EIM_D18__ECSPI1_MOSI | MUX_PAD_CTRL(SPI_PAD_CTRL),
300         MX6Q_PAD_EIM_D16__ECSPI1_SCLK | MUX_PAD_CTRL(SPI_PAD_CTRL),
301 };
302
303 void setup_spi(void)
304 {
305         gpio_direction_output(CONFIG_SF_DEFAULT_CS, 1);
306         imx_iomux_v3_setup_multiple_pads(ecspi1_pads,
307                                          ARRAY_SIZE(ecspi1_pads));
308 }
309 #endif
310
311 int board_phy_config(struct phy_device *phydev)
312 {
313         /* min rx data delay */
314         ksz9021_phy_extended_write(phydev,
315                         MII_KSZ9021_EXT_RGMII_RX_DATA_SKEW, 0x0);
316         /* min tx data delay */
317         ksz9021_phy_extended_write(phydev,
318                         MII_KSZ9021_EXT_RGMII_TX_DATA_SKEW, 0x0);
319         /* max rx/tx clock delay, min rx/tx control */
320         ksz9021_phy_extended_write(phydev,
321                         MII_KSZ9021_EXT_RGMII_CLOCK_SKEW, 0xf0f0);
322         if (phydev->drv->config)
323                 phydev->drv->config(phydev);
324
325         return 0;
326 }
327
328 int board_eth_init(bd_t *bis)
329 {
330         int ret;
331
332         setup_iomux_enet();
333
334         ret = cpu_eth_init(bis);
335         if (ret)
336                 printf("FEC MXC: %s:failed\n", __func__);
337
338         return 0;
339 }
340
341 static void setup_buttons(void)
342 {
343         imx_iomux_v3_setup_multiple_pads(button_pads,
344                                          ARRAY_SIZE(button_pads));
345 }
346
347 #ifdef CONFIG_CMD_SATA
348
349 int setup_sata(void)
350 {
351         struct iomuxc_base_regs *const iomuxc_regs
352                 = (struct iomuxc_base_regs *) IOMUXC_BASE_ADDR;
353         int ret = enable_sata_clock();
354         if (ret)
355                 return ret;
356
357         clrsetbits_le32(&iomuxc_regs->gpr[13],
358                         IOMUXC_GPR13_SATA_MASK,
359                         IOMUXC_GPR13_SATA_PHY_8_RXEQ_3P0DB
360                         |IOMUXC_GPR13_SATA_PHY_7_SATA2M
361                         |IOMUXC_GPR13_SATA_SPEED_3G
362                         |(3<<IOMUXC_GPR13_SATA_PHY_6_SHIFT)
363                         |IOMUXC_GPR13_SATA_SATA_PHY_5_SS_DISABLED
364                         |IOMUXC_GPR13_SATA_SATA_PHY_4_ATTEN_9_16
365                         |IOMUXC_GPR13_SATA_PHY_3_TXBOOST_0P00_DB
366                         |IOMUXC_GPR13_SATA_PHY_2_TX_1P104V
367                         |IOMUXC_GPR13_SATA_PHY_1_SLOW);
368
369         return 0;
370 }
371 #endif
372
373 int board_early_init_f(void)
374 {
375         setup_iomux_uart();
376         setup_buttons();
377
378         return 0;
379 }
380
381 int board_init(void)
382 {
383        /* address of boot parameters */
384        gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
385
386 #ifdef CONFIG_MXC_SPI
387         setup_spi();
388 #endif
389         setup_i2c(0, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info0);
390         setup_i2c(1, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info1);
391         setup_i2c(2, CONFIG_SYS_I2C_SPEED, 0x7f, &i2c_pad_info2);
392
393 #ifdef CONFIG_CMD_SATA
394         setup_sata();
395 #endif
396
397        return 0;
398 }
399
400 int checkboard(void)
401 {
402        puts("Board: MX6Q-Sabre Lite\n");
403
404        return 0;
405 }
406
407 struct button_key {
408         char const      *name;
409         unsigned        gpnum;
410         char            ident;
411 };
412
413 static struct button_key const buttons[] = {
414         {"back",        GPIO_NUMBER(2, 2),      'B'},
415         {"home",        GPIO_NUMBER(2, 4),      'H'},
416         {"menu",        GPIO_NUMBER(2, 1),      'M'},
417         {"search",      GPIO_NUMBER(2, 3),      'S'},
418         {"volup",       GPIO_NUMBER(7, 13),     'V'},
419         {"voldown",     GPIO_NUMBER(4, 5),      'v'},
420 };
421
422 /*
423  * generate a null-terminated string containing the buttons pressed
424  * returns number of keys pressed
425  */
426 static int read_keys(char *buf)
427 {
428         int i, numpressed = 0;
429         for (i = 0; i < ARRAY_SIZE(buttons); i++) {
430                 if (!gpio_get_value(buttons[i].gpnum))
431                         buf[numpressed++] = buttons[i].ident;
432         }
433         buf[numpressed] = '\0';
434         return numpressed;
435 }
436
437 static int do_kbd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
438 {
439         char envvalue[ARRAY_SIZE(buttons)+1];
440         int numpressed = read_keys(envvalue);
441         setenv("keybd", envvalue);
442         return numpressed == 0;
443 }
444
445 U_BOOT_CMD(
446         kbd, 1, 1, do_kbd,
447         "Tests for keypresses, sets 'keybd' environment variable",
448         "Returns 0 (true) to shell if key is pressed."
449 );
450
451 #ifdef CONFIG_PREBOOT
452 static char const kbd_magic_prefix[] = "key_magic";
453 static char const kbd_command_prefix[] = "key_cmd";
454
455 static void preboot_keys(void)
456 {
457         int numpressed;
458         char keypress[ARRAY_SIZE(buttons)+1];
459         numpressed = read_keys(keypress);
460         if (numpressed) {
461                 char *kbd_magic_keys = getenv("magic_keys");
462                 char *suffix;
463                 /*
464                  * loop over all magic keys
465                  */
466                 for (suffix = kbd_magic_keys; *suffix; ++suffix) {
467                         char *keys;
468                         char magic[sizeof(kbd_magic_prefix) + 1];
469                         sprintf(magic, "%s%c", kbd_magic_prefix, *suffix);
470                         keys = getenv(magic);
471                         if (keys) {
472                                 if (!strcmp(keys, keypress))
473                                         break;
474                         }
475                 }
476                 if (*suffix) {
477                         char cmd_name[sizeof(kbd_command_prefix) + 1];
478                         char *cmd;
479                         sprintf(cmd_name, "%s%c", kbd_command_prefix, *suffix);
480                         cmd = getenv(cmd_name);
481                         if (cmd) {
482                                 setenv("preboot", cmd);
483                                 return;
484                         }
485                 }
486         }
487 }
488 #endif
489
490 int misc_init_r(void)
491 {
492 #ifdef CONFIG_PREBOOT
493         preboot_keys();
494 #endif
495         return 0;
496 }