trats2: fix unused variable warnings made from interactive charger
[platform/kernel/u-boot.git] / board / samsung / trats2 / trats2.c
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/gpio.h>
12 #include <asm/arch/pinmux.h>
13 #include <asm/arch/power.h>
14 #include <asm/arch/clock.h>
15 #include <asm/arch/mipi_dsim.h>
16 #include <power/pmic.h>
17 #include <power/max77686_pmic.h>
18 #include <power/battery.h>
19 #include <power/max77693_pmic.h>
20 #include <power/max77693_muic.h>
21 #include <power/max77693_fg.h>
22 #include <libtizen.h>
23 #include <samsung/misc.h>
24 #include <errno.h>
25 #include <usb.h>
26 #include <usb/dwc2_udc.h>
27 #include <usb_mass_storage.h>
28 #include "setup.h"
29
30 DECLARE_GLOBAL_DATA_PTR;
31
32 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
33 /* For global battery and charger functions */
34 static struct power_battery *pbat;
35 static struct pmic *p_chrg, *p_muic, *p_fg, *p_bat;
36 static int power_init_done;
37 #endif
38
39 static unsigned int board_rev = -1;
40 static inline u32 get_model_rev(void);
41
42 static void check_hw_revision(void)
43 {
44         int modelrev = 0;
45         char str[12];
46         int i;
47
48         /*
49          * GPM1[1:0]: MODEL_REV[1:0]
50          * Don't set as pull-none for these N/C pin.
51          * TRM say that it may cause unexcepted state and leakage current.
52          * and pull-none is only for output function.
53          */
54         for (i = 0; i < 2; i++) {
55                 int pin = i + EXYNOS4X12_GPIO_M10;
56
57                 sprintf(str, "model_rev%d", i);
58                 gpio_request(pin, str);
59                 gpio_cfg_pin(pin, S5P_GPIO_INPUT);
60         }
61
62         /* GPM1[5:2]: HW_REV[3:0] */
63         for (i = 0; i < 4; i++) {
64                 int pin = i + EXYNOS4X12_GPIO_M12;
65
66                 sprintf(str, "hw_rev%d", i);
67                 gpio_request(pin, str);
68                 gpio_cfg_pin(pin, S5P_GPIO_INPUT);
69                 gpio_set_pull(pin, S5P_GPIO_PULL_NONE);
70         }
71
72         /* GPM1[1:0]: MODEL_REV[1:0] */
73         for (i = 0; i < 2; i++)
74                 modelrev |= (gpio_get_value(EXYNOS4X12_GPIO_M10 + i) << i);
75
76         /* board_rev[15:8] = model */
77         board_rev = modelrev << 8;
78 }
79
80 u32 get_board_rev(void)
81 {
82         return board_rev;
83 }
84
85 static inline u32 get_model_rev(void)
86 {
87         return (board_rev >> 8) & 0xff;
88 }
89
90 static void board_external_gpio_init(void)
91 {
92         /*
93          * some pins which in alive block are connected with external pull-up
94          * but it's default setting is pull-down.
95          * if that pin set as input then that floated
96          */
97
98         gpio_set_pull(EXYNOS4X12_GPIO_X02, S5P_GPIO_PULL_NONE); /* PS_ALS_INT */
99         gpio_set_pull(EXYNOS4X12_GPIO_X04, S5P_GPIO_PULL_NONE); /* TSP_nINT */
100         gpio_set_pull(EXYNOS4X12_GPIO_X07, S5P_GPIO_PULL_NONE); /* AP_PMIC_IRQ*/
101         gpio_set_pull(EXYNOS4X12_GPIO_X15, S5P_GPIO_PULL_NONE); /* IF_PMIC_IRQ*/
102         gpio_set_pull(EXYNOS4X12_GPIO_X20, S5P_GPIO_PULL_NONE); /* VOL_UP */
103         gpio_set_pull(EXYNOS4X12_GPIO_X21, S5P_GPIO_PULL_NONE); /* VOL_DOWN */
104         gpio_set_pull(EXYNOS4X12_GPIO_X23, S5P_GPIO_PULL_NONE); /* FUEL_ALERT */
105         gpio_set_pull(EXYNOS4X12_GPIO_X24, S5P_GPIO_PULL_NONE); /* ADC_INT */
106         gpio_set_pull(EXYNOS4X12_GPIO_X27, S5P_GPIO_PULL_NONE); /* nPOWER */
107         gpio_set_pull(EXYNOS4X12_GPIO_X30, S5P_GPIO_PULL_NONE); /* WPC_INT */
108         gpio_set_pull(EXYNOS4X12_GPIO_X35, S5P_GPIO_PULL_NONE); /* OK_KEY */
109         gpio_set_pull(EXYNOS4X12_GPIO_X37, S5P_GPIO_PULL_NONE); /* HDMI_HPD */
110 }
111
112 #ifdef CONFIG_SYS_I2C_INIT_BOARD
113 static void board_init_i2c(void)
114 {
115         int err;
116
117         /* I2C_7 */
118         err = exynos_pinmux_config(PERIPH_ID_I2C7, PINMUX_FLAG_NONE);
119         if (err) {
120                 debug("I2C%d not configured\n", (I2C_7));
121                 return;
122         }
123
124         /* I2C_8 */
125         gpio_request(EXYNOS4X12_GPIO_F14, "i2c8_clk");
126         gpio_request(EXYNOS4X12_GPIO_F15, "i2c8_data");
127         gpio_direction_output(EXYNOS4X12_GPIO_F14, 1);
128         gpio_direction_output(EXYNOS4X12_GPIO_F15, 1);
129
130         /* I2C_9 */
131         gpio_request(EXYNOS4X12_GPIO_M21, "i2c9_clk");
132         gpio_request(EXYNOS4X12_GPIO_M20, "i2c9_data");
133         gpio_direction_output(EXYNOS4X12_GPIO_M21, 1);
134         gpio_direction_output(EXYNOS4X12_GPIO_M20, 1);
135 }
136 #endif
137
138 #ifdef CONFIG_SYS_I2C_SOFT
139 int get_soft_i2c_scl_pin(void)
140 {
141         if (I2C_ADAP_HWNR)
142                 return EXYNOS4X12_GPIO_M21; /* I2C9 */
143         else
144                 return EXYNOS4X12_GPIO_F14; /* I2C8 */
145 }
146
147 int get_soft_i2c_sda_pin(void)
148 {
149         if (I2C_ADAP_HWNR)
150                 return EXYNOS4X12_GPIO_M20; /* I2C9 */
151         else
152                 return EXYNOS4X12_GPIO_F15; /* I2C8 */
153 }
154 #endif
155
156 int exynos_early_init_f(void)
157 {
158         board_external_gpio_init();
159
160         return 0;
161 }
162
163 int exynos_init(void)
164 {
165         struct exynos4_power *pwr =
166                 (struct exynos4_power *)samsung_get_base_power();
167
168         check_hw_revision();
169         printf("HW Revision:\t0x%04x\n", board_rev);
170
171         /*
172          * First bootloader on the TRATS2 platform uses
173          * INFORM4 and INFORM5 registers for recovery
174          *
175          * To indicate correct boot chain - those two
176          * registers must be cleared out
177          */
178         writel(0, &pwr->inform4);
179         writel(0, &pwr->inform5);
180
181         return 0;
182 }
183
184 int exynos_power_init(void)
185 {
186 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
187         int chrg;
188         struct power_battery *pb;
189         struct pmic *p_chrg, *p_muic, *p_fg, *p_bat;
190
191 #ifdef CONFIG_SYS_I2C_INIT_BOARD
192         board_init_i2c();
193 #endif
194         pmic_init(I2C_7);               /* I2C adapter 7 - bus name s3c24x0_7 */
195         pmic_init_max77686();
196         pmic_init_max77693(I2C_10);     /* I2C adapter 10 - bus name soft1 */
197         power_muic_init(I2C_10);        /* I2C adapter 10 - bus name soft1 */
198         power_fg_init(I2C_9);           /* I2C adapter 9 - bus name soft0 */
199         power_bat_init(0);
200
201         p_chrg = pmic_get("MAX77693_PMIC");
202         if (!p_chrg) {
203                 puts("MAX77693_PMIC: Not found\n");
204                 return -ENODEV;
205         }
206
207         p_muic = pmic_get("MAX77693_MUIC");
208         if (!p_muic) {
209                 puts("MAX77693_MUIC: Not found\n");
210                 return -ENODEV;
211         }
212
213         p_fg = pmic_get("MAX77693_FG");
214         if (!p_fg) {
215                 puts("MAX17042_FG: Not found\n");
216                 return -ENODEV;
217         }
218
219         if (p_chrg->chrg->chrg_bat_present(p_chrg) == 0)
220                 puts("No battery detected\n");
221
222         p_bat = pmic_get("BAT_TRATS2");
223         if (!p_bat) {
224                 puts("BAT_TRATS2: Not found\n");
225                 return -ENODEV;
226         }
227
228         p_fg->parent =  p_bat;
229         p_chrg->parent = p_bat;
230         p_muic->parent = p_bat;
231
232 #ifdef CONFIG_INTERACTIVE_CHARGER
233         p_bat->low_power_mode = board_low_power_mode;
234 #endif
235         p_bat->pbat->battery_init(p_bat, p_fg, p_chrg, p_muic);
236
237         pb = p_bat->pbat;
238         chrg = p_muic->chrg->chrg_type(p_muic);
239         debug("CHARGER TYPE: %d\n", chrg);
240
241         if (!p_chrg->chrg->chrg_bat_present(p_chrg)) {
242                 puts("No battery detected\n");
243                 return 0;
244         }
245
246         p_fg->fg->fg_battery_check(p_fg, p_bat);
247
248         if (pb->bat->state == CHARGE && chrg == CHARGER_USB)
249                 puts("CHARGE Battery !\n");
250
251         pbat = p_bat->pbat;
252         power_init_done = 1;
253 #endif
254         return 0;
255 }
256
257 #ifdef CONFIG_USB_GADGET
258 static int s5pc210_phy_control(int on)
259 {
260 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
261         int ret = 0;
262         unsigned int val;
263         struct pmic *p, *p_pmic, *p_muic;
264
265         p_pmic = pmic_get("MAX77686_PMIC");
266         if (!p_pmic)
267                 return -ENODEV;
268
269         if (pmic_probe(p_pmic))
270                 return -1;
271
272         p_muic = pmic_get("MAX77693_MUIC");
273         if (!p_muic)
274                 return -ENODEV;
275
276         if (pmic_probe(p_muic))
277                 return -1;
278
279         if (on) {
280                 ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_ON);
281                 if (ret)
282                         return -1;
283
284                 p = pmic_get("MAX77693_PMIC");
285                 if (!p)
286                         return -ENODEV;
287
288                 if (pmic_probe(p))
289                         return -1;
290
291                 /* SAFEOUT */
292                 ret = pmic_reg_read(p, MAX77693_SAFEOUT, &val);
293                 if (ret)
294                         return -1;
295
296                 val |= MAX77693_ENSAFEOUT1;
297                 ret = pmic_reg_write(p, MAX77693_SAFEOUT, val);
298                 if (ret)
299                         return -1;
300
301                 /* PATH: USB */
302                 ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1,
303                         MAX77693_MUIC_CTRL1_DN1DP2);
304
305         } else {
306                 ret = max77686_set_ldo_mode(p_pmic, 12, OPMODE_LPM);
307                 if (ret)
308                         return -1;
309
310                 /* PATH: UART */
311                 ret = pmic_reg_write(p_muic, MAX77693_MUIC_CONTROL1,
312                         MAX77693_MUIC_CTRL1_UT1UR2);
313         }
314
315         if (ret)
316                 return -1;
317 #endif
318         return 0;
319 }
320
321 struct dwc2_plat_otg_data s5pc210_otg_data = {
322         .phy_control    = s5pc210_phy_control,
323         .regs_phy       = EXYNOS4X12_USBPHY_BASE,
324         .regs_otg       = EXYNOS4X12_USBOTG_BASE,
325         .usb_phy_ctrl   = EXYNOS4X12_USBPHY_CONTROL,
326         .usb_flags      = PHY0_SLEEP,
327 };
328
329 int board_usb_init(int index, enum usb_init_type init)
330 {
331         debug("USB_udc_probe\n");
332         return dwc2_udc_probe(&s5pc210_otg_data);
333 }
334
335 int g_dnl_board_usb_cable_connected(void)
336 {
337 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
338         struct pmic *muic = pmic_get("MAX77693_MUIC");
339         if (!muic)
340                 return 0;
341
342         return !!muic->chrg->chrg_type(muic);
343 #else
344         return false;
345 #endif
346 }
347 #endif
348
349 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
350 static int pmic_init_max77686(void)
351 {
352         struct pmic *p = pmic_get("MAX77686_PMIC");
353
354         if (pmic_probe(p))
355                 return -1;
356
357         /* BUCK/LDO Output Voltage */
358         max77686_set_ldo_voltage(p, 21, 2800000);       /* LDO21 VTF_2.8V */
359         max77686_set_ldo_voltage(p, 23, 3300000);       /* LDO23 TSP_AVDD_3.3V*/
360         max77686_set_ldo_voltage(p, 24, 1800000);       /* LDO24 TSP_VDD_1.8V */
361
362         /* BUCK/LDO Output Mode */
363         max77686_set_buck_mode(p, 1, OPMODE_ON);        /* BUCK1 VMIF_1.1V_AP */
364         max77686_set_buck_mode(p, 2, OPMODE_ON);        /* BUCK2 VARM_1.0V_AP */
365         max77686_set_buck_mode(p, 3, OPMODE_ON);        /* BUCK3 VINT_1.0V_AP */
366         max77686_set_buck_mode(p, 4, OPMODE_ON);        /* BUCK4 VG3D_1.0V_AP */
367         max77686_set_buck_mode(p, 5, OPMODE_ON);        /* BUCK5 VMEM_1.2V_AP */
368         max77686_set_buck_mode(p, 6, OPMODE_ON);        /* BUCK6 VCC_SUB_1.35V*/
369         max77686_set_buck_mode(p, 7, OPMODE_ON);        /* BUCK7 VCC_SUB_2.0V */
370         max77686_set_buck_mode(p, 8, OPMODE_OFF);       /* VMEM_VDDF_2.85V */
371         max77686_set_buck_mode(p, 9, OPMODE_OFF);       /* CAM_ISP_CORE_1.2V*/
372
373         max77686_set_ldo_mode(p, 1, OPMODE_ON_AUTO_LPM);  /* LDO1 VALIVE_1.0V_AP*/
374         max77686_set_ldo_mode(p, 2, OPMODE_ON_AUTO_OFF);  /* LDO2 VM1M2_1.2V_AP */
375         max77686_set_ldo_mode(p, 3, OPMODE_ON_AUTO_LPM);  /* LDO3 VCC_1.8V_AP */
376         max77686_set_ldo_mode(p, 4, OPMODE_ON_AUTO_LPM);  /* LDO4 VCC_2.8V_AP */
377         max77686_set_ldo_mode(p, 5, OPMODE_OFF);          /* LDO5 VCC_1.8V_IO */
378         max77686_set_ldo_mode(p, 6, OPMODE_ON_AUTO_OFF);  /* LDO6 VMPLL_1.0V_AP */
379         max77686_set_ldo_mode(p, 7, OPMODE_ON_AUTO_OFF);  /* LDO7 VPLL_1.0V_AP */
380         max77686_set_ldo_mode(p, 8, OPMODE_ON);           /* LDO8 VMIPI_1.0V_AP */
381         max77686_set_ldo_mode(p, 9, OPMODE_OFF);          /* LDO9 CAM_ISP_MIPI_1.2 */
382         max77686_set_ldo_mode(p, 10, OPMODE_ON);          /* LDO10 VMIPI_1.8V_AP */
383         max77686_set_ldo_mode(p, 11, OPMODE_ON_AUTO_OFF); /* LDO11 VABB1_1.8V_AP */
384         max77686_set_ldo_mode(p, 12, OPMODE_ON_AUTO_LPM); /* LDO12 VUOTG_3.0V_AP */
385         max77686_set_ldo_mode(p, 13, OPMODE_OFF);         /* LDO13 VC2C_1.8V_AP */
386         max77686_set_ldo_mode(p, 14, OPMODE_ON_AUTO_OFF); /* LDO14 VABB02_1.8V_AP */
387         max77686_set_ldo_mode(p, 15, OPMODE_ON_AUTO_OFF); /* LDO15 VHSIC_1.0V_AP */
388         max77686_set_ldo_mode(p, 16, OPMODE_ON_AUTO_OFF); /* LDO16 VHSIC_1.8V_AP */
389         max77686_set_ldo_mode(p, 17, OPMODE_OFF);         /* LDO17 CAM_SENSOR_CORE_1.2 */
390         max77686_set_ldo_mode(p, 18, OPMODE_OFF);         /* LDO18 CAM_ISP_SEN_IO_1.8V */
391         max77686_set_ldo_mode(p, 19, OPMODE_OFF);         /* LDO19 VT_CAM_1.8V */
392         max77686_set_ldo_mode(p, 20, OPMODE_ON);          /* LDO20 VDDQ_PRE_1.8V */
393         max77686_set_ldo_mode(p, 21, OPMODE_OFF);         /* LDO21 VTF_2.8V */
394         max77686_set_ldo_mode(p, 22, OPMODE_OFF);         /* LDO22 VMEM_VDD_2.8V */
395         max77686_set_ldo_mode(p, 23, OPMODE_OFF);         /* LDO23 TSP_AVDD_3.3V */
396         max77686_set_ldo_mode(p, 24, OPMODE_OFF);         /* LDO24 TSP_VDD_1.8V */
397         max77686_set_ldo_mode(p, 25, OPMODE_ON_AUTO_LPM); /* LDO25 VCC_3.3V_LCD */
398         max77686_set_ldo_mode(p, 26, OPMODE_OFF);         /* LDO26 VCC_3.0V_MOTOR*/
399
400         return 0;
401 }
402 #endif
403
404 /*
405  * LCD
406  */
407
408 #ifdef CONFIG_LCD
409 int mipi_power(void)
410 {
411 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
412         struct pmic *p = pmic_get("MAX77686_PMIC");
413
414         /* LDO8 VMIPI_1.0V_AP */
415         max77686_set_ldo_mode(p, 8, OPMODE_ON);
416         /* LDO10 VMIPI_1.8V_AP */
417         max77686_set_ldo_mode(p, 10, OPMODE_ON);
418 #endif
419
420         return 0;
421 }
422
423 void exynos_lcd_power_on(void)
424 {
425 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
426         struct pmic *p = pmic_get("MAX77686_PMIC");
427
428         /* LCD_2.2V_EN: GPC0[1] */
429         gpio_request(EXYNOS4X12_GPIO_C01, "lcd_2v2_en");
430         gpio_set_pull(EXYNOS4X12_GPIO_C01, S5P_GPIO_PULL_UP);
431         gpio_direction_output(EXYNOS4X12_GPIO_C01, 1);
432
433         /* LDO25 VCC_3.1V_LCD */
434         pmic_probe(p);
435         max77686_set_ldo_voltage(p, 25, 3100000);
436         max77686_set_ldo_mode(p, 25, OPMODE_LPM);
437 #endif
438 }
439
440 void exynos_reset_lcd(void)
441 {
442         /* reset lcd */
443         gpio_request(EXYNOS4X12_GPIO_F21, "lcd_reset");
444         gpio_direction_output(EXYNOS4X12_GPIO_F21, 0);
445         udelay(10);
446         gpio_set_value(EXYNOS4X12_GPIO_F21, 1);
447 }
448
449 void exynos_lcd_misc_init(vidinfo_t *vid)
450 {
451 #ifdef CONFIG_TIZEN
452         get_tizen_logo_info(vid);
453 #endif
454 #ifdef CONFIG_S6E8AX0
455         s6e8ax0_init();
456 #endif
457 }
458 #endif /* LCD */
459
460 void low_clock_mode(void)
461 {
462         struct exynos4x12_clock *clk = (struct exynos4x12_clock *)
463                                         samsung_get_base_clock();
464
465         unsigned int cfg_apll_con0;
466         unsigned int cfg_src_cpu;
467         unsigned int cfg_div_cpu0;
468         unsigned int cfg_div_cpu1;
469         unsigned int clk_gate_cfg;
470
471         /* Turn off unnecessary clocks */
472         clk_gate_cfg = 0x0;
473         writel(clk_gate_cfg, &clk->gate_ip_image);              /* IMAGE */
474         writel(clk_gate_cfg, &clk->gate_ip_cam);                /* CAM */
475         writel(clk_gate_cfg, &clk->gate_ip_tv);                 /* TV */
476         writel(clk_gate_cfg, &clk->gate_ip_mfc);                /* MFC */
477         writel(clk_gate_cfg, &clk->gate_ip_g3d);                /* G3D */
478         writel(clk_gate_cfg, &clk->gate_ip_gps);                /* GPS */
479         writel(clk_gate_cfg, &clk->gate_ip_isp1);               /* ISP1 */
480
481         /*
482          * Set CMU_CPU clocks src to MPLL
483          * Bit values:                 0 ; 1
484          * MUX_APLL_SEL:        FIN_PLL;   FOUT_APLL
485          * MUX_CORE_SEL:        MOUT_APLL; SCLK_MPLL
486          * MUX_HPM_SEL:         MOUT_APLL; SCLK_MPLL_USER_C
487          * MUX_MPLL_USER_SEL_C: FIN_PLL;   SCLK_MPLL
488         */
489         cfg_src_cpu = MUX_APLL_SEL(1) | MUX_CORE_SEL(1) | MUX_HPM_SEL(1) |
490                       MUX_MPLL_USER_SEL_C(1);
491         writel(cfg_src_cpu, &clk->src_cpu);
492
493         /* Disable APLL */
494         cfg_apll_con0 = readl(&clk->apll_con0);
495         writel(cfg_apll_con0 & ~PLL_ENABLE(1), &clk->apll_con0);
496
497         /* Set APLL to 200MHz */
498         cfg_apll_con0 = SDIV(2) | PDIV(3) | MDIV(100) | FSEL(1) | PLL_ENABLE(1);
499         writel(cfg_apll_con0, &clk->apll_con0);
500
501         /* Wait for PLL to be locked */
502         while (!(readl(&clk->apll_con0) & PLL_LOCKED_BIT))
503                 continue;
504
505         /* Set CMU_CPU clock src to APLL */
506         cfg_src_cpu = MUX_APLL_SEL(1) | MUX_CORE_SEL(0) | MUX_HPM_SEL(0) |
507                       MUX_MPLL_USER_SEL_C(0);
508         writel(cfg_src_cpu, &clk->src_cpu);
509
510         /* Wait for MUX ready status */
511         while (readl(&clk->src_cpu) & MUX_STAT_CPU_CHANGING)
512                 continue;
513
514         /*
515          * Set dividers for MOUTcore = 200 MHz
516          * coreout =      MOUT / (ratio + 1) = 200 MHz
517          * corem0 =     armclk / (ratio + 1) = 200 MHz
518          * corem1 =     armclk / (ratio + 1) = 200 MHz
519          * periph =     armclk / (ratio + 1) = 200 MHz
520          * atbout =       MOUT / (ratio + 1) = 200 MHz
521          * pclkdbgout = atbout / (ratio + 1) = 200 MHz
522          * sclkapll = MOUTapll / (ratio + 1) = 50 MHz
523          * armclk =   core_out / (ratio + 1) = 200 MHz
524         */
525         cfg_div_cpu0 = CORE_RATIO(0) | COREM0_RATIO(0) | COREM1_RATIO(0) |
526                        PERIPH_RATIO(0) | ATB_RATIO(0) | PCLK_DBG_RATIO(1) |
527                        APLL_RATIO(3) | CORE2_RATIO(0);
528         writel(cfg_div_cpu0, &clk->div_cpu0);
529
530         /* Wait for divider ready status */
531         while (readl(&clk->div_stat_cpu0) & DIV_STAT_CPU0_CHANGING)
532                 continue;
533
534         /*
535          * For MOUThpm = 200 MHz (MOUTapll)
536          * doutcopy = MOUThpm / (ratio + 1) = 100
537          * sclkhpm = doutcopy / (ratio + 1) = 100
538          * cores_out = armclk / (ratio + 1) = 200
539          */
540         cfg_div_cpu1 = COPY_RATIO(1) | HPM_RATIO(0) | CORES_RATIO(0);
541         writel(cfg_div_cpu1, &clk->div_cpu1);   /* DIV_CPU1 */
542
543         /* Wait for divider ready status */
544         while (readl(&clk->div_stat_cpu1) & DIV_STAT_CPU1_CHANGING)
545                 continue;
546 }
547
548 #ifdef CONFIG_INTERACTIVE_CHARGER
549 static int low_power_mode_set;
550
551 void board_low_power_mode(void)
552 {
553         struct exynos4x12_power *pwr = (struct exynos4x12_power *)
554                                         samsung_get_base_power();
555
556         unsigned int pwr_core_cfg = 0x0;
557         unsigned int pwr_cfg = 0x0;
558
559         /* Set low power mode only once */
560         if (low_power_mode_set)
561                 return;
562
563         /* Power down CORES: 1, 2, 3 */
564         /* LOCAL_PWR_CFG [1:0] 0x3 EN, 0x0 DIS */
565         writel(pwr_core_cfg, &pwr->arm_core1_configuration);
566         writel(pwr_core_cfg, &pwr->arm_core2_configuration);
567         writel(pwr_core_cfg, &pwr->arm_core3_configuration);
568
569         /* Turn off unnecessary power domains */
570         writel(pwr_cfg, &pwr->xxti_configuration);              /* XXTI */
571         writel(pwr_cfg, &pwr->cam_configuration);               /* CAM */
572         writel(pwr_cfg, &pwr->tv_configuration);                /* TV */
573         writel(pwr_cfg, &pwr->mfc_configuration);               /* MFC */
574         writel(pwr_cfg, &pwr->g3d_configuration);               /* G3D */
575         writel(pwr_cfg, &pwr->gps_configuration);               /* GPS */
576         writel(pwr_cfg, &pwr->gps_alive_configuration);         /* GPS_ALIVE */
577
578         /* Set CPU clock to 200MHz */
579         low_clock_mode();
580
581         low_power_mode_set = 1;
582 }
583 #endif
584
585 #ifdef CONFIG_CMD_POWEROFF
586 void board_poweroff(void)
587 {
588         unsigned int val;
589         struct exynos4x12_power *power =
590                 (struct exynos4x12_power *)samsung_get_base_power();
591
592         val = readl(&power->ps_hold_control);
593         val |= EXYNOS_PS_HOLD_CONTROL_EN_OUTPUT; /* set to output */
594         val &= ~EXYNOS_PS_HOLD_CONTROL_DATA_HIGH; /* set state to low */
595         writel(val, &power->ps_hold_control);
596
597         while (1);
598         /* Should not reach here */
599 }
600 #endif
601
602 /* Functions for interactive charger in board/samsung/common/misc.c */
603 #ifdef CONFIG_INTERACTIVE_CHARGER
604 int charger_enable(void)
605 {
606 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
607         if (!power_init_done) {
608                 if (exynos_power_init()) {
609                         puts("Can't init board power subsystem");
610                         return -1;
611                 }
612         }
613
614         if (!pbat->battery_charge) {
615                 puts("Can't enable charger\n");
616                 return -1;
617         }
618
619         /* Enable charger */
620         if (pbat->battery_charge(p_bat)) {
621                 puts("Charger enable error\n");
622                 return -1;
623         }
624 #endif
625
626         return 0;
627 }
628
629 int charger_type(void)
630 {
631 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
632         if (!power_init_done) {
633                 if (exynos_power_init()) {
634                         puts("Can't init board power subsystem");
635                         return -1;
636                 }
637         }
638
639         if (!p_muic->chrg->chrg_type) {
640                 puts("Can't get charger type\n");
641                 return -1;
642         }
643
644         return p_muic->chrg->chrg_type(p_muic);
645 #else
646         return 0;
647 #endif
648 }
649
650 int battery_present(void)
651 {
652 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
653         if (!power_init_done) {
654                 if (exynos_power_init()) {
655                         puts("Can't init board power subsystem");
656                         return -1;
657                 }
658         }
659
660         if (!p_chrg->chrg->chrg_bat_present) {
661                 puts("Can't get battery state\n");
662                 return -1;
663         }
664
665         if (!p_chrg->chrg->chrg_bat_present(p_chrg)) {
666                 puts("Battery not present.\n");
667                 return 0;
668         }
669 #endif
670
671         return 1;
672 }
673
674 int battery_state(unsigned int *soc)
675 {
676 #ifndef CONFIG_DM_I2C /* TODO(maintainer): Convert to driver model */
677         struct battery *bat = pbat->bat;
678
679         if (!power_init_done) {
680                 if (exynos_power_init()) {
681                         printf("Can't init board power subsystem");
682                         return -1;
683                 }
684         }
685
686         if (!p_fg->fg->fg_battery_update) {
687                 puts("Can't update battery state\n");
688                 return -1;
689         }
690
691         /* Check battery state */
692         if (p_fg->fg->fg_battery_update(p_fg, p_bat)) {
693                 puts("Battery update error\n");
694                 return -1;
695         }
696
697         debug("[BAT]:\n#state:%u\n#soc:%3.1u\n#vcell:%u\n", bat->state,
698                                                             bat->state_of_chrg,
699                                                             bat->voltage_uV);
700
701         *soc = bat->state_of_chrg;
702 #endif
703         return 0;
704 }
705 #endif