spl_boot.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. /*
  2. * Freescale i.MX28 Boot setup
  3. *
  4. * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
  5. * on behalf of DENX Software Engineering GmbH
  6. *
  7. * See file CREDITS for list of people who contributed to this
  8. * project.
  9. *
  10. * This program is free software; you can redistribute it and/or
  11. * modify it under the terms of the GNU General Public License as
  12. * published by the Free Software Foundation; either version 2 of
  13. * the License, or (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  23. * MA 02111-1307 USA
  24. */
  25. #include <common.h>
  26. #include <config.h>
  27. #include <asm/io.h>
  28. #include <asm/arch/iomux-mx28.h>
  29. #include <asm/arch/imx-regs.h>
  30. #include <asm/arch/sys_proto.h>
  31. #include <asm/gpio.h>
  32. #include "mx28_init.h"
  33. /*
  34. * This delay function is intended to be used only in early stage of boot, where
  35. * clock are not set up yet. The timer used here is reset on every boot and
  36. * takes a few seconds to roll. The boot doesn't take that long, so to keep the
  37. * code simple, it doesn't take rolling into consideration.
  38. */
  39. #define HW_DIGCTRL_MICROSECONDS 0x8001c0c0
  40. void early_delay(int delay)
  41. {
  42. uint32_t st = readl(HW_DIGCTRL_MICROSECONDS);
  43. st += delay;
  44. while (st > readl(HW_DIGCTRL_MICROSECONDS))
  45. ;
  46. }
  47. #define MUX_CONFIG_BOOTMODE_PAD (MXS_PAD_3V3 | MXS_PAD_4MA | MXS_PAD_NOPULL)
  48. const iomux_cfg_t iomux_boot[] = {
  49. MX28_PAD_LCD_D00__GPIO_1_0 | MUX_CONFIG_BOOTMODE_PAD,
  50. MX28_PAD_LCD_D01__GPIO_1_1 | MUX_CONFIG_BOOTMODE_PAD,
  51. MX28_PAD_LCD_D02__GPIO_1_2 | MUX_CONFIG_BOOTMODE_PAD,
  52. MX28_PAD_LCD_D03__GPIO_1_3 | MUX_CONFIG_BOOTMODE_PAD,
  53. MX28_PAD_LCD_D04__GPIO_1_4 | MUX_CONFIG_BOOTMODE_PAD,
  54. MX28_PAD_LCD_D05__GPIO_1_5 | MUX_CONFIG_BOOTMODE_PAD,
  55. };
  56. uint8_t mx28_get_bootmode_index(void)
  57. {
  58. uint8_t bootmode = 0;
  59. int i;
  60. uint8_t masked;
  61. /* Setup IOMUX of bootmode pads to GPIO */
  62. mxs_iomux_setup_multiple_pads(iomux_boot, ARRAY_SIZE(iomux_boot));
  63. /* Setup bootmode pins as GPIO input */
  64. gpio_direction_input(MX28_PAD_LCD_D00__GPIO_1_0);
  65. gpio_direction_input(MX28_PAD_LCD_D01__GPIO_1_1);
  66. gpio_direction_input(MX28_PAD_LCD_D02__GPIO_1_2);
  67. gpio_direction_input(MX28_PAD_LCD_D03__GPIO_1_3);
  68. gpio_direction_input(MX28_PAD_LCD_D04__GPIO_1_4);
  69. gpio_direction_input(MX28_PAD_LCD_D05__GPIO_1_5);
  70. /* Read bootmode pads */
  71. bootmode |= (gpio_get_value(MX28_PAD_LCD_D00__GPIO_1_0) ? 1 : 0) << 0;
  72. bootmode |= (gpio_get_value(MX28_PAD_LCD_D01__GPIO_1_1) ? 1 : 0) << 1;
  73. bootmode |= (gpio_get_value(MX28_PAD_LCD_D02__GPIO_1_2) ? 1 : 0) << 2;
  74. bootmode |= (gpio_get_value(MX28_PAD_LCD_D03__GPIO_1_3) ? 1 : 0) << 3;
  75. bootmode |= (gpio_get_value(MX28_PAD_LCD_D04__GPIO_1_4) ? 1 : 0) << 4;
  76. bootmode |= (gpio_get_value(MX28_PAD_LCD_D05__GPIO_1_5) ? 1 : 0) << 5;
  77. for (i = 0; i < ARRAY_SIZE(mx28_boot_modes); i++) {
  78. masked = bootmode & mx28_boot_modes[i].boot_mask;
  79. if (masked == mx28_boot_modes[i].boot_pads)
  80. break;
  81. }
  82. return i;
  83. }
  84. void mx28_common_spl_init(const iomux_cfg_t *iomux_setup,
  85. const unsigned int iomux_size)
  86. {
  87. struct mx28_spl_data *data = (struct mx28_spl_data *)
  88. ((CONFIG_SYS_TEXT_BASE - sizeof(struct mx28_spl_data)) & ~0xf);
  89. uint8_t bootmode = mx28_get_bootmode_index();
  90. mxs_iomux_setup_multiple_pads(iomux_setup, iomux_size);
  91. mx28_power_init();
  92. mx28_mem_init();
  93. data->mem_dram_size = mx28_mem_get_size();
  94. data->boot_mode_idx = bootmode;
  95. mx28_power_wait_pswitch();
  96. }
  97. /* Support aparatus */
  98. inline void board_init_f(unsigned long bootflag)
  99. {
  100. for (;;)
  101. ;
  102. }
  103. inline void board_init_r(gd_t *id, ulong dest_addr)
  104. {
  105. for (;;)
  106. ;
  107. }
  108. #ifndef CONFIG_SPL_SERIAL_SUPPORT
  109. void serial_putc(const char c) {}
  110. void serial_puts(const char *s) {}
  111. #endif
  112. void hang(void) __attribute__ ((noreturn));
  113. void hang(void)
  114. {
  115. for (;;)
  116. ;
  117. }