blob: 1f64f217c345fc9d1c24f21939f12c4bf5c4f759 [file] [log] [blame]
Stephan Gerholdcb9589f2021-07-08 20:33:48 +02001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (C) 2019 Stephan Gerhold
4 *
5 * Adapted from old U-Boot and Linux kernel implementation:
6 * Copyright (C) STMicroelectronics 2009
7 * Copyright (C) ST-Ericsson SA 2010
8 */
9
10#include <common.h>
11#include <dm.h>
12#include <regmap.h>
13#include <syscon.h>
14#include <linux/bitops.h>
15#include <linux/err.h>
16#include <power/ab8500.h>
17#include <power/pmic.h>
18
19/* CPU mailbox registers */
20#define PRCM_MBOX_CPU_VAL 0x0fc
21#define PRCM_MBOX_CPU_SET 0x100
22#define PRCM_MBOX_CPU_CLR 0x104
23
24#define PRCM_ARM_IT1_CLR 0x48C
25#define PRCM_ARM_IT1_VAL 0x494
26
27#define PRCM_TCDM_RANGE 2
28#define PRCM_REQ_MB5 0xE44
29#define PRCM_ACK_MB5 0xDF4
30#define _PRCM_MBOX_HEADER 0xFE8
31#define PRCM_MBOX_HEADER_REQ_MB5 (_PRCM_MBOX_HEADER + 0x5)
32#define PRCMU_I2C_MBOX_BIT BIT(5)
33
34/* Mailbox 5 Requests */
35#define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0)
36#define PRCM_REQ_MB5_I2C_HW_BITS (PRCM_REQ_MB5 + 0x1)
37#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 0x2)
38#define PRCM_REQ_MB5_I2C_VAL (PRCM_REQ_MB5 + 0x3)
39#define PRCMU_I2C(bank) (((bank) << 1) | BIT(6))
40#define PRCMU_I2C_WRITE 0
41#define PRCMU_I2C_READ 1
42#define PRCMU_I2C_STOP_EN BIT(3)
43
44/* Mailbox 5 ACKs */
45#define PRCM_ACK_MB5_I2C_STATUS (PRCM_ACK_MB5 + 0x1)
46#define PRCM_ACK_MB5_I2C_VAL (PRCM_ACK_MB5 + 0x3)
47#define PRCMU_I2C_WR_OK 0x1
48#define PRCMU_I2C_RD_OK 0x2
49
50/* AB8500 version registers */
51#define AB8500_MISC_REV_REG AB8500_MISC(0x80)
52#define AB8500_MISC_IC_NAME_REG AB8500_MISC(0x82)
53
54struct ab8500_priv {
55 struct ab8500 ab8500;
56 struct regmap *regmap;
57};
58
59static inline int prcmu_tcdm_readb(struct regmap *map, uint offset, u8 *valp)
60{
61 return regmap_raw_read_range(map, PRCM_TCDM_RANGE, offset,
62 valp, sizeof(*valp));
63}
64
65static inline int prcmu_tcdm_writeb(struct regmap *map, uint offset, u8 val)
66{
67 return regmap_raw_write_range(map, PRCM_TCDM_RANGE, offset,
68 &val, sizeof(val));
69}
70
71static int prcmu_wait_i2c_mbx_ready(struct ab8500_priv *priv)
72{
73 uint val;
74 int ret;
75
76 ret = regmap_read(priv->regmap, PRCM_ARM_IT1_VAL, &val);
77 if (ret)
78 return ret;
79
80 if (val & PRCMU_I2C_MBOX_BIT) {
81 printf("ab8500: warning: PRCMU i2c mailbox was not acked\n");
82 /* clear mailbox 5 ack irq */
83 ret = regmap_write(priv->regmap, PRCM_ARM_IT1_CLR,
84 PRCMU_I2C_MBOX_BIT);
85 if (ret)
86 return ret;
87 }
88
89 /* wait for on-going transaction, use 1s timeout */
90 return regmap_read_poll_timeout(priv->regmap, PRCM_MBOX_CPU_VAL, val,
91 !(val & PRCMU_I2C_MBOX_BIT), 0, 1000);
92}
93
94static int prcmu_wait_i2c_mbx_done(struct ab8500_priv *priv)
95{
96 uint val;
97 int ret;
98
99 /* set interrupt to XP70 */
100 ret = regmap_write(priv->regmap, PRCM_MBOX_CPU_SET, PRCMU_I2C_MBOX_BIT);
101 if (ret)
102 return ret;
103
104 /* wait for mailbox 5 (i2c) ack, use 1s timeout */
105 return regmap_read_poll_timeout(priv->regmap, PRCM_ARM_IT1_VAL, val,
106 (val & PRCMU_I2C_MBOX_BIT), 0, 1000);
107}
108
109static int ab8500_transfer(struct udevice *dev, uint bank_reg, u8 *val,
110 u8 op, u8 expected_status)
111{
112 struct ab8500_priv *priv = dev_get_priv(dev);
113 u8 reg = bank_reg & 0xff;
114 u8 bank = bank_reg >> 8;
115 u8 status;
116 int ret;
117
118 ret = prcmu_wait_i2c_mbx_ready(priv);
119 if (ret)
120 return ret;
121
122 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_MBOX_HEADER_REQ_MB5, 0);
123 if (ret)
124 return ret;
125 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_SLAVE_OP,
126 PRCMU_I2C(bank) | op);
127 if (ret)
128 return ret;
129 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_HW_BITS,
130 PRCMU_I2C_STOP_EN);
131 if (ret)
132 return ret;
133 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_REG, reg);
134 if (ret)
135 return ret;
136 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_VAL, *val);
137 if (ret)
138 return ret;
139
140 ret = prcmu_wait_i2c_mbx_done(priv);
141 if (ret) {
142 printf("%s: mailbox request timed out\n", __func__);
143 return ret;
144 }
145
146 /* read transfer result */
147 ret = prcmu_tcdm_readb(priv->regmap, PRCM_ACK_MB5_I2C_STATUS, &status);
148 if (ret)
149 return ret;
150 ret = prcmu_tcdm_readb(priv->regmap, PRCM_ACK_MB5_I2C_VAL, val);
151 if (ret)
152 return ret;
153
154 /*
155 * Clear mailbox 5 ack irq. Note that the transfer is already complete
156 * here so checking for errors does not make sense. Clearing the irq
157 * will be retried in prcmu_wait_i2c_mbx_ready() on the next transfer.
158 */
159 regmap_write(priv->regmap, PRCM_ARM_IT1_CLR, PRCMU_I2C_MBOX_BIT);
160
161 if (status != expected_status) {
162 /*
163 * AB8500 does not have the AB8500_MISC_IC_NAME_REG register,
164 * but we need to try reading it to detect AB8505.
165 * In case of an error, assume that we have AB8500.
166 */
167 if (op == PRCMU_I2C_READ && bank_reg == AB8500_MISC_IC_NAME_REG) {
168 *val = AB8500_VERSION_AB8500;
169 return 0;
170 }
171
172 printf("%s: return status %d\n", __func__, status);
173 return -EIO;
174 }
175
176 return 0;
177}
178
179static int ab8500_reg_count(struct udevice *dev)
180{
181 return AB8500_NUM_REGISTERS;
182}
183
184static int ab8500_read(struct udevice *dev, uint reg, uint8_t *buf, int len)
185{
186 int ret;
187
188 if (len != 1)
189 return -EINVAL;
190
191 *buf = 0;
192 ret = ab8500_transfer(dev, reg, buf, PRCMU_I2C_READ, PRCMU_I2C_RD_OK);
193 if (ret) {
194 printf("%s failed: %d\n", __func__, ret);
195 return ret;
196 }
197
198 return 0;
199}
200
201static int ab8500_write(struct udevice *dev, uint reg, const uint8_t *buf, int len)
202{
203 int ret;
204 u8 val;
205
206 if (len != 1)
207 return -EINVAL;
208
209 val = *buf;
210 ret = ab8500_transfer(dev, reg, &val, PRCMU_I2C_WRITE, PRCMU_I2C_WR_OK);
211 if (ret) {
212 printf("%s failed: %d\n", __func__, ret);
213 return ret;
214 }
215
216 return 0;
217}
218
219static struct dm_pmic_ops ab8500_ops = {
220 .reg_count = ab8500_reg_count,
221 .read = ab8500_read,
222 .write = ab8500_write,
223};
224
225static int ab8500_probe(struct udevice *dev)
226{
227 struct ab8500_priv *priv = dev_get_priv(dev);
228 int ret;
229
230 /* get regmap from the PRCMU parent device (syscon in U-Boot) */
231 priv->regmap = syscon_get_regmap(dev->parent);
232 if (IS_ERR(priv->regmap))
233 return PTR_ERR(priv->regmap);
234
235 ret = pmic_reg_read(dev, AB8500_MISC_IC_NAME_REG);
236 if (ret < 0) {
237 printf("ab8500: failed to read chip version: %d\n", ret);
238 return ret;
239 }
240 priv->ab8500.version = ret;
241
242 ret = pmic_reg_read(dev, AB8500_MISC_REV_REG);
243 if (ret < 0) {
244 printf("ab8500: failed to read chip id: %d\n", ret);
245 return ret;
246 }
247 priv->ab8500.chip_id = ret;
248
249 debug("ab8500: version: %#x, chip id: %#x\n",
250 priv->ab8500.version, priv->ab8500.chip_id);
251
252 return 0;
253}
254
255static const struct udevice_id ab8500_ids[] = {
256 { .compatible = "stericsson,ab8500" },
257 { }
258};
259
260U_BOOT_DRIVER(pmic_ab8500) = {
261 .name = "pmic_ab8500",
262 .id = UCLASS_PMIC,
263 .of_match = ab8500_ids,
264 .bind = dm_scan_fdt_dev,
265 .probe = ab8500_probe,
266 .ops = &ab8500_ops,
267 .priv_auto = sizeof(struct ab8500_priv),
268};