1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2011 Samsung Electronics 4 * Heungjun Kim <riverful.kim@samsung.com> 5 * Kyungmin Park <kyungmin.park@samsung.com> 6 * Donghwa Lee <dh09.lee@samsung.com> 7 */ 8 9 #include <common.h> 10 #include <lcd.h> 11 #include <asm/io.h> 12 #include <asm/gpio.h> 13 #include <asm/arch/cpu.h> 14 #include <asm/arch/pinmux.h> 15 #include <asm/arch/clock.h> 16 #include <asm/arch/mipi_dsim.h> 17 #include <asm/arch/watchdog.h> 18 #include <asm/arch/power.h> 19 #include <power/pmic.h> 20 #include <usb/dwc2_udc.h> 21 #include <power/max8997_pmic.h> 22 #include <power/max8997_muic.h> 23 #include <power/battery.h> 24 #include <power/max17042_fg.h> 25 #include <power/pmic.h> 26 #include <libtizen.h> 27 #include <usb.h> 28 #include <usb_mass_storage.h> 29 30 #include "setup.h" 31 32 unsigned int board_rev; 33 34 #ifdef CONFIG_REVISION_TAG 35 u32 get_board_rev(void) 36 { 37 return board_rev; 38 } 39 #endif 40 41 static void check_hw_revision(void); 42 struct dwc2_plat_otg_data s5pc210_otg_data; 43 44 int exynos_init(void) 45 { 46 check_hw_revision(); 47 printf("HW Revision:\t0x%x\n", board_rev); 48 49 return 0; 50 } 51 52 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ 53 static void trats_low_power_mode(void) 54 { 55 struct exynos4_clock *clk = 56 (struct exynos4_clock *)samsung_get_base_clock(); 57 struct exynos4_power *pwr = 58 (struct exynos4_power *)samsung_get_base_power(); 59 60 /* Power down CORE1 */ 61 /* LOCAL_PWR_CFG [1:0] 0x3 EN, 0x0 DIS */ 62 writel(0x0, &pwr->arm_core1_configuration); 63 64 /* Change the APLL frequency */ 65 /* ENABLE (1 enable) | LOCKED (1 locked) */ 66 /* [31] | [29] */ 67 /* FSEL | MDIV | PDIV | SDIV */ 68 /* [27] | [25:16] | [13:8] | [2:0] */ 69 writel(0xa0c80604, &clk->apll_con0); 70 71 /* Change CPU0 clock divider */ 72 /* CORE2_RATIO | APLL_RATIO | PCLK_DBG_RATIO | ATB_RATIO */ 73 /* [30:28] | [26:24] | [22:20] | [18:16] */ 74 /* PERIPH_RATIO | COREM1_RATIO | COREM0_RATIO | CORE_RATIO */ 75 /* [14:12] | [10:8] | [6:4] | [2:0] */ 76 writel(0x00000100, &clk->div_cpu0); 77 78 /* CLK_DIV_STAT_CPU0 - wait until clock gets stable (0 = stable) */ 79 while (readl(&clk->div_stat_cpu0) & 0x1111111) 80 continue; 81 82 /* Change clock divider ratio for DMC */ 83 /* DMCP_RATIO | DMCD_RATIO */ 84 /* [22:20] | [18:16] */ 85 /* DMC_RATIO | DPHY_RATIO | ACP_PCLK_RATIO | ACP_RATIO */ 86 /* [14:12] | [10:8] | [6:4] | [2:0] */ 87 writel(0x13113117, &clk->div_dmc0); 88 89 /* CLK_DIV_STAT_DMC0 - wait until clock gets stable (0 = stable) */ 90 while (readl(&clk->div_stat_dmc0) & 0x11111111) 91 continue; 92 93 /* Turn off unnecessary power domains */ 94 writel(0x0, &pwr->xxti_configuration); /* XXTI */ 95 writel(0x0, &pwr->cam_configuration); /* CAM */ 96 writel(0x0, &pwr->tv_configuration); /* TV */ 97 writel(0x0, &pwr->mfc_configuration); /* MFC */ 98 writel(0x0, &pwr->g3d_configuration); /* G3D */ 99 writel(0x0, &pwr->gps_configuration); /* GPS */ 100 writel(0x0, &pwr->gps_alive_configuration); /* GPS_ALIVE */ 101 102 /* Turn off unnecessary clocks */ 103 writel(0x0, &clk->gate_ip_cam); /* CAM */ 104 writel(0x0, &clk->gate_ip_tv); /* TV */ 105 writel(0x0, &clk->gate_ip_mfc); /* MFC */ 106 writel(0x0, &clk->gate_ip_g3d); /* G3D */ 107 writel(0x0, &clk->gate_ip_image); /* IMAGE */ 108 writel(0x0, &clk->gate_ip_gps); /* GPS */ 109 } 110 #endif 111 112 int exynos_power_init(void) 113 { 114 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ 115 int chrg, ret; 116 struct power_battery *pb; 117 struct pmic *p_fg, *p_chrg, *p_muic, *p_bat; 118 119 /* 120 * For PMIC/MUIC the I2C bus is named as I2C5, but it is connected 121 * to logical I2C adapter 0 122 * 123 * The FUEL_GAUGE is marked as I2C9 on the schematic, but connected 124 * to logical I2C adapter 1 125 */ 126 ret = power_fg_init(I2C_9); 127 ret |= power_muic_init(I2C_5); 128 ret |= power_bat_init(0); 129 if (ret) 130 return ret; 131 132 p_fg = pmic_get("MAX17042_FG"); 133 if (!p_fg) { 134 puts("MAX17042_FG: Not found\n"); 135 return -ENODEV; 136 } 137 138 p_chrg = pmic_get("MAX8997_PMIC"); 139 if (!p_chrg) { 140 puts("MAX8997_PMIC: Not found\n"); 141 return -ENODEV; 142 } 143 144 p_muic = pmic_get("MAX8997_MUIC"); 145 if (!p_muic) { 146 puts("MAX8997_MUIC: Not found\n"); 147 return -ENODEV; 148 } 149 150 p_bat = pmic_get("BAT_TRATS"); 151 if (!p_bat) { 152 puts("BAT_TRATS: Not found\n"); 153 return -ENODEV; 154 } 155 156 p_fg->parent = p_bat; 157 p_chrg->parent = p_bat; 158 p_muic->parent = p_bat; 159 160 p_bat->low_power_mode = trats_low_power_mode; 161 p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic); 162 163 pb = p_bat->pbat; 164 chrg = p_muic->chrg->chrg_type(p_muic); 165 debug("CHARGER TYPE: %d\n", chrg); 166 167 if (!p_chrg->chrg->chrg_bat_present(p_chrg)) { 168 puts("No battery detected\n"); 169 return 0; 170 } 171 172 p_fg->fg->fg_battery_check(p_fg, p_bat); 173 174 if (pb->bat->state == CHARGE && chrg == CHARGER_USB) 175 puts("CHARGE Battery !\n"); 176 #endif 177 178 return 0; 179 } 180 181 static unsigned int get_hw_revision(void) 182 { 183 int hwrev = 0; 184 char str[10]; 185 int i; 186 187 /* hw_rev[3:0] == GPE1[3:0] */ 188 for (i = 0; i < 4; i++) { 189 int pin = i + EXYNOS4_GPIO_E10; 190 191 sprintf(str, "hw_rev%d", i); 192 gpio_request(pin, str); 193 gpio_cfg_pin(pin, S5P_GPIO_INPUT); 194 gpio_set_pull(pin, S5P_GPIO_PULL_NONE); 195 } 196 197 udelay(1); 198 199 for (i = 0; i < 4; i++) 200 hwrev |= (gpio_get_value(EXYNOS4_GPIO_E10 + i) << i); 201 202 debug("hwrev 0x%x\n", hwrev); 203 204 return hwrev; 205 } 206 207 static void check_hw_revision(void) 208 { 209 int hwrev; 210 211 hwrev = get_hw_revision(); 212 213 board_rev |= hwrev; 214 } 215 216 217 #ifdef CONFIG_USB_GADGET 218 static int s5pc210_phy_control(int on) 219 { 220 struct udevice *dev; 221 int reg, ret; 222 223 ret = pmic_get("max8997-pmic", &dev); 224 if (ret) 225 return ret; 226 227 if (on) { 228 reg = pmic_reg_read(dev, MAX8997_REG_SAFEOUTCTRL); 229 reg |= ENSAFEOUT1; 230 ret = pmic_reg_write(dev, MAX8997_REG_SAFEOUTCTRL, reg); 231 if (ret) { 232 puts("MAX8997 setting error!\n"); 233 return ret; 234 } 235 reg = pmic_reg_read(dev, MAX8997_REG_LDO3CTRL); 236 reg |= EN_LDO; 237 ret = pmic_reg_write(dev, MAX8997_REG_LDO3CTRL, reg); 238 if (ret) { 239 puts("MAX8997 setting error!\n"); 240 return ret; 241 } 242 reg = pmic_reg_read(dev, MAX8997_REG_LDO8CTRL); 243 reg |= EN_LDO; 244 ret = pmic_reg_write(dev, MAX8997_REG_LDO8CTRL, reg); 245 if (ret) { 246 puts("MAX8997 setting error!\n"); 247 return ret; 248 } 249 } else { 250 reg = pmic_reg_read(dev, MAX8997_REG_LDO8CTRL); 251 reg &= DIS_LDO; 252 ret = pmic_reg_write(dev, MAX8997_REG_LDO8CTRL, reg); 253 if (ret) { 254 puts("MAX8997 setting error!\n"); 255 return ret; 256 } 257 reg = pmic_reg_read(dev, MAX8997_REG_LDO3CTRL); 258 reg &= DIS_LDO; 259 ret = pmic_reg_write(dev, MAX8997_REG_LDO3CTRL, reg); 260 if (ret) { 261 puts("MAX8997 setting error!\n"); 262 return ret; 263 } 264 reg = pmic_reg_read(dev, MAX8997_REG_SAFEOUTCTRL); 265 reg &= ~ENSAFEOUT1; 266 ret = pmic_reg_write(dev, MAX8997_REG_SAFEOUTCTRL, reg); 267 if (ret) { 268 puts("MAX8997 setting error!\n"); 269 return ret; 270 } 271 272 } 273 274 return 0; 275 } 276 277 struct dwc2_plat_otg_data s5pc210_otg_data = { 278 .phy_control = s5pc210_phy_control, 279 .regs_phy = EXYNOS4_USBPHY_BASE, 280 .regs_otg = EXYNOS4_USBOTG_BASE, 281 .usb_phy_ctrl = EXYNOS4_USBPHY_CONTROL, 282 .usb_flags = PHY0_SLEEP, 283 }; 284 285 int board_usb_init(int index, enum usb_init_type init) 286 { 287 debug("USB_udc_probe\n"); 288 return dwc2_udc_probe(&s5pc210_otg_data); 289 } 290 291 int g_dnl_board_usb_cable_connected(void) 292 { 293 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ 294 struct pmic *muic = pmic_get("MAX8997_MUIC"); 295 if (!muic) 296 return 0; 297 298 return !!muic->chrg->chrg_type(muic); 299 #else 300 return false; 301 #endif 302 303 } 304 #endif 305 306 static void pmic_reset(void) 307 { 308 gpio_direction_output(EXYNOS4_GPIO_X07, 1); 309 gpio_set_pull(EXYNOS4_GPIO_X27, S5P_GPIO_PULL_NONE); 310 } 311 312 static void board_clock_init(void) 313 { 314 struct exynos4_clock *clk = 315 (struct exynos4_clock *)samsung_get_base_clock(); 316 317 writel(CLK_SRC_CPU_VAL, (unsigned int)&clk->src_cpu); 318 writel(CLK_SRC_TOP0_VAL, (unsigned int)&clk->src_top0); 319 writel(CLK_SRC_FSYS_VAL, (unsigned int)&clk->src_fsys); 320 writel(CLK_SRC_PERIL0_VAL, (unsigned int)&clk->src_peril0); 321 322 writel(CLK_DIV_CPU0_VAL, (unsigned int)&clk->div_cpu0); 323 writel(CLK_DIV_CPU1_VAL, (unsigned int)&clk->div_cpu1); 324 writel(CLK_DIV_DMC0_VAL, (unsigned int)&clk->div_dmc0); 325 writel(CLK_DIV_DMC1_VAL, (unsigned int)&clk->div_dmc1); 326 writel(CLK_DIV_LEFTBUS_VAL, (unsigned int)&clk->div_leftbus); 327 writel(CLK_DIV_RIGHTBUS_VAL, (unsigned int)&clk->div_rightbus); 328 writel(CLK_DIV_TOP_VAL, (unsigned int)&clk->div_top); 329 writel(CLK_DIV_FSYS1_VAL, (unsigned int)&clk->div_fsys1); 330 writel(CLK_DIV_FSYS2_VAL, (unsigned int)&clk->div_fsys2); 331 writel(CLK_DIV_FSYS3_VAL, (unsigned int)&clk->div_fsys3); 332 writel(CLK_DIV_PERIL0_VAL, (unsigned int)&clk->div_peril0); 333 writel(CLK_DIV_PERIL3_VAL, (unsigned int)&clk->div_peril3); 334 335 writel(PLL_LOCKTIME, (unsigned int)&clk->apll_lock); 336 writel(PLL_LOCKTIME, (unsigned int)&clk->mpll_lock); 337 writel(PLL_LOCKTIME, (unsigned int)&clk->epll_lock); 338 writel(PLL_LOCKTIME, (unsigned int)&clk->vpll_lock); 339 writel(APLL_CON1_VAL, (unsigned int)&clk->apll_con1); 340 writel(APLL_CON0_VAL, (unsigned int)&clk->apll_con0); 341 writel(MPLL_CON1_VAL, (unsigned int)&clk->mpll_con1); 342 writel(MPLL_CON0_VAL, (unsigned int)&clk->mpll_con0); 343 writel(EPLL_CON1_VAL, (unsigned int)&clk->epll_con1); 344 writel(EPLL_CON0_VAL, (unsigned int)&clk->epll_con0); 345 writel(VPLL_CON1_VAL, (unsigned int)&clk->vpll_con1); 346 writel(VPLL_CON0_VAL, (unsigned int)&clk->vpll_con0); 347 348 writel(CLK_GATE_IP_CAM_VAL, (unsigned int)&clk->gate_ip_cam); 349 writel(CLK_GATE_IP_VP_VAL, (unsigned int)&clk->gate_ip_tv); 350 writel(CLK_GATE_IP_MFC_VAL, (unsigned int)&clk->gate_ip_mfc); 351 writel(CLK_GATE_IP_G3D_VAL, (unsigned int)&clk->gate_ip_g3d); 352 writel(CLK_GATE_IP_IMAGE_VAL, (unsigned int)&clk->gate_ip_image); 353 writel(CLK_GATE_IP_LCD0_VAL, (unsigned int)&clk->gate_ip_lcd0); 354 writel(CLK_GATE_IP_LCD1_VAL, (unsigned int)&clk->gate_ip_lcd1); 355 writel(CLK_GATE_IP_FSYS_VAL, (unsigned int)&clk->gate_ip_fsys); 356 writel(CLK_GATE_IP_GPS_VAL, (unsigned int)&clk->gate_ip_gps); 357 writel(CLK_GATE_IP_PERIL_VAL, (unsigned int)&clk->gate_ip_peril); 358 writel(CLK_GATE_IP_PERIR_VAL, (unsigned int)&clk->gate_ip_perir); 359 writel(CLK_GATE_BLOCK_VAL, (unsigned int)&clk->gate_block); 360 } 361 362 static void board_power_init(void) 363 { 364 struct exynos4_power *pwr = 365 (struct exynos4_power *)samsung_get_base_power(); 366 367 /* PS HOLD */ 368 writel(EXYNOS4_PS_HOLD_CON_VAL, (unsigned int)&pwr->ps_hold_control); 369 370 /* Set power down */ 371 writel(0, (unsigned int)&pwr->cam_configuration); 372 writel(0, (unsigned int)&pwr->tv_configuration); 373 writel(0, (unsigned int)&pwr->mfc_configuration); 374 writel(0, (unsigned int)&pwr->g3d_configuration); 375 writel(0, (unsigned int)&pwr->lcd1_configuration); 376 writel(0, (unsigned int)&pwr->gps_configuration); 377 writel(0, (unsigned int)&pwr->gps_alive_configuration); 378 379 /* It is necessary to power down core 1 */ 380 /* to successfully boot CPU1 in kernel */ 381 writel(0, (unsigned int)&pwr->arm_core1_configuration); 382 } 383 384 static void exynos_uart_init(void) 385 { 386 /* UART_SEL GPY4[7] (part2) at EXYNOS4 */ 387 gpio_request(EXYNOS4_GPIO_Y47, "uart_sel"); 388 gpio_set_pull(EXYNOS4_GPIO_Y47, S5P_GPIO_PULL_UP); 389 gpio_direction_output(EXYNOS4_GPIO_Y47, 1); 390 } 391 392 int exynos_early_init_f(void) 393 { 394 wdt_stop(); 395 pmic_reset(); 396 board_clock_init(); 397 exynos_uart_init(); 398 board_power_init(); 399 400 return 0; 401 } 402 403 void exynos_reset_lcd(void) 404 { 405 gpio_request(EXYNOS4_GPIO_Y45, "lcd_reset"); 406 gpio_direction_output(EXYNOS4_GPIO_Y45, 1); 407 udelay(10000); 408 gpio_direction_output(EXYNOS4_GPIO_Y45, 0); 409 udelay(10000); 410 gpio_direction_output(EXYNOS4_GPIO_Y45, 1); 411 } 412 413 int lcd_power(void) 414 { 415 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ 416 int ret = 0; 417 struct pmic *p = pmic_get("MAX8997_PMIC"); 418 if (!p) 419 return -ENODEV; 420 421 if (pmic_probe(p)) 422 return 0; 423 424 /* LDO15 voltage: 2.2v */ 425 ret |= pmic_reg_write(p, MAX8997_REG_LDO15CTRL, 0x1c | EN_LDO); 426 /* LDO13 voltage: 3.0v */ 427 ret |= pmic_reg_write(p, MAX8997_REG_LDO13CTRL, 0x2c | EN_LDO); 428 429 if (ret) { 430 puts("MAX8997 LDO setting error!\n"); 431 return -1; 432 } 433 #endif 434 return 0; 435 } 436 437 int mipi_power(void) 438 { 439 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */ 440 int ret = 0; 441 struct pmic *p = pmic_get("MAX8997_PMIC"); 442 if (!p) 443 return -ENODEV; 444 445 if (pmic_probe(p)) 446 return 0; 447 448 /* LDO3 voltage: 1.1v */ 449 ret |= pmic_reg_write(p, MAX8997_REG_LDO3CTRL, 0x6 | EN_LDO); 450 /* LDO4 voltage: 1.8v */ 451 ret |= pmic_reg_write(p, MAX8997_REG_LDO4CTRL, 0x14 | EN_LDO); 452 453 if (ret) { 454 puts("MAX8997 LDO setting error!\n"); 455 return -1; 456 } 457 #endif 458 return 0; 459 } 460 461 #ifdef CONFIG_LCD 462 void exynos_lcd_misc_init(vidinfo_t *vid) 463 { 464 #ifdef CONFIG_TIZEN 465 get_tizen_logo_info(vid); 466 #endif 467 #ifdef CONFIG_S6E8AX0 468 s6e8ax0_init(); 469 env_set("lcdinfo", "lcd=s6e8ax0"); 470 #endif 471 } 472 #endif 473