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