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.
15 #include <device/mmio.h>
16 #include <console/console.h>
18 #include <device/i2c_simple.h>
20 #include <soc/addressmap.h>
25 static void do_bus_clear(int bus
)
27 struct tegra_i2c_bus_info
*info
= &tegra_i2c_info
[bus
];
28 struct tegra_i2c_regs
* const regs
= info
->base
;
30 int i
, timeout_ms
= 10;
32 // BUS CLEAR regs (from TRM):
33 // 1. Reset the I2C controller (already done)
34 // 2. Set the # of clock pulses required (using default of 9)
35 // 3. Select STOP condition (using default of 1 = STOP)
36 // 4. Set TERMINATE condition (1 = IMMEDIATE)
37 bc
= read32(®s
->bus_clear_config
);
38 bc
|= I2C_BUS_CLEAR_CONFIG_BC_TERMINATE_IMMEDIATE
;
39 write32(®s
->bus_clear_config
, bc
);
40 // 4.1 Set MSTR_CONFIG_LOAD and wait for clear
41 write32(®s
->config_load
, I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE
);
42 for (i
= 0; i
< timeout_ms
* 10 && (read32(®s
->config_load
) &
43 I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE
); i
++) {
44 printk(BIOS_DEBUG
, "%s: wait for MSTR_CONFIG_LOAD to clear\n",
48 // 5. Set ENABLE to start the bus clear op
49 write32(®s
->bus_clear_config
, bc
| I2C_BUS_CLEAR_CONFIG_BC_ENABLE
);
50 for (i
= 0; i
< timeout_ms
* 10 && (read32(®s
->bus_clear_config
) &
51 I2C_BUS_CLEAR_CONFIG_BC_ENABLE
); i
++) {
52 printk(BIOS_DEBUG
, "%s: wait for bus clear completion\n",
58 static int tegra_i2c_send_recv(int bus
, int read
,
59 uint32_t *headers
, int header_words
,
60 uint8_t *data
, int data_len
)
62 struct tegra_i2c_bus_info
*info
= &tegra_i2c_info
[bus
];
63 struct tegra_i2c_regs
* const regs
= info
->base
;
66 uint32_t status
= read32(®s
->fifo_status
);
67 int tx_empty
= status
& I2C_FIFO_STATUS_TX_FIFO_EMPTY_CNT_MASK
;
68 tx_empty
>>= I2C_FIFO_STATUS_TX_FIFO_EMPTY_CNT_SHIFT
;
69 int rx_full
= status
& I2C_FIFO_STATUS_RX_FIFO_FULL_CNT_MASK
;
70 rx_full
>>= I2C_FIFO_STATUS_RX_FIFO_FULL_CNT_SHIFT
;
72 while (header_words
&& tx_empty
) {
73 write32(®s
->tx_packet_fifo
, *headers
++);
80 while (data_len
&& rx_full
) {
81 uint32_t word
= read32(®s
->rx_fifo
);
82 int todo
= MIN(data_len
, sizeof(word
));
84 memcpy(data
, &word
, todo
);
90 while (data_len
&& tx_empty
) {
92 int todo
= MIN(data_len
, sizeof(word
));
94 memcpy(&word
, data
, todo
);
95 write32(®s
->tx_packet_fifo
, word
);
103 uint32_t transfer_status
=
104 read32(®s
->packet_transfer_status
);
106 if (transfer_status
& I2C_PKT_STATUS_NOACK_ADDR
) {
108 "%s: The address was not acknowledged.\n",
110 info
->reset_func(info
->reset_bit
);
113 } else if (transfer_status
& I2C_PKT_STATUS_NOACK_DATA
) {
115 "%s: The data was not acknowledged.\n",
117 info
->reset_func(info
->reset_bit
);
120 } else if (transfer_status
& I2C_PKT_STATUS_ARB_LOST
) {
122 "%s: Lost arbitration.\n",
124 info
->reset_func(info
->reset_bit
);
126 /* Use Tegra bus clear registers to unlock SDA */
129 /* re-init i2c controller */
132 /* Return w/error, let caller decide what to do */
140 static int tegra_i2c_request(int bus
, unsigned int chip
, int cont
, int restart
,
141 int read
, void *data
, int data_len
)
145 if (restart
&& cont
) {
146 printk(BIOS_ERR
, "%s: Repeat start and continue xfer are "
147 "mutually exclusive.\n", __func__
);
151 headers
[0] = (0 << IOHEADER_PROTHDRSZ_SHIFT
) |
152 (1 << IOHEADER_PKTID_SHIFT
) |
153 (bus
<< IOHEADER_CONTROLLER_ID_SHIFT
) |
154 IOHEADER_PROTOCOL_I2C
| IOHEADER_PKTTYPE_REQUEST
;
156 headers
[1] = (data_len
- 1) << IOHEADER_PAYLOADSIZE_SHIFT
;
158 uint32_t slave_addr
= (chip
<< 1) | (read
? 1 : 0);
159 headers
[2] = IOHEADER_I2C_REQ_ADDR_MODE_7BIT
|
160 (slave_addr
<< IOHEADER_I2C_REQ_SLAVE_ADDR_SHIFT
);
162 headers
[2] |= IOHEADER_I2C_REQ_READ
;
164 headers
[2] |= IOHEADER_I2C_REQ_REPEAT_START
;
166 headers
[2] |= IOHEADER_I2C_REQ_CONTINUE_XFER
;
168 return tegra_i2c_send_recv(bus
, read
, headers
, ARRAY_SIZE(headers
),
172 static int i2c_transfer_segment(unsigned int bus
, unsigned int chip
, int restart
,
173 int read
, void *buf
, int len
)
175 const uint32_t max_payload
=
176 (IOHEADER_PAYLOADSIZE_MASK
+ 1) >> IOHEADER_PAYLOADSIZE_SHIFT
;
179 int todo
= MIN(len
, max_payload
);
180 int cont
= (todo
< len
);
181 if (tegra_i2c_request(bus
, chip
, cont
, restart
,
190 int platform_i2c_transfer(unsigned int bus
, struct i2c_msg
*segments
, int count
)
192 struct i2c_msg
*seg
= segments
;
195 if (bus
>= num_i2c_buses
) {
196 printk(BIOS_ERR
, "%s: ERROR: invalid I2C bus (%u)\n", __func__
,
201 for (i
= 0; i
< count
; seg
++, i
++) {
202 if (i2c_transfer_segment(bus
, seg
->slave
, i
< count
- 1,
203 seg
->flags
& I2C_M_RD
,
210 void i2c_init(unsigned int bus
)
212 struct tegra_i2c_regs
*regs
;
214 if (bus
>= num_i2c_buses
) {
215 printk(BIOS_ERR
, "%s: ERROR: invalid I2C bus (%u)\n", __func__
,
220 regs
= tegra_i2c_info
[bus
].base
;
222 write32(®s
->cnfg
, I2C_CNFG_PACKET_MODE_EN
);