xref: /aosp_15_r20/external/coreboot/src/soc/rockchip/common/i2c.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <device/mmio.h>
4 #include <assert.h>
5 #include <console/console.h>
6 #include <delay.h>
7 #include <device/i2c_simple.h>
8 #include <soc/addressmap.h>
9 #include <soc/grf.h>
10 #include <soc/soc.h>
11 #include <soc/i2c.h>
12 #include <soc/clock.h>
13 #include <stddef.h>
14 #include <stdint.h>
15 
16 #define RETRY_COUNT	3
17 /* 100000us = 100ms */
18 #define I2C_TIMEOUT_US	100000
19 #define I2C_BUS_MAX	6
20 #define I2C_NOACK	2
21 #define I2C_TIMEOUT	3
22 
23 #define i2c_info(x...) do {if (0) printk(BIOS_DEBUG, x); } while (0)
24 
25 struct rk_i2c_regs {
26 	u32 i2c_con;
27 	u32 i2c_clkdiv;
28 	u32 i2c_mrxaddr;
29 	u32 i2c_mrxraddr;
30 	u32 i2c_mtxcnt;
31 	u32 i2c_mrxcnt;
32 	u32 i2c_ien;
33 	u32 i2c_ipd;
34 	u32 i2c_fcnt;
35 	u32 reserved0[(0x100 - 0x24) / 4];
36 	u32 txdata[8];
37 	u32 reserved1[(0x200 - 0x120) / 4];
38 	u32 rxdata[8];
39 };
40 
41 static const uintptr_t i2c_bus[] = IC_BASES;
42 
43 /* Con register bits. */
44 #define I2C_ACT2NAK			(1<<6)
45 #define I2C_NAK				(1<<5)
46 #define I2C_STOP				(1<<4)
47 #define I2C_START			(1<<3)
48 #define I2C_MODE_TX			(0<<1)
49 #define I2C_MODE_TRX		(1<<1)
50 #define I2C_MODE_RX			(2<<1)
51 #define I2C_EN				(1<<0)
52 
53 #define I2C_8BIT	(1<<24)
54 #define I2C_16BIT	(3<<24)
55 #define I2C_24BIT	(7<<24)
56 
57 /* Mtxcnt register bits. */
58 #define I2C_CNT(cnt)		((cnt) & 0x3F)
59 
60 #define I2C_NAKRCVI	(1<<6)
61 #define I2C_STOPI	(1<<5)
62 #define I2C_STARTI	(1<<4)
63 #define I2C_MBRFI	(1<<3)
64 #define I2C_MBTFI	(1<<2)
65 #define I2C_BRFI	(1<<1)
66 #define I2C_BTFI	(1<<0)
67 #define I2C_CLEANI	0x7F
68 
i2c_send_start(struct rk_i2c_regs * reg_addr)69 static int i2c_send_start(struct rk_i2c_regs *reg_addr)
70 {
71 	int res = 0;
72 	int timeout = I2C_TIMEOUT_US;
73 
74 	i2c_info("I2c Start::Send Start bit\n");
75 	write32(&reg_addr->i2c_ipd, I2C_CLEANI);
76 	write32(&reg_addr->i2c_con, I2C_EN | I2C_START);
77 	while (timeout--) {
78 		if (read32(&reg_addr->i2c_ipd) & I2C_STARTI)
79 			break;
80 		udelay(1);
81 	}
82 
83 	if (timeout <= 0) {
84 		printk(BIOS_ERR, "I2C Start::Send Start Bit Timeout\n");
85 		res = I2C_TIMEOUT;
86 	}
87 
88 	return res;
89 }
90 
i2c_send_stop(struct rk_i2c_regs * reg_addr)91 static int i2c_send_stop(struct rk_i2c_regs *reg_addr)
92 {
93 	int res = 0;
94 	int timeout = I2C_TIMEOUT_US;
95 
96 	i2c_info("I2c Stop::Send Stop bit\n");
97 	write32(&reg_addr->i2c_ipd, I2C_CLEANI);
98 	write32(&reg_addr->i2c_con, I2C_EN | I2C_STOP);
99 	while (timeout--) {
100 		if (read32(&reg_addr->i2c_ipd) & I2C_STOPI)
101 			break;
102 		udelay(1);
103 	}
104 	write32(&reg_addr->i2c_con, 0);
105 	if (timeout <= 0) {
106 		printk(BIOS_ERR, "I2C Stop::Send Stop Bit Timeout\n");
107 		res = I2C_TIMEOUT;
108 	}
109 
110 	return res;
111 }
112 
i2c_read(struct rk_i2c_regs * reg_addr,struct i2c_msg segment)113 static int i2c_read(struct rk_i2c_regs *reg_addr, struct i2c_msg segment)
114 {
115 	int res = 0;
116 	uint8_t *data = segment.buf;
117 	unsigned int bytes_remaining = segment.len;
118 	unsigned int con = 0;
119 
120 	write32(&reg_addr->i2c_mrxaddr, I2C_8BIT | segment.slave << 1 | 1);
121 	write32(&reg_addr->i2c_mrxraddr, 0);
122 	con = I2C_MODE_TRX | I2C_EN | I2C_ACT2NAK;
123 	while (bytes_remaining) {
124 		int timeout = CONFIG_I2C_TRANSFER_TIMEOUT_US;
125 		size_t size = MIN(bytes_remaining, 32);
126 		bytes_remaining -= size;
127 		if (!bytes_remaining)
128 			con |= I2C_EN | I2C_NAK;
129 
130 		i2c_info("I2C Read::%zu bytes\n", size);
131 		write32(&reg_addr->i2c_ipd, I2C_CLEANI);
132 		write32(&reg_addr->i2c_con, con);
133 		write32(&reg_addr->i2c_mrxcnt, size);
134 
135 		while (timeout--) {
136 			if (read32(&reg_addr->i2c_ipd) & I2C_NAKRCVI) {
137 				write32(&reg_addr->i2c_mrxcnt, 0);
138 				write32(&reg_addr->i2c_con, 0);
139 				return I2C_NOACK;
140 			}
141 			if (read32(&reg_addr->i2c_ipd) & I2C_MBRFI)
142 				break;
143 			udelay(1);
144 		}
145 		if (timeout <= 0) {
146 			printk(BIOS_ERR, "I2C Read::Recv Data Timeout\n");
147 			write32(&reg_addr->i2c_mrxcnt, 0);
148 			write32(&reg_addr->i2c_con, 0);
149 			return I2C_TIMEOUT;
150 		}
151 
152 		buffer_from_fifo32(data, size, &reg_addr->rxdata, 4, 4);
153 		data += size;
154 		con = I2C_MODE_RX | I2C_EN | I2C_ACT2NAK;
155 	}
156 	return res;
157 }
158 
i2c_write(struct rk_i2c_regs * reg_addr,struct i2c_msg segment)159 static int i2c_write(struct rk_i2c_regs *reg_addr, struct i2c_msg segment)
160 {
161 	int res = 0;
162 	uint8_t *data = segment.buf;
163 	int bytes_remaining = segment.len + 1;
164 
165 	/* Prepend one byte for the slave address to the transfer. */
166 	u32 prefix = segment.slave << 1;
167 	int prefsz = 1;
168 
169 	while (bytes_remaining) {
170 		int timeout = CONFIG_I2C_TRANSFER_TIMEOUT_US;
171 		size_t size = MIN(bytes_remaining, 32);
172 		buffer_to_fifo32_prefix(data, prefix, prefsz, size,
173 					&reg_addr->txdata, 4, 4);
174 		data += size - prefsz;
175 
176 		i2c_info("I2C Write::%zu bytes\n", size);
177 		write32(&reg_addr->i2c_ipd, I2C_CLEANI);
178 		write32(&reg_addr->i2c_con,
179 			I2C_EN | I2C_MODE_TX | I2C_ACT2NAK);
180 		write32(&reg_addr->i2c_mtxcnt, size);
181 
182 		while (timeout--) {
183 			if (read32(&reg_addr->i2c_ipd) & I2C_NAKRCVI) {
184 				write32(&reg_addr->i2c_mtxcnt, 0);
185 				write32(&reg_addr->i2c_con, 0);
186 				return I2C_NOACK;
187 			}
188 			if (read32(&reg_addr->i2c_ipd) & I2C_MBTFI)
189 				break;
190 			udelay(1);
191 		}
192 
193 		if (timeout <= 0) {
194 			printk(BIOS_ERR, "I2C Write::Send Data Timeout\n");
195 			write32(&reg_addr->i2c_mtxcnt, 0);
196 			write32(&reg_addr->i2c_con, 0);
197 			return I2C_TIMEOUT;
198 		}
199 
200 		bytes_remaining -= size;
201 		prefsz = 0;
202 		prefix = 0;
203 	}
204 	return res;
205 }
206 
i2c_do_xfer(void * reg_addr,struct i2c_msg segment)207 static int i2c_do_xfer(void *reg_addr, struct i2c_msg segment)
208 {
209 	int res = 0;
210 
211 	if (i2c_send_start(reg_addr))
212 		return I2C_TIMEOUT;
213 	if (segment.flags & I2C_M_RD)
214 		res = i2c_read(reg_addr, segment);
215 	else
216 		res = i2c_write(reg_addr, segment);
217 	return i2c_send_stop(reg_addr) || res;
218 }
219 
platform_i2c_transfer(unsigned int bus,struct i2c_msg * segments,int seg_count)220 int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments,
221 			  int seg_count)
222 {
223 	int i;
224 	int res = 0;
225 	struct rk_i2c_regs *regs = (struct rk_i2c_regs *)(i2c_bus[bus]);
226 	struct i2c_msg *seg = segments;
227 
228 	for (i = 0; i < seg_count; i++, seg++) {
229 		res = i2c_do_xfer(regs, *seg);
230 		if (res)
231 			break;
232 	}
233 	return res;
234 }
235 
i2c_init(unsigned int bus,unsigned int hz)236 void i2c_init(unsigned int bus, unsigned int hz)
237 {
238 	unsigned int clk_div;
239 	unsigned int divl;
240 	unsigned int divh;
241 	unsigned int i2c_src_clk;
242 	unsigned int i2c_clk;
243 	struct rk_i2c_regs *regs = (struct rk_i2c_regs *)(i2c_bus[bus]);
244 
245 	i2c_src_clk = rkclk_i2c_clock_for_bus(bus);
246 
247 	/* SCL Divisor = 8*(CLKDIVL + 1 + CLKDIVH + 1)
248 	   SCL = PCLK / SCLK Divisor */
249 	clk_div = DIV_ROUND_UP(i2c_src_clk, hz * 8);
250 	divh = clk_div * 3 / 7 - 1;
251 	divl = clk_div - divh - 2;
252 	i2c_clk = i2c_src_clk / (8 * (divl + 1 + divh + 1));
253 	printk(BIOS_DEBUG, "I2C bus %u: %uHz (divh = %u, divl = %u)\n",
254 	       bus, i2c_clk, divh, divl);
255 	assert((divh < 65536) && (divl < 65536) && hz - i2c_clk < 15*KHz);
256 	write32(&regs->i2c_clkdiv, (divh << 16) | (divl << 0));
257 }
258