blob: f982a4789d69b78eeb6dd0ebf282b1f3031005bd [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 SPMI Driver
39 *
40 * Copyright 2018 MediaTek Co.,Ltd.
41 *
42 * DESCRIPTION:
43 * This file provides API for other drivers to access PMIC registers
44 *
45 */
46
47#include <spmi.h>
48#include <pmif.h>
49#include <pmif_sw.h>
50#include <spmi_sw.h>
51#include <mt6315_upmu_hw.h>
52
53static int mt6885_spmi_regs[] = {
54 [SPMI_OP_ST_CTRL] = 0x0000,
55 [SPMI_GRP_ID_EN] = 0x0004,
56 [SPMI_OP_ST_STA] = 0x0008,
57 [SPMI_MST_SAMPL] = 0x000c,
58 [SPMI_MST_REQ_EN] = 0x0010,
59#if SPMI_RCS_SUPPORT
60 [SPMI_RCS_CTRL] = 0x0014,
61 [SPMI_SLV_3_0_EINT] = 0x0020,
62 [SPMI_SLV_7_4_EINT] = 0x0024,
63 [SPMI_SLV_B_8_EINT] = 0x0028,
64 [SPMI_SLV_F_C_EINT] = 0x002c,
65#endif /* #if SPMI_RCS_SUPPORT */
66 [SPMI_REC_CTRL] = 0x0040,
67 [SPMI_REC0] = 0x0044,
68 [SPMI_REC1] = 0x0048,
69 [SPMI_REC2] = 0x004c,
70 [SPMI_REC3] = 0x0050,
71 [SPMI_REC4] = 0x0054,
72#if SPMI_RCS_SUPPORT
73 [SPMI_REC_CMD_DEC] = 0x005c,
74 [SPMI_DEC_DBG] = 0x00f8,
75#endif
76 [SPMI_MST_DBG] = 0x00fc,
77};
78
79static struct pmif *pmif_spmi_arb_ctrl[SPMI_MASTER_MAX];
80#if MT63xx_EVB
81#if defined(MT6885) || defined(MT6873)
82struct spmi_device spmi_dev[] = {
83 {
84 .slvid = SPMI_SLAVE_3,
85 .grpiden = 0x800,
86 .type = BUCK_MD,
87 .type_id = BUCK_MD_ID,
88 .mstid = SPMI_MASTER_0,/* spmi-m */
89 .hwcid_addr = 0x09,
90 .hwcid_val = 0x15,
91 .swcid_addr = 0x0b,
92 .swcid_val = 0x15,
93 .pmif_arb = NULL,
94 }, {
95 .slvid = SPMI_SLAVE_6,
96 .grpiden = 0x800,
97 .type = BUCK_CPU,
98 .type_id = BUCK_CPU_ID,
99 .mstid = SPMI_MASTER_0,/* spmi-m */
100 .hwcid_addr = 0x09,
101 .hwcid_val = 0x15,
102 .swcid_addr = 0x0b,
103 .swcid_val = 0x15,
104 .pmif_arb = NULL,
105 }, {
106 .slvid = SPMI_SLAVE_7,
107 .grpiden = 0x800,
108 .type = BUCK_GPU,
109 .type_id = BUCK_GPU_ID,
110 .mstid = SPMI_MASTER_0,/* spmi-m */
111 .hwcid_addr = 0x09,
112 .hwcid_val = 0x15,
113 .swcid_addr = 0x0b,
114 .swcid_val = 0x15,
115 .pmif_arb = NULL,
116 },
117};
118#elif defined(MT6853)
119#if defined(MT6315)
120struct spmi_device spmi_dev[] = {
121 {
122 .slvid = SPMI_SLAVE_3,
123 .grpiden = 0x800,
124 .type = BUCK_MD,
125 .type_id = BUCK_MD_ID,
126 .mstid = SPMI_MASTER_1,/* spmi-m */
127 .hwcid_addr = 0x09,
128 .hwcid_val = 0x15,
129 .swcid_addr = 0x0b,
130 .swcid_val = 0x15,
131 .pmif_arb = NULL,
132 },
133};
134#else
135struct spmi_device spmi_dev[] = {
136 {
137 .slvid = SPMI_SLAVE_9,
138 .grpiden = 0x0,
139 .type = SUB_PMIC,
140 .type_id = SUB_PMIC_ID,
141 .mstid = SPMI_MASTER_1,/* spmi-m */
142 .hwcid_addr = 0x0000,
143 .hwcid_val = 0x70,/* check [7:4] */
144 .swcid_addr = 0x0001,
145 .swcid_val = 0x08,/* check [3:0] */
146 .pmif_arb = NULL,
147 }, {
148 .slvid = SPMI_SLAVE_8,
149 .grpiden = 0x0,
150 .type = BUCK_MD,
151 .type_id = BUCK_MD_ID,
152 .mstid = SPMI_MASTER_P_1, /* spmi-p */
153 .hwcid_addr = 0x0706,
154 .hwcid_val = 0x00,
155 .swcid_addr = 0x0706,
156 .swcid_val = 0x00,
157 .pmif_arb = NULL,
158 },
159};
160#endif
161#elif defined(CHIP10992)
162struct spmi_device spmi_dev[] = {
163 {
164 .slvid = SPMI_SLAVE_4,
165 .grpiden = 0x1 << 0xB,
166 .type = MAIN_PMIC,
167 .type_id = MAIN_PMIC_ID,
168 .mstid = SPMI_MASTER_1,/* spmi-m */
169 .hwcid_addr = 0x09,
170 .hwcid_val = 0x30,
171 .swcid_addr = 0x0b,
172 .swcid_val = 0x30,
173 .pmif_arb = NULL,
174 }, {
175 .slvid = SPMI_SLAVE_4,
176 .grpiden = 0x1 << 0xB,
177 .type = BUCK_MD,
178 .type_id = BUCK_MD_ID,
179 .mstid = SPMI_MASTER_P_1,/* spmi-p */
180 .hwcid_addr = 0x01A0, /* TOP_VRCTL_VR0_EN */
181 .hwcid_val = 0xFF, /* All BUCK EN = 0xFF */
182 .pmif_arb = NULL,
183 },
184};
185#endif /* end of #if defined(MT6885) || defined(MT6873) */
186#else
187struct spmi_device spmi_dev[] = {
188 {
189 .slvid = SPMI_SLAVE_12,
190 .grpiden = 0x100,
191 .type = BUCK_MD,
192 .type_id = BUCK_MD_ID,
193 .pmif_arb = NULL,
194 }, {
195 .slvid = SPMI_SLAVE_10,
196 .grpiden = 0x100,
197 .type = BUCK_CPU,
198 .type_id = BUCK_CPU_ID,
199 .pmif_arb = NULL,
200 }, {
201 .slvid = SPMI_SLAVE_11,
202 .grpiden = 0x100,
203 .type = BUCK_GPU,
204 .type_id = BUCK_GPU_ID,
205 .pmif_arb = NULL,
206 },
207};
208#endif
209unsigned char spmi_device_cnt;
210
211/* spmi internal API declaration */
212static int spmi_config_master(unsigned int mstid, kal_bool en);
213static int spmi_config_slave(struct spmi_device *dev);
214static int spmi_cali_rd_clock_polarity(struct spmi_device *dev,
215 unsigned int mstid);
216static int spmi_ctrl_op_st(int mstid, unsigned int grpiden,
217 unsigned int sid, unsigned int cmd);
218#if SPMI_RCS_SUPPORT
219static int spmi_enable_rcs(struct spmi_device *dev, unsigned int mstid);
220int spmi_read_eint_sta(unsigned char *slv_eint_sta);
221#endif
222#if SPMI_DEBUG
223static int spmi_rw_test(struct spmi_device *dev);
224static int spmi_read_check(struct spmi_device *dev);
225static int spmi_drv_ut(struct spmi_device *dev, unsigned int ut);
226#endif
227int spmi_enable_group_id(int mstid, unsigned int grpiden);
228int spmi_lock_slave_reg(struct spmi_device *dev);
229int spmi_unlock_slave_reg(struct spmi_device *dev);
230
231#if SPMI_NO_PMIC
232int spmi_init(struct pmif *pmif_arb)
233{
234 SPMI_INFO("do Nothing.\n");
235 return 0;
236}
237
238#else /* #ifdef SPMI_NO_PMIC */
239/*
240 * Function : mtk_spmi_readl()
241 * Description : mtk spmi controller read api
242 * Parameter :
243 * Return :
244 */
245unsigned int spmi_readl(int mstid, enum spmi_regs reg)
246{
247 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
248
249 return DRV_Reg32(arb->spmimst_base + arb->spmimst_regs[reg]);
250}
251
252/*
253 * Function : mtk_spmi_writel()
254 * Description : mtk spmi controller write api
255 * Parameter :
256 * Return :
257 */
258void spmi_writel(int mstid, enum spmi_regs reg, unsigned int val)
259{
260 struct pmif *arb = get_pmif_controller(PMIF_SPMI, mstid);
261
262 DRV_WriteReg32(arb->spmimst_base + arb->spmimst_regs[reg], val);
263}
264
265/*
266 * Function : spmi_lock_slave_reg()
267 * Description : protect spmi slv register to be write
268 * Parameter :
269 * Return :
270 */
271int spmi_lock_slave_reg(struct spmi_device *dev)
272{
273 const unsigned char wpk_key = 0x0;
274 const unsigned char wpk_key_h = 0x0;
275
276 if ((dev->slvid == SPMI_SLAVE_6) ||
277 (dev->slvid == SPMI_SLAVE_7) ||
278 (dev->slvid == SPMI_SLAVE_3)) {
279 /* enable dig_wpk key, write 0x0*/
280 spmi_ext_register_writel(dev, MT6315_PMIC_DIG_WPK_KEY_ADDR,
281 &wpk_key, 1);
282 spmi_ext_register_writel(dev, MT6315_PMIC_DIG_WPK_KEY_H_ADDR,
283 &wpk_key_h, 1);
284 }
285
286 return 0;
287}
288
289/*
290 * Function : spmi_unlock_slave_reg()
291 * Description : unlock spmi slv register to write
292 * Parameter :
293 * Return :
294 */
295int spmi_unlock_slave_reg(struct spmi_device *dev)
296{
297 const unsigned char wpk_key = 0x15;
298 const unsigned char wpk_key_h = 0x63;
299
300 if ((dev->slvid == SPMI_SLAVE_6) ||
301 (dev->slvid == SPMI_SLAVE_7) ||
302 (dev->slvid == SPMI_SLAVE_3)) {
303 /* disable dig_wpk key, write 0x6315*/
304 spmi_ext_register_writel(dev, MT6315_PMIC_DIG_WPK_KEY_ADDR,
305 &wpk_key, 1);
306 spmi_ext_register_writel(dev, MT6315_PMIC_DIG_WPK_KEY_H_ADDR,
307 &wpk_key_h, 1);
308 }
309
310 return 0;
311}
312
313static int spmi_config_master(unsigned int mstid, kal_bool en)
314{
315 /* Software reset */
316 DRV_WriteReg32(WDT_SWSYSRST2, 0x85 << 24 | 0x1 << 4);
317
318#if !defined(CONFIG_FPGA_EARLY_PORTING)
319 /* TBD */
320 DRV_WriteReg32(CLK_CFG_16_CLR, 0x7 | (0x1 << 4) | (0x1 << 7));
321 DRV_WriteReg32(CLK_CFG_UPDATE2, 0x1 << 2);
322#endif
323
324 /* Software reset */
325 DRV_WriteReg32(WDT_SWSYSRST2, 0x85 << 24);
326
327 /* Enable SPMI */
328 spmi_writel(mstid, SPMI_MST_REQ_EN, en);
329
330 SPMI_INFO("%s done\n", __func__);
331
332 return 0;
333}
334
335static int spmi_config_slave(struct spmi_device *dev)
336{
337 return 0;
338}
339
340static int spmi_cali_rd_clock_polarity(struct spmi_device *dev,
341 unsigned int mstid)
342{
343 unsigned int i = 0;
344#if 0 //TBD
345/* under construction !*/
346/* under construction !*/
347/* under construction !*/
348#endif
349 struct cali cali_data[] = {
350 {SPMI_CK_DLY_1T, SPMI_CK_POL_POS},
351 {SPMI_CK_NO_DLY, SPMI_CK_POL_POS},
352 {SPMI_CK_NO_DLY, SPMI_CK_POL_NEG}
353 };
354
355 /* Indicate sampling clock polarity, 1: Positive 0: Negative */
356 for (i = 0;i < 3; i++) {
357 spmi_writel(mstid, SPMI_MST_SAMPL,
358 (cali_data[i].dly << 0x1) | cali_data[i].pol);
359 /* for exception reboot, we only call UT/spmi_read_check w/o
360 * write test. It avoid to affect exception record.
361 */
362#if SPMI_DEBUG
363 if (spmi_read_check(dev) == 0) {
364 SPMI_DBG("dly:%d, pol:%d\n", cali_data[i].dly,
365 cali_data[i].pol);
366 break;
367 }
368#endif
369 }
370 if (i == 3) {
371 SPMI_ERR("FATAL ERROR");
372 ASSERT(0);
373 }
374
375#if 0 //TBD
376/* under construction !*/
377/* under construction !*/
378/* under construction !*/
379/* under construction !*/
380/* under construction !*/
381/* under construction !*/
382/* under construction !*/
383/* under construction !*/
384/* under construction !*/
385/* under construction !*/
386/* under construction !*/
387/* under construction !*/
388/* under construction !*/
389/* under construction !*/
390/* under construction !*/
391/* under construction !*/
392/* under construction !*/
393/* under construction !*/
394/* under construction !*/
395/* under construction !*/
396/* under construction !*/
397/* under construction !*/
398/* under construction !*/
399/* under construction !*/
400/* under construction !*/
401/* under construction !*/
402/* under construction !*/
403/* under construction !*/
404/* under construction !*/
405/* under construction !*/
406/* under construction !*/
407/* under construction !*/
408/* under construction !*/
409/* under construction !*/
410/* under construction !*/
411/* under construction !*/
412/* under construction !*/
413/* under construction !*/
414/* under construction !*/
415/* under construction !*/
416/* under construction !*/
417/* under construction !*/
418/* under construction !*/
419/* under construction !*/
420/* under construction !*/
421#endif
422 return 0;
423}
424
425#if SPMI_RCS_SUPPORT
426static int spmi_enable_rcs(struct spmi_device *dev, unsigned int mstid)
427{
428 unsigned char wdata = 0, rdata = 0, i = 0;
429
430 /* clear int status */
431 wdata = 0xc0;
432 spmi_ext_register_writel(dev, MT6315_PMIC_RG_INT_STATUS_RCS0_ADDR,
433 &wdata, 1);
434
435 /* config match mode */
436 wdata = 0x2;
437 spmi_ext_register_writel(dev, MT6315_PMIC_RG_INT_RCS1_ADDR, &wdata, 1);
438 spmi_ext_register_readl(dev, MT6315_PMIC_RG_INT_RCS1_ADDR, &rdata, 1);
439 SPMI_DBG("slvid:%x After set RG_INT_RCS1[0x%x]=0x%x\n", dev->slvid,
440 MT6315_PMIC_RG_INT_RCS1_ADDR, rdata);
441
442 /* set
443 * RG_RCS_ABIT[1] = 1
444 * RG_RCS_CMD[3:2] = 1
445 * RG_RCS_ID[7:4] = 0
446 */
447 spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ABIT_ADDR, &rdata, 1);
448 wdata = rdata |
449 (0x1 << MT6315_PMIC_RG_RCS_ABIT_SHIFT) |
450 (0x1 << MT6315_PMIC_RG_RCS_CMD_SHIFT);
451 wdata &= ~(0xf << MT6315_PMIC_RG_RCS_ID_SHIFT);
452 spmi_ext_register_writel(dev, MT6315_PMIC_RG_RCS_ABIT_ADDR, &wdata, 1);
453 spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ABIT_ADDR, &rdata, 1);
454 SPMI_DBG("slvid:%x After set SPMI_RCS_FUN0[0x%x]=0x%x\n", dev->slvid,
455 MT6315_PMIC_RG_RCS_ABIT_ADDR, rdata);
456
457 /* set rcs_addr = slvid */
458 wdata = dev->slvid;
459 spmi_ext_register_writel(dev, MT6315_PMIC_RG_RCS_ADDR_ADDR, &wdata, 1);
460 spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ADDR_ADDR, &rdata, 1);
461 SPMI_DBG("slvid:%x After set RCS_ADDR[0x%x]=0x%x\n", dev->slvid,
462 MT6315_PMIC_RG_RCS_ADDR_ADDR, rdata);
463
464 /* set mask */
465 wdata = 0x0;
466 spmi_ext_register_writel(dev, MT6315_PMIC_RG_INT_MASK_RCS0_ADDR,
467 &wdata, 1);
468 spmi_ext_register_readl(dev, MT6315_PMIC_RG_INT_MASK_RCS0_ADDR,
469 &rdata, 1);
470 SPMI_DBG("slvid:%x After set RG_INT_MASK[0x%x]=0x%x\n", dev->slvid,
471 MT6315_PMIC_RG_INT_MASK_RCS0_ADDR, rdata);
472
473 /* set top rcs0/rcs1 interrupt enable */
474 wdata = (0x1 << MT6315_PMIC_RG_INT_EN_RCS0_SHIFT) |
475 (0x1 << MT6315_PMIC_RG_INT_EN_RCS1_SHIFT);
476 spmi_ext_register_writel(dev, MT6315_PMIC_RG_INT_EN_RCS0_ADDR,
477 &wdata, 1);
478 spmi_ext_register_readl(dev, MT6315_PMIC_RG_INT_EN_RCS0_ADDR,
479 &rdata, 1);
480 SPMI_DBG("slvid:%x After set RG_INT_EN[0x%x]=0x%x\n", dev->slvid,
481 MT6315_PMIC_RG_INT_EN_RCS0_ADDR, rdata);
482
483 /* enable rcs function */
484 spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ENABLE_ADDR,
485 &rdata, 1);
486 wdata = rdata | (0x1 << MT6315_PMIC_RG_RCS_ENABLE_SHIFT);
487 spmi_ext_register_writel(dev, MT6315_PMIC_RG_RCS_ENABLE_ADDR,
488 &wdata, 1);
489 spmi_ext_register_readl(dev, MT6315_PMIC_RG_RCS_ENABLE_ADDR,
490 &rdata, 1);
491 SPMI_DBG("slvid:%x After set Enable[0x%x]=0x%x\n", dev->slvid,
492 MT6315_PMIC_RG_RCS_ENABLE_ADDR, rdata);
493
494}
495
496int spmi_read_eint_sta(unsigned char *slv_eint_sta)
497{
498 struct pmif *arb = get_pmif_controller(PMIF_SPMI, SPMI_MASTER_0);
499 unsigned char offset = 0, j = 0, rdata = 0;
500 unsigned int regs = 0;
501
502 for (offset = 0; offset < 4; offset++) {
503 regs = arb->spmimst_regs[SPMI_SLV_3_0_EINT] + (offset*4);
504 rdata = DRV_Reg32(arb->spmimst_base + regs);
505 *(slv_eint_sta + j) = rdata & 0xff;
506 *(slv_eint_sta + j+1) = (rdata >> 8) & 0xff;
507 *(slv_eint_sta + j+2) = (rdata >> 16) & 0xff;
508 *(slv_eint_sta + j+3) = (rdata >> 24) & 0xff;
509 j += 4;
510 }
511
512 for (offset = 0; offset < 16; offset++) {
513 SPMI_INFO("%d, slv_eint_sta[0x%x]\n", offset,
514 *(slv_eint_sta + offset));
515 }
516 spmi_writel(mstid, SPMI_SLV_3_0_EINT, 0xffffffff);
517 spmi_writel(mstid, SPMI_SLV_7_4_EINT, 0xffffffff);
518 spmi_writel(mstid, SPMI_SLV_B_8_EINT, 0xffffffff);
519 spmi_writel(mstid, SPMI_SLV_F_C_EINT, 0xffffffff);
520
521 SPMI_INFO("%s, [0x%x]=0x%x\n", __func__,
522 arb->spmimst_base + arb->spmimst_regs[SPMI_DEC_DBG],
523 spmi_readl(mstid, SPMI_DEC_DBG));
524}
525#endif
526
527#if SPMI_EXTADDR_SUPPORT
528int spmi_register_zero_write_extaddr(struct spmi_device *dev,
529 unsigned int addr, unsigned char data)
530{
531 unsigned char wdata = 0;
532
533 spmi_unlock_slave_reg(dev);
534
535 if ((dev->slvid == SPMI_SLAVE_6) ||
536 (dev->slvid == SPMI_SLAVE_7) ||
537 (dev->slvid == SPMI_SLAVE_3)) {
538 /* assign specific addr */
539 wdata = (addr&0xff);
540 spmi_ext_register_writel(dev,
541 MT6315_PMIC_RG_EXTADR_REG0_W_ADDR, &wdata, 1);
542 wdata = (addr>>8)&0xff;
543 spmi_ext_register_writel(dev,
544 MT6315_PMIC_RG_EXTADR_REG0_W_H_ADDR, &wdata, 1);
545 }
546
547 spmi_lock_slave_reg(dev);
548
549 return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_ZERO_WRITE,
550 dev->slvid, addr, &data, 1);
551}
552
553int spmi_register_zero_write_set_extaddr(struct spmi_device *dev,
554 unsigned int addr, kal_bool en)
555{
556 unsigned char wdata = 0;
557
558 spmi_unlock_slave_reg(dev);
559
560 if ((dev->slvid == SPMI_SLAVE_6) ||
561 (dev->slvid == SPMI_SLAVE_7) ||
562 (dev->slvid == SPMI_SLAVE_3)) {
563 if (en == KAL_TRUE) {
564 /* assign specific addr */
565 wdata = (addr&0xff);
566 spmi_ext_register_writel(dev,
567 MT6315_PMIC_RG_EXTADR_REG0_W_ADDR, &wdata, 1);
568 wdata = (addr>>8)&0xff;
569 spmi_ext_register_writel(dev,
570 MT6315_PMIC_RG_EXTADR_REG0_W_H_ADDR,
571 &wdata, 1);
572 } else {
573 /* assign specific addr */
574 wdata = 0;
575 spmi_ext_register_writel(dev,
576 MT6315_PMIC_RG_EXTADR_REG0_W_ADDR,
577 &wdata, 1);
578 spmi_ext_register_writel(dev,
579 MT6315_PMIC_RG_EXTADR_REG0_W_H_ADDR,
580 &wdata, 1);
581 }
582 }
583
584 spmi_lock_slave_reg(dev);
585
586 return 0;
587}
588
589int spmi_register_read_extaddr(struct spmi_device *dev, unsigned int addr,
590 unsigned char *buf)
591{
592 unsigned char wdata = 0;
593
594 spmi_unlock_slave_reg(dev);
595
596 if ((dev->slvid == SPMI_SLAVE_6) ||
597 (dev->slvid == SPMI_SLAVE_7) ||
598 (dev->slvid == SPMI_SLAVE_3)) {
599 /* assign specific addr */
600 wdata = ((addr >> 5) & 0xff);
601 spmi_ext_register_writel(dev,
602 MT6315_PMIC_RG_EXTADR_REG_RW_ADDR, &wdata, 1);
603 wdata = ((addr >> 5) & 0xff00);
604 spmi_ext_register_writel(dev,
605 MT6315_PMIC_RG_EXTADR_REG_RW_H_ADDR, &wdata, 1);
606 }
607
608 spmi_lock_slave_reg(dev);
609
610 return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_READ,
611 dev->slvid, addr, buf, 1);
612}
613
614int spmi_register_write_extaddr(struct spmi_device *dev, unsigned int addr,
615 unsigned char data)
616{
617 unsigned char wdata = 0;
618
619 spmi_unlock_slave_reg(dev);
620
621 if ((dev->slvid == SPMI_SLAVE_6) ||
622 (dev->slvid == SPMI_SLAVE_7) ||
623 (dev->slvid == SPMI_SLAVE_3)) {
624 /* assign specific addr */
625 wdata = ((addr >> 5) & 0xff);
626 spmi_ext_register_writel(dev,
627 MT6315_PMIC_RG_EXTADR_REG_RW_ADDR, &wdata, 1);
628 wdata = ((addr >> 5) & 0xff00);
629 spmi_ext_register_writel(dev,
630 MT6315_PMIC_RG_EXTADR_REG_RW_H_ADDR,
631 &wdata, 1);
632 }
633
634 spmi_lock_slave_reg(dev);
635
636 return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_WRITE,
637 dev->slvid, addr, &data, 1);
638}
639
640int spmi_register_rw_set_extaddr(struct spmi_device *dev, unsigned int addr,
641 kal_bool en)
642{
643 unsigned char wdata = 0;
644
645 spmi_unlock_slave_reg(dev);
646
647 if ((dev->slvid == SPMI_SLAVE_6) ||
648 (dev->slvid == SPMI_SLAVE_7) ||
649 (dev->slvid == SPMI_SLAVE_3)) {
650 if (en == KAL_TRUE) {
651 /* assign specific addr */
652 wdata = ((addr >> 5) & 0xff);
653 spmi_ext_register_writel(dev,
654 MT6315_PMIC_RG_EXTADR_REG_RW_ADDR,
655 &wdata, 1);
656 wdata = ((addr >> 5) & 0xff00);
657 spmi_ext_register_writel(dev,
658 MT6315_PMIC_RG_EXTADR_REG_RW_H_ADDR,
659 &wdata, 1);
660 } else {
661 /* assign specific addr */
662 wdata = 0;
663 spmi_ext_register_writel(dev,
664 MT6315_PMIC_RG_EXTADR_REG_RW_ADDR,
665 &wdata, 1);
666 spmi_ext_register_writel(dev,
667 MT6315_PMIC_RG_EXTADR_REG_RW_H_ADDR,
668 &wdata, 1);
669 }
670 }
671
672 spmi_lock_slave_reg(dev);
673
674 return 0;
675}
676
677int spmi_ext_register_read_extaddr(struct spmi_device *dev, unsigned int addr,
678 unsigned char *buf, unsigned short len)
679{
680 unsigned char wdata = 0;
681
682 spmi_unlock_slave_reg(dev);
683
684 if ((dev->slvid == SPMI_SLAVE_6) ||
685 (dev->slvid == SPMI_SLAVE_7) ||
686 (dev->slvid == SPMI_SLAVE_3)) {
687 /* assign specific addr */
688 wdata = ((addr >> 8) & 0xff);
689 spmi_ext_register_writel(dev,
690 MT6315_PMIC_RG_EXTADR_EXT_REG_RW_ADDR,
691 &wdata, 1);
692 }
693
694 spmi_lock_slave_reg(dev);
695
696 return dev->pmif_arb->read_cmd(dev->pmif_arb, SPMI_CMD_EXT_READ,
697 dev->slvid, addr, buf, len);
698}
699
700int spmi_ext_register_write_extaddr(struct spmi_device *dev, unsigned int addr,
701 const unsigned char *buf, unsigned short len)
702{
703 unsigned char wdata = 0;
704
705 spmi_unlock_slave_reg(dev);
706
707 if ((dev->slvid == SPMI_SLAVE_6) ||
708 (dev->slvid == SPMI_SLAVE_7) ||
709 (dev->slvid == SPMI_SLAVE_3)) {
710 /* assign specific addr */
711 wdata = ((addr >> 8) & 0xff);
712 spmi_ext_register_writel(dev,
713 MT6315_PMIC_RG_EXTADR_EXT_REG_RW_ADDR, &wdata, 1);
714 }
715
716 spmi_lock_slave_reg(dev);
717
718 return dev->pmif_arb->write_cmd(dev->pmif_arb, SPMI_CMD_EXT_WRITE,
719 dev->slvid, addr, buf, len);
720}
721
722int spmi_ext_register_rw_set_extaddr(struct spmi_device *dev,
723 unsigned int addr, kal_bool en)
724{
725 unsigned char wdata = 0;
726
727 spmi_unlock_slave_reg(dev);
728
729 if ((dev->slvid == SPMI_SLAVE_6) ||
730 (dev->slvid == SPMI_SLAVE_7) ||
731 (dev->slvid == SPMI_SLAVE_3)) {
732 /* assign specific addr */
733 if (en == KAL_TRUE) {
734 wdata = ((addr >> 8) & 0xff);
735 spmi_ext_register_writel(dev,
736 MT6315_PMIC_RG_EXTADR_EXT_REG_RW_ADDR,
737 &wdata, 1);
738 } else {
739 wdata = 0;
740 spmi_ext_register_writel(dev,
741 MT6315_PMIC_RG_EXTADR_EXT_REG_RW_ADDR,
742 &wdata, 1);
743 }
744 }
745
746 spmi_lock_slave_reg(dev);
747
748 return 0;
749}
750#endif /* end of SPMI_EXTADDR_SUPPORT */
751
752static int spmi_ctrl_op_st(int mstid, unsigned int grpiden, unsigned int sid,
753 unsigned int cmd)
754{
755 unsigned int rdata = 0x0;
756
757 /* gid is 0x800 */
758 spmi_writel(mstid, SPMI_GRP_ID_EN, grpiden);
759#if MT63xx_EVB
760 if (grpiden == (1 << SPMI_GROUP_ID))
761 spmi_writel(mstid, SPMI_OP_ST_CTRL,
762 (cmd << 0x4) | SPMI_GROUP_ID);
763#else
764 if (grpiden == 0x100)
765 spmi_writel(mstid, SPMI_OP_ST_CTRL, (cmd << 0x4) | 0x8);
766#endif
767 else
768 spmi_writel(mstid, SPMI_OP_ST_CTRL, (cmd << 0x4) | sid);
769
770 SPMI_WARN("spmi_ctrl_op_st 0x%x\n", spmi_readl(mstid, SPMI_OP_ST_CTRL));
771
772 do
773 {
774 rdata = spmi_readl(mstid, SPMI_OP_ST_STA);
775 SPMI_DBG("spmi_ctrl_op_st 0x%x\n", rdata);
776
777 if (((rdata >> 0x1) & SPMI_OP_ST_NACK) == SPMI_OP_ST_NACK) {
778 break;
779 }
780 }while((rdata & SPMI_OP_ST_BUSY) == SPMI_OP_ST_BUSY);
781
782 return 0;
783}
784
785int spmi_command_reset(int mstid, struct spmi_device *dev, unsigned int grpiden)
786{
787#if MT63xx_EVB
788 if (grpiden != (1 << SPMI_GROUP_ID))
789 dev->slvid = grpiden;
790#else
791 if (grpiden != 0x100)
792 dev->slvid = grpiden;
793#endif
794 return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_RESET);
795}
796int spmi_command_sleep(int mstid, struct spmi_device *dev, unsigned int grpiden)
797{
798#if MT63xx_EVB
799 if (grpiden != (1 << SPMI_GROUP_ID))
800 dev->slvid = grpiden;
801#else
802 if (grpiden != 0x100)
803 dev->slvid = grpiden;
804#endif
805 return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_SLEEP);
806}
807int spmi_command_wakeup(int mstid, struct spmi_device *dev, unsigned int grpiden)
808{
809#if MT63xx_EVB
810 if (grpiden != (1 << SPMI_GROUP_ID))
811 dev->slvid = grpiden;
812#else
813 if (grpiden != 0x100)
814 dev->slvid = grpiden;
815#endif
816 return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_WAKEUP);
817}
818int spmi_command_shutdown(int mstid, struct spmi_device *dev, unsigned int grpiden)
819{
820#if MT63xx_EVB
821 if (grpiden != (1 << SPMI_GROUP_ID))
822 dev->slvid = grpiden;
823#else
824 if (grpiden != 0x100)
825 dev->slvid = grpiden;
826#endif
827 return spmi_ctrl_op_st(mstid, grpiden, dev->slvid, SPMI_SHUTDOWN);
828}
829
830int spmi_enable_group_id(int mstid, unsigned int grpiden)
831{
832 spmi_writel(mstid, SPMI_GRP_ID_EN, grpiden);
833
834 return 0;
835}
836
837#if SPMI_DEBUG
838static int spmi_rw_test(struct spmi_device *dev)
839{
840 unsigned char wdata = 0, rdata = 0;
841
842 if (dev->mstid == SPMI_MASTER_P_1) {
843 SPMI_INFO("SPMI-P doesn't do %s\n", __func__);
844 return 0;
845 }
846 switch (dev->slvid) {
847 case SPMI_SLAVE_3:
848 case SPMI_SLAVE_6:
849 case SPMI_SLAVE_7:
850 wdata = DEFAULT_VALUE_READ_TEST;
851 spmi_ext_register_writel(dev, MT6315_PMIC_TOP_MDB_RSV1_ADDR,
852 &wdata, 1);
853 spmi_ext_register_readl(dev, MT6315_PMIC_TOP_MDB_RSV1_ADDR,
854 &rdata, 1);
855 if (rdata != DEFAULT_VALUE_READ_TEST) {
856 SPMI_ERR("%s fail_r, slvid:%d rdata = 0x%x.\n",
857 __func__, dev->slvid, rdata);
858 return -EIO;
859 } else
860 SPMI_DBG("%s pass_r, slvid:%d\n", __func__, dev->slvid);
861
862 wdata = DEFAULT_VALUE_WRITE_TEST;
863 spmi_ext_register_writel(dev, MT6315_PMIC_TOP_MDB_RSV1_H_ADDR,
864 &wdata, 1);
865
866 spmi_ext_register_readl(dev, MT6315_PMIC_TOP_MDB_RSV1_H_ADDR,
867 &rdata, 1);
868 if (rdata != DEFAULT_VALUE_WRITE_TEST) {
869 SPMI_ERR("%s fail_w, slvid:%d rdata = 0x%x.\n",
870 __func__, dev->slvid, rdata);
871 return -EIO;
872 } else
873 SPMI_DBG("%s pass_w, slvid:%d\n", __func__, dev->slvid);
874
875 break;
876 case SPMI_SLAVE_9:
877 spmi_read_check(dev);
878 break;
879 case SPMI_SLAVE_8:
880 default:
881 SPMI_ERR("%s not be here, slvid:%d\n", __func__, dev->slvid);
882 break;
883 }
884 return 0;
885}
886
887static int spmi_read_check(struct spmi_device *dev)
888{
889 unsigned char rdata = 0;
890
891 spmi_ext_register_readl(dev, dev->hwcid_addr, &rdata, 1);
892 /* mt6362 can only check 0x00[7:4], other mt63xx can align the rule */
893 if ((rdata & 0xF0) != (dev->hwcid_val & 0xF0)) {
894 SPMI_ERR("%s next, slvid:%d rdata = 0x%x.\n",
895 __func__, dev->slvid, rdata);
896 return -EIO;
897 } else
898 SPMI_DBG("%s done, slvid:%d\n", __func__, dev->slvid);
899
900 return 0;
901}
902
903static int spmi_drv_ut(struct spmi_device *dev, unsigned int ut)
904{
905 int ret = 0;
906
907 switch (ut) {
908 case 1:
909 ret = spmi_rw_test(dev);
910 break;
911 case 2:
912 ret = spmi_read_check(dev);
913 break;
914 case 3:
915 break;
916 default:
917 break;
918 }
919
920 return ret;
921}
922#endif /* end of #if SPMI_DEBUG */
923
924struct spmi_device *get_spmi_device(int mstid, unsigned int slv_type)
925{
926 unsigned int i;
927
928 for (i = 0; i < spmi_device_cnt; i++) {
929 if (slv_type == spmi_dev[i].type) {
930 return &spmi_dev[i];
931 }
932 }
933
934 return NULL;
935}
936
937int spmi_init(struct pmif *pmif_arb)
938{
939 int i = 0;
940#if SPMI_DEBUG
941 int ret = 0;
942#endif
943
944 if (pmif_arb == NULL) /* null check */ {
945 SPMI_ERR("arguments err\n");
946 return -EINVAL;
947 }
948
949 pmif_arb->spmimst_regs = mt6885_spmi_regs;
950 pmif_spmi_arb_ctrl[pmif_arb->mstid] = pmif_arb;
951 spmi_device_cnt = sizeof(spmi_dev)/sizeof(spmi_dev[0]);
952
953 if (is_pmif_spmi_init_done(pmif_arb->mstid) != 0)
954 spmi_config_master(pmif_arb->mstid, KAL_TRUE);
955
956 for (i = 0; i < spmi_device_cnt; i++) {
957 if (pmif_arb->mstid == spmi_dev[i].mstid) {
958 spmi_dev[i].pmif_arb = pmif_spmi_arb_ctrl[pmif_arb->mstid];
959 if (is_pmif_spmi_init_done(pmif_arb->mstid) != 0) {
960 spmi_config_slave(&spmi_dev[i]);
961 spmi_cali_rd_clock_polarity(&spmi_dev[i],
962 pmif_arb->mstid);
963 }
964#if SPMI_MONITOR_SUPPORT
965 /* dump 1st time slave debug register when booting */
966 spmi_dump_slv_record_reg(&spmi_dev[i]);
967#endif
968#if SPMI_RCS_SUPPORT
969 if (is_pmif_spmi_init_done() != 0) {
970 /* enable master rcs support */
971 spmi_writel(pmif_arb->mstid, SPMI_MST_RCS_CTRL, 0x15);
972 spmi_enable_rcs(&spmi_dev[i], pmif_arb->mstid);
973 }
974#endif
975
976#if SPMI_DEBUG
977 /* shouldn't enable at here*/
978 ret = spmi_drv_ut(&spmi_dev[i], 1);
979 if(ret) {
980 SPMI_ERR("EIO err\n");
981 return ret;
982 }
983#endif
984 /*TBD spmi_lock_slave_reg(&spmi_dev[i]); */
985 }
986 }
987 SPMI_INFO("%s done\n", __func__);
988
989 return 0;
990}
991
992#endif /* #ifdef SPMI_NO_PMIC */