2 * This file is part of the coreboot project.
4 * Copyright 2013 Google Inc.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
16 #include <device/mmio.h>
17 #include <console/console.h>
19 #include <device/i2c_simple.h>
21 #include <soc/addressmap.h>
26 static void do_bus_clear(int bus
)
28 struct tegra_i2c_bus_info
*info
= &tegra_i2c_info
[bus
];
29 struct tegra_i2c_regs
* const regs
= info
->base
;
31 int i
, timeout_ms
= 10;
33 // BUS CLEAR regs (from TRM):
34 // 1. Reset the I2C controller (already done)
35 // 2. Set the # of clock pulses required (using default of 9)
36 // 3. Select STOP condition (using default of 1 = STOP)
37 // 4. Set TERMINATE condition (1 = IMMEDIATE)
38 bc
= read32(®s
->bus_clear_config
);
39 bc
|= I2C_BUS_CLEAR_CONFIG_BC_TERMINATE_IMMEDIATE
;
40 write32(®s
->bus_clear_config
, bc
);
41 // 4.1 Set MSTR_CONFIG_LOAD and wait for clear
42 write32(®s
->config_load
, I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE
);
43 for (i
= 0; i
< timeout_ms
* 10 && (read32(®s
->config_load
) &
44 I2C_CONFIG_LOAD_MSTR_CONFIG_LOAD_ENABLE
); i
++) {
45 printk(BIOS_DEBUG
, "%s: wait for MSTR_CONFIG_LOAD to clear\n",
49 // 5. Set ENABLE to start the bus clear op
50 write32(®s
->bus_clear_config
, bc
| I2C_BUS_CLEAR_CONFIG_BC_ENABLE
);
51 for (i
= 0; i
< timeout_ms
* 10 && (read32(®s
->bus_clear_config
) &
52 I2C_BUS_CLEAR_CONFIG_BC_ENABLE
); i
++) {
53 printk(BIOS_DEBUG
, "%s: wait for bus clear completion\n",
59 static int tegra_i2c_send_recv(int bus
, int read
,
60 uint32_t *headers
, int header_words
,
61 uint8_t *data
, int data_len
)
63 struct tegra_i2c_bus_info
*info
= &tegra_i2c_info
[bus
];
64 struct tegra_i2c_regs
* const regs
= info
->base
;
67 uint32_t status
= read32(®s
->fifo_status
);
68 int tx_empty
= status
& I2C_FIFO_STATUS_TX_FIFO_EMPTY_CNT_MASK
;
69 tx_empty
>>= I2C_FIFO_STATUS_TX_FIFO_EMPTY_CNT_SHIFT
;
70 int rx_full
= status
& I2C_FIFO_STATUS_RX_FIFO_FULL_CNT_MASK
;
71 rx_full
>>= I2C_FIFO_STATUS_RX_FIFO_FULL_CNT_SHIFT
;
73 while (header_words
&& tx_empty
) {
74 write32(®s
->tx_packet_fifo
, *headers
++);
81 while (data_len
&& rx_full
) {
82 uint32_t word
= read32(®s
->rx_fifo
);
83 int todo
= MIN(data_len
, sizeof(word
));
85 memcpy(data
, &word
, todo
);
91 while (data_len
&& tx_empty
) {
93 int todo
= MIN(data_len
, sizeof(word
));
95 memcpy(&word
, data
, todo
);
96 write32(®s
->tx_packet_fifo
, word
);
104 uint32_t transfer_status
=
105 read32(®s
->packet_transfer_status
);
107 if (transfer_status
& I2C_PKT_STATUS_NOACK_ADDR
) {
109 "%s: The address was not acknowledged.\n",
111 info
->reset_func(info
->reset_bit
);
114 } else if (transfer_status
& I2C_PKT_STATUS_NOACK_DATA
) {
116 "%s: The data was not acknowledged.\n",
118 info
->reset_func(info
->reset_bit
);
121 } else if (transfer_status
& I2C_PKT_STATUS_ARB_LOST
) {
123 "%s: Lost arbitration.\n",
125 info
->reset_func(info
->reset_bit
);
127 /* Use Tegra bus clear registers to unlock SDA */
130 /* re-init i2c controller */
133 /* Return w/error, let caller decide what to do */
141 static int tegra_i2c_request(int bus
, unsigned int chip
, int cont
, int restart
,
142 int read
, void *data
, int data_len
)
146 if (restart
&& cont
) {
147 printk(BIOS_ERR
, "%s: Repeat start and continue xfer are "
148 "mutually exclusive.\n", __func__
);
152 headers
[0] = (0 << IOHEADER_PROTHDRSZ_SHIFT
) |
153 (1 << IOHEADER_PKTID_SHIFT
) |
154 (bus
<< IOHEADER_CONTROLLER_ID_SHIFT
) |
155 IOHEADER_PROTOCOL_I2C
| IOHEADER_PKTTYPE_REQUEST
;
157 headers
[1] = (data_len
- 1) << IOHEADER_PAYLOADSIZE_SHIFT
;
159 uint32_t slave_addr
= (chip
<< 1) | (read
? 1 : 0);
160 headers
[2] = IOHEADER_I2C_REQ_ADDR_MODE_7BIT
|
161 (slave_addr
<< IOHEADER_I2C_REQ_SLAVE_ADDR_SHIFT
);
163 headers
[2] |= IOHEADER_I2C_REQ_READ
;
165 headers
[2] |= IOHEADER_I2C_REQ_REPEAT_START
;
167 headers
[2] |= IOHEADER_I2C_REQ_CONTINUE_XFER
;
169 return tegra_i2c_send_recv(bus
, read
, headers
, ARRAY_SIZE(headers
),
173 static int i2c_transfer_segment(unsigned int bus
, unsigned int chip
, int restart
,
174 int read
, void *buf
, int len
)
176 const uint32_t max_payload
=
177 (IOHEADER_PAYLOADSIZE_MASK
+ 1) >> IOHEADER_PAYLOADSIZE_SHIFT
;
180 int todo
= MIN(len
, max_payload
);
181 int cont
= (todo
< len
);
182 if (tegra_i2c_request(bus
, chip
, cont
, restart
,
191 int platform_i2c_transfer(unsigned int bus
, struct i2c_msg
*segments
, int count
)
193 struct i2c_msg
*seg
= segments
;
196 if (bus
>= num_i2c_buses
) {
197 printk(BIOS_ERR
, "%s: ERROR: invalid I2C bus (%u)\n", __func__
,
202 for (i
= 0; i
< count
; seg
++, i
++) {
203 if (i2c_transfer_segment(bus
, seg
->slave
, i
< count
- 1,
204 seg
->flags
& I2C_M_RD
,
211 void i2c_init(unsigned int bus
)
213 struct tegra_i2c_regs
*regs
;
215 if (bus
>= num_i2c_buses
) {
216 printk(BIOS_ERR
, "%s: ERROR: invalid I2C bus (%u)\n", __func__
,
221 regs
= tegra_i2c_info
[bus
].base
;
223 write32(®s
->cnfg
, I2C_CNFG_PACKET_MODE_EN
);