/board/exmeritus/hww1u1a/hww1u1a.c

https://gitlab.com/veo-labs/u-boot · C · 262 lines · 162 code · 49 blank · 51 comment · 17 complexity · 0f11a879a7abf32cb811f18612c2c211 MD5 · raw file

  1. /*
  2. * Copyright 2009-2011 eXMeritus, A Boeing Company
  3. * Copyright 2007-2009 Freescale Semiconductor, Inc.
  4. *
  5. * SPDX-License-Identifier: GPL-2.0+
  6. */
  7. #include <common.h>
  8. #include <command.h>
  9. #include <pci.h>
  10. #include <asm/processor.h>
  11. #include <asm/mmu.h>
  12. #include <asm/cache.h>
  13. #include <asm/immap_85xx.h>
  14. #include <asm/fsl_pci.h>
  15. #include <fsl_ddr_sdram.h>
  16. #include <asm/io.h>
  17. #include <miiphy.h>
  18. #include <libfdt.h>
  19. #include <linux/ctype.h>
  20. #include <fdt_support.h>
  21. #include <fsl_mdio.h>
  22. #include <tsec.h>
  23. #include <asm/fsl_law.h>
  24. #include <netdev.h>
  25. #include <malloc.h>
  26. #include <i2c.h>
  27. #include <pca953x.h>
  28. #include "gpios.h"
  29. DECLARE_GLOBAL_DATA_PTR;
  30. int checkboard(void)
  31. {
  32. unsigned int gpio_high = 0;
  33. unsigned int gpio_low = 0;
  34. unsigned int gpio_in = 0;
  35. unsigned int i;
  36. struct ccsr_ddr __iomem *ddr;
  37. puts("Board: HWW-1U-1A ");
  38. /*
  39. * First just figure out which CPU we're on, then use that to
  40. * configure the lists of other GPIOs to be programmed.
  41. */
  42. mpc85xx_gpio_set_in(GPIO_CPU_ID);
  43. if (hww1u1a_is_cpu_a()) {
  44. puts("CPU A\n");
  45. /* We want to turn on some LEDs */
  46. gpio_high |= GPIO_CPUA_CPU_READY;
  47. gpio_low |= GPIO_CPUA_DEBUG_LED1;
  48. gpio_low |= GPIO_CPUA_DEBUG_LED2;
  49. /* Disable the unused transmitters */
  50. gpio_low |= GPIO_CPUA_TDIS1A;
  51. gpio_high |= GPIO_CPUA_TDIS1B;
  52. gpio_low |= GPIO_CPUA_TDIS2A;
  53. gpio_high |= GPIO_CPUA_TDIS2B;
  54. } else {
  55. puts("CPU B\n");
  56. /* We want to turn on some LEDs */
  57. gpio_high |= GPIO_CPUB_CPU_READY;
  58. gpio_low |= GPIO_CPUB_DEBUG_LED1;
  59. gpio_low |= GPIO_CPUB_DEBUG_LED2;
  60. /* Enable the appropriate receivers */
  61. gpio_high |= GPIO_CPUB_RMUX_SEL0A;
  62. gpio_high |= GPIO_CPUB_RMUX_SEL0B;
  63. gpio_low |= GPIO_CPUB_RMUX_SEL1A;
  64. gpio_low |= GPIO_CPUB_RMUX_SEL1B;
  65. }
  66. /* These GPIOs are common */
  67. gpio_in |= IRQ_I2CINT | IRQ_FANINT | IRQ_DIMM_EVENT;
  68. gpio_low |= GPIO_RS422_RE;
  69. gpio_high |= GPIO_RS422_DE;
  70. /* Ok, now go ahead and program all of those in one go */
  71. mpc85xx_gpio_set(gpio_high|gpio_low|gpio_in,
  72. gpio_high|gpio_low,
  73. gpio_high);
  74. /*
  75. * If things have been taken out of reset early (for example, by one
  76. * of the BDI3000 debuggers), then we need to put them back in reset
  77. * and delay a while before we continue.
  78. */
  79. if (mpc85xx_gpio_get(GPIO_RESETS)) {
  80. ddr = (struct ccsr_ddr __iomem *)CONFIG_SYS_FSL_DDR_ADDR;
  81. puts("Debugger detected... extra device reset enabled!\n");
  82. /* Put stuff into reset and disable the DDR controller */
  83. mpc85xx_gpio_set_low(GPIO_RESETS);
  84. out_be32(&ddr->sdram_cfg, 0x00000000);
  85. puts(" Waiting 1 sec for reset...");
  86. for (i = 0; i < 10; i++) {
  87. udelay(100000);
  88. puts(".");
  89. }
  90. puts("\n");
  91. }
  92. /* Now bring everything back out of reset again */
  93. mpc85xx_gpio_set_high(GPIO_RESETS);
  94. return 0;
  95. }
  96. /*
  97. * This little shell function just returns whether or not it's CPU A.
  98. * It can be used to select the right device-tree when booting, etc.
  99. */
  100. int do_hww1u1a_test_cpu_a(cmd_tbl_t *cmdtp, int flag,
  101. int argc, char * const argv[])
  102. {
  103. if (argc > 1)
  104. cmd_usage(cmdtp);
  105. if (hww1u1a_is_cpu_a())
  106. return 0;
  107. else
  108. return 1;
  109. }
  110. U_BOOT_CMD(
  111. test_cpu_a, 1, 0, do_hww1u1a_test_cpu_a,
  112. "Test if this is CPU A (versus B) on the eXMeritus HWW-1U-1A board",
  113. ""
  114. );
  115. /* Create a prompt-like string: "uboot@HOSTNAME% " */
  116. #define PROMPT_PREFIX "uboot@exm"
  117. #define PROMPT_SUFFIX "% "
  118. /* This function returns a PS1 prompt based on the serial number */
  119. static char *hww1u1a_prompt;
  120. const char *hww1u1a_get_ps1(void)
  121. {
  122. unsigned long len, i, j;
  123. const char *serialnr;
  124. /* If our prompt was already set, just use that */
  125. if (hww1u1a_prompt)
  126. return hww1u1a_prompt;
  127. /* Use our serial number if present, otherwise a default */
  128. serialnr = getenv("serial#");
  129. if (!serialnr || !serialnr[0])
  130. serialnr = "999999-X";
  131. /*
  132. * We will turn the serial number into a hostname by:
  133. * (A) Delete all non-alphanumerics.
  134. * (B) Lowercase all letters.
  135. * (C) Prefix "exm".
  136. * (D) Suffix "a" for CPU A and "b" for CPU B.
  137. */
  138. for (i = 0, len = 0; serialnr[i]; i++) {
  139. if (isalnum(serialnr[i]))
  140. len++;
  141. }
  142. len += sizeof(PROMPT_PREFIX PROMPT_SUFFIX) + 1; /* Includes NUL */
  143. hww1u1a_prompt = malloc(len);
  144. if (!hww1u1a_prompt)
  145. return PROMPT_PREFIX "UNKNOWN(ENOMEM)" PROMPT_SUFFIX;
  146. /* Now actually fill it in */
  147. i = 0;
  148. /* Handle the prefix */
  149. for (j = 0; j < sizeof(PROMPT_PREFIX) - 1; j++)
  150. hww1u1a_prompt[i++] = PROMPT_PREFIX[j];
  151. /* Now the serial# part of the hostname */
  152. for (j = 0; serialnr[j]; j++)
  153. if (isalnum(serialnr[j]))
  154. hww1u1a_prompt[i++] = tolower(serialnr[j]);
  155. /* Now the CPU id ("a" or "b") */
  156. hww1u1a_prompt[i++] = hww1u1a_is_cpu_a() ? 'a' : 'b';
  157. /* Finally the suffix */
  158. for (j = 0; j < sizeof(PROMPT_SUFFIX); j++)
  159. hww1u1a_prompt[i++] = PROMPT_SUFFIX[j];
  160. /* This should all have added up, but just in case */
  161. hww1u1a_prompt[len - 1] = '\0';
  162. /* Now we're done */
  163. return hww1u1a_prompt;
  164. }
  165. void pci_init_board(void)
  166. {
  167. fsl_pcie_init_board(0);
  168. }
  169. int board_early_init_r(void)
  170. {
  171. const unsigned int flashbase = CONFIG_SYS_FLASH_BASE;
  172. const u8 flash_esel = find_tlb_idx((void *)flashbase, 1);
  173. /*
  174. * Remap bootflash region to caching-inhibited
  175. * so that flash can be erased properly.
  176. */
  177. /* Flush d-cache and invalidate i-cache of any FLASH data */
  178. flush_dcache();
  179. invalidate_icache();
  180. /* invalidate existing TLB entry for FLASH */
  181. disable_tlb(flash_esel);
  182. set_tlb(1, flashbase, CONFIG_SYS_FLASH_BASE_PHYS,
  183. MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G,
  184. 0, flash_esel, BOOKE_PAGESZ_256M, 1);
  185. return 0;
  186. }
  187. int board_eth_init(bd_t *bis)
  188. {
  189. struct tsec_info_struct tsec_info[4];
  190. struct fsl_pq_mdio_info mdio_info;
  191. SET_STD_TSEC_INFO(tsec_info[0], 1);
  192. SET_STD_TSEC_INFO(tsec_info[1], 2);
  193. SET_STD_TSEC_INFO(tsec_info[2], 3);
  194. if (hww1u1a_is_cpu_a())
  195. tsec_info[2].phyaddr = TSEC3_PHY_ADDR_CPUA;
  196. else
  197. tsec_info[2].phyaddr = TSEC3_PHY_ADDR_CPUB;
  198. mdio_info.regs = (struct tsec_mii_mng *)CONFIG_SYS_MDIO_BASE_ADDR;
  199. mdio_info.name = DEFAULT_MII_NAME;
  200. fsl_pq_mdio_init(bis, &mdio_info);
  201. tsec_eth_init(bis, tsec_info, 3);
  202. return pci_eth_init(bis);
  203. }
  204. void ft_board_setup(void *blob, bd_t *bd)
  205. {
  206. phys_addr_t base;
  207. phys_size_t size;
  208. ft_cpu_setup(blob, bd);
  209. base = getenv_bootm_low();
  210. size = getenv_bootm_size();
  211. fdt_fixup_memory(blob, (u64)base, (u64)size);
  212. FT_FSL_PCI_SETUP;
  213. }