1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <console/console.h>
6 #include <device/i2c_simple.h>
8 #include <soc/addressmap.h>
13 static void do_bus_clear(int bus
)
15 struct tegra_i2c_bus_info
*info
= &tegra_i2c_info
[bus
];
16 struct tegra_i2c_regs
* const regs
= info
->base
;
18 int i
, timeout_ms
= 10;
20 // BUS CLEAR regs (from TRM):
21 // 1. Reset the I2C controller (already done)
22 // 2. Set the # of clock pulses required (using default of 9)
23 // 3. Select STOP condition (using default of 1 = STOP)
24 // 4. Set TERMINATE condition (1 = IMMEDIATE)
25 bc
= read32(®s
->bus_clear_config
);
26 bc
|= I2C_BUS_CLEAR_CONFIG_BC_TERMINATE_IMMEDIATE
;
27 write32(®s
->bus_clear_config
, bc
);
28 // 4.1 Set MSTR_CONFIG_LOAD and wait for clear
29 write32(®s
->config_load
, I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE
);
30 for (i
= 0; i
< timeout_ms
* 10 && (read32(®s
->config_load
) &
31 I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE
); i
++) {
32 printk(BIOS_DEBUG
, "%s: wait for MSTR_CONFIG_LOAD to clear\n",
36 // 5. Set ENABLE to start the bus clear op
37 write32(®s
->bus_clear_config
, bc
| I2C_BUS_CLEAR_CONFIG_BC_ENABLE
);
38 for (i
= 0; i
< timeout_ms
* 10 && (read32(®s
->bus_clear_config
) &
39 I2C_BUS_CLEAR_CONFIG_BC_ENABLE
); i
++) {
40 printk(BIOS_DEBUG
, "%s: wait for bus clear completion\n",
46 static int tegra_i2c_send_recv(int bus
, int read
,
47 uint32_t *headers
, int header_words
,
48 uint8_t *data
, int data_len
)
50 struct tegra_i2c_bus_info
*info
= &tegra_i2c_info
[bus
];
51 struct tegra_i2c_regs
* const regs
= info
->base
;
54 uint32_t status
= read32(®s
->fifo_status
);
55 int tx_empty
= status
& I2C_FIFO_STATUS_TX_FIFO_EMPTY_CNT_MASK
;
56 tx_empty
>>= I2C_FIFO_STATUS_TX_FIFO_EMPTY_CNT_SHIFT
;
57 int rx_full
= status
& I2C_FIFO_STATUS_RX_FIFO_FULL_CNT_MASK
;
58 rx_full
>>= I2C_FIFO_STATUS_RX_FIFO_FULL_CNT_SHIFT
;
60 while (header_words
&& tx_empty
) {
61 write32(®s
->tx_packet_fifo
, *headers
++);
68 while (data_len
&& rx_full
) {
69 uint32_t word
= read32(®s
->rx_fifo
);
70 int todo
= MIN(data_len
, sizeof(word
));
72 memcpy(data
, &word
, todo
);
78 while (data_len
&& tx_empty
) {
80 int todo
= MIN(data_len
, sizeof(word
));
82 memcpy(&word
, data
, todo
);
83 write32(®s
->tx_packet_fifo
, word
);
91 uint32_t transfer_status
=
92 read32(®s
->packet_transfer_status
);
94 if (transfer_status
& I2C_PKT_STATUS_NOACK_ADDR
) {
96 "%s: The address was not acknowledged.\n",
98 info
->reset_func(info
->reset_bit
);
101 } else if (transfer_status
& I2C_PKT_STATUS_NOACK_DATA
) {
103 "%s: The data was not acknowledged.\n",
105 info
->reset_func(info
->reset_bit
);
108 } else if (transfer_status
& I2C_PKT_STATUS_ARB_LOST
) {
110 "%s: Lost arbitration.\n",
112 info
->reset_func(info
->reset_bit
);
114 /* Use Tegra bus clear registers to unlock SDA */
117 /* re-init i2c controller */
120 /* Return w/error, let caller decide what to do */
128 static int tegra_i2c_request(int bus
, unsigned int chip
, int cont
, int restart
,
129 int read
, void *data
, int data_len
)
133 if (restart
&& cont
) {
134 printk(BIOS_ERR
, "%s: Repeat start and continue xfer are "
135 "mutually exclusive.\n", __func__
);
139 headers
[0] = (0 << IOHEADER_PROTHDRSZ_SHIFT
) |
140 (1 << IOHEADER_PKTID_SHIFT
) |
141 (bus
<< IOHEADER_CONTROLLER_ID_SHIFT
) |
142 IOHEADER_PROTOCOL_I2C
| IOHEADER_PKTTYPE_REQUEST
;
144 headers
[1] = (data_len
- 1) << IOHEADER_PAYLOADSIZE_SHIFT
;
146 uint32_t slave_addr
= (chip
<< 1) | (read
? 1 : 0);
147 headers
[2] = IOHEADER_I2C_REQ_ADDR_MODE_7BIT
|
148 (slave_addr
<< IOHEADER_I2C_REQ_SLAVE_ADDR_SHIFT
);
150 headers
[2] |= IOHEADER_I2C_REQ_READ
;
152 headers
[2] |= IOHEADER_I2C_REQ_REPEAT_START
;
154 headers
[2] |= IOHEADER_I2C_REQ_CONTINUE_XFER
;
156 return tegra_i2c_send_recv(bus
, read
, headers
, ARRAY_SIZE(headers
),
160 static int i2c_transfer_segment(unsigned int bus
, unsigned int chip
, int restart
,
161 int read
, void *buf
, int len
)
163 const uint32_t max_payload
=
164 (IOHEADER_PAYLOADSIZE_MASK
+ 1) >> IOHEADER_PAYLOADSIZE_SHIFT
;
167 int todo
= MIN(len
, max_payload
);
168 int cont
= (todo
< len
);
169 if (tegra_i2c_request(bus
, chip
, cont
, restart
,
178 int platform_i2c_transfer(unsigned int bus
, struct i2c_msg
*segments
, int count
)
180 struct i2c_msg
*seg
= segments
;
183 if (bus
>= num_i2c_buses
) {
184 printk(BIOS_ERR
, "%s: ERROR: invalid I2C bus (%u)\n", __func__
,
189 for (i
= 0; i
< count
; seg
++, i
++) {
190 if (i2c_transfer_segment(bus
, seg
->slave
, i
< count
- 1,
191 seg
->flags
& I2C_M_RD
,
198 void i2c_init(unsigned int bus
)
200 struct tegra_i2c_regs
*regs
;
202 if (bus
>= num_i2c_buses
) {
203 printk(BIOS_ERR
, "%s: ERROR: invalid I2C bus (%u)\n", __func__
,
208 regs
= tegra_i2c_info
[bus
].base
;
210 write32(®s
->cnfg
, I2C_CNFG_PACKET_MODE_EN
);