1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 2009 Wind River Systems, Inc.
3*4882a593Smuzhiyun * Tom Rix <Tom.Rix at windriver.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * twl4030_power_reset_init is derived from code on omapzoom,
8*4882a593Smuzhiyun * git://git.omapzoom.com/repo/u-boot.git
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * Copyright (C) 2007-2009 Texas Instruments, Inc.
11*4882a593Smuzhiyun *
12*4882a593Smuzhiyun * twl4030_power_init is from cpu/omap3/common.c, power_init_r
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * (C) Copyright 2004-2008
15*4882a593Smuzhiyun * Texas Instruments, <www.ti.com>
16*4882a593Smuzhiyun *
17*4882a593Smuzhiyun * Author :
18*4882a593Smuzhiyun * Sunil Kumar <sunilsaini05 at gmail.com>
19*4882a593Smuzhiyun * Shashi Ranjan <shashiranjanmca05 at gmail.com>
20*4882a593Smuzhiyun *
21*4882a593Smuzhiyun * Derived from Beagle Board and 3430 SDP code by
22*4882a593Smuzhiyun * Richard Woodruff <r-woodruff2 at ti.com>
23*4882a593Smuzhiyun * Syed Mohammed Khasim <khasim at ti.com>
24*4882a593Smuzhiyun */
25*4882a593Smuzhiyun
26*4882a593Smuzhiyun #include <twl4030.h>
27*4882a593Smuzhiyun
28*4882a593Smuzhiyun /*
29*4882a593Smuzhiyun * Power Reset
30*4882a593Smuzhiyun */
twl4030_power_reset_init(void)31*4882a593Smuzhiyun void twl4030_power_reset_init(void)
32*4882a593Smuzhiyun {
33*4882a593Smuzhiyun u8 val = 0;
34*4882a593Smuzhiyun if (twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
35*4882a593Smuzhiyun TWL4030_PM_MASTER_P1_SW_EVENTS, &val)) {
36*4882a593Smuzhiyun printf("Error:TWL4030: failed to read the power register\n");
37*4882a593Smuzhiyun printf("Could not initialize hardware reset\n");
38*4882a593Smuzhiyun } else {
39*4882a593Smuzhiyun val |= TWL4030_PM_MASTER_SW_EVENTS_STOPON_PWRON;
40*4882a593Smuzhiyun if (twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
41*4882a593Smuzhiyun TWL4030_PM_MASTER_P1_SW_EVENTS, val)) {
42*4882a593Smuzhiyun printf("Error:TWL4030: failed to write the power register\n");
43*4882a593Smuzhiyun printf("Could not initialize hardware reset\n");
44*4882a593Smuzhiyun }
45*4882a593Smuzhiyun }
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun /*
49*4882a593Smuzhiyun * Power off
50*4882a593Smuzhiyun */
twl4030_power_off(void)51*4882a593Smuzhiyun void twl4030_power_off(void)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun u8 data;
54*4882a593Smuzhiyun
55*4882a593Smuzhiyun /* PM master unlock (CFG and TST keys) */
56*4882a593Smuzhiyun
57*4882a593Smuzhiyun data = 0xCE;
58*4882a593Smuzhiyun twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
59*4882a593Smuzhiyun TWL4030_PM_MASTER_PROTECT_KEY, data);
60*4882a593Smuzhiyun data = 0xEC;
61*4882a593Smuzhiyun twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
62*4882a593Smuzhiyun TWL4030_PM_MASTER_PROTECT_KEY, data);
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun /* VBAT start disable */
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
67*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_P1_TRANSITION, &data);
68*4882a593Smuzhiyun data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT;
69*4882a593Smuzhiyun twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
70*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_P1_TRANSITION, data);
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
73*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_P2_TRANSITION, &data);
74*4882a593Smuzhiyun data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT;
75*4882a593Smuzhiyun twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
76*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_P2_TRANSITION, data);
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
79*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_P3_TRANSITION, &data);
80*4882a593Smuzhiyun data &= ~TWL4030_PM_MASTER_CFG_TRANSITION_STARTON_VBAT;
81*4882a593Smuzhiyun twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
82*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_P3_TRANSITION, data);
83*4882a593Smuzhiyun
84*4882a593Smuzhiyun /* High jitter for PWRANA2 */
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
87*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_PWRANA2, &data);
88*4882a593Smuzhiyun data &= ~(TWL4030_PM_MASTER_CFG_PWRANA2_LOJIT0_LOWV |
89*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_PWRANA2_LOJIT1_LOWV);
90*4882a593Smuzhiyun twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
91*4882a593Smuzhiyun TWL4030_PM_MASTER_CFG_PWRANA2, data);
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun /* PM master lock */
94*4882a593Smuzhiyun
95*4882a593Smuzhiyun data = 0xFF;
96*4882a593Smuzhiyun twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
97*4882a593Smuzhiyun TWL4030_PM_MASTER_PROTECT_KEY, data);
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun /* Power off */
100*4882a593Smuzhiyun
101*4882a593Smuzhiyun twl4030_i2c_read_u8(TWL4030_CHIP_PM_MASTER,
102*4882a593Smuzhiyun TWL4030_PM_MASTER_P1_SW_EVENTS, &data);
103*4882a593Smuzhiyun data |= TWL4030_PM_MASTER_SW_EVENTS_DEVOFF;
104*4882a593Smuzhiyun twl4030_i2c_write_u8(TWL4030_CHIP_PM_MASTER,
105*4882a593Smuzhiyun TWL4030_PM_MASTER_P1_SW_EVENTS, data);
106*4882a593Smuzhiyun }
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun /*
109*4882a593Smuzhiyun * Set Device Group and Voltage
110*4882a593Smuzhiyun */
twl4030_pmrecv_vsel_cfg(u8 vsel_reg,u8 vsel_val,u8 dev_grp,u8 dev_grp_sel)111*4882a593Smuzhiyun void twl4030_pmrecv_vsel_cfg(u8 vsel_reg, u8 vsel_val,
112*4882a593Smuzhiyun u8 dev_grp, u8 dev_grp_sel)
113*4882a593Smuzhiyun {
114*4882a593Smuzhiyun int ret;
115*4882a593Smuzhiyun
116*4882a593Smuzhiyun /* Select the Voltage */
117*4882a593Smuzhiyun ret = twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, vsel_reg,
118*4882a593Smuzhiyun vsel_val);
119*4882a593Smuzhiyun if (ret != 0) {
120*4882a593Smuzhiyun printf("Could not write vsel to reg %02x (%d)\n",
121*4882a593Smuzhiyun vsel_reg, ret);
122*4882a593Smuzhiyun return;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun /* Select the Device Group (enable the supply if dev_grp_sel != 0) */
126*4882a593Smuzhiyun ret = twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, dev_grp,
127*4882a593Smuzhiyun dev_grp_sel);
128*4882a593Smuzhiyun if (ret != 0)
129*4882a593Smuzhiyun printf("Could not write grp_sel to reg %02x (%d)\n",
130*4882a593Smuzhiyun dev_grp, ret);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
twl4030_power_init(void)133*4882a593Smuzhiyun void twl4030_power_init(void)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun /* set VAUX3 to 2.8V */
136*4882a593Smuzhiyun twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VAUX3_DEDICATED,
137*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VAUX3_VSEL_28,
138*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VAUX3_DEV_GRP,
139*4882a593Smuzhiyun TWL4030_PM_RECEIVER_DEV_GRP_P1);
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun /* set VPLL2 to 1.8V */
142*4882a593Smuzhiyun twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VPLL2_DEDICATED,
143*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VPLL2_VSEL_18,
144*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VPLL2_DEV_GRP,
145*4882a593Smuzhiyun TWL4030_PM_RECEIVER_DEV_GRP_ALL);
146*4882a593Smuzhiyun
147*4882a593Smuzhiyun /* set VDAC to 1.8V */
148*4882a593Smuzhiyun twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VDAC_DEDICATED,
149*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VDAC_VSEL_18,
150*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VDAC_DEV_GRP,
151*4882a593Smuzhiyun TWL4030_PM_RECEIVER_DEV_GRP_P1);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
twl4030_power_mmc_init(int dev_index)154*4882a593Smuzhiyun void twl4030_power_mmc_init(int dev_index)
155*4882a593Smuzhiyun {
156*4882a593Smuzhiyun if (dev_index == 0) {
157*4882a593Smuzhiyun /* Set VMMC1 to 3.15 Volts */
158*4882a593Smuzhiyun twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VMMC1_DEDICATED,
159*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VMMC1_VSEL_32,
160*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VMMC1_DEV_GRP,
161*4882a593Smuzhiyun TWL4030_PM_RECEIVER_DEV_GRP_P1);
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun mdelay(100); /* ramp-up delay from Linux code */
164*4882a593Smuzhiyun } else if (dev_index == 1) {
165*4882a593Smuzhiyun /* Set VMMC2 to 3.15 Volts */
166*4882a593Smuzhiyun twl4030_pmrecv_vsel_cfg(TWL4030_PM_RECEIVER_VMMC2_DEDICATED,
167*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VMMC2_VSEL_32,
168*4882a593Smuzhiyun TWL4030_PM_RECEIVER_VMMC2_DEV_GRP,
169*4882a593Smuzhiyun TWL4030_PM_RECEIVER_DEV_GRP_P1);
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun mdelay(100); /* ramp-up delay from Linux code */
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun #ifdef CONFIG_CMD_POWEROFF
do_poweroff(cmd_tbl_t * cmdtp,int flag,int argc,char * const argv[])176*4882a593Smuzhiyun int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun twl4030_power_off();
179*4882a593Smuzhiyun
180*4882a593Smuzhiyun return 0;
181*4882a593Smuzhiyun }
182*4882a593Smuzhiyun #endif
183