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 <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 22 /*TODO drop this table in favour of device tree */ 23 static const struct hikey_gpio_platdata hi6220_gpio[] = { 24 { 0, HI6220_GPIO_BASE(0)}, 25 { 1, HI6220_GPIO_BASE(1)}, 26 { 2, HI6220_GPIO_BASE(2)}, 27 { 3, HI6220_GPIO_BASE(3)}, 28 { 4, HI6220_GPIO_BASE(4)}, 29 { 5, HI6220_GPIO_BASE(5)}, 30 { 6, HI6220_GPIO_BASE(6)}, 31 { 7, HI6220_GPIO_BASE(7)}, 32 { 8, HI6220_GPIO_BASE(8)}, 33 { 9, HI6220_GPIO_BASE(9)}, 34 { 10, HI6220_GPIO_BASE(10)}, 35 { 11, HI6220_GPIO_BASE(11)}, 36 { 12, HI6220_GPIO_BASE(12)}, 37 { 13, HI6220_GPIO_BASE(13)}, 38 { 14, HI6220_GPIO_BASE(14)}, 39 { 15, HI6220_GPIO_BASE(15)}, 40 { 16, HI6220_GPIO_BASE(16)}, 41 { 17, HI6220_GPIO_BASE(17)}, 42 { 18, HI6220_GPIO_BASE(18)}, 43 { 19, HI6220_GPIO_BASE(19)}, 44 45 }; 46 47 U_BOOT_DEVICES(hi6220_gpios) = { 48 { "gpio_hi6220", &hi6220_gpio[0] }, 49 { "gpio_hi6220", &hi6220_gpio[1] }, 50 { "gpio_hi6220", &hi6220_gpio[2] }, 51 { "gpio_hi6220", &hi6220_gpio[3] }, 52 { "gpio_hi6220", &hi6220_gpio[4] }, 53 { "gpio_hi6220", &hi6220_gpio[5] }, 54 { "gpio_hi6220", &hi6220_gpio[6] }, 55 { "gpio_hi6220", &hi6220_gpio[7] }, 56 { "gpio_hi6220", &hi6220_gpio[8] }, 57 { "gpio_hi6220", &hi6220_gpio[9] }, 58 { "gpio_hi6220", &hi6220_gpio[10] }, 59 { "gpio_hi6220", &hi6220_gpio[11] }, 60 { "gpio_hi6220", &hi6220_gpio[12] }, 61 { "gpio_hi6220", &hi6220_gpio[13] }, 62 { "gpio_hi6220", &hi6220_gpio[14] }, 63 { "gpio_hi6220", &hi6220_gpio[15] }, 64 { "gpio_hi6220", &hi6220_gpio[16] }, 65 { "gpio_hi6220", &hi6220_gpio[17] }, 66 { "gpio_hi6220", &hi6220_gpio[18] }, 67 { "gpio_hi6220", &hi6220_gpio[19] }, 68 }; 69 70 DECLARE_GLOBAL_DATA_PTR; 71 72 struct peri_sc_periph_regs *peri_sc = 73 (struct peri_sc_periph_regs *)HI6220_PERI_BASE; 74 75 struct alwayson_sc_regs *ao_sc = 76 (struct alwayson_sc_regs *)ALWAYSON_CTRL_BASE; 77 78 /* status offset from enable reg */ 79 #define STAT_EN_OFF 0x2 80 81 void hi6220_clk_enable(u32 bitfield, unsigned int *clk_base) 82 { 83 uint32_t data; 84 85 data = readl(clk_base); 86 data |= bitfield; 87 88 writel(bitfield, clk_base); 89 do { 90 data = readl(clk_base + STAT_EN_OFF); 91 } while ((data & bitfield) == 0); 92 } 93 94 /* status offset from disable reg */ 95 #define STAT_DIS_OFF 0x1 96 97 void hi6220_clk_disable(u32 bitfield, unsigned int *clk_base) 98 { 99 uint32_t data; 100 101 data = readl(clk_base); 102 data |= bitfield; 103 104 writel(data, clk_base); 105 do { 106 data = readl(clk_base + STAT_DIS_OFF); 107 } while (data & bitfield); 108 } 109 110 #define EYE_PATTERN 0x70533483 111 112 int board_usb_init(int index, enum usb_init_type init) 113 { 114 unsigned int data; 115 116 /* enable USB clock */ 117 hi6220_clk_enable(PERI_CLK0_USBOTG, &peri_sc->clk0_en); 118 119 /* take usb IPs out of reset */ 120 writel(PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY | 121 PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K, 122 &peri_sc->rst0_dis); 123 do { 124 data = readl(&peri_sc->rst0_stat); 125 data &= PERI_RST0_USBOTG_BUS | PERI_RST0_POR_PICOPHY | 126 PERI_RST0_USBOTG | PERI_RST0_USBOTG_32K; 127 } while (data); 128 129 /*CTRL 5*/ 130 data = readl(&peri_sc->ctrl5); 131 data &= ~PERI_CTRL5_PICOPHY_BC_MODE; 132 data |= PERI_CTRL5_USBOTG_RES_SEL | PERI_CTRL5_PICOPHY_ACAENB; 133 data |= 0x300; 134 writel(data, &peri_sc->ctrl5); 135 136 /*CTRL 4*/ 137 138 /* configure USB PHY */ 139 data = readl(&peri_sc->ctrl4); 140 141 /* make PHY out of low power mode */ 142 data &= ~PERI_CTRL4_PICO_SIDDQ; 143 data &= ~PERI_CTRL4_PICO_OGDISABLE; 144 data |= PERI_CTRL4_PICO_VBUSVLDEXTSEL | PERI_CTRL4_PICO_VBUSVLDEXT; 145 writel(data, &peri_sc->ctrl4); 146 147 writel(EYE_PATTERN, &peri_sc->ctrl8); 148 149 mdelay(5); 150 return 0; 151 } 152 153 static int config_sd_carddetect(void) 154 { 155 int ret; 156 157 /* configure GPIO8 as nopull */ 158 writel(0, 0xf8001830); 159 160 gpio_request(8, "SD CD"); 161 162 gpio_direction_input(8); 163 ret = gpio_get_value(8); 164 165 if (!ret) { 166 printf("%s: SD card present\n", __func__); 167 return 1; 168 } 169 170 printf("%s: SD card not present\n", __func__); 171 return 0; 172 } 173 174 175 static void mmc1_init_pll(void) 176 { 177 uint32_t data; 178 179 /* select SYSPLL as the source of MMC1 */ 180 /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ 181 writel(1 << 11 | 1 << 27, &peri_sc->clk0_sel); 182 do { 183 data = readl(&peri_sc->clk0_sel); 184 } while (!(data & (1 << 11))); 185 186 /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ 187 writel(1 << 30, &peri_sc->clk0_sel); 188 do { 189 data = readl(&peri_sc->clk0_sel); 190 } while (data & (1 << 14)); 191 192 hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en); 193 194 hi6220_clk_enable(PERI_CLK12_MMC1_SRC, &peri_sc->clk12_en); 195 196 do { 197 /* 1.2GHz / 50 = 24MHz */ 198 writel(0x31 | (1 << 7), &peri_sc->clkcfg8bit2); 199 data = readl(&peri_sc->clkcfg8bit2); 200 } while ((data & 0x31) != 0x31); 201 } 202 203 static void mmc1_reset_clk(void) 204 { 205 unsigned int data; 206 207 /* disable mmc1 bus clock */ 208 hi6220_clk_disable(PERI_CLK0_MMC1, &peri_sc->clk0_dis); 209 210 /* enable mmc1 bus clock */ 211 hi6220_clk_enable(PERI_CLK0_MMC1, &peri_sc->clk0_en); 212 213 /* reset mmc1 clock domain */ 214 writel(PERI_RST0_MMC1, &peri_sc->rst0_en); 215 216 /* bypass mmc1 clock phase */ 217 data = readl(&peri_sc->ctrl2); 218 data |= 3 << 2; 219 writel(data, &peri_sc->ctrl2); 220 221 /* disable low power */ 222 data = readl(&peri_sc->ctrl13); 223 data |= 1 << 4; 224 writel(data, &peri_sc->ctrl13); 225 do { 226 data = readl(&peri_sc->rst0_stat); 227 } while (!(data & PERI_RST0_MMC1)); 228 229 /* unreset mmc0 clock domain */ 230 writel(PERI_RST0_MMC1, &peri_sc->rst0_dis); 231 do { 232 data = readl(&peri_sc->rst0_stat); 233 } while (data & PERI_RST0_MMC1); 234 } 235 236 /* PMU SSI is the IP that maps the external PMU hi6553 registers as IO */ 237 static void hi6220_pmussi_init(void) 238 { 239 uint32_t data; 240 241 /* Take PMUSSI out of reset */ 242 writel(ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N, 243 &ao_sc->rst4_dis); 244 do { 245 data = readl(&ao_sc->rst4_stat); 246 } while (data & ALWAYSON_SC_PERIPH_RST4_DIS_PRESET_PMUSSI_N); 247 248 /* set PMU SSI clock latency for read operation */ 249 data = readl(&ao_sc->mcu_subsys_ctrl3); 250 data &= ~ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_MASK; 251 data |= ALWAYSON_SC_MCU_SUBSYS_CTRL3_RCLK_3; 252 writel(data, &ao_sc->mcu_subsys_ctrl3); 253 254 /* enable PMUSSI clock */ 255 data = ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_CCPU | 256 ALWAYSON_SC_PERIPH_CLK5_EN_PCLK_PMUSSI_MCU; 257 258 hi6220_clk_enable(data, &ao_sc->clk5_en); 259 260 /* Output high to PMIC on PWR_HOLD_GPIO0_0 */ 261 gpio_request(0, "PWR_HOLD_GPIO0_0"); 262 gpio_direction_output(0, 1); 263 } 264 265 int misc_init_r(void) 266 { 267 return 0; 268 } 269 270 int board_init(void) 271 { 272 gd->flags = 0; 273 274 return 0; 275 } 276 277 #ifdef CONFIG_GENERIC_MMC 278 279 static int init_dwmmc(void) 280 { 281 int ret; 282 283 #ifdef CONFIG_DWMMC 284 285 /* mmc0 clocks are already configured by ATF */ 286 ret = hi6220_pinmux_config(PERIPH_ID_SDMMC0); 287 if (ret) 288 printf("%s: Error configuring pinmux for eMMC (%d)\n" 289 , __func__, ret); 290 291 ret |= hi6220_dwmci_add_port(0, HI6220_MMC0_BASE, 8); 292 if (ret) 293 printf("%s: Error adding eMMC port (%d)\n", __func__, ret); 294 295 296 /* take mmc1 (sd slot) out of reset, configure clocks and pinmuxing */ 297 mmc1_init_pll(); 298 mmc1_reset_clk(); 299 300 ret |= hi6220_pinmux_config(PERIPH_ID_SDMMC1); 301 if (ret) 302 printf("%s: Error configuring pinmux for eMMC (%d)\n" 303 , __func__, ret); 304 305 config_sd_carddetect(); 306 307 ret |= hi6220_dwmci_add_port(1, HI6220_MMC1_BASE, 4); 308 if (ret) 309 printf("%s: Error adding SD port (%d)\n", __func__, ret); 310 311 #endif 312 return ret; 313 } 314 315 /* setup board specific PMIC */ 316 int power_init_board(void) 317 { 318 /* init the hi6220 pmussi ip */ 319 hi6220_pmussi_init(); 320 321 power_hi6553_init((u8 *)HI6220_PMUSSI_BASE); 322 323 return 0; 324 } 325 326 int board_mmc_init(bd_t *bis) 327 { 328 int ret; 329 330 /* add the eMMC and sd ports */ 331 ret = init_dwmmc(); 332 333 if (ret) 334 debug("init_dwmmc failed\n"); 335 336 return ret; 337 } 338 #endif 339 340 int dram_init(void) 341 { 342 gd->ram_size = PHYS_SDRAM_1_SIZE; 343 return 0; 344 } 345 346 void dram_init_banksize(void) 347 { 348 gd->bd->bi_dram[0].start = PHYS_SDRAM_1; 349 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; 350 } 351 352 /* Use the Watchdog to cause reset */ 353 void reset_cpu(ulong addr) 354 { 355 /* TODO program the watchdog */ 356 } 357