2 * This file is part of the coreboot project.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
17 #include <console/console.h>
21 #include <device/mmio.h>
23 #include <device/i2c_simple.h>
25 static inline void i2c_dma_reset(struct mt_i2c_dma_regs
*dma_regs
)
27 write32(&dma_regs
->dma_rst
, 0x1);
29 write32(&dma_regs
->dma_rst
, 0x2);
31 write32(&dma_regs
->dma_rst
, 0x0);
35 static inline void mtk_i2c_dump_info(struct mt_i2c_regs
*regs
)
37 printk(BIOS_ERR
, "I2C register:\nSLAVE_ADDR %x\nINTR_MASK %x\n"
38 "INTR_STAT %x\nCONTROL %x\nTRANSFER_LEN %x\nTRANSAC_LEN %x\n"
39 "DELAY_LEN %x\nTIMING %x\nSTART %x\nFIFO_STAT %x\nIO_CONFIG %x\n"
40 "HS %x\nDEBUGSTAT %x\nEXT_CONF %x\n",
41 read32(®s
->slave_addr
),
42 read32(®s
->intr_mask
),
43 read32(®s
->intr_stat
),
44 read32(®s
->control
),
45 read32(®s
->transfer_len
),
46 read32(®s
->transac_len
),
47 read32(®s
->delay_len
),
48 read32(®s
->timing
),
50 read32(®s
->fifo_stat
),
51 read32(®s
->io_config
),
53 read32(®s
->debug_stat
),
54 read32(®s
->ext_conf
));
57 static uint32_t mtk_i2c_transfer(uint8_t bus
, struct i2c_msg
*seg
,
60 uint32_t ret_code
= I2C_OK
;
62 uint32_t time_out_val
= 0;
64 uint32_t write_len
= 0;
65 uint32_t read_len
= 0;
66 uint8_t *write_buffer
= NULL
;
67 uint8_t *read_buffer
= NULL
;
68 struct mt_i2c_regs
*regs
;
69 struct mt_i2c_dma_regs
*dma_regs
;
72 regs
= mtk_i2c_bus_controller
[bus
].i2c_regs
;
73 dma_regs
= mtk_i2c_bus_controller
[bus
].i2c_dma_regs
;
79 assert(seg
[0].len
> 0 && seg
[0].len
<= 255);
80 write_len
= seg
[0].len
;
81 write_buffer
= seg
[0].buf
;
85 assert(seg
[0].len
> 0 && seg
[0].len
<= 255);
86 read_len
= seg
[0].len
;
87 read_buffer
= seg
[0].buf
;
90 /* Must use special write-then-read mode for repeated starts. */
91 case I2C_WRITE_READ_MODE
:
92 assert(seg
[0].len
> 0 && seg
[0].len
<= 255);
93 assert(seg
[1].len
> 0 && seg
[1].len
<= 255);
94 write_len
= seg
[0].len
;
95 read_len
= seg
[1].len
;
96 write_buffer
= seg
[0].buf
;
97 read_buffer
= seg
[1].buf
;
101 /* Clear interrupt status */
102 write32(®s
->intr_stat
, I2C_TRANSAC_COMP
| I2C_ACKERR
|
105 write32(®s
->fifo_addr_clr
, 0x1);
107 /* Enable interrupt */
108 write32(®s
->intr_mask
, I2C_HS_NACKERR
| I2C_ACKERR
|
113 memcpy(_dma_coherent
, write_buffer
, write_len
);
115 /* control registers */
116 write32(®s
->control
, ASYNC_MODE
| DMAACK_EN
|
117 ACK_ERR_DET_EN
| DMA_EN
| CLK_EXT
|
118 REPEATED_START_FLAG
);
120 /* Set transfer and transaction len */
121 write32(®s
->transac_len
, 1);
122 write32(®s
->transfer_len
, write_len
);
124 /* set i2c write slave address*/
125 write32(®s
->slave_addr
, addr
<< 1);
127 /* Prepare buffer data to start transfer */
128 write32(&dma_regs
->dma_con
, I2C_DMA_CON_TX
);
129 write32(&dma_regs
->dma_tx_mem_addr
, (uintptr_t)_dma_coherent
);
130 write32(&dma_regs
->dma_tx_len
, write_len
);
134 /* control registers */
135 write32(®s
->control
, ASYNC_MODE
| DMAACK_EN
|
136 ACK_ERR_DET_EN
| DMA_EN
| CLK_EXT
|
137 REPEATED_START_FLAG
);
139 /* Set transfer and transaction len */
140 write32(®s
->transac_len
, 1);
141 write32(®s
->transfer_len
, read_len
);
143 /* set i2c read slave address*/
144 write32(®s
->slave_addr
, (addr
<< 1 | 0x1));
146 /* Prepare buffer data to start transfer */
147 write32(&dma_regs
->dma_con
, I2C_DMA_CON_RX
);
148 write32(&dma_regs
->dma_rx_mem_addr
, (uintptr_t)_dma_coherent
);
149 write32(&dma_regs
->dma_rx_len
, read_len
);
152 case I2C_WRITE_READ_MODE
:
153 memcpy(_dma_coherent
, write_buffer
, write_len
);
155 /* control registers */
156 write32(®s
->control
, ASYNC_MODE
| DMAACK_EN
|
157 DIR_CHG
| ACK_ERR_DET_EN
| DMA_EN
|
158 CLK_EXT
| REPEATED_START_FLAG
);
160 /* Set transfer and transaction len */
161 write32(®s
->transfer_len
, write_len
);
162 write32(®s
->transfer_aux_len
, read_len
);
163 write32(®s
->transac_len
, 2);
165 /* set i2c write slave address*/
166 write32(®s
->slave_addr
, addr
<< 1);
168 /* Prepare buffer data to start transfer */
169 write32(&dma_regs
->dma_con
, I2C_DMA_CLR_FLAG
);
170 write32(&dma_regs
->dma_tx_mem_addr
, (uintptr_t)_dma_coherent
);
171 write32(&dma_regs
->dma_tx_len
, write_len
);
172 write32(&dma_regs
->dma_rx_mem_addr
, (uintptr_t)_dma_coherent
);
173 write32(&dma_regs
->dma_rx_len
, read_len
);
177 write32(&dma_regs
->dma_int_flag
, I2C_DMA_CLR_FLAG
);
178 write32(&dma_regs
->dma_en
, I2C_DMA_START_EN
);
180 /* start transfer transaction */
181 write32(®s
->start
, 0x1);
183 stopwatch_init_msecs_expire(&sw
, 100);
185 /* polling mode : see if transaction complete */
187 status
= read32(®s
->intr_stat
);
188 if (status
& I2C_HS_NACKERR
) {
189 ret_code
= I2C_TRANSFER_FAIL_HS_NACKERR
;
190 printk(BIOS_ERR
, "[i2c%d] transfer NACK error\n", bus
);
191 mtk_i2c_dump_info(regs
);
193 } else if (status
& I2C_ACKERR
) {
194 ret_code
= I2C_TRANSFER_FAIL_ACKERR
;
195 printk(BIOS_ERR
, "[i2c%d] transfer ACK error\n", bus
);
196 mtk_i2c_dump_info(regs
);
198 } else if (status
& I2C_TRANSAC_COMP
) {
200 memcpy(read_buffer
, _dma_coherent
, read_len
);
204 if (stopwatch_expired(&sw
)) {
205 ret_code
= I2C_TRANSFER_FAIL_TIMEOUT
;
206 printk(BIOS_ERR
, "[i2c%d] transfer timeout:%d\n", bus
,
208 mtk_i2c_dump_info(regs
);
213 write32(®s
->intr_stat
, I2C_TRANSAC_COMP
| I2C_ACKERR
|
217 write32(®s
->intr_mask
, I2C_HS_NACKERR
| I2C_ACKERR
|
220 /* reset the i2c controller for next i2c transfer. */
221 write32(®s
->softreset
, 0x1);
223 i2c_dma_reset(dma_regs
);
228 static bool mtk_i2c_should_combine(struct i2c_msg
*seg
, int left_count
)
230 return (left_count
>= 2 &&
231 !(seg
[0].flags
& I2C_M_RD
) &&
232 (seg
[1].flags
& I2C_M_RD
) &&
233 seg
[0].slave
== seg
[1].slave
);
236 int platform_i2c_transfer(unsigned int bus
, struct i2c_msg
*segments
,
243 for (i
= 0; i
< seg_count
; i
++) {
244 if (mtk_i2c_should_combine(&segments
[i
], seg_count
- i
)) {
245 mode
= I2C_WRITE_READ_MODE
;
247 mode
= (segments
[i
].flags
& I2C_M_RD
) ?
248 I2C_READ_MODE
: I2C_WRITE_MODE
;
251 ret
= mtk_i2c_transfer(bus
, &segments
[i
], mode
);
256 if (mode
== I2C_WRITE_READ_MODE
)