1 /* 2 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved. 3 * Sanghee Kim <sh0130.kim@samsung.com> 4 * Piotr Wilczek <p.wilczek@samsung.com> 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <lcd.h> 11 #include <asm/arch/pinmux.h> 12 #include <asm/arch/power.h> 13 #include <asm/arch/mipi_dsim.h> 14 #include <power/pmic.h> 15 #include <power/max77686_pmic.h> 16 #include <power/battery.h> 17 #include <power/max77693_pmic.h> 18 #include <power/max77693_muic.h> 19 #include <power/max77693_fg.h> 20 #include <libtizen.h> 21 #include <errno.h> 22 #include <usb.h> 23 #include <usb/s3c_udc.h> 24 #include <usb_mass_storage.h> 25 26 DECLARE_GLOBAL_DATA_PTR; 27 28 static struct exynos4x12_gpio_part1 *gpio1; 29 static struct exynos4x12_gpio_part2 *gpio2; 30 31 static unsigned int board_rev = -1; 32 33 static inline u32 get_model_rev(void); 34 35 static void check_hw_revision(void) 36 { 37 int modelrev = 0; 38 int i; 39 40 gpio2 = (struct exynos4x12_gpio_part2 *)samsung_get_base_gpio_part2(); 41 42 /* 43 * GPM1[1:0]: MODEL_REV[1:0] 44 * Don't set as pull-none for these N/C pin. 45 * TRM say that it may cause unexcepted state and leakage current. 46 * and pull-none is only for output function. 47 */ 48 for (i = 0; i < 2; i++) 49 s5p_gpio_cfg_pin(&gpio2->m1, i, GPIO_INPUT); 50 51 /* GPM1[5:2]: HW_REV[3:0] */ 52 for (i = 2; i < 6; i++) { 53 s5p_gpio_cfg_pin(&gpio2->m1, i, GPIO_INPUT); 54 s5p_gpio_set_pull(&gpio2->m1, i, GPIO_PULL_NONE); 55 } 56 57 /* GPM1[1:0]: MODEL_REV[1:0] */ 58 for (i = 0; i < 2; i++) 59 modelrev |= (s5p_gpio_get_value(&gpio2->m1, i) << i); 60 61 /* board_rev[15:8] = model */ 62 board_rev = modelrev << 8; 63 } 64 65 u32 get_board_rev(void) 66 { 67 return board_rev; 68 } 69 70 static inline u32 get_model_rev(void) 71 { 72 return (board_rev >> 8) & 0xff; 73 } 74 75 static void board_external_gpio_init(void) 76 { 77 gpio2 = (struct exynos4x12_gpio_part2 *)samsung_get_base_gpio_part2(); 78 79 /* 80 * some pins which in alive block are connected with external pull-up 81 * but it's default setting is pull-down. 82 * if that pin set as input then that floated 83 */ 84 85 s5p_gpio_set_pull(&gpio2->x0, 2, GPIO_PULL_NONE); /* PS_ALS_INT */ 86 s5p_gpio_set_pull(&gpio2->x0, 4, GPIO_PULL_NONE); /* TSP_nINT */ 87 s5p_gpio_set_pull(&gpio2->x0, 7, GPIO_PULL_NONE); /* AP_PMIC_IRQ*/ 88 s5p_gpio_set_pull(&gpio2->x1, 5, GPIO_PULL_NONE); /* IF_PMIC_IRQ*/ 89 s5p_gpio_set_pull(&gpio2->x2, 0, GPIO_PULL_NONE); /* VOL_UP */ 90 s5p_gpio_set_pull(&gpio2->x2, 1, GPIO_PULL_NONE); /* VOL_DOWN */ 91 s5p_gpio_set_pull(&gpio2->x2, 3, GPIO_PULL_NONE); /* FUEL_ALERT */ 92 s5p_gpio_set_pull(&gpio2->x2, 4, GPIO_PULL_NONE); /* ADC_INT */ 93 s5p_gpio_set_pull(&gpio2->x2, 7, GPIO_PULL_NONE); /* nPOWER */ 94 s5p_gpio_set_pull(&gpio2->x3, 0, GPIO_PULL_NONE); /* WPC_INT */ 95 s5p_gpio_set_pull(&gpio2->x3, 5, GPIO_PULL_NONE); /* OK_KEY */ 96 s5p_gpio_set_pull(&gpio2->x3, 7, GPIO_PULL_NONE); /* HDMI_HPD */ 97 } 98 99 #ifdef CONFIG_SYS_I2C_INIT_BOARD 100 static void board_init_i2c(void) 101 { 102 int err; 103 104 gpio1 = (struct exynos4x12_gpio_part1 *)samsung_get_base_gpio_part1(); 105 gpio2 = (struct exynos4x12_gpio_part2 *)samsung_get_base_gpio_part2(); 106 107 /* I2C_7 */ 108 err = exynos_pinmux_config(PERIPH_ID_I2C7, PINMUX_FLAG_NONE); 109 if (err) { 110 debug("I2C%d not configured\n", (I2C_7)); 111 return; 112 } 113 114 /* I2C_8 */ 115 s5p_gpio_direction_output(&gpio1->f1, 4, 1); 116 s5p_gpio_direction_output(&gpio1->f1, 5, 1); 117 118 /* I2C_9 */ 119 s5p_gpio_direction_output(&gpio2->m2, 1, 1); 120 s5p_gpio_direction_output(&gpio2->m2, 0, 1); 121 } 122 #endif 123 124 #ifdef CONFIG_SYS_I2C_SOFT 125 int get_soft_i2c_scl_pin(void) 126 { 127 if (I2C_ADAP_HWNR) 128 return exynos4x12_gpio_get(2, m2, 1); /* I2C9 */ 129 else 130 return exynos4x12_gpio_get(1, f1, 4); /* I2C8 */ 131 } 132 133 int get_soft_i2c_sda_pin(void) 134 { 135 if (I2C_ADAP_HWNR) 136 return exynos4x12_gpio_get(2, m2, 0); /* I2C9 */ 137 else 138 return exynos4x12_gpio_get(1, f1, 5); /* I2C8 */ 139 } 140 #endif 141 142 int exynos_early_init_f(void) 143 { 144 board_external_gpio_init(); 145 146 return 0; 147 } 148 149 static int pmic_init_max77686(void); 150 151 int exynos_init(void) 152 { 153 struct exynos4_power *pwr = 154 (struct exynos4_power *)samsung_get_base_power(); 155 156 check_hw_revision(); 157 printf("HW Revision:\t0x%04x\n", board_rev); 158 159 /* 160 * First bootloader on the TRATS2 platform uses 161 * INFORM4 and INFORM5 registers for recovery 162 * 163 * To indicate correct boot chain - those two 164 * registers must be cleared out 165 */ 166 writel(0, &pwr->inform4); 167 writel(0, &pwr->inform5); 168 169 return 0; 170 } 171 172 int exynos_power_init(void) 173 { 174 int chrg; 175 struct power_battery *pb; 176 struct pmic *p_chrg, *p_muic, *p_fg, *p_bat; 177 178 #ifdef CONFIG_SYS_I2C_INIT_BOARD 179 board_init_i2c(); 180 #endif 181 pmic_init(I2C_7); /* I2C adapter 7 - bus name s3c24x0_7 */ 182 pmic_init_max77686(); 183 pmic_init_max77693(I2C_10); /* I2C adapter 10 - bus name soft1 */ 184 power_muic_init(I2C_10); /* I2C adapter 10 - bus name soft1 */ 185 power_fg_init(I2C_9); /* I2C adapter 9 - bus name soft0 */ 186 power_bat_init(0); 187 188 p_chrg = pmic_get("MAX77693_PMIC"); 189 if (!p_chrg) { 190 puts("MAX77693_PMIC: Not found\n"); 191 return -ENODEV; 192 } 193 194 p_muic = pmic_get("MAX77693_MUIC"); 195 if (!p_muic) { 196 puts("MAX77693_MUIC: Not found\n"); 197 return -ENODEV; 198 } 199 200 p_fg = pmic_get("MAX77693_FG"); 201 if (!p_fg) { 202 puts("MAX17042_FG: Not found\n"); 203 return -ENODEV; 204 } 205 206 if (p_chrg->chrg->chrg_bat_present(p_chrg) == 0) 207 puts("No battery detected\n"); 208 209 p_bat = pmic_get("BAT_TRATS2"); 210 if (!p_bat) { 211 puts("BAT_TRATS2: Not found\n"); 212 return -ENODEV; 213 } 214 215 p_fg->parent = p_bat; 216 p_chrg->parent = p_bat; 217 p_muic->parent = p_bat; 218 219 p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic); 220 221 pb = p_bat->pbat; 222 chrg = p_muic->chrg->chrg_type(p_muic); 223 debug("CHARGER TYPE: %d\n", chrg); 224 225 if (!p_chrg->chrg->chrg_bat_present(p_chrg)) { 226 puts("No battery detected\n"); 227 return -1; 228 } 229 230 p_fg->fg->fg_battery_check(p_fg, p_bat); 231 232 if (pb->bat->state == CHARGE && chrg == CHARGER_USB) 233 puts("CHARGE Battery !\n"); 234 235 return 0; 236 } 237 238 #ifdef CONFIG_USB_GADGET 239 static int s5pc210_phy_control(int on) 240 { 241 int ret = 0; 242 unsigned int val; 243 struct pmic *p, *p_pmic, *p_muic; 244 245 p_pmic = pmic_get("MAX77686_PMIC"); 246 if (!p_pmic) 247 return -ENODEV; 248 249 if (pmic_probe(p_pmic)) 250 return -1; 251 252 p_muic = pmic_get("MAX77693_MUIC"); 253 if (!p_muic) 254 return -ENODEV; 255 256 if (pmic_probe(p_muic)) 257 return -1; 258 259 if (on) { 260 ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON); 261 if (ret) 262 return -1; 263 264 p = pmic_get("MAX77693_PMIC"); 265 if (!p) 266 return -ENODEV; 267 268 if (pmic_probe(p)) 269 return -1; 270 271 /* SAFEOUT */ 272 ret = pmic_reg_read(p, MAX77693_SAFEOUT, &val); 273 if (ret) 274 return -1; 275 276 val |= MAX77693_ENSAFEOUT1; 277 ret = pmic_reg_write(p, MAX77693_SAFEOUT, val); 278 if (ret) 279 return -1; 280 281 /* PATH: USB */ 282 ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1, 283 MAX77693_MUIC_CTRL1_DN1DP2); 284 285 } else { 286 ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM); 287 if (ret) 288 return -1; 289 290 /* PATH: UART */ 291 ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1, 292 MAX77693_MUIC_CTRL1_UT1UR2); 293 } 294 295 if (ret) 296 return -1; 297 298 return 0; 299 } 300 301 struct s3c_plat_otg_data s5pc210_otg_data = { 302 .phy_control = s5pc210_phy_control, 303 .regs_phy = EXYNOS4X12_USBPHY_BASE, 304 .regs_otg = EXYNOS4X12_USBOTG_BASE, 305 .usb_phy_ctrl = EXYNOS4X12_USBPHY_CONTROL, 306 .usb_flags = PHY0_SLEEP, 307 }; 308 309 int board_usb_init(int index, enum usb_init_type init) 310 { 311 debug("USB_udc_probe\n"); 312 return s3c_udc_probe(&s5pc210_otg_data); 313 } 314 315 int g_dnl_board_usb_cable_connected(void) 316 { 317 struct pmic *muic = pmic_get("MAX77693_MUIC"); 318 if (!muic) 319 return 0; 320 321 return !!muic->chrg->chrg_type(muic); 322 } 323 #endif 324 325 static int pmic_init_max77686(void) 326 { 327 struct pmic *p = pmic_get("MAX77686_PMIC"); 328 329 if (pmic_probe(p)) 330 return -1; 331 332 /* BUCK/LDO Output Voltage */ 333 max77686_set_ldo_voltage(p, 21, 2800000); /* LDO21 VTF_2.8V */ 334 max77686_set_ldo_voltage(p, 23, 3300000); /* LDO23 TSP_AVDD_3.3V*/ 335 max77686_set_ldo_voltage(p, 24, 1800000); /* LDO24 TSP_VDD_1.8V */ 336 337 /* BUCK/LDO Output Mode */ 338 max77686_set_buck_mode(p, 1, OPMODE_STANDBY); /* BUCK1 VMIF_1.1V_AP */ 339 max77686_set_buck_mode(p, 2, OPMODE_ON); /* BUCK2 VARM_1.0V_AP */ 340 max77686_set_buck_mode(p, 3, OPMODE_ON); /* BUCK3 VINT_1.0V_AP */ 341 max77686_set_buck_mode(p, 4, OPMODE_ON); /* BUCK4 VG3D_1.0V_AP */ 342 max77686_set_buck_mode(p, 5, OPMODE_ON); /* BUCK5 VMEM_1.2V_AP */ 343 max77686_set_buck_mode(p, 6, OPMODE_ON); /* BUCK6 VCC_SUB_1.35V*/ 344 max77686_set_buck_mode(p, 7, OPMODE_ON); /* BUCK7 VCC_SUB_2.0V */ 345 max77686_set_buck_mode(p, 8, OPMODE_OFF); /* VMEM_VDDF_2.85V */ 346 max77686_set_buck_mode(p, 9, OPMODE_OFF); /* CAM_ISP_CORE_1.2V*/ 347 348 max77686_set_ldo_mode(p, 1, OPMODE_LPM); /* LDO1 VALIVE_1.0V_AP*/ 349 max77686_set_ldo_mode(p, 2, OPMODE_STANDBY); /* LDO2 VM1M2_1.2V_AP */ 350 max77686_set_ldo_mode(p, 3, OPMODE_LPM); /* LDO3 VCC_1.8V_AP */ 351 max77686_set_ldo_mode(p, 4, OPMODE_LPM); /* LDO4 VCC_2.8V_AP */ 352 max77686_set_ldo_mode(p, 5, OPMODE_OFF); /* LDO5_VCC_1.8V_IO */ 353 max77686_set_ldo_mode(p, 6, OPMODE_STANDBY); /* LDO6 VMPLL_1.0V_AP */ 354 max77686_set_ldo_mode(p, 7, OPMODE_STANDBY); /* LDO7 VPLL_1.0V_AP */ 355 max77686_set_ldo_mode(p, 8, OPMODE_LPM); /* LDO8 VMIPI_1.0V_AP */ 356 max77686_set_ldo_mode(p, 9, OPMODE_OFF); /* CAM_ISP_MIPI_1.2*/ 357 max77686_set_ldo_mode(p, 10, OPMODE_LPM); /* LDO10 VMIPI_1.8V_AP*/ 358 max77686_set_ldo_mode(p, 11, OPMODE_STANDBY); /* LDO11 VABB1_1.8V_AP*/ 359 max77686_set_ldo_mode(p, 12, OPMODE_LPM); /* LDO12 VUOTG_3.0V_AP*/ 360 max77686_set_ldo_mode(p, 13, OPMODE_OFF); /* LDO13 VC2C_1.8V_AP */ 361 max77686_set_ldo_mode(p, 14, OPMODE_STANDBY); /* VABB02_1.8V_AP */ 362 max77686_set_ldo_mode(p, 15, OPMODE_STANDBY); /* LDO15 VHSIC_1.0V_AP*/ 363 max77686_set_ldo_mode(p, 16, OPMODE_STANDBY); /* LDO16 VHSIC_1.8V_AP*/ 364 max77686_set_ldo_mode(p, 17, OPMODE_OFF); /* CAM_SENSOR_CORE_1.2*/ 365 max77686_set_ldo_mode(p, 18, OPMODE_OFF); /* CAM_ISP_SEN_IO_1.8V*/ 366 max77686_set_ldo_mode(p, 19, OPMODE_OFF); /* LDO19 VT_CAM_1.8V */ 367 max77686_set_ldo_mode(p, 20, OPMODE_ON); /* LDO20 VDDQ_PRE_1.8V*/ 368 max77686_set_ldo_mode(p, 21, OPMODE_OFF); /* LDO21 VTF_2.8V */ 369 max77686_set_ldo_mode(p, 22, OPMODE_OFF); /* LDO22 VMEM_VDD_2.8V*/ 370 max77686_set_ldo_mode(p, 23, OPMODE_OFF); /* LDO23 TSP_AVDD_3.3V*/ 371 max77686_set_ldo_mode(p, 24, OPMODE_OFF); /* LDO24 TSP_VDD_1.8V */ 372 max77686_set_ldo_mode(p, 25, OPMODE_OFF); /* LDO25 VCC_3.3V_LCD */ 373 max77686_set_ldo_mode(p, 26, OPMODE_OFF); /*LDO26 VCC_3.0V_MOTOR*/ 374 375 return 0; 376 } 377 378 /* 379 * LCD 380 */ 381 382 #ifdef CONFIG_LCD 383 int mipi_power(void) 384 { 385 struct pmic *p = pmic_get("MAX77686_PMIC"); 386 387 /* LDO8 VMIPI_1.0V_AP */ 388 max77686_set_ldo_mode(p, 8, OPMODE_ON); 389 /* LDO10 VMIPI_1.8V_AP */ 390 max77686_set_ldo_mode(p, 10, OPMODE_ON); 391 392 return 0; 393 } 394 395 void exynos_lcd_power_on(void) 396 { 397 struct pmic *p = pmic_get("MAX77686_PMIC"); 398 399 gpio1 = (struct exynos4x12_gpio_part1 *)samsung_get_base_gpio_part1(); 400 401 /* LCD_2.2V_EN: GPC0[1] */ 402 s5p_gpio_set_pull(&gpio1->c0, 1, GPIO_PULL_UP); 403 s5p_gpio_direction_output(&gpio1->c0, 1, 1); 404 405 /* LDO25 VCC_3.1V_LCD */ 406 pmic_probe(p); 407 max77686_set_ldo_voltage(p, 25, 3100000); 408 max77686_set_ldo_mode(p, 25, OPMODE_LPM); 409 } 410 411 void exynos_reset_lcd(void) 412 { 413 gpio1 = (struct exynos4x12_gpio_part1 *)samsung_get_base_gpio_part1(); 414 415 /* reset lcd */ 416 s5p_gpio_direction_output(&gpio1->f2, 1, 0); 417 udelay(10); 418 s5p_gpio_set_value(&gpio1->f2, 1, 1); 419 } 420 421 void exynos_lcd_misc_init(vidinfo_t *vid) 422 { 423 #ifdef CONFIG_TIZEN 424 get_tizen_logo_info(vid); 425 #endif 426 #ifdef CONFIG_S6E8AX0 427 s6e8ax0_init(); 428 #endif 429 } 430 #endif /* LCD */ 431