soc: Remove copyright notices
[coreboot.git] / src / soc / mediatek / common / pmic_wrap.c
blob755672f7e0fdc347727fad0c0d6317b1f4b10fed
1 /*
2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <device/mmio.h>
16 #include <soc/pmic_wrap.h>
17 #include <timer.h>
19 u32 wait_for_state_idle(u32 timeout_us, void *wacs_register,
20 void *wacs_vldclr_register, u32 *read_reg)
22 u32 reg_rdata;
24 struct stopwatch sw;
26 stopwatch_init_usecs_expire(&sw, timeout_us);
27 do {
28 reg_rdata = read32((wacs_register));
29 /* if last read command timeout,clear vldclr bit
30 read command state machine:FSM_REQ-->wfdle-->WFVLDCLR;
31 write:FSM_REQ-->idle */
32 switch (((reg_rdata >> RDATA_WACS_FSM_SHIFT) &
33 RDATA_WACS_FSM_MASK)) {
34 case WACS_FSM_WFVLDCLR:
35 write32(wacs_vldclr_register, 1);
36 pwrap_err("WACS_FSM = PMIC_WRAP_WACS_VLDCLR\n");
37 break;
38 case WACS_FSM_WFDLE:
39 pwrap_err("WACS_FSM = WACS_FSM_WFDLE\n");
40 break;
41 case WACS_FSM_REQ:
42 pwrap_err("WACS_FSM = WACS_FSM_REQ\n");
43 break;
44 default:
45 break;
48 if (stopwatch_expired(&sw))
49 return E_PWR_WAIT_IDLE_TIMEOUT;
51 } while (((reg_rdata >> RDATA_WACS_FSM_SHIFT) & RDATA_WACS_FSM_MASK) !=
52 WACS_FSM_IDLE); /* IDLE State */
53 if (read_reg)
54 *read_reg = reg_rdata;
55 return 0;
58 u32 wait_for_state_ready(loop_condition_fp fp, u32 timeout_us,
59 void *wacs_register, u32 *read_reg)
61 u32 reg_rdata;
62 struct stopwatch sw;
64 stopwatch_init_usecs_expire(&sw, timeout_us);
65 do {
66 reg_rdata = read32((wacs_register));
68 if (stopwatch_expired(&sw)) {
69 pwrap_err("timeout when waiting for idle\n");
70 return E_PWR_WAIT_IDLE_TIMEOUT;
72 } while (fp(reg_rdata)); /* IDLE State */
73 if (read_reg)
74 *read_reg = reg_rdata;
75 return 0;
78 s32 pwrap_reset_spislv(void)
80 u32 ret = 0;
82 write32(&mtk_pwrap->hiprio_arb_en, 0);
83 write32(&mtk_pwrap->wrap_en, 0);
84 write32(&mtk_pwrap->mux_sel, 1);
85 write32(&mtk_pwrap->man_en, 1);
86 write32(&mtk_pwrap->dio_en, 0);
88 write32(&mtk_pwrap->man_cmd, (OP_WR << 13) | (OP_CSL << 8));
89 /* Reset counter */
90 write32(&mtk_pwrap->man_cmd, (OP_WR << 13) | (OP_OUTS << 8));
91 write32(&mtk_pwrap->man_cmd, (OP_WR << 13) | (OP_CSH << 8));
93 * In order to pull CSN signal to PMIC,
94 * PMIC will count it then reset spi slave
96 write32(&mtk_pwrap->man_cmd, (OP_WR << 13) | (OP_OUTS << 8));
97 write32(&mtk_pwrap->man_cmd, (OP_WR << 13) | (OP_OUTS << 8));
98 write32(&mtk_pwrap->man_cmd, (OP_WR << 13) | (OP_OUTS << 8));
99 write32(&mtk_pwrap->man_cmd, (OP_WR << 13) | (OP_OUTS << 8));
101 if (wait_for_state_ready(wait_for_sync, TIMEOUT_WAIT_IDLE_US,
102 &mtk_pwrap->wacs2_rdata, 0))
103 ret = E_PWR_TIMEOUT;
105 write32(&mtk_pwrap->man_en, 0);
106 write32(&mtk_pwrap->mux_sel, 0);
108 return ret;
111 s32 pwrap_wacs2(u32 write, u16 addr, u16 wdata, u16 *rdata, u32 init_check)
113 u32 reg_rdata = 0;
114 u32 wacs_write = 0;
115 u32 wacs_addr = 0;
116 u32 wacs_cmd = 0;
117 u32 wait_result = 0;
119 if (init_check) {
120 reg_rdata = read32(&mtk_pwrap->wacs2_rdata);
121 /* Prevent someone to use pwrap before pwrap init */
122 if (((reg_rdata >> RDATA_INIT_DONE_SHIFT) &
123 RDATA_INIT_DONE_MASK) != WACS_INIT_DONE) {
124 pwrap_err("Pwrap initialization isn't finished\n");
125 return E_PWR_NOT_INIT_DONE;
128 reg_rdata = 0;
129 /* Check IDLE in advance */
130 wait_result = wait_for_state_idle(TIMEOUT_WAIT_IDLE_US,
131 &mtk_pwrap->wacs2_rdata,
132 &mtk_pwrap->wacs2_vldclr,
134 if (wait_result != 0) {
135 pwrap_err("wait_for_fsm_idle fail,wait_result=%d\n",
136 wait_result);
137 return E_PWR_WAIT_IDLE_TIMEOUT;
139 wacs_write = write << 31;
140 wacs_addr = (addr >> 1) << 16;
141 wacs_cmd = wacs_write | wacs_addr | wdata;
143 write32(&mtk_pwrap->wacs2_cmd, wacs_cmd);
144 if (write == 0) {
145 if (rdata == NULL) {
146 pwrap_err("rdata is a NULL pointer\n");
147 return E_PWR_INVALID_ARG;
149 wait_result = wait_for_state_ready(wait_for_fsm_vldclr,
150 TIMEOUT_READ_US,
151 &mtk_pwrap->wacs2_rdata,
152 &reg_rdata);
153 if (wait_result != 0) {
154 pwrap_err("wait_for_fsm_vldclr fail,wait_result=%d\n",
155 wait_result);
156 return E_PWR_WAIT_IDLE_TIMEOUT_READ;
158 *rdata = ((reg_rdata >> RDATA_WACS_RDATA_SHIFT)
159 & RDATA_WACS_RDATA_MASK);
160 write32(&mtk_pwrap->wacs2_vldclr, 1);
163 return 0;