1 /* 2 * (C) Copyright 2015 Linaro 3 * Peter Griffin <peter.griffin@linaro.org> 4 * 5 * SPDX-License-Identifier: GPL-2.0+ 6 */ 7 #include <common.h> 8 #include <dm.h> 9 #include <dm/platform_data/serial_pl01x.h> 10 #include <errno.h> 11 #include <malloc.h> 12 #include <netdev.h> 13 #include <asm/io.h> 14 #include <usb.h> 15 #include <power/hi6553_pmic.h> 16 #include <asm-generic/gpio.h> 17 #include <asm/arch/dwmmc.h> 18 #include <asm/arch/gpio.h> 19 #include <asm/arch/periph.h> 20 #include <asm/arch/pinmux.h> 21 #include <asm/arch/hi6220.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 static const struct pl01x_serial_platdata serial_platdata = { 74 #if CONFIG_CONS_INDEX == 1 75 .base = HI6220_UART0_BASE, 76 #elif CONFIG_CONS_INDEX == 4 77 .base = HI6220_UART3_BASE, 78 #else 79 #error "Unsuported console index value." 80 #endif 81 .type = TYPE_PL011, 82 .clock = 19200000 83 }; 84 85 U_BOOT_DEVICE(hikey_seriala) = { 86 .name = "serial_pl01x", 87 .platdata = &serial_platdata, 88 }; 89 90 #ifdef CONFIG_BOARD_EARLY_INIT_F 91 int board_uart_init(void) 92 { 93 switch (CONFIG_CONS_INDEX) { 94 case 1: 95 hi6220_pinmux_config(PERIPH_ID_UART0); 96 break; 97 case 4: 98 hi6220_pinmux_config(PERIPH_ID_UART3); 99 break; 100 default: 101 debug("%s: Unsupported UART selected\n", __func__); 102 return -1; 103 } 104 105 return 0; 106 } 107 108 int board_early_init_f(void) 109 { 110 board_uart_init(); 111 return 0; 112 } 113 #endif 114 115 struct peri_sc_periph_regs *peri_sc = 116 (struct peri_sc_periph_regs *)HI6220_PERI_BASE; 117 118 struct alwayson_sc_regs *ao_sc = 119 (struct alwayson_sc_regs *)ALWAYSON_CTRL_BASE; 120 121 /* status offset from enable reg */ 122 #define STAT_EN_OFF 0x2 123 124 void hi6220_clk_enable(u32 bitfield, unsigned int *clk_base) 125 { 126 uint32_t data; 127 128 data = readl(clk_base); 129 data |= bitfield; 130 131 writel(bitfield, clk_base); 132 do { 133 data = readl(clk_base + STAT_EN_OFF); 134 } while ((data & bitfield) == 0); 135 } 136 137 /* status offset from disable reg */ 138 #define STAT_DIS_OFF 0x1 139 140 void hi6220_clk_disable(u32 bitfield, unsigned int *clk_base) 141 { 142 uint32_t data; 143 144 data = readl(clk_base); 145 data |= bitfield; 146 147 writel(data, clk_base); 148 do { 149 data = readl(clk_base + STAT_DIS_OFF); 150 } while (data & bitfield); 151 } 152 153 #define EYE_PATTERN 0x70533483 154 155 int board_usb_init(int index, enum usb_init_type init) 156 { 157 unsigned int data; 158 159 /* enable USB clock */ 160 hi6220_clk_enable(PERI_CLK0_USBOTG, &peri_sc->clk0_en); 161 162 /* take usb IPs out of reset */ 163 writel(PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY | 164 PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K, 165 &peri_sc->rst0_dis); 166 do { 167 data = readl(&peri_sc->rst0_stat); 168 data &= PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY | 169 PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K; 170 } while (data); 171 172 /*CTRL 5*/ 173 data = readl(&peri_sc->ctrl5); 174 data &= ~PERI_CTRL5_PICOPHY_BC_MODE; 175 data |= PERI_CTRL5_USBOTG_RES_SEL | PERI_CTRL5_PICOPHY_ACAENB; 176 data |= 0x300; 177 writel(data, &peri_sc->ctrl5); 178 179 /*CTRL 4*/ 180 181 /* configure USB PHY */ 182 data = readl(&peri_sc->ctrl4); 183 184 /* make PHY out of low power mode */ 185 data &= ~PERI_CTRL4_PICO_SIDDQ; 186 data &= ~PERI_CTRL4_PICO_OGDISABLE; 187 data |= PERI_CTRL4_PICO_VBUSVLDEXTSEL | PERI_CTRL4_PICO_VBUSVLDEXT; 188 writel(data, &peri_sc->ctrl4); 189 190 writel(EYE_PATTERN, &peri_sc->ctrl8); 191 192 mdelay(5); 193 return 0; 194 } 195 196 static int config_sd_carddetect(void) 197 { 198 int ret; 199 200 /* configure GPIO8 as nopull */ 201 writel(0, 0xf8001830); 202 203 gpio_request(8, "SD CD"); 204 205 gpio_direction_input(8); 206 ret = gpio_get_value(8); 207 208 if (!ret) { 209 printf("%s: SD card present\n", __func__); 210 return 1; 211 } 212 213 printf("%s: SD card not present\n", __func__); 214 return 0; 215 } 216 217 218 static void mmc1_init_pll(void) 219 { 220 uint32_t data; 221 222 /* select SYSPLL as the source of MMC1 */ 223 /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ 224 writel(1 << 11 | 1 << 27, &peri_sc->clk0_sel); 225 do { 226 data = readl(&peri_sc->clk0_sel); 227 } while (!(data & (1 << 11))); 228 229 /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ 230 writel(1 << 30, &peri_sc->clk0_sel); 231 do { 232 data = readl(&peri_sc->clk0_sel); 233 } while (data & (1 << 14)); 234 235 hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en); 236 237 hi6220_clk_enable(PERI_CLK12_MMC1_SRC, &peri_sc->clk12_en); 238 239 do { 240 /* 1.2GHz / 50 = 24MHz */ 241 writel(0x31 | (1 << 7), &peri_sc->clkcfg8bit2); 242 data = readl(&peri_sc->clkcfg8bit2); 243 } while ((data & 0x31) != 0x31); 244 } 245 246 static void mmc1_reset_clk(void) 247 { 248 unsigned int data; 249 250 /* disable mmc1 bus clock */ 251 hi6220_clk_disable(PERI_CLK0_MMC1, &peri_sc->clk0_dis); 252 253 /* enable mmc1 bus clock */ 254 hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en); 255 256 /* reset mmc1 clock domain */ 257 writel(PERI_RST0_MMC1, &peri_sc->rst0_en); 258 259 /* bypass mmc1 clock phase */ 260 data = readl(&peri_sc->ctrl2); 261 data |= 3 << 2; 262 writel(data, &peri_sc->ctrl2); 263 264 /* disable low power */ 265 data = readl(&peri_sc->ctrl13); 266 data |= 1 << 4; 267 writel(data, &peri_sc->ctrl13); 268 do { 269 data = readl(&peri_sc->rst0_stat); 270 } while (!(data & PERI_RST0_MMC1)); 271 272 /* unreset mmc0 clock domain */ 273 writel(PERI_RST0_MMC1, &peri_sc->rst0_dis); 274 do { 275 data = readl(&peri_sc->rst0_stat); 276 } while (data & PERI_RST0_MMC1); 277 } 278 279 /* PMU SSI is the IP that maps the external PMU hi6553 registers as IO */ 280 static void hi6220_pmussi_init(void) 281 { 282 uint32_t data; 283 284 /* Take PMUSSI out of reset */ 285 writel(ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N, 286 &ao_sc->rst4_dis); 287 do { 288 data = readl(&ao_sc->rst4_stat); 289 } while (data & ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N); 290 291 /* set PMU SSI clock latency for read operation */ 292 data = readl(&ao_sc->mcu_subsys_ctrl3); 293 data &= ~ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_MASK; 294 data |= ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_3; 295 writel(data, &ao_sc->mcu_subsys_ctrl3); 296 297 /* enable PMUSSI clock */ 298 data = ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_CCPU | 299 ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_MCU; 300 301 hi6220_clk_enable(data, &ao_sc->clk5_en); 302 303 /* Output high to PMIC on PWR_HOLD_GPIO0_0 */ 304 gpio_request(0, "PWR_HOLD_GPIO0_0"); 305 gpio_direction_output(0, 1); 306 } 307 308 int misc_init_r(void) 309 { 310 return 0; 311 } 312 313 int board_init(void) 314 { 315 return 0; 316 } 317 318 #ifdef CONFIG_GENERIC_MMC 319 320 static int init_dwmmc(void) 321 { 322 int ret; 323 324 #ifdef CONFIG_DWMMC 325 326 /* mmc0 clocks are already configured by ATF */ 327 ret = hi6220_pinmux_config(PERIPH_ID_SDMMC0); 328 if (ret) 329 printf("%s: Error configuring pinmux for eMMC (%d)\n" 330 , __func__, ret); 331 332 ret |= hi6220_dwmci_add_port(0, HI6220_MMC0_BASE, 8); 333 if (ret) 334 printf("%s: Error adding eMMC port (%d)\n", __func__, ret); 335 336 337 /* take mmc1 (sd slot) out of reset, configure clocks and pinmuxing */ 338 mmc1_init_pll(); 339 mmc1_reset_clk(); 340 341 ret |= hi6220_pinmux_config(PERIPH_ID_SDMMC1); 342 if (ret) 343 printf("%s: Error configuring pinmux for eMMC (%d)\n" 344 , __func__, ret); 345 346 config_sd_carddetect(); 347 348 ret |= hi6220_dwmci_add_port(1, HI6220_MMC1_BASE, 4); 349 if (ret) 350 printf("%s: Error adding SD port (%d)\n", __func__, ret); 351 352 #endif 353 return ret; 354 } 355 356 /* setup board specific PMIC */ 357 int power_init_board(void) 358 { 359 /* init the hi6220 pmussi ip */ 360 hi6220_pmussi_init(); 361 362 power_hi6553_init((u8 *)HI6220_PMUSSI_BASE); 363 364 return 0; 365 } 366 367 int board_mmc_init(bd_t *bis) 368 { 369 int ret; 370 371 /* add the eMMC and sd ports */ 372 ret = init_dwmmc(); 373 374 if (ret) 375 debug("init_dwmmc failed\n"); 376 377 return ret; 378 } 379 #endif 380 381 int dram_init(void) 382 { 383 gd->ram_size = PHYS_SDRAM_1_SIZE; 384 return 0; 385 } 386 387 void dram_init_banksize(void) 388 { 389 gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 390 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; 391 } 392 393 /* Use the Watchdog to cause reset */ 394 void reset_cpu(ulong addr) 395 { 396 /* TODO program the watchdog */ 397 } 398