blob: 7ef3e764b1422855ceaa003f32c3fe9822cec567 [file] [log] [blame]
yu.dongc33b3072024-08-21 23:14:49 -07001/* Copyright Statement:
2 *
3 * This software/firmware and related documentation ("MediaTek Software") are
4 * protected under relevant copyright laws. The information contained herein is
5 * confidential and proprietary to MediaTek Inc. and/or its licensors. Without
6 * the prior written permission of MediaTek inc. and/or its licensors, any
7 * reproduction, modification, use or disclosure of MediaTek Software, and
8 * information contained herein, in whole or in part, shall be strictly
9 * prohibited.
10 *
11 * MediaTek Inc. (C) 2019. All rights reserved.
12 *
13 * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
14 * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
15 * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER
16 * ON AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL
17 * WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
19 * NONINFRINGEMENT. NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH
20 * RESPECT TO THE SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY,
21 * INCORPORATED IN, OR SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES
22 * TO LOOK ONLY TO SUCH THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO.
23 * RECEIVER EXPRESSLY ACKNOWLEDGES THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO
24 * OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK
25 * SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE
26 * RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
27 * STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S
28 * ENTIRE AND CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE
29 * RELEASED HEREUNDER WILL BE, AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE
30 * MEDIATEK SOFTWARE AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE
31 * CHARGE PAID BY RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
32 *
33 * The following software/firmware and/or related documentation ("MediaTek
34 * Software") have been modified by MediaTek Inc. All revisions are subject to
35 * any receiver's applicable license agreements with MediaTek Inc.
36 */
37/*
38 * MTK PMIF Driver
39 *
40 * Copyright 2019 MediaTek Co.,Ltd.
41 *
42 * DESCRIPTION:
43 * This file provides API for other drivers to access PMIC registers
44 *
45 */
46
47#include <pmif.h>
48#include <spmi.h>
49#include <pmif_sw.h>
50#include <spmi_sw.h>
51
52#define GET_SWINF_0_FSM(x) ((x>>1) & 0x00000007)
53#define GET_PMIF_INIT_DONE(x) ((x>>15) & 0x00000001)
54#define TIMEOUT_WAIT_IDLE (1000000) /* ap latency concern 1ms */
55
56#define PMIF_CMD_PER_3 (0x1 << PMIF_CMD_EXT_REG_LONG)
57#define PMIF_CMD_PER_1_3 \
58 ((0x1 << PMIF_CMD_REG) | (0x1 << PMIF_CMD_EXT_REG_LONG))
59#define PMIF_CMD_PER_2_3 \
60 ((0x1 << PMIF_CMD_EXT_REG) | (0x1 << PMIF_CMD_EXT_REG_LONG))
61
62static int pmif_spmi_read_cmd(struct pmif *arb, unsigned char opc,
63 unsigned char sid, unsigned short addr, unsigned char *buf,
64 unsigned short len);
65static int pmif_spmi_write_cmd(struct pmif *arb, unsigned char opc,
66 unsigned char sid, unsigned short addr, const unsigned char *buf,
67 unsigned short len);
68#if PMIF_NO_PMIC
69static int pmif_spmi_read_cmd(struct pmif *arb, unsigned char opc,
70 unsigned char sid, unsigned short addr, unsigned char *buf,
71 unsigned short len)
72{
73 PMIF_INFO("do Nothing.\n");
74 return 0;
75}
76
77static int pmif_spmi_write_cmd(struct pmif *arb, unsigned char opc,
78 unsigned char sid, unsigned short addr, const unsigned char *buf,
79 unsigned short len)
80{
81 PMIF_INFO("do Nothing.\n");
82 return 0;
83}
84
85/* init interface */
86int pmif_spmi_init(int mstid)
87{
88 PMIF_INFO("do Nothing.\n");
89 return 0;
90}
91#else /* #if PMIF_NO_PMIC */
92/* pmif internal API declaration */
93#if PMIF_TIMEOUT
94static unsigned long long pmif_get_current_time(void);
95static int pmif_timeout_ns(unsigned long long start_time_ns,
96 unsigned long long timeout_time_ns);
97static unsigned long long pmif_time2ns(unsigned long long time_us);
98#endif
99static void pmif_enable_soft_reset(int mstid);
100static void pmif_spmi_enable_clk_set(int mstid);
101static void pmif_spmi_force_normal_mode(int mstid);
102static void pmif_spmi_enable_swinf(int mstid, unsigned int chan_no,
103 unsigned int swinf_no);
104static void pmif_spmi_enable_cmdIssue(int mstid, kal_bool en);
105static void pmif_spmi_enable(int mstid);
106
107
108enum pmif_regs {
109 PMIF_INIT_DONE,
110 PMIF_INF_EN,
111 PMIF_INF_CMD_PER_0,
112 PMIF_INF_CMD_PER_1,
113 PMIF_INF_CMD_PER_2,
114 PMIF_INF_CMD_PER_3,
115 PMIF_INF_MAX_BYTECNT_PER_0,
116 PMIF_INF_MAX_BYTECNT_PER_1,
117 PMIF_INF_MAX_BYTECNT_PER_2,
118 PMIF_INF_MAX_BYTECNT_PER_3,
119 PMIF_ARB_EN,
120 PMIF_CMDISSUE_EN,
121 PMIF_TIMER_CTRL,
122 PMIF_SPI_MODE_CTRL,
123 PMIF_IRQ_EVENT_EN_0,
124 PMIF_IRQ_FLAG_0,
125 PMIF_IRQ_CLR_0,
126 PMIF_SWINF_0_ACC,
127 PMIF_SWINF_0_WDATA_31_0,
128 PMIF_SWINF_0_WDATA_63_32,
129 PMIF_SWINF_0_RDATA_31_0,
130 PMIF_SWINF_0_RDATA_63_32,
131 PMIF_SWINF_0_VLD_CLR,
132 PMIF_SWINF_0_STA,
133 PMIF_SWINF_1_ACC,
134 PMIF_SWINF_1_WDATA_31_0,
135 PMIF_SWINF_1_WDATA_63_32,
136 PMIF_SWINF_1_RDATA_31_0,
137 PMIF_SWINF_1_RDATA_63_32,
138 PMIF_SWINF_1_VLD_CLR,
139 PMIF_SWINF_1_STA,
140 PMIF_SWINF_2_ACC,
141 PMIF_SWINF_2_WDATA_31_0,
142 PMIF_SWINF_2_WDATA_63_32,
143 PMIF_SWINF_2_RDATA_31_0,
144 PMIF_SWINF_2_RDATA_63_32,
145 PMIF_SWINF_2_VLD_CLR,
146 PMIF_SWINF_2_STA,
147 PMIF_SWINF_3_ACC,
148 PMIF_SWINF_3_WDATA_31_0,
149 PMIF_SWINF_3_WDATA_63_32,
150 PMIF_SWINF_3_RDATA_31_0,
151 PMIF_SWINF_3_RDATA_63_32,
152 PMIF_SWINF_3_VLD_CLR,
153 PMIF_SWINF_3_STA,
154};
155
156static int mt6885_regs[] = {
157 [PMIF_INIT_DONE] = 0x0000,
158 [PMIF_INF_EN] = 0x0024,
159 [PMIF_INF_CMD_PER_0] = 0x002c,
160 [PMIF_INF_CMD_PER_1] = 0x0030,
161 [PMIF_INF_CMD_PER_2] = 0x0034,
162 [PMIF_INF_CMD_PER_3] = 0x0038,
163 [PMIF_INF_MAX_BYTECNT_PER_0] = 0x003c,
164 [PMIF_INF_MAX_BYTECNT_PER_1] = 0x0040,
165 [PMIF_INF_MAX_BYTECNT_PER_2] = 0x0044,
166 [PMIF_INF_MAX_BYTECNT_PER_3] = 0x0048,
167 [PMIF_ARB_EN] = 0x0150,
168 [PMIF_CMDISSUE_EN] = 0x03B4,
169 [PMIF_TIMER_CTRL] = 0x03E0,
170 [PMIF_SPI_MODE_CTRL] = 0x0400,
171 [PMIF_IRQ_EVENT_EN_0] = 0x0418,
172 [PMIF_IRQ_FLAG_0] = 0x0420,
173 [PMIF_IRQ_CLR_0] = 0x0424,
174 [PMIF_SWINF_0_ACC] = 0x0C00,
175 [PMIF_SWINF_0_WDATA_31_0] = 0x0C04,
176 [PMIF_SWINF_0_WDATA_63_32] = 0x0C08,
177 [PMIF_SWINF_0_RDATA_31_0] = 0x0C14,
178 [PMIF_SWINF_0_RDATA_63_32] = 0x0C18,
179 [PMIF_SWINF_0_VLD_CLR] = 0x0C24,
180 [PMIF_SWINF_0_STA] = 0x0C28,
181 [PMIF_SWINF_1_ACC] = 0x0C40,
182 [PMIF_SWINF_1_WDATA_31_0] = 0x0C44,
183 [PMIF_SWINF_1_WDATA_63_32] = 0x0C48,
184 [PMIF_SWINF_1_RDATA_31_0] = 0x0C54,
185 [PMIF_SWINF_1_RDATA_63_32] = 0x0C58,
186 [PMIF_SWINF_1_VLD_CLR] = 0x0C64,
187 [PMIF_SWINF_1_STA] = 0x0C68,
188 [PMIF_SWINF_2_ACC] = 0x0C80,
189 [PMIF_SWINF_2_WDATA_31_0] = 0x0C84,
190 [PMIF_SWINF_2_WDATA_63_32] = 0x0C88,
191 [PMIF_SWINF_2_RDATA_31_0] = 0x0C94,
192 [PMIF_SWINF_2_RDATA_63_32] = 0x0C98,
193 [PMIF_SWINF_2_VLD_CLR] = 0x0CA4,
194 [PMIF_SWINF_2_STA] = 0x0CA8,
195 [PMIF_SWINF_3_ACC] = 0x0CC0,
196 [PMIF_SWINF_3_WDATA_31_0] = 0x0CC4,
197 [PMIF_SWINF_3_WDATA_63_32] = 0x0CC8,
198 [PMIF_SWINF_3_RDATA_31_0] = 0x0CD4,
199 [PMIF_SWINF_3_RDATA_63_32] = 0x0CD8,
200 [PMIF_SWINF_3_VLD_CLR] = 0x0CE4,
201 [PMIF_SWINF_3_STA] = 0x0CE8,
202};
203
204#if defined(CHIP10992)
205static int mt6880_regs[] = {
206 [PMIF_INIT_DONE] = 0x0000,
207 [PMIF_INF_EN] = 0x0024,
208 [PMIF_INF_CMD_PER_0] = 0x002c,
209 [PMIF_INF_CMD_PER_1] = 0x0030,
210 [PMIF_INF_CMD_PER_2] = 0x0034,
211 [PMIF_INF_CMD_PER_3] = 0x0038,
212 [PMIF_INF_MAX_BYTECNT_PER_0] = 0x003c,
213 [PMIF_INF_MAX_BYTECNT_PER_1] = 0x0040,
214 [PMIF_INF_MAX_BYTECNT_PER_2] = 0x0044,
215 [PMIF_INF_MAX_BYTECNT_PER_3] = 0x0048,
216 [PMIF_ARB_EN] = 0x0150,
217 [PMIF_CMDISSUE_EN] = 0x03B8,
218 [PMIF_TIMER_CTRL] = 0x03E4,
219 [PMIF_SPI_MODE_CTRL] = 0x0408,
220 [PMIF_IRQ_EVENT_EN_0] = 0x0420,
221 [PMIF_IRQ_FLAG_0] = 0x0428,
222 [PMIF_IRQ_CLR_0] = 0x042C,
223 [PMIF_SWINF_0_ACC] = 0x0800,
224 [PMIF_SWINF_0_WDATA_31_0] = 0x0804,
225 [PMIF_SWINF_0_RDATA_31_0] = 0x0814,
226 [PMIF_SWINF_0_VLD_CLR] = 0x0824,
227 [PMIF_SWINF_0_STA] = 0x0828,
228 [PMIF_SWINF_1_ACC] = 0x0840,
229 [PMIF_SWINF_1_WDATA_31_0] = 0x0844,
230 [PMIF_SWINF_1_RDATA_31_0] = 0x0854,
231 [PMIF_SWINF_1_VLD_CLR] = 0x0864,
232 [PMIF_SWINF_1_STA] = 0x0868,
233 [PMIF_SWINF_2_ACC] = 0x0880,
234 [PMIF_SWINF_2_WDATA_31_0] = 0x0884,
235 [PMIF_SWINF_2_RDATA_31_0] = 0x0894,
236 [PMIF_SWINF_2_VLD_CLR] = 0x08A4,
237 [PMIF_SWINF_2_STA] = 0x08A8,
238 [PMIF_SWINF_3_ACC] = 0x08C0,
239 [PMIF_SWINF_3_WDATA_31_0] = 0x08C4,
240 [PMIF_SWINF_3_RDATA_31_0] = 0x08D4,
241 [PMIF_SWINF_3_VLD_CLR] = 0x08E4,
242 [PMIF_SWINF_3_STA] = 0x08E8,
243};
244#else
245static int mt6853_regs[] = {
246 [PMIF_INIT_DONE] = 0x0000,
247 [PMIF_INF_EN] = 0x0024,
248 [PMIF_INF_CMD_PER_0] = 0x002c,
249 [PMIF_INF_CMD_PER_1] = 0x0030,
250 [PMIF_INF_CMD_PER_2] = 0x0034,
251 [PMIF_INF_CMD_PER_3] = 0x0038,
252 [PMIF_INF_MAX_BYTECNT_PER_0] = 0x003c,
253 [PMIF_INF_MAX_BYTECNT_PER_1] = 0x0040,
254 [PMIF_INF_MAX_BYTECNT_PER_2] = 0x0044,
255 [PMIF_INF_MAX_BYTECNT_PER_3] = 0x0048,
256 [PMIF_ARB_EN] = 0x0150,
257 [PMIF_CMDISSUE_EN] = 0x03B8,
258 [PMIF_TIMER_CTRL] = 0x03E4,
259 [PMIF_SPI_MODE_CTRL] = 0x0408,
260 [PMIF_IRQ_EVENT_EN_0] = 0x0420,
261 [PMIF_IRQ_FLAG_0] = 0x0428,
262 [PMIF_IRQ_CLR_0] = 0x042C,
263 [PMIF_SWINF_0_ACC] = 0x0C00,
264 [PMIF_SWINF_0_WDATA_31_0] = 0x0C04,
265 [PMIF_SWINF_0_WDATA_63_32] = 0x0C08,
266 [PMIF_SWINF_0_RDATA_31_0] = 0x0C14,
267 [PMIF_SWINF_0_RDATA_63_32] = 0x0C18,
268 [PMIF_SWINF_0_VLD_CLR] = 0x0C24,
269 [PMIF_SWINF_0_STA] = 0x0C28,
270 [PMIF_SWINF_1_ACC] = 0x0C40,
271 [PMIF_SWINF_1_WDATA_31_0] = 0x0C44,
272 [PMIF_SWINF_1_WDATA_63_32] = 0x0C48,
273 [PMIF_SWINF_1_RDATA_31_0] = 0x0C54,
274 [PMIF_SWINF_1_RDATA_63_32] = 0x0C58,
275 [PMIF_SWINF_1_VLD_CLR] = 0x0C64,
276 [PMIF_SWINF_1_STA] = 0x0C68,
277 [PMIF_SWINF_2_ACC] = 0x0C80,
278 [PMIF_SWINF_2_WDATA_31_0] = 0x0C84,
279 [PMIF_SWINF_2_WDATA_63_32] = 0x0C88,
280 [PMIF_SWINF_2_RDATA_31_0] = 0x0C94,
281 [PMIF_SWINF_2_RDATA_63_32] = 0x0C98,
282 [PMIF_SWINF_2_VLD_CLR] = 0x0CA4,
283 [PMIF_SWINF_2_STA] = 0x0CA8,
284 [PMIF_SWINF_3_ACC] = 0x0CC0,
285 [PMIF_SWINF_3_WDATA_31_0] = 0x0CC4,
286 [PMIF_SWINF_3_WDATA_63_32] = 0x0CC8,
287 [PMIF_SWINF_3_RDATA_31_0] = 0x0CD4,
288 [PMIF_SWINF_3_RDATA_63_32] = 0x0CD8,
289 [PMIF_SWINF_3_VLD_CLR] = 0x0CE4,
290 [PMIF_SWINF_3_STA] = 0x0CE8,
291};
292#endif
293
294static struct pmif pmif_spmi_arb[] = {
295 {
296 .base = (unsigned int *)PMIF_SPMI_BASE,
297 .regs = mt6885_regs,
298 .spmimst_base = (unsigned int *)SPMI_MST_BASE,
299 .swinf_ch_start = PMIF_SWINF_0_CHAN_NO,
300 .swinf_no = PMIF_AP_SWINF_NO,
301 .write = 0x0,
302 .mstid = SPMI_MASTER_0,
303 .pmifid = PMIF_PMIFID,
304 .read_cmd = pmif_spmi_read_cmd,
305 .write_cmd = pmif_spmi_write_cmd,
306 .pmif_enable_clk_set = pmif_spmi_enable_clk_set,
307 .pmif_force_normal_mode = pmif_spmi_force_normal_mode,
308 .pmif_enable_swinf = pmif_spmi_enable_swinf,
309 .pmif_enable_cmdIssue = pmif_spmi_enable_cmdIssue,
310 .pmif_enable = pmif_spmi_enable,
311 .is_pmif_init_done = is_pmif_spmi_init_done,
312 },
313 {
314 .base = (unsigned int *)PMIF_SPMI_BASE,
315#if defined(CHIP10992)
316 .regs = mt6880_regs,
317#else
318 .regs = mt6853_regs,
319#endif
320 .spmimst_base = (unsigned int *)SPMI_MST_BASE,
321 .swinf_ch_start = PMIF_SWINF_0_CHAN_NO,
322 .swinf_no = PMIF_AP_SWINF_NO,
323 .write = 0x0,
324 .mstid = SPMI_MASTER_1,
325 .pmifid = PMIF_PMIFID,
326 .read_cmd = pmif_spmi_read_cmd,
327 .write_cmd = pmif_spmi_write_cmd,
328 .pmif_enable_clk_set = pmif_spmi_enable_clk_set,
329 .pmif_force_normal_mode = pmif_spmi_force_normal_mode,
330 .pmif_enable_swinf = pmif_spmi_enable_swinf,
331 .pmif_enable_cmdIssue = pmif_spmi_enable_cmdIssue,
332 .pmif_enable = pmif_spmi_enable,
333 .is_pmif_init_done = is_pmif_spmi_init_done,
334 },
335#if !defined(MT6885) && !defined(MT6873)
336 {
337 .base = (unsigned int *)PMIF_SPMI_P_BASE,
338#if defined(CHIP10992)
339 .regs = mt6880_regs,
340#else
341 .regs = mt6853_regs,
342#endif
343 .spmimst_base = (unsigned int *)SPMI_MST_P_BASE,
344 .swinf_ch_start = PMIF_SWINF_0_CHAN_NO_P,
345 .swinf_no = PMIF_AP_SWINF_NO_P,
346 .write = 0x0,
347 .mstid = SPMI_MASTER_P_1,
348 .pmifid = PMIF_PMIFID_2,
349 .read_cmd = pmif_spmi_read_cmd,
350 .write_cmd = pmif_spmi_write_cmd,
351 .pmif_enable_clk_set = pmif_spmi_enable_clk_set,
352 .pmif_force_normal_mode = pmif_spmi_force_normal_mode,
353 .pmif_enable_swinf = pmif_spmi_enable_swinf,
354 .pmif_enable_cmdIssue = pmif_spmi_enable_cmdIssue,
355 .pmif_enable = pmif_spmi_enable,
356 .is_pmif_init_done = is_pmif_spmi_init_done,
357 },
358#endif
359};
360/* static struct pmif pmif_spi_arb[0]; */
361
362/* pmif timeout */
363#if PMIF_TIMEOUT
364static unsigned long long pmif_get_current_time(void)
365{
366 return gpt4_get_current_tick();
367}
368
369static int pmif_timeout_ns(unsigned long long start_time_ns,
370 unsigned long long timeout_time_ns)
371{
372 return gpt4_timeout_tick(start_time_ns, timeout_time_ns);
373}
374
375static unsigned long long pmif_time2ns(unsigned long long time_us)
376{
377 return gpt4_time2tick_us(time_us);
378}
379#endif
380static inline unsigned int pmif_check_idle(int mstid) {
381 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
382 unsigned int reg_rdata, offset = 0;
383#if PMIF_TIMEOUT
384 unsigned long long start_time_ns = 0, end_time_ns = 0, timeout_ns = 0;
385 unsigned long time_cnt = 100000;
386
387 start_time_ns = pmif_get_current_time();
388 timeout_ns = pmif_time2ns(TIMEOUT_WAIT_IDLE);
389#endif
390
391 do {
392#if PMIF_TIMEOUT
393 if (pmif_timeout_ns(start_time_ns, timeout_ns)) {
394 end_time_ns = pmif_get_current_time();
395 PMIF_ERR("%s timeout %d %d\n", __func__, start_time_ns,
396 end_time_ns - start_time_ns);
397 return -ETIMEDOUT;
398 }
399 if ((time_cnt--) == 0) {
400 PMIF_ERR("%s timeout %d %d\n", __func__, start_time_ns,
401 end_time_ns - start_time_ns);
402 return -ETIMEDOUT;
403 }
404#endif
405 offset = arb->regs[PMIF_SWINF_0_STA] + (0x40 * arb->swinf_no);
406 reg_rdata = DRV_Reg32(arb->base + offset);
407 } while(GET_SWINF_0_FSM(reg_rdata) != SWINF_FSM_IDLE);
408
409 return 0;
410}
411
412static inline unsigned int pmif_check_vldclr(int mstid) {
413 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
414 unsigned int reg_rdata, offset = 0;
415#if PMIF_TIMEOUT
416 unsigned long long start_time_ns = 0, end_time_ns = 0, timeout_ns = 0;
417 unsigned long time_cnt = 100000;
418
419 start_time_ns = pmif_get_current_time();
420 timeout_ns = pmif_time2ns(TIMEOUT_WAIT_IDLE);
421#endif
422
423 do {
424#if PMIF_TIMEOUT
425 if (pmif_timeout_ns(start_time_ns, timeout_ns)) {
426 end_time_ns = pmif_get_current_time();
427 PMIF_ERR("%s timeout %d %d\n", __func__, start_time_ns,
428 end_time_ns - start_time_ns);
429 return -ETIMEDOUT;
430 }
431 if ((time_cnt--) == 0) {
432 PMIF_ERR("%s timeout %d %d\n", __func__, start_time_ns,
433 end_time_ns - start_time_ns);
434 return -ETIMEDOUT;
435 }
436#endif
437 offset = arb->regs[PMIF_SWINF_0_STA] + (0x40 * arb->swinf_no);
438 reg_rdata = DRV_Reg32(arb->base + offset);
439 } while(GET_SWINF_0_FSM(reg_rdata) != SWINF_FSM_WFVLDCLR);
440
441 return 0;
442}
443static void pmif_enable_soft_reset(int mstid)
444{
445 DRV_WriteReg32(INFRA_GLOBALCON_RST2_SET, 0x1 << 14);
446 DRV_WriteReg32(INFRA_GLOBALCON_RST2_CLR, 0x1 << 14);
447
448 PMIF_INFO("%s done\n", __func__);
449}
450
451static void pmif_spmi_enable_clk_set(int mstid)
452{
453#if !defined(CONFIG_FPGA_EARLY_PORTING)
454 /* TBD */
455 DRV_WriteReg32(CLK_CFG_8_CLR, (0x1 << 15) | (0x1 << 12) | (0x7 << 8));
456 DRV_WriteReg32(CLK_CFG_UPDATE1, 0x1 << 2);
457#endif
458
459 /* sys_ck cg enable, turn off clock */
460 DRV_WriteReg32(MODULE_SW_CG_0_SET, 0x0000000f);
461 /* turn off clock */
462 DRV_WriteReg32(MODULE_SW_CG_2_SET, 0x00000100);
463
464 /* toggle SPMI sw reset */
465 pmif_enable_soft_reset(mstid);
466
467 /* sys_ck cg enable, turn on clock */
468 DRV_WriteReg32(MODULE_SW_CG_0_CLR, 0x0000000f);
469 /* turn on clock */
470 DRV_WriteReg32(MODULE_SW_CG_2_CLR, 0x00000100);
471
472 PMIF_INFO("%s done\n", __func__);
473}
474
475static void pmif_spmi_force_normal_mode(int mstid)
476{
477 struct pmif *arb = get_pmif_controller(PMIF_SPMI, SPMI_MASTER_0);
478 unsigned int offset = 0;
479
480 /* Force SPMI in normal mode. */
481 offset = arb->regs[PMIF_SPI_MODE_CTRL];
482 DRV_WriteReg32(arb->base + offset,
483 DRV_Reg32(arb->base + offset) & (~(0x3 << 9)));
484 DRV_WriteReg32(arb->base + offset,
485 DRV_Reg32(arb->base + offset) | (0x1 << 9));
486
487 PMIF_INFO("%s done\n", __func__);
488}
489
490static void pmif_spmi_enable_swinf(int mstid, unsigned int chan_no,
491 unsigned int swinf_no)
492{
493 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
494 unsigned int offset = 0;
495
496 /* Enable swinf */
497 offset = arb->regs[PMIF_INF_EN];
498 DRV_WriteReg32(arb->base + offset,
499 0x1 << (arb->swinf_ch_start + arb->swinf_no));
500
501 /* Enable arbitration */
502 offset = arb->regs[PMIF_ARB_EN];
503 DRV_WriteReg32(arb->base + offset,
504 0x1 << (arb->swinf_ch_start + arb->swinf_no));
505
506 PMIF_INFO("%s done\n", __func__);
507}
508
509static void pmif_spmi_enable_cmdIssue(int mstid, kal_bool en)
510{
511 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
512
513 /* Enable cmdIssue */
514 DRV_WriteReg32(arb->base + arb->regs[PMIF_CMDISSUE_EN], en);
515
516 PMIF_INFO("%s done\n", __func__);
517}
518
519static void pmif_spmi_enable(int mstid)
520{
521 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
522#if PMIF_NORMAL_BOOT
523 unsigned int bytecnt_per = 0, hw_bytecnt = 0;
524 unsigned int cmd_per = 0;
525
526 /* clear all cmd permission for per channel */
527 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_0], 0);
528 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_1], 0);
529 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_2], 0);
530 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_3], 0);
531 /* enable if we need cmd 0~3 permission for per channel */
532 cmd_per = PMIF_CMD_PER_3 << 28 | PMIF_CMD_PER_3 << 24 |
533 PMIF_CMD_PER_3 << 20 | PMIF_CMD_PER_1_3 << 16 |
534 PMIF_CMD_PER_3 << 8 | PMIF_CMD_PER_1_3 << 0;
535 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_0], cmd_per);
536 cmd_per = PMIF_CMD_PER_3 << 4;
537 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_CMD_PER_1], cmd_per);
538
539 /* set bytecnt max limitation*/
540 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_0], 0);
541 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_1], 0);
542 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_2], 0);
543 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_3], 0);
544 /* hw bytecnt indicate when we set 0, it can send 1 byte;
545 * set 1, it can send 2 byte.
546 */
547 hw_bytecnt = PMIF_BYTECNT_MAX -1;
548 if (hw_bytecnt > 0) {
549 bytecnt_per = hw_bytecnt << 28 | hw_bytecnt << 24 |
550 hw_bytecnt << 20 | hw_bytecnt << 16 |
551 hw_bytecnt << 12 | hw_bytecnt << 8 |
552 hw_bytecnt << 4 | hw_bytecnt << 0;
553 }
554 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_0],
555 bytecnt_per);
556 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_1],
557 bytecnt_per);
558 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_2],
559 bytecnt_per);
560 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_MAX_BYTECNT_PER_3],
561 bytecnt_per);
562#endif /* end of #if PMIF_NORMAL_BOOT */
563 DRV_WriteReg32(arb->base + arb->regs[PMIF_INF_EN], 0x2F5);
564 DRV_WriteReg32(arb->base + arb->regs[PMIF_ARB_EN], 0x2F5);
565 DRV_WriteReg32(arb->base + arb->regs[PMIF_TIMER_CTRL], 0x3);
566 DRV_WriteReg32(arb->base + arb->regs[PMIF_INIT_DONE], 0x1);
567
568 PMIF_INFO("%s done\n", __func__);
569}
570
571static int pmif_spmi_read_cmd(struct pmif *arb, unsigned char opc,
572 unsigned char sid, unsigned short addr, unsigned char *buf,
573 unsigned short len)
574{
575 int write = 0x0;
576 unsigned int ret = 0, offset = 0, data = 0;
577 unsigned char bc = len - 1;
578
579 if ((sid & ~(0xf)) != 0x0)
580 return -EINVAL;
581
582 if (len > PMIF_BYTECNT_MAX)
583 return -EINVAL;
584
585 /* Check the opcode */
586 if (opc >= 0x60 && opc <= 0x7F)
587 opc = PMIF_CMD_REG;
588 else if (opc >= 0x20 && opc <= 0x2F)
589 opc = PMIF_CMD_EXT_REG;
590 else if (opc >= 0x38 && opc <= 0x3F)
591 opc = PMIF_CMD_EXT_REG_LONG;
592 else
593 return -EINVAL;
594
595 /* ENTER_CRITICAL(); */
596 kal_hrt_take_itc_lock(KAL_ITC_SPMI_LOCK, KAL_INFINITE_WAIT);
597
598 /* Wait for Software Interface FSM state to be IDLE. */
599 ret = pmif_check_idle(arb->mstid);
600 if(ret)
601 return ret;
602
603 /* Send the command. */
604 offset = arb->regs[PMIF_SWINF_0_ACC] + (0x40 * arb->swinf_no);
605 DRV_WriteReg32(arb->base + offset,
606 (opc << 30) | (write << 29) | (sid << 24) | (bc << 16) | addr);
607
608 /* Wait for Software Interface FSM state to be WFVLDCLR,
609 *
610 * read the data and clear the valid flag.
611 */
612 if(write == 0)
613 {
614 ret = pmif_check_vldclr(arb->mstid);
615 if(ret)
616 return ret;
617
618 offset =
619 arb->regs[PMIF_SWINF_0_RDATA_31_0] + (0x40 * arb->swinf_no);
620 data = DRV_Reg32(arb->base + offset);
621 memcpy(buf, &data, (bc & 3) + 1);
622 offset =
623 arb->regs[PMIF_SWINF_0_VLD_CLR] + (0x40 * arb->swinf_no);
624 DRV_WriteReg32(arb->base + offset, 0x1);
625 }
626 kal_hrt_give_itc_lock(KAL_ITC_SPMI_LOCK);
627 /* EXIT_CRITICAL(); */
628
629 return 0x0;
630}
631
632static int pmif_spmi_write_cmd(struct pmif *arb, unsigned char opc,
633 unsigned char sid, unsigned short addr, const unsigned char *buf,
634 unsigned short len)
635{
636 int write = 0x1;
637 unsigned int ret = 0, offset = 0, data = 0;
638 unsigned char bc = len - 1;
639
640 if ((sid & ~(0xf)) != 0x0)
641 return -EINVAL;
642
643 if (len > PMIF_BYTECNT_MAX)
644 return -EINVAL;
645
646 /* Check the opcode */
647 if (opc >= 0x40 && opc <= 0x5F)
648 opc = PMIF_CMD_REG;
649 else if (opc <= 0x0F)
650 opc = PMIF_CMD_EXT_REG;
651 else if (opc >= 0x30 && opc <= 0x37)
652 opc = PMIF_CMD_EXT_REG_LONG;
653 else if (opc >= 0x80)
654 opc = PMIF_CMD_REG_0;
655 else
656 return -EINVAL;
657
658 /* ENTER_CRITICAL(); */
659 kal_hrt_take_itc_lock(KAL_ITC_SPMI_LOCK, KAL_INFINITE_WAIT);
660
661 /* Wait for Software Interface FSM state to be IDLE. */
662 ret = pmif_check_idle(arb->mstid);
663 if(ret)
664 return ret;
665
666 /* Set the write data. */
667 if (write == 1)
668 {
669 offset =
670 arb->regs[PMIF_SWINF_0_WDATA_31_0] + (0x40 * arb->swinf_no);
671 memcpy(&data, buf, (bc & 3) + 1);
672 DRV_WriteReg32(arb->base + offset, data);
673 }
674 /* Send the command. */
675 offset = arb->regs[PMIF_SWINF_0_ACC] + (0x40 * arb->swinf_no);
676 DRV_WriteReg32(arb->base + offset,
677 (opc << 30) | (write << 29) | (sid << 24) |
678 (bc << 16) | addr);
679
680 kal_hrt_give_itc_lock(KAL_ITC_SPMI_LOCK);
681 /* EXIT_CRITICAL(); */
682
683 return 0x0;
684}
685
686struct pmif *get_pmif_controller(int inf, int mstid)
687{
688 if (inf == PMIF_SPMI) {
689 return &pmif_spmi_arb[mstid];
690 } else if (inf == PMIF_SPI) {
691 /* TBD
692 *pmif_spi_arb[mstid].base = (unsigned int *)PMIF_SPI_BASE;
693 *pmif_spi_arb[mstid].swinf_no = 0x0;
694 *pmif_spi_arb[mstid].write = 0x0;
695 *pmif_spi_arb[mstid].pmifid = 0x0;
696 *pmif_spi_arb[mstid].read_cmd = pmif_spi_read_cmd;
697 *pmif_spi_arb[mstid].write_cmd = pmif_spi_write_cmd;
698 *pmif_spi_arb[mstid].read_cmd_nochk = pmif_spi_read_cmd_nochk;
699 *pmif_spi_arb[mstid].write_cmd_nochk =
700 * pmif_spi_write_cmd_nochk;
701 *return &pmif_spi_arb[mstid];
702 */
703 }
704
705 return 0;
706}
707int is_pmif_spmi_init_done(int mstid)
708{
709 int ret = 0;
710
711 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
712
713 ret = DRV_Reg32(arb->base + arb->regs[PMIF_INIT_DONE]);
714 PMIF_INFO("%s ret = %d\n", __func__, ret);
715 if ((ret & 0x1) == 1)
716 return 0;
717
718 return -ENODEV;
719}
720
721int pmif_spmi_init(int mstid)
722{
723 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
724 int ret = 0;
725
726 INIT_CRITICAL();
727
728 if (is_pmif_spmi_init_done(mstid) != 0) {
729 arb->pmif_enable_clk_set(mstid);
730 arb->pmif_force_normal_mode(mstid);
731 /* Enable SWINF and arbitration for AP. */
732 arb->pmif_enable_swinf(mstid, PMIF_SWINF_0_CHAN_NO,
733 PMIF_AP_SWINF_NO);
734 arb->pmif_enable_cmdIssue(mstid,KAL_TRUE);
735
736 arb->pmif_enable(mstid);
737 ret = arb->is_pmif_init_done(mstid);
738 if(ret) {
739 PMIF_ERR("init done check fail\n");
740 return -ENODEV;
741 }
742 }
743
744 ret = spmi_init(arb);
745 if(ret) {
746 PMIF_ERR("init fail\n");
747 return -ENODEV;
748 }
749
750 return 0;
751}
752
753#endif /* endif PMIF_NO_PMIC */