1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
5 #include <console/console.h>
7 #include <device/i2c_simple.h>
8 #include <soc/addressmap.h>
12 #include <soc/clock.h>
17 /* 100000us = 100ms */
18 #define I2C_TIMEOUT_US 100000
23 #define i2c_info(x...) do {if (0) printk(BIOS_DEBUG, x); } while (0)
35 u32 reserved0
[(0x100 - 0x24) / 4];
37 u32 reserved1
[(0x200 - 0x120) / 4];
41 static const uintptr_t i2c_bus
[] = IC_BASES
;
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)
53 #define I2C_8BIT (1<<24)
54 #define I2C_16BIT (3<<24)
55 #define I2C_24BIT (7<<24)
57 /* Mtxcnt register bits. */
58 #define I2C_CNT(cnt) ((cnt) & 0x3F)
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
69 static int i2c_send_start(struct rk_i2c_regs
*reg_addr
)
72 int timeout
= I2C_TIMEOUT_US
;
74 i2c_info("I2c Start::Send Start bit\n");
75 write32(®_addr
->i2c_ipd
, I2C_CLEANI
);
76 write32(®_addr
->i2c_con
, I2C_EN
| I2C_START
);
78 if (read32(®_addr
->i2c_ipd
) & I2C_STARTI
)
84 printk(BIOS_ERR
, "I2C Start::Send Start Bit Timeout\n");
91 static int i2c_send_stop(struct rk_i2c_regs
*reg_addr
)
94 int timeout
= I2C_TIMEOUT_US
;
96 i2c_info("I2c Stop::Send Stop bit\n");
97 write32(®_addr
->i2c_ipd
, I2C_CLEANI
);
98 write32(®_addr
->i2c_con
, I2C_EN
| I2C_STOP
);
100 if (read32(®_addr
->i2c_ipd
) & I2C_STOPI
)
104 write32(®_addr
->i2c_con
, 0);
106 printk(BIOS_ERR
, "I2C Stop::Send Stop Bit Timeout\n");
113 static int i2c_read(struct rk_i2c_regs
*reg_addr
, struct i2c_msg segment
)
116 uint8_t *data
= segment
.buf
;
117 unsigned int bytes_remaining
= segment
.len
;
118 unsigned int con
= 0;
120 write32(®_addr
->i2c_mrxaddr
, I2C_8BIT
| segment
.slave
<< 1 | 1);
121 write32(®_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
;
130 i2c_info("I2C Read::%zu bytes\n", size
);
131 write32(®_addr
->i2c_ipd
, I2C_CLEANI
);
132 write32(®_addr
->i2c_con
, con
);
133 write32(®_addr
->i2c_mrxcnt
, size
);
136 if (read32(®_addr
->i2c_ipd
) & I2C_NAKRCVI
) {
137 write32(®_addr
->i2c_mrxcnt
, 0);
138 write32(®_addr
->i2c_con
, 0);
141 if (read32(®_addr
->i2c_ipd
) & I2C_MBRFI
)
146 printk(BIOS_ERR
, "I2C Read::Recv Data Timeout\n");
147 write32(®_addr
->i2c_mrxcnt
, 0);
148 write32(®_addr
->i2c_con
, 0);
152 buffer_from_fifo32(data
, size
, ®_addr
->rxdata
, 4, 4);
154 con
= I2C_MODE_RX
| I2C_EN
| I2C_ACT2NAK
;
159 static int i2c_write(struct rk_i2c_regs
*reg_addr
, struct i2c_msg segment
)
162 uint8_t *data
= segment
.buf
;
163 int bytes_remaining
= segment
.len
+ 1;
165 /* Prepend one byte for the slave address to the transfer. */
166 u32 prefix
= segment
.slave
<< 1;
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 ®_addr
->txdata
, 4, 4);
174 data
+= size
- prefsz
;
176 i2c_info("I2C Write::%zu bytes\n", size
);
177 write32(®_addr
->i2c_ipd
, I2C_CLEANI
);
178 write32(®_addr
->i2c_con
,
179 I2C_EN
| I2C_MODE_TX
| I2C_ACT2NAK
);
180 write32(®_addr
->i2c_mtxcnt
, size
);
183 if (read32(®_addr
->i2c_ipd
) & I2C_NAKRCVI
) {
184 write32(®_addr
->i2c_mtxcnt
, 0);
185 write32(®_addr
->i2c_con
, 0);
188 if (read32(®_addr
->i2c_ipd
) & I2C_MBTFI
)
194 printk(BIOS_ERR
, "I2C Write::Send Data Timeout\n");
195 write32(®_addr
->i2c_mtxcnt
, 0);
196 write32(®_addr
->i2c_con
, 0);
200 bytes_remaining
-= size
;
207 static int i2c_do_xfer(void *reg_addr
, struct i2c_msg segment
)
211 if (i2c_send_start(reg_addr
))
213 if (segment
.flags
& I2C_M_RD
)
214 res
= i2c_read(reg_addr
, segment
);
216 res
= i2c_write(reg_addr
, segment
);
217 return i2c_send_stop(reg_addr
) || res
;
220 int platform_i2c_transfer(unsigned int bus
, struct i2c_msg
*segments
,
225 struct rk_i2c_regs
*regs
= (struct rk_i2c_regs
*)(i2c_bus
[bus
]);
226 struct i2c_msg
*seg
= segments
;
228 for (i
= 0; i
< seg_count
; i
++, seg
++) {
229 res
= i2c_do_xfer(regs
, *seg
);
236 void i2c_init(unsigned int bus
, unsigned int hz
)
238 unsigned int clk_div
;
241 unsigned int i2c_src_clk
;
242 unsigned int i2c_clk
;
243 struct rk_i2c_regs
*regs
= (struct rk_i2c_regs
*)(i2c_bus
[bus
]);
245 i2c_src_clk
= rkclk_i2c_clock_for_bus(bus
);
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(®s
->i2c_clkdiv
, (divh
<< 16) | (divl
<< 0));