1*054c3e0fSHaojian Zhuang /* 2*054c3e0fSHaojian Zhuang * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3*054c3e0fSHaojian Zhuang * 4*054c3e0fSHaojian Zhuang * SPDX-License-Identifier: BSD-3-Clause 5*054c3e0fSHaojian Zhuang */ 6*054c3e0fSHaojian Zhuang 7*054c3e0fSHaojian Zhuang #include <arch_helpers.h> 8*054c3e0fSHaojian Zhuang #include <gpio.h> 9*054c3e0fSHaojian Zhuang #include <hi6220.h> 10*054c3e0fSHaojian Zhuang #include <hi6553.h> 11*054c3e0fSHaojian Zhuang #include <mmio.h> 12*054c3e0fSHaojian Zhuang #include <pl061_gpio.h> 13*054c3e0fSHaojian Zhuang #include <sp804_delay_timer.h> 14*054c3e0fSHaojian Zhuang 15*054c3e0fSHaojian Zhuang #include "hikey_private.h" 16*054c3e0fSHaojian Zhuang 17*054c3e0fSHaojian Zhuang void hikey_sp804_init(void) 18*054c3e0fSHaojian Zhuang { 19*054c3e0fSHaojian Zhuang uint32_t data; 20*054c3e0fSHaojian Zhuang 21*054c3e0fSHaojian Zhuang /* select the clock of dual timer0 */ 22*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_TIMER_EN0); 23*054c3e0fSHaojian Zhuang while (data & 3) { 24*054c3e0fSHaojian Zhuang data &= ~3; 25*054c3e0fSHaojian Zhuang data |= 3 << 16; 26*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_TIMER_EN0, data); 27*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_TIMER_EN0); 28*054c3e0fSHaojian Zhuang } 29*054c3e0fSHaojian Zhuang /* enable the pclk of dual timer0 */ 30*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); 31*054c3e0fSHaojian Zhuang while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)) { 32*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_PERIPH_CLKEN4, PCLK_TIMER1 | PCLK_TIMER0); 33*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_PERIPH_CLKSTAT4); 34*054c3e0fSHaojian Zhuang } 35*054c3e0fSHaojian Zhuang /* reset dual timer0 */ 36*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); 37*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_PERIPH_RSTEN4, PCLK_TIMER1 | PCLK_TIMER0); 38*054c3e0fSHaojian Zhuang do { 39*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); 40*054c3e0fSHaojian Zhuang } while (!(data & PCLK_TIMER1) || !(data & PCLK_TIMER0)); 41*054c3e0fSHaojian Zhuang /* unreset dual timer0 */ 42*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_PERIPH_RSTDIS4, PCLK_TIMER1 | PCLK_TIMER0); 43*054c3e0fSHaojian Zhuang do { 44*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); 45*054c3e0fSHaojian Zhuang } while ((data & PCLK_TIMER1) || (data & PCLK_TIMER0)); 46*054c3e0fSHaojian Zhuang 47*054c3e0fSHaojian Zhuang sp804_timer_init(SP804_TIMER0_BASE, 10, 192); 48*054c3e0fSHaojian Zhuang } 49*054c3e0fSHaojian Zhuang 50*054c3e0fSHaojian Zhuang void hikey_gpio_init(void) 51*054c3e0fSHaojian Zhuang { 52*054c3e0fSHaojian Zhuang pl061_gpio_init(); 53*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO0_BASE, 0); 54*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO1_BASE, 1); 55*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO2_BASE, 2); 56*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO3_BASE, 3); 57*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO4_BASE, 4); 58*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO5_BASE, 5); 59*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO6_BASE, 6); 60*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO7_BASE, 7); 61*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO8_BASE, 8); 62*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO9_BASE, 9); 63*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO10_BASE, 10); 64*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO11_BASE, 11); 65*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO12_BASE, 12); 66*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO13_BASE, 13); 67*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO14_BASE, 14); 68*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO15_BASE, 15); 69*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO16_BASE, 16); 70*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO17_BASE, 17); 71*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO18_BASE, 18); 72*054c3e0fSHaojian Zhuang pl061_gpio_register(GPIO19_BASE, 19); 73*054c3e0fSHaojian Zhuang 74*054c3e0fSHaojian Zhuang /* Power on indicator LED (USER_LED1). */ 75*054c3e0fSHaojian Zhuang gpio_set_direction(32, GPIO_DIR_OUT); /* LED1 */ 76*054c3e0fSHaojian Zhuang gpio_set_value(32, GPIO_LEVEL_HIGH); 77*054c3e0fSHaojian Zhuang gpio_set_direction(33, GPIO_DIR_OUT); /* LED2 */ 78*054c3e0fSHaojian Zhuang gpio_set_value(33, GPIO_LEVEL_LOW); 79*054c3e0fSHaojian Zhuang gpio_set_direction(34, GPIO_DIR_OUT); /* LED3 */ 80*054c3e0fSHaojian Zhuang gpio_set_direction(35, GPIO_DIR_OUT); /* LED4 */ 81*054c3e0fSHaojian Zhuang } 82*054c3e0fSHaojian Zhuang 83*054c3e0fSHaojian Zhuang void hikey_pmussi_init(void) 84*054c3e0fSHaojian Zhuang { 85*054c3e0fSHaojian Zhuang uint32_t data; 86*054c3e0fSHaojian Zhuang 87*054c3e0fSHaojian Zhuang /* Initialize PWR_HOLD GPIO */ 88*054c3e0fSHaojian Zhuang gpio_set_direction(0, GPIO_DIR_OUT); 89*054c3e0fSHaojian Zhuang gpio_set_value(0, GPIO_LEVEL_LOW); 90*054c3e0fSHaojian Zhuang 91*054c3e0fSHaojian Zhuang /* 92*054c3e0fSHaojian Zhuang * After reset, PMUSSI stays in reset mode. 93*054c3e0fSHaojian Zhuang * Now make it out of reset. 94*054c3e0fSHaojian Zhuang */ 95*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_PERIPH_RSTDIS4, 96*054c3e0fSHaojian Zhuang AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); 97*054c3e0fSHaojian Zhuang do { 98*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_PERIPH_RSTSTAT4); 99*054c3e0fSHaojian Zhuang } while (data & AO_SC_PERIPH_RSTDIS4_PRESET_PMUSSI_N); 100*054c3e0fSHaojian Zhuang 101*054c3e0fSHaojian Zhuang /* Set PMUSSI clock latency for read operation. */ 102*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_MCU_SUBSYS_CTRL3); 103*054c3e0fSHaojian Zhuang data &= ~AO_SC_MCU_SUBSYS_CTRL3_RCLK_MASK; 104*054c3e0fSHaojian Zhuang data |= AO_SC_MCU_SUBSYS_CTRL3_RCLK_3; 105*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_MCU_SUBSYS_CTRL3, data); 106*054c3e0fSHaojian Zhuang 107*054c3e0fSHaojian Zhuang /* enable PMUSSI clock */ 108*054c3e0fSHaojian Zhuang data = AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_CCPU | 109*054c3e0fSHaojian Zhuang AO_SC_PERIPH_CLKEN5_PCLK_PMUSSI_MCU; 110*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_PERIPH_CLKEN5, data); 111*054c3e0fSHaojian Zhuang data = AO_SC_PERIPH_CLKEN4_PCLK_PMUSSI; 112*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_PERIPH_CLKEN4, data); 113*054c3e0fSHaojian Zhuang 114*054c3e0fSHaojian Zhuang gpio_set_value(0, GPIO_LEVEL_HIGH); 115*054c3e0fSHaojian Zhuang } 116*054c3e0fSHaojian Zhuang 117*054c3e0fSHaojian Zhuang void hikey_hi6553_init(void) 118*054c3e0fSHaojian Zhuang { 119*054c3e0fSHaojian Zhuang uint8_t data; 120*054c3e0fSHaojian Zhuang 121*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_PERI_EN_MARK, 0x1e); 122*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_NP_REG_ADJ1, 0); 123*054c3e0fSHaojian Zhuang data = DISABLE6_XO_CLK_CONN | DISABLE6_XO_CLK_NFC | 124*054c3e0fSHaojian Zhuang DISABLE6_XO_CLK_RF1 | DISABLE6_XO_CLK_RF2; 125*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_DISABLE6_XO_CLK, data); 126*054c3e0fSHaojian Zhuang 127*054c3e0fSHaojian Zhuang /* configure BUCK0 & BUCK1 */ 128*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK01_CTRL2, 0x5e); 129*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK0_CTRL7, 0x10); 130*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK1_CTRL7, 0x10); 131*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK0_CTRL5, 0x1e); 132*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK1_CTRL5, 0x1e); 133*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK0_CTRL1, 0xfc); 134*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK1_CTRL1, 0xfc); 135*054c3e0fSHaojian Zhuang 136*054c3e0fSHaojian Zhuang /* configure BUCK2 */ 137*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK2_REG1, 0x4f); 138*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK2_REG5, 0x99); 139*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK2_REG6, 0x45); 140*054c3e0fSHaojian Zhuang mdelay(1); 141*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_VSET_BUCK2_ADJ, 0x22); 142*054c3e0fSHaojian Zhuang mdelay(1); 143*054c3e0fSHaojian Zhuang 144*054c3e0fSHaojian Zhuang /* configure BUCK3 */ 145*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK3_REG3, 0x02); 146*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK3_REG5, 0x99); 147*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK3_REG6, 0x41); 148*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_VSET_BUCK3_ADJ, 0x02); 149*054c3e0fSHaojian Zhuang mdelay(1); 150*054c3e0fSHaojian Zhuang 151*054c3e0fSHaojian Zhuang /* configure BUCK4 */ 152*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK4_REG2, 0x9a); 153*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK4_REG5, 0x99); 154*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_BUCK4_REG6, 0x45); 155*054c3e0fSHaojian Zhuang 156*054c3e0fSHaojian Zhuang /* configure LDO20 */ 157*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_LDO20_REG_ADJ, 0x50); 158*054c3e0fSHaojian Zhuang 159*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_NP_REG_CHG, 0x0f); 160*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_CLK_TOP0, 0x06); 161*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_CLK_TOP3, 0xc0); 162*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_CLK_TOP4, 0x00); 163*054c3e0fSHaojian Zhuang 164*054c3e0fSHaojian Zhuang /* configure LDO7 & LDO10 for SD slot */ 165*054c3e0fSHaojian Zhuang /* enable LDO7 */ 166*054c3e0fSHaojian Zhuang data = mmio_read_8(HI6553_LDO7_REG_ADJ); 167*054c3e0fSHaojian Zhuang data = (data & 0xf8) | 0x2; 168*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_LDO7_REG_ADJ, data); 169*054c3e0fSHaojian Zhuang mdelay(5); 170*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_ENABLE2_LDO1_8, 1 << 6); 171*054c3e0fSHaojian Zhuang mdelay(5); 172*054c3e0fSHaojian Zhuang /* enable LDO10 */ 173*054c3e0fSHaojian Zhuang data = mmio_read_8(HI6553_LDO10_REG_ADJ); 174*054c3e0fSHaojian Zhuang data = (data & 0xf8) | 0x5; 175*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_LDO10_REG_ADJ, data); 176*054c3e0fSHaojian Zhuang mdelay(5); 177*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 1); 178*054c3e0fSHaojian Zhuang mdelay(5); 179*054c3e0fSHaojian Zhuang /* enable LDO15 */ 180*054c3e0fSHaojian Zhuang data = mmio_read_8(HI6553_LDO15_REG_ADJ); 181*054c3e0fSHaojian Zhuang data = (data & 0xf8) | 0x4; 182*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_LDO15_REG_ADJ, data); 183*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_ENABLE3_LDO9_16, 1 << 6); 184*054c3e0fSHaojian Zhuang mdelay(5); 185*054c3e0fSHaojian Zhuang /* enable LDO19 */ 186*054c3e0fSHaojian Zhuang data = mmio_read_8(HI6553_LDO19_REG_ADJ); 187*054c3e0fSHaojian Zhuang data |= 0x7; 188*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_LDO19_REG_ADJ, data); 189*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 2); 190*054c3e0fSHaojian Zhuang mdelay(5); 191*054c3e0fSHaojian Zhuang /* enable LDO21 */ 192*054c3e0fSHaojian Zhuang data = mmio_read_8(HI6553_LDO21_REG_ADJ); 193*054c3e0fSHaojian Zhuang data = (data & 0xf8) | 0x3; 194*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_LDO21_REG_ADJ, data); 195*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 4); 196*054c3e0fSHaojian Zhuang mdelay(5); 197*054c3e0fSHaojian Zhuang /* enable LDO22 */ 198*054c3e0fSHaojian Zhuang data = mmio_read_8(HI6553_LDO22_REG_ADJ); 199*054c3e0fSHaojian Zhuang data = (data & 0xf8) | 0x7; 200*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_LDO22_REG_ADJ, data); 201*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_ENABLE4_LDO17_22, 1 << 5); 202*054c3e0fSHaojian Zhuang mdelay(5); 203*054c3e0fSHaojian Zhuang 204*054c3e0fSHaojian Zhuang /* select 32.764KHz */ 205*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_CLK19M2_600_586_EN, 0x01); 206*054c3e0fSHaojian Zhuang 207*054c3e0fSHaojian Zhuang /* Disable vbus_det interrupts */ 208*054c3e0fSHaojian Zhuang data = mmio_read_8(HI6553_IRQ2_MASK); 209*054c3e0fSHaojian Zhuang data = data | 0x3; 210*054c3e0fSHaojian Zhuang mmio_write_8(HI6553_IRQ2_MASK, data); 211*054c3e0fSHaojian Zhuang } 212*054c3e0fSHaojian Zhuang 213*054c3e0fSHaojian Zhuang void init_mmc0_pll(void) 214*054c3e0fSHaojian Zhuang { 215*054c3e0fSHaojian Zhuang unsigned int data; 216*054c3e0fSHaojian Zhuang 217*054c3e0fSHaojian Zhuang /* select SYSPLL as the source of MMC0 */ 218*054c3e0fSHaojian Zhuang /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ 219*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_CLK_SEL0, 1 << 5 | 1 << 21); 220*054c3e0fSHaojian Zhuang do { 221*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_CLK_SEL0); 222*054c3e0fSHaojian Zhuang } while (!(data & (1 << 5))); 223*054c3e0fSHaojian Zhuang /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ 224*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_CLK_SEL0, 1 << 29); 225*054c3e0fSHaojian Zhuang do { 226*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_CLK_SEL0); 227*054c3e0fSHaojian Zhuang } while (data & (1 << 13)); 228*054c3e0fSHaojian Zhuang 229*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 0)); 230*054c3e0fSHaojian Zhuang do { 231*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); 232*054c3e0fSHaojian Zhuang } while (!(data & (1 << 0))); 233*054c3e0fSHaojian Zhuang 234*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); 235*054c3e0fSHaojian Zhuang data |= 1 << 1; 236*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); 237*054c3e0fSHaojian Zhuang 238*054c3e0fSHaojian Zhuang do { 239*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_CLKCFG8BIT1, (1 << 7) | 0xb); 240*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_CLKCFG8BIT1); 241*054c3e0fSHaojian Zhuang } while ((data & 0xb) != 0xb); 242*054c3e0fSHaojian Zhuang } 243*054c3e0fSHaojian Zhuang 244*054c3e0fSHaojian Zhuang void reset_mmc0_clk(void) 245*054c3e0fSHaojian Zhuang { 246*054c3e0fSHaojian Zhuang unsigned int data; 247*054c3e0fSHaojian Zhuang 248*054c3e0fSHaojian Zhuang /* disable mmc0 bus clock */ 249*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC0); 250*054c3e0fSHaojian Zhuang do { 251*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); 252*054c3e0fSHaojian Zhuang } while (data & PERI_CLK0_MMC0); 253*054c3e0fSHaojian Zhuang /* enable mmc0 bus clock */ 254*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC0); 255*054c3e0fSHaojian Zhuang do { 256*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); 257*054c3e0fSHaojian Zhuang } while (!(data & PERI_CLK0_MMC0)); 258*054c3e0fSHaojian Zhuang /* reset mmc0 clock domain */ 259*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC0); 260*054c3e0fSHaojian Zhuang 261*054c3e0fSHaojian Zhuang /* bypass mmc0 clock phase */ 262*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CTRL2); 263*054c3e0fSHaojian Zhuang data |= 3; 264*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL2, data); 265*054c3e0fSHaojian Zhuang 266*054c3e0fSHaojian Zhuang /* disable low power */ 267*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CTRL13); 268*054c3e0fSHaojian Zhuang data |= 1 << 3; 269*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL13, data); 270*054c3e0fSHaojian Zhuang do { 271*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); 272*054c3e0fSHaojian Zhuang } while (!(data & PERI_RST0_MMC0)); 273*054c3e0fSHaojian Zhuang 274*054c3e0fSHaojian Zhuang /* unreset mmc0 clock domain */ 275*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC0); 276*054c3e0fSHaojian Zhuang do { 277*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); 278*054c3e0fSHaojian Zhuang } while (data & PERI_RST0_MMC0); 279*054c3e0fSHaojian Zhuang } 280*054c3e0fSHaojian Zhuang 281*054c3e0fSHaojian Zhuang void init_media_clk(void) 282*054c3e0fSHaojian Zhuang { 283*054c3e0fSHaojian Zhuang unsigned int data, value; 284*054c3e0fSHaojian Zhuang 285*054c3e0fSHaojian Zhuang data = mmio_read_32(PMCTRL_MEDPLLCTRL); 286*054c3e0fSHaojian Zhuang data |= 1; 287*054c3e0fSHaojian Zhuang mmio_write_32(PMCTRL_MEDPLLCTRL, data); 288*054c3e0fSHaojian Zhuang 289*054c3e0fSHaojian Zhuang for (;;) { 290*054c3e0fSHaojian Zhuang data = mmio_read_32(PMCTRL_MEDPLLCTRL); 291*054c3e0fSHaojian Zhuang value = 1 << 28; 292*054c3e0fSHaojian Zhuang if ((data & value) == value) 293*054c3e0fSHaojian Zhuang break; 294*054c3e0fSHaojian Zhuang } 295*054c3e0fSHaojian Zhuang 296*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); 297*054c3e0fSHaojian Zhuang data = 1 << 10; 298*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); 299*054c3e0fSHaojian Zhuang } 300*054c3e0fSHaojian Zhuang 301*054c3e0fSHaojian Zhuang void init_mmc1_pll(void) 302*054c3e0fSHaojian Zhuang { 303*054c3e0fSHaojian Zhuang uint32_t data; 304*054c3e0fSHaojian Zhuang 305*054c3e0fSHaojian Zhuang /* select SYSPLL as the source of MMC1 */ 306*054c3e0fSHaojian Zhuang /* select SYSPLL as the source of MUX1 (SC_CLK_SEL0) */ 307*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_CLK_SEL0, 1 << 11 | 1 << 27); 308*054c3e0fSHaojian Zhuang do { 309*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_CLK_SEL0); 310*054c3e0fSHaojian Zhuang } while (!(data & (1 << 11))); 311*054c3e0fSHaojian Zhuang /* select MUX1 as the source of MUX2 (SC_CLK_SEL0) */ 312*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_CLK_SEL0, 1 << 30); 313*054c3e0fSHaojian Zhuang do { 314*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_CLK_SEL0); 315*054c3e0fSHaojian Zhuang } while (data & (1 << 14)); 316*054c3e0fSHaojian Zhuang 317*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKEN0, (1 << 1)); 318*054c3e0fSHaojian Zhuang do { 319*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); 320*054c3e0fSHaojian Zhuang } while (!(data & (1 << 1))); 321*054c3e0fSHaojian Zhuang 322*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKEN12); 323*054c3e0fSHaojian Zhuang data |= 1 << 2; 324*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKEN12, data); 325*054c3e0fSHaojian Zhuang 326*054c3e0fSHaojian Zhuang do { 327*054c3e0fSHaojian Zhuang /* 1.2GHz / 50 = 24MHz */ 328*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_CLKCFG8BIT2, 0x31 | (1 << 7)); 329*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_CLKCFG8BIT2); 330*054c3e0fSHaojian Zhuang } while ((data & 0x31) != 0x31); 331*054c3e0fSHaojian Zhuang } 332*054c3e0fSHaojian Zhuang 333*054c3e0fSHaojian Zhuang void reset_mmc1_clk(void) 334*054c3e0fSHaojian Zhuang { 335*054c3e0fSHaojian Zhuang unsigned int data; 336*054c3e0fSHaojian Zhuang 337*054c3e0fSHaojian Zhuang /* disable mmc1 bus clock */ 338*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKDIS0, PERI_CLK0_MMC1); 339*054c3e0fSHaojian Zhuang do { 340*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); 341*054c3e0fSHaojian Zhuang } while (data & PERI_CLK0_MMC1); 342*054c3e0fSHaojian Zhuang /* enable mmc1 bus clock */ 343*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CLKEN0, PERI_CLK0_MMC1); 344*054c3e0fSHaojian Zhuang do { 345*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CLKSTAT0); 346*054c3e0fSHaojian Zhuang } while (!(data & PERI_CLK0_MMC1)); 347*054c3e0fSHaojian Zhuang /* reset mmc1 clock domain */ 348*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_RSTEN0, PERI_RST0_MMC1); 349*054c3e0fSHaojian Zhuang 350*054c3e0fSHaojian Zhuang /* bypass mmc1 clock phase */ 351*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CTRL2); 352*054c3e0fSHaojian Zhuang data |= 3 << 2; 353*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL2, data); 354*054c3e0fSHaojian Zhuang 355*054c3e0fSHaojian Zhuang /* disable low power */ 356*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_CTRL13); 357*054c3e0fSHaojian Zhuang data |= 1 << 4; 358*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_CTRL13, data); 359*054c3e0fSHaojian Zhuang do { 360*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); 361*054c3e0fSHaojian Zhuang } while (!(data & PERI_RST0_MMC1)); 362*054c3e0fSHaojian Zhuang 363*054c3e0fSHaojian Zhuang /* unreset mmc0 clock domain */ 364*054c3e0fSHaojian Zhuang mmio_write_32(PERI_SC_PERIPH_RSTDIS0, PERI_RST0_MMC1); 365*054c3e0fSHaojian Zhuang do { 366*054c3e0fSHaojian Zhuang data = mmio_read_32(PERI_SC_PERIPH_RSTSTAT0); 367*054c3e0fSHaojian Zhuang } while (data & PERI_RST0_MMC1); 368*054c3e0fSHaojian Zhuang } 369*054c3e0fSHaojian Zhuang 370*054c3e0fSHaojian Zhuang /* Initialize PLL of both eMMC and SD controllers. */ 371*054c3e0fSHaojian Zhuang void hikey_mmc_pll_init(void) 372*054c3e0fSHaojian Zhuang { 373*054c3e0fSHaojian Zhuang init_mmc0_pll(); 374*054c3e0fSHaojian Zhuang reset_mmc0_clk(); 375*054c3e0fSHaojian Zhuang init_media_clk(); 376*054c3e0fSHaojian Zhuang 377*054c3e0fSHaojian Zhuang dsb(); 378*054c3e0fSHaojian Zhuang 379*054c3e0fSHaojian Zhuang init_mmc1_pll(); 380*054c3e0fSHaojian Zhuang reset_mmc1_clk(); 381*054c3e0fSHaojian Zhuang } 382*054c3e0fSHaojian Zhuang 383*054c3e0fSHaojian Zhuang void hikey_rtc_init(void) 384*054c3e0fSHaojian Zhuang { 385*054c3e0fSHaojian Zhuang uint32_t data; 386*054c3e0fSHaojian Zhuang 387*054c3e0fSHaojian Zhuang data = mmio_read_32(AO_SC_PERIPH_CLKEN4); 388*054c3e0fSHaojian Zhuang data |= AO_SC_PERIPH_RSTDIS4_RESET_RTC0_N; 389*054c3e0fSHaojian Zhuang mmio_write_32(AO_SC_PERIPH_CLKEN4, data); 390*054c3e0fSHaojian Zhuang } 391