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 check_hw_revision(); 154 printf("HW Revision:\t0x%04x\n", board_rev); 155 156 return 0; 157 } 158 159 int exynos_power_init(void) 160 { 161 int chrg; 162 struct power_battery *pb; 163 struct pmic *p_chrg, *p_muic, *p_fg, *p_bat; 164 165 #ifdef CONFIG_SYS_I2C_INIT_BOARD 166 board_init_i2c(); 167 #endif 168 pmic_init(I2C_7); /* I2C adapter 7 - bus name s3c24x0_7 */ 169 pmic_init_max77686(); 170 pmic_init_max77693(I2C_10); /* I2C adapter 10 - bus name soft1 */ 171 power_muic_init(I2C_10); /* I2C adapter 10 - bus name soft1 */ 172 power_fg_init(I2C_9); /* I2C adapter 9 - bus name soft0 */ 173 power_bat_init(0); 174 175 p_chrg = pmic_get("MAX77693_PMIC"); 176 if (!p_chrg) { 177 puts("MAX77693_PMIC: Not found\n"); 178 return -ENODEV; 179 } 180 181 p_muic = pmic_get("MAX77693_MUIC"); 182 if (!p_muic) { 183 puts("MAX77693_MUIC: Not found\n"); 184 return -ENODEV; 185 } 186 187 p_fg = pmic_get("MAX77693_FG"); 188 if (!p_fg) { 189 puts("MAX17042_FG: Not found\n"); 190 return -ENODEV; 191 } 192 193 if (p_chrg->chrg->chrg_bat_present(p_chrg) == 0) 194 puts("No battery detected\n"); 195 196 p_bat = pmic_get("BAT_TRATS2"); 197 if (!p_bat) { 198 puts("BAT_TRATS2: Not found\n"); 199 return -ENODEV; 200 } 201 202 p_fg->parent = p_bat; 203 p_chrg->parent = p_bat; 204 p_muic->parent = p_bat; 205 206 p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic); 207 208 pb = p_bat->pbat; 209 chrg = p_muic->chrg->chrg_type(p_muic); 210 debug("CHARGER TYPE: %d\n", chrg); 211 212 if (!p_chrg->chrg->chrg_bat_present(p_chrg)) { 213 puts("No battery detected\n"); 214 return -1; 215 } 216 217 p_fg->fg->fg_battery_check(p_fg, p_bat); 218 219 if (pb->bat->state == CHARGE && chrg == CHARGER_USB) 220 puts("CHARGE Battery !\n"); 221 222 return 0; 223 } 224 225 #ifdef CONFIG_USB_GADGET 226 static int s5pc210_phy_control(int on) 227 { 228 int ret = 0; 229 unsigned int val; 230 struct pmic *p, *p_pmic, *p_muic; 231 232 p_pmic = pmic_get("MAX77686_PMIC"); 233 if (!p_pmic) 234 return -ENODEV; 235 236 if (pmic_probe(p_pmic)) 237 return -1; 238 239 p_muic = pmic_get("MAX77693_MUIC"); 240 if (!p_muic) 241 return -ENODEV; 242 243 if (pmic_probe(p_muic)) 244 return -1; 245 246 if (on) { 247 ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON); 248 if (ret) 249 return -1; 250 251 p = pmic_get("MAX77693_PMIC"); 252 if (!p) 253 return -ENODEV; 254 255 if (pmic_probe(p)) 256 return -1; 257 258 /* SAFEOUT */ 259 ret = pmic_reg_read(p, MAX77693_SAFEOUT, &val); 260 if (ret) 261 return -1; 262 263 val |= MAX77693_ENSAFEOUT1; 264 ret = pmic_reg_write(p, MAX77693_SAFEOUT, val); 265 if (ret) 266 return -1; 267 268 /* PATH: USB */ 269 ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1, 270 MAX77693_MUIC_CTRL1_DN1DP2); 271 272 } else { 273 ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM); 274 if (ret) 275 return -1; 276 277 /* PATH: UART */ 278 ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1, 279 MAX77693_MUIC_CTRL1_UT1UR2); 280 } 281 282 if (ret) 283 return -1; 284 285 return 0; 286 } 287 288 struct s3c_plat_otg_data s5pc210_otg_data = { 289 .phy_control = s5pc210_phy_control, 290 .regs_phy = EXYNOS4X12_USBPHY_BASE, 291 .regs_otg = EXYNOS4X12_USBOTG_BASE, 292 .usb_phy_ctrl = EXYNOS4X12_USBPHY_CONTROL, 293 .usb_flags = PHY0_SLEEP, 294 }; 295 296 int board_usb_init(int index, enum usb_init_type init) 297 { 298 debug("USB_udc_probe\n"); 299 return s3c_udc_probe(&s5pc210_otg_data); 300 } 301 302 #ifdef CONFIG_USB_CABLE_CHECK 303 int usb_cable_connected(void) 304 { 305 struct pmic *muic = pmic_get("MAX77693_MUIC"); 306 if (!muic) 307 return 0; 308 309 return !!muic->chrg->chrg_type(muic); 310 } 311 #endif 312 #endif 313 314 static int pmic_init_max77686(void) 315 { 316 struct pmic *p = pmic_get("MAX77686_PMIC"); 317 318 if (pmic_probe(p)) 319 return -1; 320 321 /* BUCK/LDO Output Voltage */ 322 max77686_set_ldo_voltage(p, 21, 2800000); /* LDO21 VTF_2.8V */ 323 max77686_set_ldo_voltage(p, 23, 3300000); /* LDO23 TSP_AVDD_3.3V*/ 324 max77686_set_ldo_voltage(p, 24, 1800000); /* LDO24 TSP_VDD_1.8V */ 325 326 /* BUCK/LDO Output Mode */ 327 max77686_set_buck_mode(p, 1, OPMODE_STANDBY); /* BUCK1 VMIF_1.1V_AP */ 328 max77686_set_buck_mode(p, 2, OPMODE_ON); /* BUCK2 VARM_1.0V_AP */ 329 max77686_set_buck_mode(p, 3, OPMODE_ON); /* BUCK3 VINT_1.0V_AP */ 330 max77686_set_buck_mode(p, 4, OPMODE_ON); /* BUCK4 VG3D_1.0V_AP */ 331 max77686_set_buck_mode(p, 5, OPMODE_ON); /* BUCK5 VMEM_1.2V_AP */ 332 max77686_set_buck_mode(p, 6, OPMODE_ON); /* BUCK6 VCC_SUB_1.35V*/ 333 max77686_set_buck_mode(p, 7, OPMODE_ON); /* BUCK7 VCC_SUB_2.0V */ 334 max77686_set_buck_mode(p, 8, OPMODE_OFF); /* VMEM_VDDF_2.85V */ 335 max77686_set_buck_mode(p, 9, OPMODE_OFF); /* CAM_ISP_CORE_1.2V*/ 336 337 max77686_set_ldo_mode(p, 1, OPMODE_LPM); /* LDO1 VALIVE_1.0V_AP*/ 338 max77686_set_ldo_mode(p, 2, OPMODE_STANDBY); /* LDO2 VM1M2_1.2V_AP */ 339 max77686_set_ldo_mode(p, 3, OPMODE_LPM); /* LDO3 VCC_1.8V_AP */ 340 max77686_set_ldo_mode(p, 4, OPMODE_LPM); /* LDO4 VCC_2.8V_AP */ 341 max77686_set_ldo_mode(p, 5, OPMODE_OFF); /* LDO5_VCC_1.8V_IO */ 342 max77686_set_ldo_mode(p, 6, OPMODE_STANDBY); /* LDO6 VMPLL_1.0V_AP */ 343 max77686_set_ldo_mode(p, 7, OPMODE_STANDBY); /* LDO7 VPLL_1.0V_AP */ 344 max77686_set_ldo_mode(p, 8, OPMODE_LPM); /* LDO8 VMIPI_1.0V_AP */ 345 max77686_set_ldo_mode(p, 9, OPMODE_OFF); /* CAM_ISP_MIPI_1.2*/ 346 max77686_set_ldo_mode(p, 10, OPMODE_LPM); /* LDO10 VMIPI_1.8V_AP*/ 347 max77686_set_ldo_mode(p, 11, OPMODE_STANDBY); /* LDO11 VABB1_1.8V_AP*/ 348 max77686_set_ldo_mode(p, 12, OPMODE_LPM); /* LDO12 VUOTG_3.0V_AP*/ 349 max77686_set_ldo_mode(p, 13, OPMODE_OFF); /* LDO13 VC2C_1.8V_AP */ 350 max77686_set_ldo_mode(p, 14, OPMODE_STANDBY); /* VABB02_1.8V_AP */ 351 max77686_set_ldo_mode(p, 15, OPMODE_STANDBY); /* LDO15 VHSIC_1.0V_AP*/ 352 max77686_set_ldo_mode(p, 16, OPMODE_STANDBY); /* LDO16 VHSIC_1.8V_AP*/ 353 max77686_set_ldo_mode(p, 17, OPMODE_OFF); /* CAM_SENSOR_CORE_1.2*/ 354 max77686_set_ldo_mode(p, 18, OPMODE_OFF); /* CAM_ISP_SEN_IO_1.8V*/ 355 max77686_set_ldo_mode(p, 19, OPMODE_OFF); /* LDO19 VT_CAM_1.8V */ 356 max77686_set_ldo_mode(p, 20, OPMODE_ON); /* LDO20 VDDQ_PRE_1.8V*/ 357 max77686_set_ldo_mode(p, 21, OPMODE_OFF); /* LDO21 VTF_2.8V */ 358 max77686_set_ldo_mode(p, 22, OPMODE_OFF); /* LDO22 VMEM_VDD_2.8V*/ 359 max77686_set_ldo_mode(p, 23, OPMODE_OFF); /* LDO23 TSP_AVDD_3.3V*/ 360 max77686_set_ldo_mode(p, 24, OPMODE_OFF); /* LDO24 TSP_VDD_1.8V */ 361 max77686_set_ldo_mode(p, 25, OPMODE_OFF); /* LDO25 VCC_3.3V_LCD */ 362 max77686_set_ldo_mode(p, 26, OPMODE_OFF); /*LDO26 VCC_3.0V_MOTOR*/ 363 364 return 0; 365 } 366 367 /* 368 * LCD 369 */ 370 371 #ifdef CONFIG_LCD 372 int mipi_power(void) 373 { 374 struct pmic *p = pmic_get("MAX77686_PMIC"); 375 376 /* LDO8 VMIPI_1.0V_AP */ 377 max77686_set_ldo_mode(p, 8, OPMODE_ON); 378 /* LDO10 VMIPI_1.8V_AP */ 379 max77686_set_ldo_mode(p, 10, OPMODE_ON); 380 381 return 0; 382 } 383 384 void exynos_lcd_power_on(void) 385 { 386 struct pmic *p = pmic_get("MAX77686_PMIC"); 387 388 gpio1 = (struct exynos4x12_gpio_part1 *)samsung_get_base_gpio_part1(); 389 390 /* LCD_2.2V_EN: GPC0[1] */ 391 s5p_gpio_set_pull(&gpio1->c0, 1, GPIO_PULL_UP); 392 s5p_gpio_direction_output(&gpio1->c0, 1, 1); 393 394 /* LDO25 VCC_3.1V_LCD */ 395 pmic_probe(p); 396 max77686_set_ldo_voltage(p, 25, 3100000); 397 max77686_set_ldo_mode(p, 25, OPMODE_LPM); 398 } 399 400 void exynos_reset_lcd(void) 401 { 402 gpio1 = (struct exynos4x12_gpio_part1 *)samsung_get_base_gpio_part1(); 403 404 /* reset lcd */ 405 s5p_gpio_direction_output(&gpio1->f2, 1, 0); 406 udelay(10); 407 s5p_gpio_set_value(&gpio1->f2, 1, 1); 408 } 409 410 void exynos_lcd_misc_init(vidinfo_t *vid) 411 { 412 #ifdef CONFIG_TIZEN 413 get_tizen_logo_info(vid); 414 #endif 415 #ifdef CONFIG_S6E8AX0 416 s6e8ax0_init(); 417 #endif 418 } 419 #endif /* LCD */ 420