xref: /openbmc/u-boot/drivers/i2c/ast2600_i2c.c (revision 982f6418)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright ASPEED Technology Inc.
4  */
5 #include <linux/iopoll.h>
6 #include <common.h>
7 #include <clk.h>
8 #include <dm.h>
9 #include <errno.h>
10 #include <fdtdec.h>
11 #include <i2c.h>
12 #include <asm/io.h>
13 #include <regmap.h>
14 #include "ast2600_i2c_global.h"
15 
16 struct ast2600_i2c_regs {
17 	u32 fun_ctrl;
18 	u32 ac_timing;
19 	u32 trx_buff;
20 	u32 icr;
21 	u32 ier;
22 	u32 isr;
23 	u32 cmd_sts;
24 };
25 
26 /* 0x00 : I2CC Master/Slave Function Control Register  */
27 #define AST2600_I2CC_SLAVE_ADDR_RX_EN	BIT(20)
28 #define AST2600_I2CC_MASTER_RETRY_MASK	GENMASK(19, 18)
29 #define AST2600_I2CC_MASTER_RETRY(x)	(((x) & GENMASK(1, 0)) << 18)
30 #define AST2600_I2CC_BUS_AUTO_RELEASE	BIT(17)
31 #define AST2600_I2CC_M_SDA_LOCK_EN		BIT(16)
32 #define AST2600_I2CC_MULTI_MASTER_DIS	BIT(15)
33 #define AST2600_I2CC_M_SCL_DRIVE_EN		BIT(14)
34 #define AST2600_I2CC_MSB_STS			BIT(9)
35 #define AST2600_I2CC_SDA_DRIVE_1T_EN	BIT(8)
36 #define AST2600_I2CC_M_SDA_DRIVE_1T_EN	BIT(7)
37 #define AST2600_I2CC_M_HIGH_SPEED_EN	BIT(6)
38 /* reserver 5 : 2 */
39 #define AST2600_I2CC_SLAVE_EN			BIT(1)
40 #define AST2600_I2CC_MASTER_EN			BIT(0)
41 
42 /* 0x04 : I2CD Clock and AC Timing Control Register #1 */
43 /* Base register value. These bits are always set by the driver. */
44 #define I2CD_CACTC_BASE		0xfff00300
45 #define I2CD_TCKHIGH_SHIFT	16
46 #define I2CD_TCKLOW_SHIFT	12
47 #define I2CD_THDDAT_SHIFT	10
48 #define I2CD_TO_DIV_SHIFT	8
49 #define I2CD_BASE_DIV_SHIFT	0
50 
51 /* 0x08 : I2CC Master/Slave Transmit/Receive Byte Buffer Register */
52 #define AST2600_I2CC_TX_DIR_MASK		GENMASK(31, 29)
53 #define AST2600_I2CC_SDA_OE				BIT(28)
54 #define AST2600_I2CC_SDA_O				BIT(27)
55 #define AST2600_I2CC_SCL_OE				BIT(26)
56 #define AST2600_I2CC_SCL_O				BIT(25)
57 
58 #define AST2600_I2CC_SCL_LINE_STS		BIT(18)
59 #define AST2600_I2CC_SDA_LINE_STS		BIT(17)
60 #define AST2600_I2CC_BUS_BUSY_STS		BIT(16)
61 #define AST2600_I2CC_GET_RX_BUFF(x)		(((x) >> 8) & GENMASK(7, 0))
62 
63 /* 0x10 : I2CM Master Interrupt Control Register */
64 /* 0x14 : I2CM Master Interrupt Status Register  */
65 #define AST2600_I2CM_PKT_TIMEOUT		BIT(18)
66 #define AST2600_I2CM_PKT_ERROR			BIT(17)
67 #define AST2600_I2CM_PKT_DONE			BIT(16)
68 
69 #define AST2600_I2CM_BUS_RECOVER_FAIL	BIT(15)
70 #define AST2600_I2CM_SDA_DL_TO			BIT(14)
71 #define AST2600_I2CM_BUS_RECOVER		BIT(13)
72 #define AST2600_I2CM_SMBUS_ALT			BIT(12)
73 
74 #define AST2600_I2CM_SCL_LOW_TO			BIT(6)
75 #define AST2600_I2CM_ABNORMAL			BIT(5)
76 #define AST2600_I2CM_NORMAL_STOP		BIT(4)
77 #define AST2600_I2CM_ARBIT_LOSS			BIT(3)
78 #define AST2600_I2CM_RX_DONE			BIT(2)
79 #define AST2600_I2CM_TX_NAK				BIT(1)
80 #define AST2600_I2CM_TX_ACK				BIT(0)
81 
82 /* 0x18 : I2CM Master Command/Status Register   */
83 #define AST2600_I2CM_PKT_ADDR(x)		(((x) & GENMASK(6, 0)) << 24)
84 #define AST2600_I2CM_PKT_EN				BIT(16)
85 #define AST2600_I2CM_SDA_OE_OUT_DIR		BIT(15)
86 #define AST2600_I2CM_SDA_O_OUT_DIR		BIT(14)
87 #define AST2600_I2CM_SCL_OE_OUT_DIR		BIT(13)
88 #define AST2600_I2CM_SCL_O_OUT_DIR		BIT(12)
89 #define AST2600_I2CM_RECOVER_CMD_EN		BIT(11)
90 
91 #define AST2600_I2CM_RX_DMA_EN			BIT(9)
92 #define AST2600_I2CM_TX_DMA_EN			BIT(8)
93 /* Command Bit */
94 #define AST2600_I2CM_RX_BUFF_EN			BIT(7)
95 #define AST2600_I2CM_TX_BUFF_EN			BIT(6)
96 #define AST2600_I2CM_STOP_CMD			BIT(5)
97 #define AST2600_I2CM_RX_CMD_LAST		BIT(4)
98 #define AST2600_I2CM_RX_CMD				BIT(3)
99 
100 #define AST2600_I2CM_TX_CMD				BIT(1)
101 #define AST2600_I2CM_START_CMD			BIT(0)
102 
103 #define I2C_TIMEOUT_US 100000
104 /*
105  * Device private data
106  */
107 struct ast2600_i2c_priv {
108 	struct clk clk;
109 	struct ast2600_i2c_regs *regs;
110 	void __iomem *global;
111 };
112 
ast2600_i2c_read_data(struct ast2600_i2c_priv * priv,u8 chip_addr,u8 * buffer,size_t len,bool send_stop)113 static int ast2600_i2c_read_data(struct ast2600_i2c_priv *priv, u8 chip_addr,
114 				 u8 *buffer, size_t len, bool send_stop)
115 {
116 	int rx_cnt, ret = 0;
117 	u32 cmd, isr;
118 
119 	for (rx_cnt = 0; rx_cnt < len; rx_cnt++, buffer++) {
120 		cmd = AST2600_I2CM_PKT_EN | AST2600_I2CM_PKT_ADDR(chip_addr) |
121 		      AST2600_I2CM_RX_CMD;
122 		if (!rx_cnt)
123 			cmd |= AST2600_I2CM_START_CMD;
124 
125 		if ((len - 1) == rx_cnt)
126 			cmd |= AST2600_I2CM_RX_CMD_LAST;
127 
128 		if (send_stop && ((len - 1) == rx_cnt))
129 			cmd |= AST2600_I2CM_STOP_CMD;
130 
131 		writel(cmd, &priv->regs->cmd_sts);
132 
133 		ret = readl_poll_timeout(&priv->regs->isr, isr,
134 					 isr & AST2600_I2CM_PKT_DONE,
135 					 I2C_TIMEOUT_US);
136 		if (ret)
137 			return -ETIMEDOUT;
138 
139 		*buffer =
140 			AST2600_I2CC_GET_RX_BUFF(readl(&priv->regs->trx_buff));
141 
142 		writel(AST2600_I2CM_PKT_DONE, &priv->regs->isr);
143 
144 		if (isr & AST2600_I2CM_TX_NAK)
145 			return -EREMOTEIO;
146 	}
147 
148 	return 0;
149 }
150 
ast2600_i2c_write_data(struct ast2600_i2c_priv * priv,u8 chip_addr,u8 * buffer,size_t len,bool send_stop)151 static int ast2600_i2c_write_data(struct ast2600_i2c_priv *priv, u8 chip_addr,
152 				  u8 *buffer, size_t len, bool send_stop)
153 {
154 	int tx_cnt, ret = 0;
155 	u32 cmd, isr;
156 
157 	if (!len) {
158 		cmd = AST2600_I2CM_PKT_EN | AST2600_I2CM_PKT_ADDR(chip_addr) |
159 		      AST2600_I2CM_START_CMD;
160 		writel(cmd, &priv->regs->cmd_sts);
161 		ret = readl_poll_timeout(&priv->regs->isr, isr,
162 					 isr & AST2600_I2CM_PKT_DONE,
163 					 I2C_TIMEOUT_US);
164 		if (ret)
165 			return -ETIMEDOUT;
166 		if (isr & AST2600_I2CM_TX_NAK)
167 			return -EREMOTEIO;
168 
169 		writel(AST2600_I2CM_PKT_DONE, &priv->regs->isr);
170 	}
171 
172 	for (tx_cnt = 0; tx_cnt < len; tx_cnt++, buffer++) {
173 		cmd = AST2600_I2CM_PKT_EN | AST2600_I2CM_PKT_ADDR(chip_addr);
174 		cmd |= AST2600_I2CM_TX_CMD;
175 
176 		if (!tx_cnt)
177 			cmd |= AST2600_I2CM_START_CMD;
178 
179 		if (send_stop && ((len - 1) == tx_cnt))
180 			cmd |= AST2600_I2CM_STOP_CMD;
181 
182 		writel(*buffer, &priv->regs->trx_buff);
183 		writel(cmd, &priv->regs->cmd_sts);
184 		ret = readl_poll_timeout(&priv->regs->isr, isr,
185 					 isr & AST2600_I2CM_PKT_DONE,
186 					 I2C_TIMEOUT_US);
187 		if (ret)
188 			return -ETIMEDOUT;
189 
190 		writel(AST2600_I2CM_PKT_DONE, &priv->regs->isr);
191 
192 		if (isr & AST2600_I2CM_TX_NAK)
193 			return -EREMOTEIO;
194 	}
195 
196 	return 0;
197 }
198 
ast2600_i2c_deblock(struct udevice * dev)199 static int ast2600_i2c_deblock(struct udevice *dev)
200 {
201 	struct ast2600_i2c_priv *priv = dev_get_priv(dev);
202 	u32 csr = readl(&priv->regs->cmd_sts);
203 	u32 isr;
204 	int ret;
205 
206 	//reinit
207 	writel(0, &priv->regs->fun_ctrl);
208 	/* Enable Master Mode. Assuming single-master */
209 	writel(AST2600_I2CC_BUS_AUTO_RELEASE | AST2600_I2CC_MASTER_EN |
210 		       AST2600_I2CC_MULTI_MASTER_DIS,
211 	       &priv->regs->fun_ctrl);
212 
213 	csr = readl(&priv->regs->cmd_sts);
214 
215 	if (!(csr & AST2600_I2CC_SDA_LINE_STS) &&
216 	    (csr & AST2600_I2CC_SCL_LINE_STS)) {
217 		debug("Bus stuck (%x), attempting recovery\n", csr);
218 		writel(AST2600_I2CM_RECOVER_CMD_EN, &priv->regs->cmd_sts);
219 		ret = readl_poll_timeout(&priv->regs->isr, isr,
220 					 isr & (AST2600_I2CM_BUS_RECOVER_FAIL |
221 						AST2600_I2CM_BUS_RECOVER),
222 					 I2C_TIMEOUT_US);
223 		writel(~0, &priv->regs->isr);
224 		if (ret)
225 			return -EREMOTEIO;
226 	}
227 
228 	return 0;
229 }
230 
ast2600_i2c_xfer(struct udevice * dev,struct i2c_msg * msg,int nmsgs)231 static int ast2600_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
232 {
233 	struct ast2600_i2c_priv *priv = dev_get_priv(dev);
234 	int ret;
235 
236 	if (readl(&priv->regs->trx_buff) & AST2600_I2CC_BUS_BUSY_STS)
237 		return -EREMOTEIO;
238 
239 	for (; nmsgs > 0; nmsgs--, msg++) {
240 		if (msg->flags & I2C_M_RD) {
241 			debug("i2c_read: chip=0x%x, len=0x%x, flags=0x%x\n",
242 			      msg->addr, msg->len, msg->flags);
243 			ret = ast2600_i2c_read_data(priv, msg->addr, msg->buf,
244 						    msg->len, (nmsgs == 1));
245 		} else {
246 			debug("i2c_write: chip=0x%x, len=0x%x, flags=0x%x\n",
247 			      msg->addr, msg->len, msg->flags);
248 			ret = ast2600_i2c_write_data(priv, msg->addr, msg->buf,
249 						     msg->len, (nmsgs == 1));
250 		}
251 		if (ret) {
252 			debug("%s: error (%d)\n", __func__, ret);
253 			return -EREMOTEIO;
254 		}
255 	}
256 
257 	return 0;
258 }
259 
ast2600_i2c_set_speed(struct udevice * dev,unsigned int speed)260 static int ast2600_i2c_set_speed(struct udevice *dev, unsigned int speed)
261 {
262 	struct ast2600_i2c_priv *priv = dev_get_priv(dev);
263 	unsigned long base_clk1, base_clk2, base_clk3, base_clk4;
264 	int baseclk_idx;
265 	u32 clk_div_reg;
266 	u32 apb_clk;
267 	u32 scl_low;
268 	u32 scl_high;
269 	int divisor;
270 	int inc = 0;
271 	u32 data;
272 
273 	debug("Setting speed for I2C%d to <%u>\n", dev->seq, speed);
274 	if (!speed) {
275 		debug("No valid speed specified\n");
276 		return -EINVAL;
277 	}
278 
279 	apb_clk = clk_get_rate(&priv->clk);
280 
281 	clk_div_reg = readl(priv->global + 0x10);
282 	base_clk1 = (apb_clk * 10) / ((((clk_div_reg & 0xff) + 2) * 10) / 2);
283 	base_clk2 =
284 		(apb_clk * 10) / (((((clk_div_reg >> 8) & 0xff) + 2) * 10) / 2);
285 	base_clk3 = (apb_clk * 10) /
286 		    (((((clk_div_reg >> 16) & 0xff) + 2) * 10) / 2);
287 	base_clk4 = (apb_clk * 10) /
288 		    (((((clk_div_reg >> 24) & 0xff) + 2) * 10) / 2);
289 
290 	if ((apb_clk / speed) <= 32) {
291 		baseclk_idx = 0;
292 		divisor = DIV_ROUND_UP(apb_clk, speed);
293 	} else if ((base_clk1 / speed) <= 32) {
294 		baseclk_idx = 1;
295 		divisor = DIV_ROUND_UP(base_clk1, speed);
296 	} else if ((base_clk2 / speed) <= 32) {
297 		baseclk_idx = 2;
298 		divisor = DIV_ROUND_UP(base_clk2, speed);
299 	} else if ((base_clk3 / speed) <= 32) {
300 		baseclk_idx = 3;
301 		divisor = DIV_ROUND_UP(base_clk3, speed);
302 	} else {
303 		baseclk_idx = 4;
304 		divisor = DIV_ROUND_UP(base_clk4, speed);
305 		inc = 0;
306 		while ((divisor + inc) > 32) {
307 			inc |= divisor & 0x1;
308 			divisor >>= 1;
309 			baseclk_idx++;
310 		}
311 		divisor += inc;
312 	}
313 	divisor = min_t(int, divisor, 32);
314 	baseclk_idx &= 0xf;
315 	scl_low = ((divisor * 9) / 16) - 1;
316 	scl_low = min_t(u32, scl_low, 0xf);
317 	scl_high = (divisor - scl_low - 2) & 0xf;
318 	/* Divisor : Base Clock : tCKHighMin : tCK High : tCK Low  */
319 	data = ((scl_high - 1) << 20) | (scl_high << 16) | (scl_low << 12) |
320 	       (baseclk_idx);
321 	/* Set AC Timing */
322 	writel(data, &priv->regs->ac_timing);
323 
324 	return 0;
325 }
326 
ast2600_i2c_probe(struct udevice * dev)327 static int ast2600_i2c_probe(struct udevice *dev)
328 {
329 	struct ast2600_i2c_priv *priv = dev_get_priv(dev);
330 	struct udevice *misc_dev;
331 	int ret;
332 
333 	/* find global base address */
334 	ret = uclass_get_device_by_driver(UCLASS_MISC,
335 					  DM_GET_DRIVER(aspeed_i2c_global),
336 					  &misc_dev);
337 	if (ret) {
338 		debug("i2c global not defined\n");
339 		return ret;
340 	}
341 
342 	priv->global = devfdt_get_addr_ptr(misc_dev);
343 	if (IS_ERR(priv->global)) {
344 		debug("%s(): can't get global\n", __func__);
345 		return PTR_ERR(priv->global);
346 	}
347 
348 	/* Reset device */
349 	writel(0, &priv->regs->fun_ctrl);
350 	/* Enable Master Mode. Assuming single-master */
351 	writel(AST2600_I2CC_BUS_AUTO_RELEASE | AST2600_I2CC_MASTER_EN |
352 		       AST2600_I2CC_MULTI_MASTER_DIS,
353 	       &priv->regs->fun_ctrl);
354 
355 	writel(0, &priv->regs->ier);
356 	/* Clear Interrupt */
357 	writel(~0, &priv->regs->isr);
358 
359 	return 0;
360 }
361 
ast2600_i2c_ofdata_to_platdata(struct udevice * dev)362 static int ast2600_i2c_ofdata_to_platdata(struct udevice *dev)
363 {
364 	struct ast2600_i2c_priv *priv = dev_get_priv(dev);
365 	int ret;
366 
367 	priv->regs = devfdt_get_addr_ptr(dev);
368 	if (IS_ERR(priv->regs))
369 		return PTR_ERR(priv->regs);
370 
371 	ret = clk_get_by_index(dev, 0, &priv->clk);
372 	if (ret < 0) {
373 		debug("%s: Can't get clock for %s: %d\n", __func__, dev->name,
374 		      ret);
375 		return ret;
376 	}
377 
378 	return 0;
379 }
380 
381 static const struct dm_i2c_ops ast2600_i2c_ops = {
382 	.xfer = ast2600_i2c_xfer,
383 	.deblock = ast2600_i2c_deblock,
384 	.set_bus_speed = ast2600_i2c_set_speed,
385 };
386 
387 static const struct udevice_id ast2600_i2c_ids[] = {
388 	{ .compatible = "aspeed,ast2600-i2c-bus" },
389 	{},
390 };
391 
392 U_BOOT_DRIVER(ast2600_i2c) = {
393 	.name = "ast2600_i2c",
394 	.id = UCLASS_I2C,
395 	.of_match = ast2600_i2c_ids,
396 	.probe = ast2600_i2c_probe,
397 	.ofdata_to_platdata = ast2600_i2c_ofdata_to_platdata,
398 	.priv_auto_alloc_size = sizeof(struct ast2600_i2c_priv),
399 	.ops = &ast2600_i2c_ops,
400 };
401