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