]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - board/karo/tx6/ltc3676.c
karo: tx6: rework PMIC code to allow for different configs for same chip
[karo-tx-uboot.git] / board / karo / tx6 / ltc3676.c
1 /*
2  * Copyright (C) 2014 Lothar Waßmann <LW@KARO-electronics.de>
3  *
4  * See file CREDITS for list of people who contributed to this
5  * project.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * version 2 as published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  */
17
18 #include <common.h>
19 #include <i2c.h>
20 #include <asm/io.h>
21 #include <asm/arch/imx-regs.h>
22
23 #include "../common/karo.h"
24 #include "pmic.h"
25
26 #define LTC3676_BUCK1           0x01
27 #define LTC3676_BUCK2           0x02
28 #define LTC3676_BUCK3           0x03
29 #define LTC3676_BUCK4           0x04
30 #define LTC3676_DVB1A           0x0A
31 #define LTC3676_DVB1B           0x0B
32 #define LTC3676_DVB2A           0x0C
33 #define LTC3676_DVB2B           0x0D
34 #define LTC3676_DVB3A           0x0E
35 #define LTC3676_DVB3B           0x0F
36 #define LTC3676_DVB4A           0x10
37 #define LTC3676_DVB4B           0x11
38 #define LTC3676_MSKPG           0x13
39 #define LTC3676_CLIRQ           0x1f
40
41 #define LTC3676_BUCK_DVDT_FAST  (1 << 0)
42 #define LTC3676_BUCK_KEEP_ALIVE (1 << 1)
43 #define LTC3676_BUCK_CLK_RATE_LOW (1 << 2)
44 #define LTC3676_BUCK_PHASE_SEL  (1 << 3)
45 #define LTC3676_BUCK_ENABLE_300 (1 << 4)
46 #define LTC3676_BUCK_PULSE_SKIP (0 << 5)
47 #define LTC3676_BUCK_BURST_MODE (1 << 5)
48 #define LTC3676_BUCK_CONTINUOUS (2 << 5)
49 #define LTC3676_BUCK_ENABLE     (1 << 7)
50
51 #define LTC3676_PGOOD_MASK      (1 << 5)
52
53 #define LTC3676_MSKPG_BUCK1     (1 << 0)
54 #define LTC3676_MSKPG_BUCK2     (1 << 1)
55 #define LTC3676_MSKPG_BUCK3     (1 << 2)
56 #define LTC3676_MSKPG_BUCK4     (1 << 3)
57 #define LTC3676_MSKPG_LDO2      (1 << 5)
58 #define LTC3676_MSKPG_LDO3      (1 << 6)
59 #define LTC3676_MSKPG_LDO4      (1 << 7)
60
61 #define VDD_IO_VAL              mV_to_regval(vout_to_vref(3300, 5))
62 #define VDD_IO_VAL_LP           mV_to_regval(vout_to_vref(3100, 5))
63 #define VDD_IO_VAL_2            mV_to_regval(vout_to_vref(3300, 5_2))
64 #define VDD_IO_VAL_2_LP         mV_to_regval(vout_to_vref(3100, 5_2))
65 #define VDD_SOC_VAL             mV_to_regval(vout_to_vref(1425, 6))
66 #define VDD_SOC_VAL_LP          mV_to_regval(vout_to_vref(900, 6))
67 #define VDD_DDR_VAL             mV_to_regval(vout_to_vref(1500, 7))
68 #define VDD_DDR_VAL_LP          mV_to_regval(vout_to_vref(1500, 7))
69 #define VDD_CORE_VAL            mV_to_regval(vout_to_vref(1425, 8))
70 #define VDD_CORE_VAL_LP         mV_to_regval(vout_to_vref(900, 8))
71
72 /* LDO1 */
73 #define R1_1                    470
74 #define R2_1                    150
75 /* LDO4 */
76 #define R1_4                    470
77 #define R2_4                    150
78 /* Buck1 */
79 #define R1_5                    390
80 #define R2_5                    110
81 #define R1_5_2                  470
82 #define R2_5_2                  150
83 /* Buck2 (SOC) */
84 #define R1_6                    150
85 #define R2_6                    180
86 /* Buck3 (DDR) */
87 #define R1_7                    150
88 #define R2_7                    140
89 /* Buck4 (CORE) */
90 #define R1_8                    150
91 #define R2_8                    180
92
93 /* calculate voltages in 10mV */
94 #define R1(idx)                 R1_##idx
95 #define R2(idx)                 R2_##idx
96
97 #define v2r(v,n,m)              DIV_ROUND(((((v) < (n)) ? (n) : (v)) - (n)), (m))
98 #define r2v(r,n,m)              (((r) * (m) + (n)) / 10)
99
100 #define vout_to_vref(vout, idx) ((vout) * R2(idx) / (R1(idx) + R2(idx)))
101 #define vref_to_vout(vref, idx) DIV_ROUND_UP((vref) * (R1(idx) + R2(idx)), R2(idx))
102
103 #define mV_to_regval(mV)        v2r((mV) * 10, 4125, 125)
104 #define regval_to_mV(r)         r2v(r, 4125, 125)
105
106 static struct pmic_regs ltc3676_regs[] = {
107         { LTC3676_MSKPG, ~LTC3676_MSKPG_BUCK1, },
108         { LTC3676_DVB2B, VDD_SOC_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
109         { LTC3676_DVB3B, VDD_DDR_VAL_LP, ~0x3f, },
110         { LTC3676_DVB4B, VDD_CORE_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
111         { LTC3676_DVB2A, VDD_SOC_VAL, ~0x3f, },
112         { LTC3676_DVB3A, VDD_DDR_VAL, ~0x3f, },
113         { LTC3676_DVB4A, VDD_CORE_VAL, ~0x3f, },
114         { LTC3676_BUCK1, LTC3676_BUCK_BURST_MODE | LTC3676_BUCK_CLK_RATE_LOW, },
115         { LTC3676_BUCK2, LTC3676_BUCK_BURST_MODE, },
116         { LTC3676_BUCK3, LTC3676_BUCK_BURST_MODE, },
117         { LTC3676_BUCK4, LTC3676_BUCK_BURST_MODE, },
118         { LTC3676_CLIRQ, 0, }, /* clear interrupt status */
119 };
120
121 static struct pmic_regs ltc3676_regs_1[] = {
122         { LTC3676_DVB1B, VDD_IO_VAL_LP | LTC3676_PGOOD_MASK, ~0x3f, },
123         { LTC3676_DVB1A, VDD_IO_VAL, ~0x3f, },
124 };
125
126 static struct pmic_regs ltc3676_regs_2[] = {
127         { LTC3676_DVB1B, VDD_IO_VAL_2_LP | LTC3676_PGOOD_MASK, ~0x3f, },
128         { LTC3676_DVB1A, VDD_IO_VAL_2, ~0x3f, },
129 };
130
131 static int tx6_rev_2(void)
132 {
133         struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
134         struct fuse_bank5_regs *fuse = (void *)ocotp->bank[5].fuse_regs;
135         u32 pad_settings = readl(&fuse->pad_settings);
136
137         debug("Fuse pad_settings @ %p = %02x\n",
138                 &fuse->pad_settings, pad_settings);
139         return pad_settings & 1;
140 }
141
142 static int ltc3676_setup_regs(uchar slave_addr, struct pmic_regs *r,
143                         size_t count)
144 {
145         int ret;
146         int i;
147
148         for (i = 0; i < count; i++, r++) {
149 #ifdef DEBUG
150                 unsigned char value;
151
152                 ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
153                 if (ret) {
154                         printf("%s: failed to read PMIC register %02x: %d\n",
155                                 __func__, r->addr, ret);
156                         return ret;
157                 }
158                 if ((value & ~r->mask) != r->val) {
159                         printf("Changing PMIC reg %02x from %02x to %02x\n",
160                                 r->addr, value, r->val);
161                 }
162 #endif
163                 ret = i2c_write(slave_addr, r->addr, 1, &r->val, 1);
164                 if (ret) {
165                         printf("%s: failed to write PMIC register %02x: %d\n",
166                                 __func__, r->addr, ret);
167                         return ret;
168                 }
169 #ifdef DEBUG
170                 ret = i2c_read(slave_addr, r->addr, 1, &value, 1);
171                 if (ret) {
172                         printf("%s: failed to read PMIC register %02x: %d\n",
173                                 __func__, r->addr, ret);
174                         return ret;
175                 }
176                 if (value != r->val) {
177                         printf("Failed to set PMIC reg %02x to %02x; actual value: %02x\n",
178                                 r->addr, r->val, value);
179                 }
180 #endif
181         }
182         return 0;
183 }
184
185 int ltc3676_pmic_setup(uchar slave_addr, struct pmic_regs *regs,
186                         size_t count)
187 {
188         int ret;
189         unsigned char value;
190
191         ret = i2c_read(slave_addr, 0x11, 1, &value, 1);
192         if (ret) {
193                 printf("%s: i2c_read error: %d\n", __func__, ret);
194                 return ret;
195         }
196
197         ret = ltc3676_setup_regs(slave_addr, ltc3676_regs,
198                                 ARRAY_SIZE(ltc3676_regs));
199         if (ret)
200                 return ret;
201
202         ret = i2c_read(slave_addr, LTC3676_DVB4A, 1, &value, 1);
203         if (ret == 0) {
204                 printf("VDDCORE set to %umV\n",
205                         vref_to_vout(regval_to_mV(value), 8));
206         } else {
207                 printf("Failed to read VDDCORE register setting\n");
208         }
209
210         ret = i2c_read(slave_addr, LTC3676_DVB2A, 1, &value, 1);
211         if (ret == 0) {
212                 printf("VDDSOC  set to %umV\n",
213                         vref_to_vout(regval_to_mV(value), 6));
214         } else {
215                 printf("Failed to read VDDSOC register setting\n");
216         }
217
218         if (tx6_rev_2()) {
219                 ret = ltc3676_setup_regs(slave_addr, ltc3676_regs_2,
220                                 ARRAY_SIZE(ltc3676_regs_2));
221
222                 ret = i2c_read(slave_addr, LTC3676_DVB1A, 1, &value, 1);
223                 if (ret == 0) {
224                         printf("VDDIO   set to %umV\n",
225                                 vref_to_vout(regval_to_mV(value), 5_2));
226                 } else {
227                         printf("Failed to read VDDIO register setting\n");
228                 }
229         } else {
230                 ret = ltc3676_setup_regs(slave_addr, ltc3676_regs_1,
231                                 ARRAY_SIZE(ltc3676_regs_1));
232         }
233         return ret;
234 }