xref: /openbmc/u-boot/drivers/i2c/i2c-uniphier-f.c (revision e8f80a5a)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (C) 2014      Panasonic Corporation
4  * Copyright (C) 2015-2016 Socionext Inc.
5  *   Author: Masahiro Yamada <yamada.masahiro@socionext.com>
6  */
7 
8 #include <linux/errno.h>
9 #include <linux/io.h>
10 #include <linux/iopoll.h>
11 #include <linux/sizes.h>
12 #include <linux/types.h>
13 #include <dm.h>
14 #include <i2c.h>
15 #include <fdtdec.h>
16 
17 struct uniphier_fi2c_regs {
18 	u32 cr;				/* control register */
19 #define I2C_CR_MST	(1 << 3)	/* master mode */
20 #define I2C_CR_STA	(1 << 2)	/* start condition */
21 #define I2C_CR_STO	(1 << 1)	/* stop condition */
22 #define I2C_CR_NACK	(1 << 0)	/* not ACK */
23 	u32 dttx;			/* send FIFO (write-only) */
24 #define dtrx		dttx		/* receive FIFO (read-only) */
25 #define I2C_DTTX_CMD	(1 << 8)	/* send command (slave addr) */
26 #define I2C_DTTX_RD	(1 << 0)	/* read */
27 	u32 __reserved;			/* no register at offset 0x08 */
28 	u32 slad;			/* slave address */
29 	u32 cyc;			/* clock cycle control */
30 	u32 lctl;			/* clock low period control */
31 	u32 ssut;			/* restart/stop setup time control */
32 	u32 dsut;			/* data setup time control */
33 	u32 intr;			/* interrupt status */
34 	u32 ie;				/* interrupt enable */
35 	u32 ic;				/* interrupt clear */
36 #define I2C_INT_TE	(1 << 9)	/* TX FIFO empty */
37 #define I2C_INT_RB	(1 << 4)	/* received specified bytes */
38 #define I2C_INT_NA	(1 << 2)	/* no answer */
39 #define I2C_INT_AL	(1 << 1)	/* arbitration lost */
40 	u32 sr;				/* status register */
41 #define I2C_SR_DB	(1 << 12)	/* device busy */
42 #define I2C_SR_BB	(1 << 8)	/* bus busy */
43 #define I2C_SR_RFF	(1 << 3)	/* Rx FIFO full */
44 #define I2C_SR_RNE	(1 << 2)	/* Rx FIFO not empty */
45 #define I2C_SR_TNF	(1 << 1)	/* Tx FIFO not full */
46 #define I2C_SR_TFE	(1 << 0)	/* Tx FIFO empty */
47 	u32 __reserved2;		/* no register at offset 0x30 */
48 	u32 rst;			/* reset control */
49 #define I2C_RST_TBRST	(1 << 2)	/* clear Tx FIFO */
50 #define I2C_RST_RBRST	(1 << 1)	/* clear Rx FIFO */
51 #define I2C_RST_RST	(1 << 0)	/* forcible bus reset */
52 	u32 bm;				/* bus monitor */
53 	u32 noise;			/* noise filter control */
54 	u32 tbc;			/* Tx byte count setting */
55 	u32 rbc;			/* Rx byte count setting */
56 	u32 tbcm;			/* Tx byte count monitor */
57 	u32 rbcm;			/* Rx byte count monitor */
58 	u32 brst;			/* bus reset */
59 #define I2C_BRST_FOEN	(1 << 1)	/* normal operation */
60 #define I2C_BRST_RSCLO	(1 << 0)	/* release SCL low fixing */
61 };
62 
63 #define FIOCLK	50000000
64 
65 struct uniphier_fi2c_priv {
66 	struct udevice *dev;
67 	struct uniphier_fi2c_regs __iomem *regs;	/* register base */
68 	unsigned long fioclk;			/* internal operation clock */
69 	unsigned long timeout;			/* time out (us) */
70 };
71 
uniphier_fi2c_reset(struct uniphier_fi2c_priv * priv)72 static void uniphier_fi2c_reset(struct uniphier_fi2c_priv *priv)
73 {
74 	writel(I2C_RST_RST, &priv->regs->rst);
75 }
76 
uniphier_fi2c_check_bus_busy(struct uniphier_fi2c_priv * priv)77 static int uniphier_fi2c_check_bus_busy(struct uniphier_fi2c_priv *priv)
78 {
79 	u32 val;
80 	int ret;
81 
82 	ret = readl_poll_timeout(&priv->regs->sr, val, !(val & I2C_SR_DB), 100);
83 	if (ret < 0) {
84 		dev_dbg(priv->dev, "error: device busy too long. reset...\n");
85 		uniphier_fi2c_reset(priv);
86 	}
87 
88 	return ret;
89 }
90 
uniphier_fi2c_probe(struct udevice * dev)91 static int uniphier_fi2c_probe(struct udevice *dev)
92 {
93 	fdt_addr_t addr;
94 	struct uniphier_fi2c_priv *priv = dev_get_priv(dev);
95 
96 	addr = devfdt_get_addr(dev);
97 	if (addr == FDT_ADDR_T_NONE)
98 		return -EINVAL;
99 
100 	priv->regs = devm_ioremap(dev, addr, SZ_128);
101 	if (!priv->regs)
102 		return -ENOMEM;
103 
104 	priv->fioclk = FIOCLK;
105 
106 	priv->dev = dev;
107 
108 	/* bus forcible reset */
109 	uniphier_fi2c_reset(priv);
110 
111 	writel(I2C_BRST_FOEN | I2C_BRST_RSCLO, &priv->regs->brst);
112 
113 	return 0;
114 }
115 
wait_for_irq(struct uniphier_fi2c_priv * priv,u32 flags,bool * stop)116 static int wait_for_irq(struct uniphier_fi2c_priv *priv, u32 flags,
117 			bool *stop)
118 {
119 	u32 irq;
120 	int ret;
121 
122 	ret = readl_poll_timeout(&priv->regs->intr, irq, irq & flags,
123 				 priv->timeout);
124 	if (ret < 0) {
125 		dev_dbg(priv->dev, "error: time out\n");
126 		return ret;
127 	}
128 
129 	if (irq & I2C_INT_AL) {
130 		dev_dbg(priv->dev, "error: arbitration lost\n");
131 		*stop = false;
132 		return ret;
133 	}
134 
135 	if (irq & I2C_INT_NA) {
136 		dev_dbg(priv->dev, "error: no answer\n");
137 		return ret;
138 	}
139 
140 	return 0;
141 }
142 
issue_stop(struct uniphier_fi2c_priv * priv,int old_ret)143 static int issue_stop(struct uniphier_fi2c_priv *priv, int old_ret)
144 {
145 	int ret;
146 
147 	dev_dbg(priv->dev, "stop condition\n");
148 	writel(I2C_CR_MST | I2C_CR_STO, &priv->regs->cr);
149 
150 	ret = uniphier_fi2c_check_bus_busy(priv);
151 	if (ret < 0)
152 		dev_dbg(priv->dev, "error: device busy after operation\n");
153 
154 	return old_ret ? old_ret : ret;
155 }
156 
uniphier_fi2c_transmit(struct uniphier_fi2c_priv * priv,uint addr,uint len,const u8 * buf,bool * stop)157 static int uniphier_fi2c_transmit(struct uniphier_fi2c_priv *priv, uint addr,
158 				  uint len, const u8 *buf, bool *stop)
159 {
160 	int ret;
161 	const u32 irq_flags = I2C_INT_TE | I2C_INT_NA | I2C_INT_AL;
162 	struct uniphier_fi2c_regs __iomem *regs = priv->regs;
163 
164 	dev_dbg(priv->dev, "%s: addr = %x, len = %d\n", __func__, addr, len);
165 
166 	writel(I2C_DTTX_CMD | addr << 1, &regs->dttx);
167 
168 	writel(irq_flags, &regs->ie);
169 	writel(irq_flags, &regs->ic);
170 
171 	dev_dbg(priv->dev, "start condition\n");
172 	writel(I2C_CR_MST | I2C_CR_STA, &regs->cr);
173 
174 	ret = wait_for_irq(priv, irq_flags, stop);
175 	if (ret < 0)
176 		goto error;
177 
178 	while (len--) {
179 		dev_dbg(priv->dev, "sending %x\n", *buf);
180 		writel(*buf++, &regs->dttx);
181 
182 		writel(irq_flags, &regs->ic);
183 
184 		ret = wait_for_irq(priv, irq_flags, stop);
185 		if (ret < 0)
186 			goto error;
187 	}
188 
189 error:
190 	writel(irq_flags, &regs->ic);
191 
192 	if (*stop)
193 		ret = issue_stop(priv, ret);
194 
195 	return ret;
196 }
197 
uniphier_fi2c_receive(struct uniphier_fi2c_priv * priv,uint addr,uint len,u8 * buf,bool * stop)198 static int uniphier_fi2c_receive(struct uniphier_fi2c_priv *priv, uint addr,
199 				 uint len, u8 *buf, bool *stop)
200 {
201 	int ret = 0;
202 	const u32 irq_flags = I2C_INT_RB | I2C_INT_NA | I2C_INT_AL;
203 	struct uniphier_fi2c_regs __iomem *regs = priv->regs;
204 
205 	dev_dbg(priv->dev, "%s: addr = %x, len = %d\n", __func__, addr, len);
206 
207 	/*
208 	 * In case 'len == 0', only the slave address should be sent
209 	 * for probing, which is covered by the transmit function.
210 	 */
211 	if (len == 0)
212 		return uniphier_fi2c_transmit(priv, addr, len, buf, stop);
213 
214 	writel(I2C_DTTX_CMD | I2C_DTTX_RD | addr << 1, &regs->dttx);
215 
216 	writel(0, &regs->rbc);
217 	writel(irq_flags, &regs->ie);
218 	writel(irq_flags, &regs->ic);
219 
220 	dev_dbg(priv->dev, "start condition\n");
221 	writel(I2C_CR_MST | I2C_CR_STA | (len == 1 ? I2C_CR_NACK : 0),
222 	       &regs->cr);
223 
224 	while (len--) {
225 		ret = wait_for_irq(priv, irq_flags, stop);
226 		if (ret < 0)
227 			goto error;
228 
229 		*buf++ = readl(&regs->dtrx);
230 		dev_dbg(priv->dev, "received %x\n", *(buf - 1));
231 
232 		if (len == 1)
233 			writel(I2C_CR_MST | I2C_CR_NACK, &regs->cr);
234 
235 		writel(irq_flags, &regs->ic);
236 	}
237 
238 error:
239 	writel(irq_flags, &regs->ic);
240 
241 	if (*stop)
242 		ret = issue_stop(priv, ret);
243 
244 	return ret;
245 }
246 
uniphier_fi2c_xfer(struct udevice * bus,struct i2c_msg * msg,int nmsgs)247 static int uniphier_fi2c_xfer(struct udevice *bus, struct i2c_msg *msg,
248 			     int nmsgs)
249 {
250 	int ret;
251 	struct uniphier_fi2c_priv *priv = dev_get_priv(bus);
252 	bool stop;
253 
254 	ret = uniphier_fi2c_check_bus_busy(priv);
255 	if (ret < 0)
256 		return ret;
257 
258 	for (; nmsgs > 0; nmsgs--, msg++) {
259 		/* If next message is read, skip the stop condition */
260 		stop = nmsgs > 1 && msg[1].flags & I2C_M_RD ? false : true;
261 
262 		if (msg->flags & I2C_M_RD)
263 			ret = uniphier_fi2c_receive(priv, msg->addr, msg->len,
264 						    msg->buf, &stop);
265 		else
266 			ret = uniphier_fi2c_transmit(priv, msg->addr, msg->len,
267 						     msg->buf, &stop);
268 
269 		if (ret < 0)
270 			break;
271 	}
272 
273 	return ret;
274 }
275 
uniphier_fi2c_set_bus_speed(struct udevice * bus,unsigned int speed)276 static int uniphier_fi2c_set_bus_speed(struct udevice *bus, unsigned int speed)
277 {
278 	int ret;
279 	unsigned int clk_count;
280 	struct uniphier_fi2c_priv *priv = dev_get_priv(bus);
281 	struct uniphier_fi2c_regs __iomem *regs = priv->regs;
282 
283 	/* max supported frequency is 400 kHz */
284 	if (speed > 400000)
285 		return -EINVAL;
286 
287 	ret = uniphier_fi2c_check_bus_busy(priv);
288 	if (ret < 0)
289 		return ret;
290 
291 	/* make sure the bus is idle when changing the frequency */
292 	writel(I2C_BRST_RSCLO, &regs->brst);
293 
294 	clk_count = priv->fioclk / speed;
295 
296 	writel(clk_count, &regs->cyc);
297 	writel(clk_count / 2, &regs->lctl);
298 	writel(clk_count / 2, &regs->ssut);
299 	writel(clk_count / 16, &regs->dsut);
300 
301 	writel(I2C_BRST_FOEN | I2C_BRST_RSCLO, &regs->brst);
302 
303 	/*
304 	 * Theoretically, each byte can be transferred in
305 	 * 1000000 * 9 / speed usec.
306 	 * This time out value is long enough.
307 	 */
308 	priv->timeout = 100000000L / speed;
309 
310 	return 0;
311 }
312 
313 static const struct dm_i2c_ops uniphier_fi2c_ops = {
314 	.xfer = uniphier_fi2c_xfer,
315 	.set_bus_speed = uniphier_fi2c_set_bus_speed,
316 };
317 
318 static const struct udevice_id uniphier_fi2c_of_match[] = {
319 	{ .compatible = "socionext,uniphier-fi2c" },
320 	{ /* sentinel */ }
321 };
322 
323 U_BOOT_DRIVER(uniphier_fi2c) = {
324 	.name = "uniphier-fi2c",
325 	.id = UCLASS_I2C,
326 	.of_match = uniphier_fi2c_of_match,
327 	.probe = uniphier_fi2c_probe,
328 	.priv_auto_alloc_size = sizeof(struct uniphier_fi2c_priv),
329 	.ops = &uniphier_fi2c_ops,
330 };
331