hikey960.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * (C) Copyright 2019 Linaro
  4. * Author: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
  5. */
  6. #include <common.h>
  7. #include <cpu_func.h>
  8. #include <dm.h>
  9. #include <errno.h>
  10. #include <asm/cache.h>
  11. #include <init.h>
  12. #include <asm/io.h>
  13. #include <asm/arch/hi3660.h>
  14. #include <asm/armv8/mmu.h>
  15. #include <asm/psci.h>
  16. #include <linux/arm-smccc.h>
  17. #include <linux/delay.h>
  18. #include <linux/psci.h>
  19. #define PMIC_REG_TO_BUS_ADDR(x) (x << 2)
  20. #define PMIC_VSEL_MASK 0x7
  21. DECLARE_GLOBAL_DATA_PTR;
  22. #if !CONFIG_IS_ENABLED(OF_CONTROL)
  23. #include <dm/platform_data/serial_pl01x.h>
  24. static const struct pl01x_serial_plat serial_plat = {
  25. .base = HI3660_UART6_BASE,
  26. .type = TYPE_PL011,
  27. .clock = 19200000
  28. };
  29. U_BOOT_DEVICE(hikey960_serial0) = {
  30. .name = "serial_pl01x",
  31. .plat = &serial_plat,
  32. };
  33. #endif
  34. static struct mm_region hikey_mem_map[] = {
  35. {
  36. .virt = 0x0UL, /* DDR */
  37. .phys = 0x0UL,
  38. .size = 0xC0000000UL,
  39. .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) |
  40. PTE_BLOCK_INNER_SHARE
  41. }, {
  42. .virt = 0xE0000000UL, /* Peripheral block */
  43. .phys = 0xE0000000UL,
  44. .size = 0x20000000UL,
  45. .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
  46. PTE_BLOCK_NON_SHARE |
  47. PTE_BLOCK_PXN | PTE_BLOCK_UXN
  48. }, {
  49. /* List terminator */
  50. 0,
  51. }
  52. };
  53. struct mm_region *mem_map = hikey_mem_map;
  54. int board_early_init_f(void)
  55. {
  56. return 0;
  57. }
  58. int misc_init_r(void)
  59. {
  60. return 0;
  61. }
  62. int dram_init(void)
  63. {
  64. gd->ram_size = PHYS_SDRAM_1_SIZE;
  65. return 0;
  66. }
  67. int dram_init_banksize(void)
  68. {
  69. gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
  70. gd->bd->bi_dram[0].size = gd->ram_size;
  71. return 0;
  72. }
  73. void hikey960_sd_init(void)
  74. {
  75. u32 data;
  76. /* Enable FPLL0 */
  77. data = readl(SCTRL_SCFPLLCTRL0);
  78. data |= SCTRL_SCFPLLCTRL0_FPLL0_EN;
  79. writel(data, SCTRL_SCFPLLCTRL0);
  80. /* Configure LDO16 */
  81. data = readl(PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x79)) &
  82. PMIC_VSEL_MASK;
  83. data |= 6;
  84. writel(data, PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x79));
  85. data = readl(PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x78));
  86. data |= 2;
  87. writel(data, PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x78));
  88. udelay(100);
  89. /* Configure LDO9 */
  90. data = readl(PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x6b)) &
  91. PMIC_VSEL_MASK;
  92. data |= 5;
  93. writel(data, PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x6b));
  94. data = readl(PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x6a));
  95. data |= 2;
  96. writel(data, PMU_REG_BASE + PMIC_REG_TO_BUS_ADDR(0x6a));
  97. udelay(100);
  98. /* GPIO CD */
  99. writel(0, PINMUX4_SDDET);
  100. /* SD Pinconf */
  101. writel(15 << 4, PINCONF3_SDCLK);
  102. writel((1 << 0) | (8 << 4), PINCONF3_SDCMD);
  103. writel((1 << 0) | (8 << 4), PINCONF3_SDDATA0);
  104. writel((1 << 0) | (8 << 4), PINCONF3_SDDATA1);
  105. writel((1 << 0) | (8 << 4), PINCONF3_SDDATA2);
  106. writel((1 << 0) | (8 << 4), PINCONF3_SDDATA3);
  107. /* Set SD clock mux */
  108. do {
  109. data = readl(CRG_REG_BASE + 0xb8);
  110. data |= ((1 << 6) | (1 << 6 << 16) | (0 << 4) | (3 << 4 << 16));
  111. writel(data, CRG_REG_BASE + 0xb8);
  112. data = readl(CRG_REG_BASE + 0xb8);
  113. } while ((data & ((1 << 6) | (3 << 4))) != ((1 << 6) | (0 << 4)));
  114. /* Take SD out of reset */
  115. writel(1 << 18, CRG_PERRSTDIS4);
  116. do {
  117. data = readl(CRG_PERRSTSTAT4);
  118. } while ((data & (1 << 18)) == (1 << 18));
  119. /* Enable hclk_gate_sd */
  120. data = readl(CRG_REG_BASE + 0);
  121. data |= (1 << 30);
  122. writel(data, CRG_REG_BASE + 0);
  123. /* Enable clk_andgt_mmc */
  124. data = readl(CRG_REG_BASE + 0xf4);
  125. data |= ((1 << 3) | (1 << 3 << 16));
  126. writel(data, CRG_REG_BASE + 0xf4);
  127. /* Enable clk_gate_sd */
  128. data = readl(CRG_PEREN4);
  129. data |= (1 << 17);
  130. writel(data, CRG_PEREN4);
  131. do {
  132. data = readl(CRG_PERCLKEN4);
  133. } while ((data & (1 << 17)) != (1 << 17));
  134. }
  135. static void show_psci_version(void)
  136. {
  137. struct arm_smccc_res res;
  138. arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0, 0, 0, 0, 0, &res);
  139. printf("PSCI: v%ld.%ld\n",
  140. PSCI_VERSION_MAJOR(res.a0),
  141. PSCI_VERSION_MINOR(res.a0));
  142. }
  143. int board_init(void)
  144. {
  145. /* Init SD */
  146. hikey960_sd_init();
  147. show_psci_version();
  148. return 0;
  149. }
  150. void reset_cpu(ulong addr)
  151. {
  152. psci_system_reset();
  153. }