1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * (C) Copyright 2015 Linaro 4 * Peter Griffin <peter.griffin@linaro.org> 5 */ 6 #include <common.h> 7 #include <dm.h> 8 #include <dm/platform_data/serial_pl01x.h> 9 #include <errno.h> 10 #include <malloc.h> 11 #include <netdev.h> 12 #include <asm/io.h> 13 #include <usb.h> 14 #include <power/hi6553_pmic.h> 15 #include <asm-generic/gpio.h> 16 #include <asm/arch/dwmmc.h> 17 #include <asm/arch/gpio.h> 18 #include <asm/arch/periph.h> 19 #include <asm/arch/pinmux.h> 20 #include <asm/arch/hi6220.h> 21 #include <asm/armv8/mmu.h> 22 23 /*TODO drop this table in favour of device tree */ 24 static const struct hikey_gpio_platdata hi6220_gpio[] = { 25 { 0, HI6220_GPIO_BASE(0)}, 26 { 1, HI6220_GPIO_BASE(1)}, 27 { 2, HI6220_GPIO_BASE(2)}, 28 { 3, HI6220_GPIO_BASE(3)}, 29 { 4, HI6220_GPIO_BASE(4)}, 30 { 5, HI6220_GPIO_BASE(5)}, 31 { 6, HI6220_GPIO_BASE(6)}, 32 { 7, HI6220_GPIO_BASE(7)}, 33 { 8, HI6220_GPIO_BASE(8)}, 34 { 9, HI6220_GPIO_BASE(9)}, 35 { 10, HI6220_GPIO_BASE(10)}, 36 { 11, HI6220_GPIO_BASE(11)}, 37 { 12, HI6220_GPIO_BASE(12)}, 38 { 13, HI6220_GPIO_BASE(13)}, 39 { 14, HI6220_GPIO_BASE(14)}, 40 { 15, HI6220_GPIO_BASE(15)}, 41 { 16, HI6220_GPIO_BASE(16)}, 42 { 17, HI6220_GPIO_BASE(17)}, 43 { 18, HI6220_GPIO_BASE(18)}, 44 { 19, HI6220_GPIO_BASE(19)}, 45 46 }; 47 48 U_BOOT_DEVICES(hi6220_gpios) = { 49 { "gpio_hi6220", &hi6220_gpio[0] }, 50 { "gpio_hi6220", &hi6220_gpio[1] }, 51 { "gpio_hi6220", &hi6220_gpio[2] }, 52 { "gpio_hi6220", &hi6220_gpio[3] }, 53 { "gpio_hi6220", &hi6220_gpio[4] }, 54 { "gpio_hi6220", &hi6220_gpio[5] }, 55 { "gpio_hi6220", &hi6220_gpio[6] }, 56 { "gpio_hi6220", &hi6220_gpio[7] }, 57 { "gpio_hi6220", &hi6220_gpio[8] }, 58 { "gpio_hi6220", &hi6220_gpio[9] }, 59 { "gpio_hi6220", &hi6220_gpio[10] }, 60 { "gpio_hi6220", &hi6220_gpio[11] }, 61 { "gpio_hi6220", &hi6220_gpio[12] }, 62 { "gpio_hi6220", &hi6220_gpio[13] }, 63 { "gpio_hi6220", &hi6220_gpio[14] }, 64 { "gpio_hi6220", &hi6220_gpio[15] }, 65 { "gpio_hi6220", &hi6220_gpio[16] }, 66 { "gpio_hi6220", &hi6220_gpio[17] }, 67 { "gpio_hi6220", &hi6220_gpio[18] }, 68 { "gpio_hi6220", &hi6220_gpio[19] }, 69 }; 70 71 DECLARE_GLOBAL_DATA_PTR; 72 73 #if !CONFIG_IS_ENABLED(OF_CONTROL) 74 75 static const struct pl01x_serial_platdata serial_platdata = { 76 #if CONFIG_CONS_INDEX == 1 77 .base = HI6220_UART0_BASE, 78 #elif CONFIG_CONS_INDEX == 4 79 .base = HI6220_UART3_BASE, 80 #else 81 #error "Unsupported console index value." 82 #endif 83 .type = TYPE_PL011, 84 .clock = 19200000 85 }; 86 87 U_BOOT_DEVICE(hikey_seriala) = { 88 .name = "serial_pl01x", 89 .platdata = &serial_platdata, 90 }; 91 #endif 92 93 static struct mm_region hikey_mem_map[] = { 94 { 95 .virt = 0x0UL, 96 .phys = 0x0UL, 97 .size = 0x80000000UL, 98 .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | 99 PTE_BLOCK_INNER_SHARE 100 }, { 101 .virt = 0x80000000UL, 102 .phys = 0x80000000UL, 103 .size = 0x80000000UL, 104 .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | 105 PTE_BLOCK_NON_SHARE | 106 PTE_BLOCK_PXN | PTE_BLOCK_UXN 107 }, { 108 /* List terminator */ 109 0, 110 } 111 }; 112 113 struct mm_region *mem_map = hikey_mem_map; 114 115 #ifdef CONFIG_BOARD_EARLY_INIT_F 116 int board_uart_init(void) 117 { 118 switch (CONFIG_CONS_INDEX) { 119 case 1: 120 hi6220_pinmux_config(PERIPH_ID_UART0); 121 break; 122 case 4: 123 hi6220_pinmux_config(PERIPH_ID_UART3); 124 break; 125 default: 126 debug("%s: Unsupported UART selected\n", __func__); 127 return -1; 128 } 129 130 return 0; 131 } 132 133 int board_early_init_f(void) 134 { 135 board_uart_init(); 136 return 0; 137 } 138 #endif 139 140 struct peri_sc_periph_regs *peri_sc = 141 (struct peri_sc_periph_regs *)HI6220_PERI_BASE; 142 143 struct alwayson_sc_regs *ao_sc = 144 (struct alwayson_sc_regs *)ALWAYSON_CTRL_BASE; 145 146 /* status offset from enable reg */ 147 #define STAT_EN_OFF 0x2 148 149 void hi6220_clk_enable(u32 bitfield, unsigned int *clk_base) 150 { 151 uint32_t data; 152 153 data = readl(clk_base); 154 data |= bitfield; 155 156 writel(bitfield, clk_base); 157 do { 158 data = readl(clk_base + STAT_EN_OFF); 159 } while ((data & bitfield) == 0); 160 } 161 162 /* status offset from disable reg */ 163 #define STAT_DIS_OFF 0x1 164 165 void hi6220_clk_disable(u32 bitfield, unsigned int *clk_base) 166 { 167 uint32_t data; 168 169 data = readl(clk_base); 170 data |= bitfield; 171 172 writel(data, clk_base); 173 do { 174 data = readl(clk_base + STAT_DIS_OFF); 175 } while (data & bitfield); 176 } 177 178 #define EYE_PATTERN 0x70533483 179 180 int board_usb_init(int index, enum usb_init_type init) 181 { 182 unsigned int data; 183 184 /* enable USB clock */ 185 hi6220_clk_enable(PERI_CLK0_USBOTG, &peri_sc->clk0_en); 186 187 /* take usb IPs out of reset */ 188 writel(PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY | 189 PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K, 190 &peri_sc->rst0_dis); 191 do { 192 data = readl(&peri_sc->rst0_stat); 193 data &= PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY | 194 PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K; 195 } while (data); 196 197 /*CTRL 5*/ 198 data = readl(&peri_sc->ctrl5); 199 data &= ~PERI_CTRL5_PICOPHY_BC_MODE; 200 data |= PERI_CTRL5_USBOTG_RES_SEL | PERI_CTRL5_PICOPHY_ACAENB; 201 data |= 0x300; 202 writel(data, &peri_sc->ctrl5); 203 204 /*CTRL 4*/ 205 206 /* configure USB PHY */ 207 data = readl(&peri_sc->ctrl4); 208 209 /* make PHY out of low power mode */ 210 data &= ~PERI_CTRL4_PICO_SIDDQ; 211 data &= ~PERI_CTRL4_PICO_OGDISABLE; 212 data |= PERI_CTRL4_PICO_VBUSVLDEXTSEL | PERI_CTRL4_PICO_VBUSVLDEXT; 213 writel(data, &peri_sc->ctrl4); 214 215 writel(EYE_PATTERN, &peri_sc->ctrl8); 216 217 mdelay(5); 218 return 0; 219 } 220 221 static int config_sd_carddetect(void) 222 { 223 int ret; 224 225 /* configure GPIO8 as nopull */ 226 writel(0, 0xf8001830); 227 228 gpio_request(8, "SD CD"); 229 230 gpio_direction_input(8); 231 ret = gpio_get_value(8); 232 233 if (!ret) { 234 printf("%s: SD card present\n", __func__); 235 return 1; 236 } 237 238 printf("%s: SD card not present\n", __func__); 239 return 0; 240 } 241 242 243 static void mmc1_init_pll(void) 244 { 245 uint32_t data; 246 247 /* select SYSPLL as the source of MMC1 */ 248 /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ 249 writel(1 << 11 | 1 << 27, &peri_sc->clk0_sel); 250 do { 251 data = readl(&peri_sc->clk0_sel); 252 } while (!(data & (1 << 11))); 253 254 /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ 255 writel(1 << 30, &peri_sc->clk0_sel); 256 do { 257 data = readl(&peri_sc->clk0_sel); 258 } while (data & (1 << 14)); 259 260 hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en); 261 262 hi6220_clk_enable(PERI_CLK12_MMC1_SRC, &peri_sc->clk12_en); 263 264 do { 265 /* 1.2GHz / 50 = 24MHz */ 266 writel(0x31 | (1 << 7), &peri_sc->clkcfg8bit2); 267 data = readl(&peri_sc->clkcfg8bit2); 268 } while ((data & 0x31) != 0x31); 269 } 270 271 static void mmc1_reset_clk(void) 272 { 273 unsigned int data; 274 275 /* disable mmc1 bus clock */ 276 hi6220_clk_disable(PERI_CLK0_MMC1, &peri_sc->clk0_dis); 277 278 /* enable mmc1 bus clock */ 279 hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en); 280 281 /* reset mmc1 clock domain */ 282 writel(PERI_RST0_MMC1, &peri_sc->rst0_en); 283 284 /* bypass mmc1 clock phase */ 285 data = readl(&peri_sc->ctrl2); 286 data |= 3 << 2; 287 writel(data, &peri_sc->ctrl2); 288 289 /* disable low power */ 290 data = readl(&peri_sc->ctrl13); 291 data |= 1 << 4; 292 writel(data, &peri_sc->ctrl13); 293 do { 294 data = readl(&peri_sc->rst0_stat); 295 } while (!(data & PERI_RST0_MMC1)); 296 297 /* unreset mmc1 clock domain */ 298 writel(PERI_RST0_MMC1, &peri_sc->rst0_dis); 299 do { 300 data = readl(&peri_sc->rst0_stat); 301 } while (data & PERI_RST0_MMC1); 302 } 303 304 static void mmc0_reset_clk(void) 305 { 306 unsigned int data; 307 308 /* disable mmc0 bus clock */ 309 hi6220_clk_disable(PERI_CLK0_MMC0, &peri_sc->clk0_dis); 310 311 /* enable mmc0 bus clock */ 312 hi6220_clk_enable(PERI_CLK0_MMC0, &peri_sc->clk0_en); 313 314 /* reset mmc0 clock domain */ 315 writel(PERI_RST0_MMC0, &peri_sc->rst0_en); 316 317 /* bypass mmc0 clock phase */ 318 data = readl(&peri_sc->ctrl2); 319 data |= 3; 320 writel(data, &peri_sc->ctrl2); 321 322 /* disable low power */ 323 data = readl(&peri_sc->ctrl13); 324 data |= 1 << 3; 325 writel(data, &peri_sc->ctrl13); 326 do { 327 data = readl(&peri_sc->rst0_stat); 328 } while (!(data & PERI_RST0_MMC0)); 329 330 /* unreset mmc0 clock domain */ 331 writel(PERI_RST0_MMC0, &peri_sc->rst0_dis); 332 do { 333 data = readl(&peri_sc->rst0_stat); 334 } while (data & PERI_RST0_MMC0); 335 } 336 337 338 /* PMU SSI is the IP that maps the external PMU hi6553 registers as IO */ 339 static void hi6220_pmussi_init(void) 340 { 341 uint32_t data; 342 343 /* Take PMUSSI out of reset */ 344 writel(ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N, 345 &ao_sc->rst4_dis); 346 do { 347 data = readl(&ao_sc->rst4_stat); 348 } while (data & ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N); 349 350 /* set PMU SSI clock latency for read operation */ 351 data = readl(&ao_sc->mcu_subsys_ctrl3); 352 data &= ~ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_MASK; 353 data |= ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_3; 354 writel(data, &ao_sc->mcu_subsys_ctrl3); 355 356 /* enable PMUSSI clock */ 357 data = ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_CCPU | 358 ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_MCU; 359 360 hi6220_clk_enable(data, &ao_sc->clk5_en); 361 362 /* Output high to PMIC on PWR_HOLD_GPIO0_0 */ 363 gpio_request(0, "PWR_HOLD_GPIO0_0"); 364 gpio_direction_output(0, 1); 365 } 366 367 int misc_init_r(void) 368 { 369 return 0; 370 } 371 372 int board_init(void) 373 { 374 return 0; 375 } 376 377 #ifdef CONFIG_MMC 378 379 static int init_dwmmc(void) 380 { 381 int ret = 0; 382 383 #ifdef CONFIG_MMC_DW 384 385 /* mmc0 pll is already configured by ATF */ 386 mmc0_reset_clk(); 387 ret = hi6220_pinmux_config(PERIPH_ID_SDMMC0); 388 if (ret) 389 printf("%s: Error configuring pinmux for eMMC (%d)\n" 390 , __func__, ret); 391 392 ret |= hi6220_dwmci_add_port(0, HI6220_MMC0_BASE, 8); 393 if (ret) 394 printf("%s: Error adding eMMC port (%d)\n", __func__, ret); 395 396 397 /* take mmc1 (sd slot) out of reset, configure clocks and pinmuxing */ 398 mmc1_init_pll(); 399 mmc1_reset_clk(); 400 401 ret |= hi6220_pinmux_config(PERIPH_ID_SDMMC1); 402 if (ret) 403 printf("%s: Error configuring pinmux for eMMC (%d)\n" 404 , __func__, ret); 405 406 config_sd_carddetect(); 407 408 ret |= hi6220_dwmci_add_port(1, HI6220_MMC1_BASE, 4); 409 if (ret) 410 printf("%s: Error adding SD port (%d)\n", __func__, ret); 411 412 #endif 413 return ret; 414 } 415 416 /* setup board specific PMIC */ 417 int power_init_board(void) 418 { 419 /* init the hi6220 pmussi ip */ 420 hi6220_pmussi_init(); 421 422 power_hi6553_init((u8 *)HI6220_PMUSSI_BASE); 423 424 return 0; 425 } 426 427 int board_mmc_init(bd_t *bis) 428 { 429 int ret; 430 431 /* add the eMMC and sd ports */ 432 ret = init_dwmmc(); 433 434 if (ret) 435 debug("init_dwmmc failed\n"); 436 437 return ret; 438 } 439 #endif 440 441 int dram_init(void) 442 { 443 gd->ram_size = PHYS_SDRAM_1_SIZE; 444 return 0; 445 } 446 447 int dram_init_banksize(void) 448 { 449 /* 450 * Reserve regions below from DT memory node (which gets generated 451 * by U-Boot from the dram banks in arch_fixup_fdt() before booting 452 * the kernel. This will then match the kernel hikey dts memory node. 453 * 454 * 0x05e0,0000 - 0x05ef,ffff: MCU firmware runtime using 455 * 0x05f0,1000 - 0x05f0,1fff: Reboot reason 456 * 0x06df,f000 - 0x06df,ffff: Mailbox message data 457 * 0x0740,f000 - 0x0740,ffff: MCU firmware section 458 * 0x21f0,0000 - 0x21ff,ffff: pstore/ramoops buffer 459 * 0x3e00,0000 - 0x3fff,ffff: OP-TEE 460 */ 461 462 gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 463 gd->bd->bi_dram[0].size = 0x05e00000; 464 465 gd->bd->bi_dram[1].start = 0x05f00000; 466 gd->bd->bi_dram[1].size = 0x00001000; 467 468 gd->bd->bi_dram[2].start = 0x05f02000; 469 gd->bd->bi_dram[2].size = 0x00efd000; 470 471 gd->bd->bi_dram[3].start = 0x06e00000; 472 gd->bd->bi_dram[3].size = 0x0060f000; 473 474 gd->bd->bi_dram[4].start = 0x07410000; 475 gd->bd->bi_dram[4].size = 0x1aaf0000; 476 477 gd->bd->bi_dram[5].start = 0x22000000; 478 gd->bd->bi_dram[5].size = 0x1c000000; 479 480 return 0; 481 } 482 483 void reset_cpu(ulong addr) 484 { 485 writel(0x48698284, &ao_sc->stat0); 486 wfi(); 487 } 488