mb/google/brya/var/orisa: Update Type C DisplayPort HPD Configuration
[coreboot2.git] / src / soc / nvidia / tegra / i2c.c
blobbde2d1a402137deacc0536d01e2cf95133d84ae5
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <console/console.h>
5 #include <delay.h>
6 #include <device/i2c_simple.h>
7 #include <string.h>
8 #include <soc/addressmap.h>
9 #include <stdint.h>
11 #include "i2c.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;
17 uint32_t bc;
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(&regs->bus_clear_config);
26 bc |= I2C_BUS_CLEAR_CONFIG_BC_TERMINATE_IMMEDIATE;
27 write32(&regs->bus_clear_config, bc);
28 // 4.1 Set MSTR_CONFIG_LOAD and wait for clear
29 write32(&regs->config_load, I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE);
30 for (i = 0; i < timeout_ms * 10 && (read32(&regs->config_load) &
31 I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE); i++) {
32 printk(BIOS_DEBUG, "%s: wait for MSTR_CONFIG_LOAD to clear\n",
33 __func__);
34 udelay(100);
36 // 5. Set ENABLE to start the bus clear op
37 write32(&regs->bus_clear_config, bc | I2C_BUS_CLEAR_CONFIG_BC_ENABLE);
38 for (i = 0; i < timeout_ms * 10 && (read32(&regs->bus_clear_config) &
39 I2C_BUS_CLEAR_CONFIG_BC_ENABLE); i++) {
40 printk(BIOS_DEBUG, "%s: wait for bus clear completion\n",
41 __func__);
42 udelay(100);
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;
53 while (data_len) {
54 uint32_t status = read32(&regs->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(&regs->tx_packet_fifo, *headers++);
62 header_words--;
63 tx_empty--;
66 if (!header_words) {
67 if (read) {
68 while (data_len && rx_full) {
69 uint32_t word = read32(&regs->rx_fifo);
70 int todo = MIN(data_len, sizeof(word));
72 memcpy(data, &word, todo);
73 data_len -= todo;
74 data += sizeof(word);
75 rx_full--;
77 } else {
78 while (data_len && tx_empty) {
79 uint32_t word;
80 int todo = MIN(data_len, sizeof(word));
82 memcpy(&word, data, todo);
83 write32(&regs->tx_packet_fifo, word);
84 data_len -= todo;
85 data += sizeof(word);
86 tx_empty--;
91 uint32_t transfer_status =
92 read32(&regs->packet_transfer_status);
94 if (transfer_status & I2C_PKT_STATUS_NOACK_ADDR) {
95 printk(BIOS_ERR,
96 "%s: The address was not acknowledged.\n",
97 __func__);
98 info->reset_func(info->reset_bit);
99 i2c_init(bus);
100 return -1;
101 } else if (transfer_status & I2C_PKT_STATUS_NOACK_DATA) {
102 printk(BIOS_ERR,
103 "%s: The data was not acknowledged.\n",
104 __func__);
105 info->reset_func(info->reset_bit);
106 i2c_init(bus);
107 return -1;
108 } else if (transfer_status & I2C_PKT_STATUS_ARB_LOST) {
109 printk(BIOS_ERR,
110 "%s: Lost arbitration.\n",
111 __func__);
112 info->reset_func(info->reset_bit);
114 /* Use Tegra bus clear registers to unlock SDA */
115 do_bus_clear(bus);
117 /* re-init i2c controller */
118 i2c_init(bus);
120 /* Return w/error, let caller decide what to do */
121 return -1;
125 return 0;
128 static int tegra_i2c_request(int bus, unsigned int chip, int cont, int restart,
129 int read, void *data, int data_len)
131 uint32_t headers[3];
133 if (restart && cont) {
134 printk(BIOS_ERR, "%s: Repeat start and continue xfer are "
135 "mutually exclusive.\n", __func__);
136 return -1;
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);
149 if (read)
150 headers[2] |= IOHEADER_I2C_REQ_READ;
151 if (restart)
152 headers[2] |= IOHEADER_I2C_REQ_REPEAT_START;
153 if (cont)
154 headers[2] |= IOHEADER_I2C_REQ_CONTINUE_XFER;
156 return tegra_i2c_send_recv(bus, read, headers, ARRAY_SIZE(headers),
157 data, data_len);
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;
166 while (len) {
167 int todo = MIN(len, max_payload);
168 int cont = (todo < len);
169 if (tegra_i2c_request(bus, chip, cont, restart,
170 read, buf, todo))
171 return -1;
172 len -= todo;
173 buf += todo;
175 return 0;
178 int platform_i2c_transfer(unsigned int bus, struct i2c_msg *segments, int count)
180 struct i2c_msg *seg = segments;
181 int i;
183 if (bus >= num_i2c_buses) {
184 printk(BIOS_ERR, "%s: ERROR: invalid I2C bus (%u)\n", __func__,
185 bus);
186 return -1;
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,
192 seg->buf, seg->len))
193 return -1;
195 return 0;
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__,
204 bus);
205 return;
208 regs = tegra_i2c_info[bus].base;
210 write32(&regs->cnfg, I2C_CNFG_PACKET_MODE_EN);