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