hikey960.c 3.9 KB

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