162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * drivers/i2c/busses/i2c-tegra.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2010 Google, Inc.
662306a36Sopenharmony_ci * Author: Colin Cross <ccross@android.com>
762306a36Sopenharmony_ci */
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/acpi.h>
1062306a36Sopenharmony_ci#include <linux/bitfield.h>
1162306a36Sopenharmony_ci#include <linux/clk.h>
1262306a36Sopenharmony_ci#include <linux/delay.h>
1362306a36Sopenharmony_ci#include <linux/dmaengine.h>
1462306a36Sopenharmony_ci#include <linux/dma-mapping.h>
1562306a36Sopenharmony_ci#include <linux/err.h>
1662306a36Sopenharmony_ci#include <linux/i2c.h>
1762306a36Sopenharmony_ci#include <linux/init.h>
1862306a36Sopenharmony_ci#include <linux/interrupt.h>
1962306a36Sopenharmony_ci#include <linux/io.h>
2062306a36Sopenharmony_ci#include <linux/iopoll.h>
2162306a36Sopenharmony_ci#include <linux/irq.h>
2262306a36Sopenharmony_ci#include <linux/kernel.h>
2362306a36Sopenharmony_ci#include <linux/ktime.h>
2462306a36Sopenharmony_ci#include <linux/module.h>
2562306a36Sopenharmony_ci#include <linux/of.h>
2662306a36Sopenharmony_ci#include <linux/pinctrl/consumer.h>
2762306a36Sopenharmony_ci#include <linux/platform_device.h>
2862306a36Sopenharmony_ci#include <linux/pm_runtime.h>
2962306a36Sopenharmony_ci#include <linux/reset.h>
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define BYTES_PER_FIFO_WORD 4
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci#define I2C_CNFG				0x000
3462306a36Sopenharmony_ci#define I2C_CNFG_DEBOUNCE_CNT			GENMASK(14, 12)
3562306a36Sopenharmony_ci#define I2C_CNFG_PACKET_MODE_EN			BIT(10)
3662306a36Sopenharmony_ci#define I2C_CNFG_NEW_MASTER_FSM			BIT(11)
3762306a36Sopenharmony_ci#define I2C_CNFG_MULTI_MASTER_MODE		BIT(17)
3862306a36Sopenharmony_ci#define I2C_STATUS				0x01c
3962306a36Sopenharmony_ci#define I2C_SL_CNFG				0x020
4062306a36Sopenharmony_ci#define I2C_SL_CNFG_NACK			BIT(1)
4162306a36Sopenharmony_ci#define I2C_SL_CNFG_NEWSL			BIT(2)
4262306a36Sopenharmony_ci#define I2C_SL_ADDR1				0x02c
4362306a36Sopenharmony_ci#define I2C_SL_ADDR2				0x030
4462306a36Sopenharmony_ci#define I2C_TLOW_SEXT				0x034
4562306a36Sopenharmony_ci#define I2C_TX_FIFO				0x050
4662306a36Sopenharmony_ci#define I2C_RX_FIFO				0x054
4762306a36Sopenharmony_ci#define I2C_PACKET_TRANSFER_STATUS		0x058
4862306a36Sopenharmony_ci#define I2C_FIFO_CONTROL			0x05c
4962306a36Sopenharmony_ci#define I2C_FIFO_CONTROL_TX_FLUSH		BIT(1)
5062306a36Sopenharmony_ci#define I2C_FIFO_CONTROL_RX_FLUSH		BIT(0)
5162306a36Sopenharmony_ci#define I2C_FIFO_CONTROL_TX_TRIG(x)		(((x) - 1) << 5)
5262306a36Sopenharmony_ci#define I2C_FIFO_CONTROL_RX_TRIG(x)		(((x) - 1) << 2)
5362306a36Sopenharmony_ci#define I2C_FIFO_STATUS				0x060
5462306a36Sopenharmony_ci#define I2C_FIFO_STATUS_TX			GENMASK(7, 4)
5562306a36Sopenharmony_ci#define I2C_FIFO_STATUS_RX			GENMASK(3, 0)
5662306a36Sopenharmony_ci#define I2C_INT_MASK				0x064
5762306a36Sopenharmony_ci#define I2C_INT_STATUS				0x068
5862306a36Sopenharmony_ci#define I2C_INT_BUS_CLR_DONE			BIT(11)
5962306a36Sopenharmony_ci#define I2C_INT_PACKET_XFER_COMPLETE		BIT(7)
6062306a36Sopenharmony_ci#define I2C_INT_NO_ACK				BIT(3)
6162306a36Sopenharmony_ci#define I2C_INT_ARBITRATION_LOST		BIT(2)
6262306a36Sopenharmony_ci#define I2C_INT_TX_FIFO_DATA_REQ		BIT(1)
6362306a36Sopenharmony_ci#define I2C_INT_RX_FIFO_DATA_REQ		BIT(0)
6462306a36Sopenharmony_ci#define I2C_CLK_DIVISOR				0x06c
6562306a36Sopenharmony_ci#define I2C_CLK_DIVISOR_STD_FAST_MODE		GENMASK(31, 16)
6662306a36Sopenharmony_ci#define I2C_CLK_DIVISOR_HSMODE			GENMASK(15, 0)
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci#define DVC_CTRL_REG1				0x000
6962306a36Sopenharmony_ci#define DVC_CTRL_REG1_INTR_EN			BIT(10)
7062306a36Sopenharmony_ci#define DVC_CTRL_REG3				0x008
7162306a36Sopenharmony_ci#define DVC_CTRL_REG3_SW_PROG			BIT(26)
7262306a36Sopenharmony_ci#define DVC_CTRL_REG3_I2C_DONE_INTR_EN		BIT(30)
7362306a36Sopenharmony_ci#define DVC_STATUS				0x00c
7462306a36Sopenharmony_ci#define DVC_STATUS_I2C_DONE_INTR		BIT(30)
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci#define I2C_ERR_NONE				0x00
7762306a36Sopenharmony_ci#define I2C_ERR_NO_ACK				BIT(0)
7862306a36Sopenharmony_ci#define I2C_ERR_ARBITRATION_LOST		BIT(1)
7962306a36Sopenharmony_ci#define I2C_ERR_UNKNOWN_INTERRUPT		BIT(2)
8062306a36Sopenharmony_ci#define I2C_ERR_RX_BUFFER_OVERFLOW		BIT(3)
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci#define PACKET_HEADER0_HEADER_SIZE		GENMASK(29, 28)
8362306a36Sopenharmony_ci#define PACKET_HEADER0_PACKET_ID		GENMASK(23, 16)
8462306a36Sopenharmony_ci#define PACKET_HEADER0_CONT_ID			GENMASK(15, 12)
8562306a36Sopenharmony_ci#define PACKET_HEADER0_PROTOCOL			GENMASK(7, 4)
8662306a36Sopenharmony_ci#define PACKET_HEADER0_PROTOCOL_I2C		1
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#define I2C_HEADER_CONT_ON_NAK			BIT(21)
8962306a36Sopenharmony_ci#define I2C_HEADER_READ				BIT(19)
9062306a36Sopenharmony_ci#define I2C_HEADER_10BIT_ADDR			BIT(18)
9162306a36Sopenharmony_ci#define I2C_HEADER_IE_ENABLE			BIT(17)
9262306a36Sopenharmony_ci#define I2C_HEADER_REPEAT_START			BIT(16)
9362306a36Sopenharmony_ci#define I2C_HEADER_CONTINUE_XFER		BIT(15)
9462306a36Sopenharmony_ci#define I2C_HEADER_SLAVE_ADDR_SHIFT		1
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci#define I2C_BUS_CLEAR_CNFG			0x084
9762306a36Sopenharmony_ci#define I2C_BC_SCLK_THRESHOLD			GENMASK(23, 16)
9862306a36Sopenharmony_ci#define I2C_BC_STOP_COND			BIT(2)
9962306a36Sopenharmony_ci#define I2C_BC_TERMINATE			BIT(1)
10062306a36Sopenharmony_ci#define I2C_BC_ENABLE				BIT(0)
10162306a36Sopenharmony_ci#define I2C_BUS_CLEAR_STATUS			0x088
10262306a36Sopenharmony_ci#define I2C_BC_STATUS				BIT(0)
10362306a36Sopenharmony_ci
10462306a36Sopenharmony_ci#define I2C_CONFIG_LOAD				0x08c
10562306a36Sopenharmony_ci#define I2C_MSTR_CONFIG_LOAD			BIT(0)
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci#define I2C_CLKEN_OVERRIDE			0x090
10862306a36Sopenharmony_ci#define I2C_MST_CORE_CLKEN_OVR			BIT(0)
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci#define I2C_INTERFACE_TIMING_0			0x094
11162306a36Sopenharmony_ci#define  I2C_INTERFACE_TIMING_THIGH		GENMASK(13, 8)
11262306a36Sopenharmony_ci#define  I2C_INTERFACE_TIMING_TLOW		GENMASK(5, 0)
11362306a36Sopenharmony_ci#define I2C_INTERFACE_TIMING_1			0x098
11462306a36Sopenharmony_ci#define  I2C_INTERFACE_TIMING_TBUF		GENMASK(29, 24)
11562306a36Sopenharmony_ci#define  I2C_INTERFACE_TIMING_TSU_STO		GENMASK(21, 16)
11662306a36Sopenharmony_ci#define  I2C_INTERFACE_TIMING_THD_STA		GENMASK(13, 8)
11762306a36Sopenharmony_ci#define  I2C_INTERFACE_TIMING_TSU_STA		GENMASK(5, 0)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci#define I2C_HS_INTERFACE_TIMING_0		0x09c
12062306a36Sopenharmony_ci#define  I2C_HS_INTERFACE_TIMING_THIGH		GENMASK(13, 8)
12162306a36Sopenharmony_ci#define  I2C_HS_INTERFACE_TIMING_TLOW		GENMASK(5, 0)
12262306a36Sopenharmony_ci#define I2C_HS_INTERFACE_TIMING_1		0x0a0
12362306a36Sopenharmony_ci#define  I2C_HS_INTERFACE_TIMING_TSU_STO	GENMASK(21, 16)
12462306a36Sopenharmony_ci#define  I2C_HS_INTERFACE_TIMING_THD_STA	GENMASK(13, 8)
12562306a36Sopenharmony_ci#define  I2C_HS_INTERFACE_TIMING_TSU_STA	GENMASK(5, 0)
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#define I2C_MST_FIFO_CONTROL			0x0b4
12862306a36Sopenharmony_ci#define I2C_MST_FIFO_CONTROL_RX_FLUSH		BIT(0)
12962306a36Sopenharmony_ci#define I2C_MST_FIFO_CONTROL_TX_FLUSH		BIT(1)
13062306a36Sopenharmony_ci#define I2C_MST_FIFO_CONTROL_RX_TRIG(x)		(((x) - 1) <<  4)
13162306a36Sopenharmony_ci#define I2C_MST_FIFO_CONTROL_TX_TRIG(x)		(((x) - 1) << 16)
13262306a36Sopenharmony_ci
13362306a36Sopenharmony_ci#define I2C_MST_FIFO_STATUS			0x0b8
13462306a36Sopenharmony_ci#define I2C_MST_FIFO_STATUS_TX			GENMASK(23, 16)
13562306a36Sopenharmony_ci#define I2C_MST_FIFO_STATUS_RX			GENMASK(7, 0)
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ci/* configuration load timeout in microseconds */
13862306a36Sopenharmony_ci#define I2C_CONFIG_LOAD_TIMEOUT			1000000
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci/* packet header size in bytes */
14162306a36Sopenharmony_ci#define I2C_PACKET_HEADER_SIZE			12
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci/*
14462306a36Sopenharmony_ci * I2C Controller will use PIO mode for transfers up to 32 bytes in order to
14562306a36Sopenharmony_ci * avoid DMA overhead, otherwise external APB DMA controller will be used.
14662306a36Sopenharmony_ci * Note that the actual MAX PIO length is 20 bytes because 32 bytes include
14762306a36Sopenharmony_ci * I2C_PACKET_HEADER_SIZE.
14862306a36Sopenharmony_ci */
14962306a36Sopenharmony_ci#define I2C_PIO_MODE_PREFERRED_LEN		32
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci/*
15262306a36Sopenharmony_ci * msg_end_type: The bus control which needs to be sent at end of transfer.
15362306a36Sopenharmony_ci * @MSG_END_STOP: Send stop pulse.
15462306a36Sopenharmony_ci * @MSG_END_REPEAT_START: Send repeat-start.
15562306a36Sopenharmony_ci * @MSG_END_CONTINUE: Don't send stop or repeat-start.
15662306a36Sopenharmony_ci */
15762306a36Sopenharmony_cienum msg_end_type {
15862306a36Sopenharmony_ci	MSG_END_STOP,
15962306a36Sopenharmony_ci	MSG_END_REPEAT_START,
16062306a36Sopenharmony_ci	MSG_END_CONTINUE,
16162306a36Sopenharmony_ci};
16262306a36Sopenharmony_ci
16362306a36Sopenharmony_ci/**
16462306a36Sopenharmony_ci * struct tegra_i2c_hw_feature : per hardware generation features
16562306a36Sopenharmony_ci * @has_continue_xfer_support: continue-transfer supported
16662306a36Sopenharmony_ci * @has_per_pkt_xfer_complete_irq: Has enable/disable capability for transfer
16762306a36Sopenharmony_ci *		completion interrupt on per packet basis.
16862306a36Sopenharmony_ci * @has_config_load_reg: Has the config load register to load the new
16962306a36Sopenharmony_ci *		configuration.
17062306a36Sopenharmony_ci * @clk_divisor_hs_mode: Clock divisor in HS mode.
17162306a36Sopenharmony_ci * @clk_divisor_std_mode: Clock divisor in standard mode. It is
17262306a36Sopenharmony_ci *		applicable if there is no fast clock source i.e. single clock
17362306a36Sopenharmony_ci *		source.
17462306a36Sopenharmony_ci * @clk_divisor_fast_mode: Clock divisor in fast mode. It is
17562306a36Sopenharmony_ci *		applicable if there is no fast clock source i.e. single clock
17662306a36Sopenharmony_ci *		source.
17762306a36Sopenharmony_ci * @clk_divisor_fast_plus_mode: Clock divisor in fast mode plus. It is
17862306a36Sopenharmony_ci *		applicable if there is no fast clock source (i.e. single
17962306a36Sopenharmony_ci *		clock source).
18062306a36Sopenharmony_ci * @has_multi_master_mode: The I2C controller supports running in single-master
18162306a36Sopenharmony_ci *		or multi-master mode.
18262306a36Sopenharmony_ci * @has_slcg_override_reg: The I2C controller supports a register that
18362306a36Sopenharmony_ci *		overrides the second level clock gating.
18462306a36Sopenharmony_ci * @has_mst_fifo: The I2C controller contains the new MST FIFO interface that
18562306a36Sopenharmony_ci *		provides additional features and allows for longer messages to
18662306a36Sopenharmony_ci *		be transferred in one go.
18762306a36Sopenharmony_ci * @quirks: I2C adapter quirks for limiting write/read transfer size and not
18862306a36Sopenharmony_ci *		allowing 0 length transfers.
18962306a36Sopenharmony_ci * @supports_bus_clear: Bus Clear support to recover from bus hang during
19062306a36Sopenharmony_ci *		SDA stuck low from device for some unknown reasons.
19162306a36Sopenharmony_ci * @has_apb_dma: Support of APBDMA on corresponding Tegra chip.
19262306a36Sopenharmony_ci * @tlow_std_mode: Low period of the clock in standard mode.
19362306a36Sopenharmony_ci * @thigh_std_mode: High period of the clock in standard mode.
19462306a36Sopenharmony_ci * @tlow_fast_fastplus_mode: Low period of the clock in fast/fast-plus modes.
19562306a36Sopenharmony_ci * @thigh_fast_fastplus_mode: High period of the clock in fast/fast-plus modes.
19662306a36Sopenharmony_ci * @setup_hold_time_std_mode: Setup and hold time for start and stop conditions
19762306a36Sopenharmony_ci *		in standard mode.
19862306a36Sopenharmony_ci * @setup_hold_time_fast_fast_plus_mode: Setup and hold time for start and stop
19962306a36Sopenharmony_ci *		conditions in fast/fast-plus modes.
20062306a36Sopenharmony_ci * @setup_hold_time_hs_mode: Setup and hold time for start and stop conditions
20162306a36Sopenharmony_ci *		in HS mode.
20262306a36Sopenharmony_ci * @has_interface_timing_reg: Has interface timing register to program the tuned
20362306a36Sopenharmony_ci *		timing settings.
20462306a36Sopenharmony_ci */
20562306a36Sopenharmony_cistruct tegra_i2c_hw_feature {
20662306a36Sopenharmony_ci	bool has_continue_xfer_support;
20762306a36Sopenharmony_ci	bool has_per_pkt_xfer_complete_irq;
20862306a36Sopenharmony_ci	bool has_config_load_reg;
20962306a36Sopenharmony_ci	u32 clk_divisor_hs_mode;
21062306a36Sopenharmony_ci	u32 clk_divisor_std_mode;
21162306a36Sopenharmony_ci	u32 clk_divisor_fast_mode;
21262306a36Sopenharmony_ci	u32 clk_divisor_fast_plus_mode;
21362306a36Sopenharmony_ci	bool has_multi_master_mode;
21462306a36Sopenharmony_ci	bool has_slcg_override_reg;
21562306a36Sopenharmony_ci	bool has_mst_fifo;
21662306a36Sopenharmony_ci	const struct i2c_adapter_quirks *quirks;
21762306a36Sopenharmony_ci	bool supports_bus_clear;
21862306a36Sopenharmony_ci	bool has_apb_dma;
21962306a36Sopenharmony_ci	u32 tlow_std_mode;
22062306a36Sopenharmony_ci	u32 thigh_std_mode;
22162306a36Sopenharmony_ci	u32 tlow_fast_fastplus_mode;
22262306a36Sopenharmony_ci	u32 thigh_fast_fastplus_mode;
22362306a36Sopenharmony_ci	u32 setup_hold_time_std_mode;
22462306a36Sopenharmony_ci	u32 setup_hold_time_fast_fast_plus_mode;
22562306a36Sopenharmony_ci	u32 setup_hold_time_hs_mode;
22662306a36Sopenharmony_ci	bool has_interface_timing_reg;
22762306a36Sopenharmony_ci};
22862306a36Sopenharmony_ci
22962306a36Sopenharmony_ci/**
23062306a36Sopenharmony_ci * struct tegra_i2c_dev - per device I2C context
23162306a36Sopenharmony_ci * @dev: device reference for power management
23262306a36Sopenharmony_ci * @hw: Tegra I2C HW feature
23362306a36Sopenharmony_ci * @adapter: core I2C layer adapter information
23462306a36Sopenharmony_ci * @div_clk: clock reference for div clock of I2C controller
23562306a36Sopenharmony_ci * @clocks: array of I2C controller clocks
23662306a36Sopenharmony_ci * @nclocks: number of clocks in the array
23762306a36Sopenharmony_ci * @rst: reset control for the I2C controller
23862306a36Sopenharmony_ci * @base: ioremapped registers cookie
23962306a36Sopenharmony_ci * @base_phys: physical base address of the I2C controller
24062306a36Sopenharmony_ci * @cont_id: I2C controller ID, used for packet header
24162306a36Sopenharmony_ci * @irq: IRQ number of transfer complete interrupt
24262306a36Sopenharmony_ci * @is_dvc: identifies the DVC I2C controller, has a different register layout
24362306a36Sopenharmony_ci * @is_vi: identifies the VI I2C controller, has a different register layout
24462306a36Sopenharmony_ci * @msg_complete: transfer completion notifier
24562306a36Sopenharmony_ci * @msg_buf_remaining: size of unsent data in the message buffer
24662306a36Sopenharmony_ci * @msg_len: length of message in current transfer
24762306a36Sopenharmony_ci * @msg_err: error code for completed message
24862306a36Sopenharmony_ci * @msg_buf: pointer to current message data
24962306a36Sopenharmony_ci * @msg_read: indicates that the transfer is a read access
25062306a36Sopenharmony_ci * @timings: i2c timings information like bus frequency
25162306a36Sopenharmony_ci * @multimaster_mode: indicates that I2C controller is in multi-master mode
25262306a36Sopenharmony_ci * @dma_chan: DMA channel
25362306a36Sopenharmony_ci * @dma_phys: handle to DMA resources
25462306a36Sopenharmony_ci * @dma_buf: pointer to allocated DMA buffer
25562306a36Sopenharmony_ci * @dma_buf_size: DMA buffer size
25662306a36Sopenharmony_ci * @dma_mode: indicates active DMA transfer
25762306a36Sopenharmony_ci * @dma_complete: DMA completion notifier
25862306a36Sopenharmony_ci * @atomic_mode: indicates active atomic transfer
25962306a36Sopenharmony_ci */
26062306a36Sopenharmony_cistruct tegra_i2c_dev {
26162306a36Sopenharmony_ci	struct device *dev;
26262306a36Sopenharmony_ci	struct i2c_adapter adapter;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	const struct tegra_i2c_hw_feature *hw;
26562306a36Sopenharmony_ci	struct reset_control *rst;
26662306a36Sopenharmony_ci	unsigned int cont_id;
26762306a36Sopenharmony_ci	unsigned int irq;
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ci	phys_addr_t base_phys;
27062306a36Sopenharmony_ci	void __iomem *base;
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	struct clk_bulk_data clocks[2];
27362306a36Sopenharmony_ci	unsigned int nclocks;
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	struct clk *div_clk;
27662306a36Sopenharmony_ci	struct i2c_timings timings;
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci	struct completion msg_complete;
27962306a36Sopenharmony_ci	size_t msg_buf_remaining;
28062306a36Sopenharmony_ci	unsigned int msg_len;
28162306a36Sopenharmony_ci	int msg_err;
28262306a36Sopenharmony_ci	u8 *msg_buf;
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci	struct completion dma_complete;
28562306a36Sopenharmony_ci	struct dma_chan *dma_chan;
28662306a36Sopenharmony_ci	unsigned int dma_buf_size;
28762306a36Sopenharmony_ci	struct device *dma_dev;
28862306a36Sopenharmony_ci	dma_addr_t dma_phys;
28962306a36Sopenharmony_ci	void *dma_buf;
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	bool multimaster_mode;
29262306a36Sopenharmony_ci	bool atomic_mode;
29362306a36Sopenharmony_ci	bool dma_mode;
29462306a36Sopenharmony_ci	bool msg_read;
29562306a36Sopenharmony_ci	bool is_dvc;
29662306a36Sopenharmony_ci	bool is_vi;
29762306a36Sopenharmony_ci};
29862306a36Sopenharmony_ci
29962306a36Sopenharmony_ci#define IS_DVC(dev) (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) && (dev)->is_dvc)
30062306a36Sopenharmony_ci#define IS_VI(dev)  (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) && (dev)->is_vi)
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_cistatic void dvc_writel(struct tegra_i2c_dev *i2c_dev, u32 val,
30362306a36Sopenharmony_ci		       unsigned int reg)
30462306a36Sopenharmony_ci{
30562306a36Sopenharmony_ci	writel_relaxed(val, i2c_dev->base + reg);
30662306a36Sopenharmony_ci}
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_cistatic u32 dvc_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
30962306a36Sopenharmony_ci{
31062306a36Sopenharmony_ci	return readl_relaxed(i2c_dev->base + reg);
31162306a36Sopenharmony_ci}
31262306a36Sopenharmony_ci
31362306a36Sopenharmony_ci/*
31462306a36Sopenharmony_ci * If necessary, i2c_writel() and i2c_readl() will offset the register
31562306a36Sopenharmony_ci * in order to talk to the I2C block inside the DVC block.
31662306a36Sopenharmony_ci */
31762306a36Sopenharmony_cistatic u32 tegra_i2c_reg_addr(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
31862306a36Sopenharmony_ci{
31962306a36Sopenharmony_ci	if (IS_DVC(i2c_dev))
32062306a36Sopenharmony_ci		reg += (reg >= I2C_TX_FIFO) ? 0x10 : 0x40;
32162306a36Sopenharmony_ci	else if (IS_VI(i2c_dev))
32262306a36Sopenharmony_ci		reg = 0xc00 + (reg << 2);
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ci	return reg;
32562306a36Sopenharmony_ci}
32662306a36Sopenharmony_ci
32762306a36Sopenharmony_cistatic void i2c_writel(struct tegra_i2c_dev *i2c_dev, u32 val, unsigned int reg)
32862306a36Sopenharmony_ci{
32962306a36Sopenharmony_ci	writel_relaxed(val, i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
33062306a36Sopenharmony_ci
33162306a36Sopenharmony_ci	/* read back register to make sure that register writes completed */
33262306a36Sopenharmony_ci	if (reg != I2C_TX_FIFO)
33362306a36Sopenharmony_ci		readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
33462306a36Sopenharmony_ci	else if (IS_VI(i2c_dev))
33562306a36Sopenharmony_ci		readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, I2C_INT_STATUS));
33662306a36Sopenharmony_ci}
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistatic u32 i2c_readl(struct tegra_i2c_dev *i2c_dev, unsigned int reg)
33962306a36Sopenharmony_ci{
34062306a36Sopenharmony_ci	return readl_relaxed(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg));
34162306a36Sopenharmony_ci}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_cistatic void i2c_writesl(struct tegra_i2c_dev *i2c_dev, void *data,
34462306a36Sopenharmony_ci			unsigned int reg, unsigned int len)
34562306a36Sopenharmony_ci{
34662306a36Sopenharmony_ci	writesl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
34762306a36Sopenharmony_ci}
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_cistatic void i2c_writesl_vi(struct tegra_i2c_dev *i2c_dev, void *data,
35062306a36Sopenharmony_ci			   unsigned int reg, unsigned int len)
35162306a36Sopenharmony_ci{
35262306a36Sopenharmony_ci	u32 *data32 = data;
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_ci	/*
35562306a36Sopenharmony_ci	 * VI I2C controller has known hardware bug where writes get stuck
35662306a36Sopenharmony_ci	 * when immediate multiple writes happen to TX_FIFO register.
35762306a36Sopenharmony_ci	 * Recommended software work around is to read I2C register after
35862306a36Sopenharmony_ci	 * each write to TX_FIFO register to flush out the data.
35962306a36Sopenharmony_ci	 */
36062306a36Sopenharmony_ci	while (len--)
36162306a36Sopenharmony_ci		i2c_writel(i2c_dev, *data32++, reg);
36262306a36Sopenharmony_ci}
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_cistatic void i2c_readsl(struct tegra_i2c_dev *i2c_dev, void *data,
36562306a36Sopenharmony_ci		       unsigned int reg, unsigned int len)
36662306a36Sopenharmony_ci{
36762306a36Sopenharmony_ci	readsl(i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg), data, len);
36862306a36Sopenharmony_ci}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_cistatic void tegra_i2c_mask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
37162306a36Sopenharmony_ci{
37262306a36Sopenharmony_ci	u32 int_mask;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	int_mask = i2c_readl(i2c_dev, I2C_INT_MASK) & ~mask;
37562306a36Sopenharmony_ci	i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
37662306a36Sopenharmony_ci}
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_cistatic void tegra_i2c_unmask_irq(struct tegra_i2c_dev *i2c_dev, u32 mask)
37962306a36Sopenharmony_ci{
38062306a36Sopenharmony_ci	u32 int_mask;
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_ci	int_mask = i2c_readl(i2c_dev, I2C_INT_MASK) | mask;
38362306a36Sopenharmony_ci	i2c_writel(i2c_dev, int_mask, I2C_INT_MASK);
38462306a36Sopenharmony_ci}
38562306a36Sopenharmony_ci
38662306a36Sopenharmony_cistatic void tegra_i2c_dma_complete(void *args)
38762306a36Sopenharmony_ci{
38862306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = args;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci	complete(&i2c_dev->dma_complete);
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_cistatic int tegra_i2c_dma_submit(struct tegra_i2c_dev *i2c_dev, size_t len)
39462306a36Sopenharmony_ci{
39562306a36Sopenharmony_ci	struct dma_async_tx_descriptor *dma_desc;
39662306a36Sopenharmony_ci	enum dma_transfer_direction dir;
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_ci	dev_dbg(i2c_dev->dev, "starting DMA for length: %zu\n", len);
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci	reinit_completion(&i2c_dev->dma_complete);
40162306a36Sopenharmony_ci
40262306a36Sopenharmony_ci	dir = i2c_dev->msg_read ? DMA_DEV_TO_MEM : DMA_MEM_TO_DEV;
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	dma_desc = dmaengine_prep_slave_single(i2c_dev->dma_chan, i2c_dev->dma_phys,
40562306a36Sopenharmony_ci					       len, dir, DMA_PREP_INTERRUPT |
40662306a36Sopenharmony_ci					       DMA_CTRL_ACK);
40762306a36Sopenharmony_ci	if (!dma_desc) {
40862306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "failed to get %s DMA descriptor\n",
40962306a36Sopenharmony_ci			i2c_dev->msg_read ? "RX" : "TX");
41062306a36Sopenharmony_ci		return -EINVAL;
41162306a36Sopenharmony_ci	}
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_ci	dma_desc->callback = tegra_i2c_dma_complete;
41462306a36Sopenharmony_ci	dma_desc->callback_param = i2c_dev;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	dmaengine_submit(dma_desc);
41762306a36Sopenharmony_ci	dma_async_issue_pending(i2c_dev->dma_chan);
41862306a36Sopenharmony_ci
41962306a36Sopenharmony_ci	return 0;
42062306a36Sopenharmony_ci}
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_cistatic void tegra_i2c_release_dma(struct tegra_i2c_dev *i2c_dev)
42362306a36Sopenharmony_ci{
42462306a36Sopenharmony_ci	if (i2c_dev->dma_buf) {
42562306a36Sopenharmony_ci		dma_free_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size,
42662306a36Sopenharmony_ci				  i2c_dev->dma_buf, i2c_dev->dma_phys);
42762306a36Sopenharmony_ci		i2c_dev->dma_buf = NULL;
42862306a36Sopenharmony_ci	}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_ci	if (i2c_dev->dma_chan) {
43162306a36Sopenharmony_ci		dma_release_channel(i2c_dev->dma_chan);
43262306a36Sopenharmony_ci		i2c_dev->dma_chan = NULL;
43362306a36Sopenharmony_ci	}
43462306a36Sopenharmony_ci}
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_cistatic int tegra_i2c_init_dma(struct tegra_i2c_dev *i2c_dev)
43762306a36Sopenharmony_ci{
43862306a36Sopenharmony_ci	dma_addr_t dma_phys;
43962306a36Sopenharmony_ci	u32 *dma_buf;
44062306a36Sopenharmony_ci	int err;
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	if (IS_VI(i2c_dev))
44362306a36Sopenharmony_ci		return 0;
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci	if (i2c_dev->hw->has_apb_dma) {
44662306a36Sopenharmony_ci		if (!IS_ENABLED(CONFIG_TEGRA20_APB_DMA)) {
44762306a36Sopenharmony_ci			dev_dbg(i2c_dev->dev, "APB DMA support not enabled\n");
44862306a36Sopenharmony_ci			return 0;
44962306a36Sopenharmony_ci		}
45062306a36Sopenharmony_ci	} else if (!IS_ENABLED(CONFIG_TEGRA186_GPC_DMA)) {
45162306a36Sopenharmony_ci		dev_dbg(i2c_dev->dev, "GPC DMA support not enabled\n");
45262306a36Sopenharmony_ci		return 0;
45362306a36Sopenharmony_ci	}
45462306a36Sopenharmony_ci
45562306a36Sopenharmony_ci	/*
45662306a36Sopenharmony_ci	 * The same channel will be used for both RX and TX.
45762306a36Sopenharmony_ci	 * Keeping the name as "tx" for backward compatibility
45862306a36Sopenharmony_ci	 * with existing devicetrees.
45962306a36Sopenharmony_ci	 */
46062306a36Sopenharmony_ci	i2c_dev->dma_chan = dma_request_chan(i2c_dev->dev, "tx");
46162306a36Sopenharmony_ci	if (IS_ERR(i2c_dev->dma_chan)) {
46262306a36Sopenharmony_ci		err = PTR_ERR(i2c_dev->dma_chan);
46362306a36Sopenharmony_ci		i2c_dev->dma_chan = NULL;
46462306a36Sopenharmony_ci		goto err_out;
46562306a36Sopenharmony_ci	}
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	i2c_dev->dma_dev = i2c_dev->dma_chan->device->dev;
46862306a36Sopenharmony_ci	i2c_dev->dma_buf_size = i2c_dev->hw->quirks->max_write_len +
46962306a36Sopenharmony_ci				I2C_PACKET_HEADER_SIZE;
47062306a36Sopenharmony_ci
47162306a36Sopenharmony_ci	dma_buf = dma_alloc_coherent(i2c_dev->dma_dev, i2c_dev->dma_buf_size,
47262306a36Sopenharmony_ci				     &dma_phys, GFP_KERNEL | __GFP_NOWARN);
47362306a36Sopenharmony_ci	if (!dma_buf) {
47462306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "failed to allocate DMA buffer\n");
47562306a36Sopenharmony_ci		err = -ENOMEM;
47662306a36Sopenharmony_ci		goto err_out;
47762306a36Sopenharmony_ci	}
47862306a36Sopenharmony_ci
47962306a36Sopenharmony_ci	i2c_dev->dma_buf = dma_buf;
48062306a36Sopenharmony_ci	i2c_dev->dma_phys = dma_phys;
48162306a36Sopenharmony_ci
48262306a36Sopenharmony_ci	return 0;
48362306a36Sopenharmony_ci
48462306a36Sopenharmony_cierr_out:
48562306a36Sopenharmony_ci	tegra_i2c_release_dma(i2c_dev);
48662306a36Sopenharmony_ci	if (err != -EPROBE_DEFER) {
48762306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "cannot use DMA: %d\n", err);
48862306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "falling back to PIO\n");
48962306a36Sopenharmony_ci		return 0;
49062306a36Sopenharmony_ci	}
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	return err;
49362306a36Sopenharmony_ci}
49462306a36Sopenharmony_ci
49562306a36Sopenharmony_ci/*
49662306a36Sopenharmony_ci * One of the Tegra I2C blocks is inside the DVC (Digital Voltage Controller)
49762306a36Sopenharmony_ci * block.  This block is identical to the rest of the I2C blocks, except that
49862306a36Sopenharmony_ci * it only supports master mode, it has registers moved around, and it needs
49962306a36Sopenharmony_ci * some extra init to get it into I2C mode.  The register moves are handled
50062306a36Sopenharmony_ci * by i2c_readl() and i2c_writel().
50162306a36Sopenharmony_ci */
50262306a36Sopenharmony_cistatic void tegra_dvc_init(struct tegra_i2c_dev *i2c_dev)
50362306a36Sopenharmony_ci{
50462306a36Sopenharmony_ci	u32 val;
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	val = dvc_readl(i2c_dev, DVC_CTRL_REG3);
50762306a36Sopenharmony_ci	val |= DVC_CTRL_REG3_SW_PROG;
50862306a36Sopenharmony_ci	val |= DVC_CTRL_REG3_I2C_DONE_INTR_EN;
50962306a36Sopenharmony_ci	dvc_writel(i2c_dev, val, DVC_CTRL_REG3);
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	val = dvc_readl(i2c_dev, DVC_CTRL_REG1);
51262306a36Sopenharmony_ci	val |= DVC_CTRL_REG1_INTR_EN;
51362306a36Sopenharmony_ci	dvc_writel(i2c_dev, val, DVC_CTRL_REG1);
51462306a36Sopenharmony_ci}
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_cistatic void tegra_i2c_vi_init(struct tegra_i2c_dev *i2c_dev)
51762306a36Sopenharmony_ci{
51862306a36Sopenharmony_ci	u32 value;
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci	value = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, 2) |
52162306a36Sopenharmony_ci		FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, 4);
52262306a36Sopenharmony_ci	i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_0);
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci	value = FIELD_PREP(I2C_INTERFACE_TIMING_TBUF, 4) |
52562306a36Sopenharmony_ci		FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STO, 7) |
52662306a36Sopenharmony_ci		FIELD_PREP(I2C_INTERFACE_TIMING_THD_STA, 4) |
52762306a36Sopenharmony_ci		FIELD_PREP(I2C_INTERFACE_TIMING_TSU_STA, 4);
52862306a36Sopenharmony_ci	i2c_writel(i2c_dev, value, I2C_INTERFACE_TIMING_1);
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_THIGH, 3) |
53162306a36Sopenharmony_ci		FIELD_PREP(I2C_HS_INTERFACE_TIMING_TLOW, 8);
53262306a36Sopenharmony_ci	i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_0);
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	value = FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STO, 11) |
53562306a36Sopenharmony_ci		FIELD_PREP(I2C_HS_INTERFACE_TIMING_THD_STA, 11) |
53662306a36Sopenharmony_ci		FIELD_PREP(I2C_HS_INTERFACE_TIMING_TSU_STA, 11);
53762306a36Sopenharmony_ci	i2c_writel(i2c_dev, value, I2C_HS_INTERFACE_TIMING_1);
53862306a36Sopenharmony_ci
53962306a36Sopenharmony_ci	value = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND;
54062306a36Sopenharmony_ci	i2c_writel(i2c_dev, value, I2C_BUS_CLEAR_CNFG);
54162306a36Sopenharmony_ci
54262306a36Sopenharmony_ci	i2c_writel(i2c_dev, 0x0, I2C_TLOW_SEXT);
54362306a36Sopenharmony_ci}
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_cistatic int tegra_i2c_poll_register(struct tegra_i2c_dev *i2c_dev,
54662306a36Sopenharmony_ci				   u32 reg, u32 mask, u32 delay_us,
54762306a36Sopenharmony_ci				   u32 timeout_us)
54862306a36Sopenharmony_ci{
54962306a36Sopenharmony_ci	void __iomem *addr = i2c_dev->base + tegra_i2c_reg_addr(i2c_dev, reg);
55062306a36Sopenharmony_ci	u32 val;
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	if (!i2c_dev->atomic_mode)
55362306a36Sopenharmony_ci		return readl_relaxed_poll_timeout(addr, val, !(val & mask),
55462306a36Sopenharmony_ci						  delay_us, timeout_us);
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	return readl_relaxed_poll_timeout_atomic(addr, val, !(val & mask),
55762306a36Sopenharmony_ci						 delay_us, timeout_us);
55862306a36Sopenharmony_ci}
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_cistatic int tegra_i2c_flush_fifos(struct tegra_i2c_dev *i2c_dev)
56162306a36Sopenharmony_ci{
56262306a36Sopenharmony_ci	u32 mask, val, offset;
56362306a36Sopenharmony_ci	int err;
56462306a36Sopenharmony_ci
56562306a36Sopenharmony_ci	if (i2c_dev->hw->has_mst_fifo) {
56662306a36Sopenharmony_ci		mask = I2C_MST_FIFO_CONTROL_TX_FLUSH |
56762306a36Sopenharmony_ci		       I2C_MST_FIFO_CONTROL_RX_FLUSH;
56862306a36Sopenharmony_ci		offset = I2C_MST_FIFO_CONTROL;
56962306a36Sopenharmony_ci	} else {
57062306a36Sopenharmony_ci		mask = I2C_FIFO_CONTROL_TX_FLUSH |
57162306a36Sopenharmony_ci		       I2C_FIFO_CONTROL_RX_FLUSH;
57262306a36Sopenharmony_ci		offset = I2C_FIFO_CONTROL;
57362306a36Sopenharmony_ci	}
57462306a36Sopenharmony_ci
57562306a36Sopenharmony_ci	val = i2c_readl(i2c_dev, offset);
57662306a36Sopenharmony_ci	val |= mask;
57762306a36Sopenharmony_ci	i2c_writel(i2c_dev, val, offset);
57862306a36Sopenharmony_ci
57962306a36Sopenharmony_ci	err = tegra_i2c_poll_register(i2c_dev, offset, mask, 1000, 1000000);
58062306a36Sopenharmony_ci	if (err) {
58162306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "failed to flush FIFO\n");
58262306a36Sopenharmony_ci		return err;
58362306a36Sopenharmony_ci	}
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	return 0;
58662306a36Sopenharmony_ci}
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_cistatic int tegra_i2c_wait_for_config_load(struct tegra_i2c_dev *i2c_dev)
58962306a36Sopenharmony_ci{
59062306a36Sopenharmony_ci	int err;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	if (!i2c_dev->hw->has_config_load_reg)
59362306a36Sopenharmony_ci		return 0;
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_ci	i2c_writel(i2c_dev, I2C_MSTR_CONFIG_LOAD, I2C_CONFIG_LOAD);
59662306a36Sopenharmony_ci
59762306a36Sopenharmony_ci	err = tegra_i2c_poll_register(i2c_dev, I2C_CONFIG_LOAD, 0xffffffff,
59862306a36Sopenharmony_ci				      1000, I2C_CONFIG_LOAD_TIMEOUT);
59962306a36Sopenharmony_ci	if (err) {
60062306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "failed to load config\n");
60162306a36Sopenharmony_ci		return err;
60262306a36Sopenharmony_ci	}
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	return 0;
60562306a36Sopenharmony_ci}
60662306a36Sopenharmony_ci
60762306a36Sopenharmony_cistatic int tegra_i2c_init(struct tegra_i2c_dev *i2c_dev)
60862306a36Sopenharmony_ci{
60962306a36Sopenharmony_ci	u32 val, clk_divisor, clk_multiplier, tsu_thd, tlow, thigh, non_hs_mode;
61062306a36Sopenharmony_ci	acpi_handle handle = ACPI_HANDLE(i2c_dev->dev);
61162306a36Sopenharmony_ci	struct i2c_timings *t = &i2c_dev->timings;
61262306a36Sopenharmony_ci	int err;
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	/*
61562306a36Sopenharmony_ci	 * The reset shouldn't ever fail in practice. The failure will be a
61662306a36Sopenharmony_ci	 * sign of a severe problem that needs to be resolved. Still we don't
61762306a36Sopenharmony_ci	 * want to fail the initialization completely because this may break
61862306a36Sopenharmony_ci	 * kernel boot up since voltage regulators use I2C. Hence, we will
61962306a36Sopenharmony_ci	 * emit a noisy warning on error, which won't stay unnoticed and
62062306a36Sopenharmony_ci	 * won't hose machine entirely.
62162306a36Sopenharmony_ci	 */
62262306a36Sopenharmony_ci	if (handle)
62362306a36Sopenharmony_ci		err = acpi_evaluate_object(handle, "_RST", NULL, NULL);
62462306a36Sopenharmony_ci	else
62562306a36Sopenharmony_ci		err = reset_control_reset(i2c_dev->rst);
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	WARN_ON_ONCE(err);
62862306a36Sopenharmony_ci
62962306a36Sopenharmony_ci	if (IS_DVC(i2c_dev))
63062306a36Sopenharmony_ci		tegra_dvc_init(i2c_dev);
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	val = I2C_CNFG_NEW_MASTER_FSM | I2C_CNFG_PACKET_MODE_EN |
63362306a36Sopenharmony_ci	      FIELD_PREP(I2C_CNFG_DEBOUNCE_CNT, 2);
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	if (i2c_dev->hw->has_multi_master_mode)
63662306a36Sopenharmony_ci		val |= I2C_CNFG_MULTI_MASTER_MODE;
63762306a36Sopenharmony_ci
63862306a36Sopenharmony_ci	i2c_writel(i2c_dev, val, I2C_CNFG);
63962306a36Sopenharmony_ci	i2c_writel(i2c_dev, 0, I2C_INT_MASK);
64062306a36Sopenharmony_ci
64162306a36Sopenharmony_ci	if (IS_VI(i2c_dev))
64262306a36Sopenharmony_ci		tegra_i2c_vi_init(i2c_dev);
64362306a36Sopenharmony_ci
64462306a36Sopenharmony_ci	switch (t->bus_freq_hz) {
64562306a36Sopenharmony_ci	case I2C_MAX_STANDARD_MODE_FREQ + 1 ... I2C_MAX_FAST_MODE_PLUS_FREQ:
64662306a36Sopenharmony_ci	default:
64762306a36Sopenharmony_ci		tlow = i2c_dev->hw->tlow_fast_fastplus_mode;
64862306a36Sopenharmony_ci		thigh = i2c_dev->hw->thigh_fast_fastplus_mode;
64962306a36Sopenharmony_ci		tsu_thd = i2c_dev->hw->setup_hold_time_fast_fast_plus_mode;
65062306a36Sopenharmony_ci
65162306a36Sopenharmony_ci		if (t->bus_freq_hz > I2C_MAX_FAST_MODE_FREQ)
65262306a36Sopenharmony_ci			non_hs_mode = i2c_dev->hw->clk_divisor_fast_plus_mode;
65362306a36Sopenharmony_ci		else
65462306a36Sopenharmony_ci			non_hs_mode = i2c_dev->hw->clk_divisor_fast_mode;
65562306a36Sopenharmony_ci		break;
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	case 0 ... I2C_MAX_STANDARD_MODE_FREQ:
65862306a36Sopenharmony_ci		tlow = i2c_dev->hw->tlow_std_mode;
65962306a36Sopenharmony_ci		thigh = i2c_dev->hw->thigh_std_mode;
66062306a36Sopenharmony_ci		tsu_thd = i2c_dev->hw->setup_hold_time_std_mode;
66162306a36Sopenharmony_ci		non_hs_mode = i2c_dev->hw->clk_divisor_std_mode;
66262306a36Sopenharmony_ci		break;
66362306a36Sopenharmony_ci	}
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	/* make sure clock divisor programmed correctly */
66662306a36Sopenharmony_ci	clk_divisor = FIELD_PREP(I2C_CLK_DIVISOR_HSMODE,
66762306a36Sopenharmony_ci				 i2c_dev->hw->clk_divisor_hs_mode) |
66862306a36Sopenharmony_ci		      FIELD_PREP(I2C_CLK_DIVISOR_STD_FAST_MODE, non_hs_mode);
66962306a36Sopenharmony_ci	i2c_writel(i2c_dev, clk_divisor, I2C_CLK_DIVISOR);
67062306a36Sopenharmony_ci
67162306a36Sopenharmony_ci	if (i2c_dev->hw->has_interface_timing_reg) {
67262306a36Sopenharmony_ci		val = FIELD_PREP(I2C_INTERFACE_TIMING_THIGH, thigh) |
67362306a36Sopenharmony_ci		      FIELD_PREP(I2C_INTERFACE_TIMING_TLOW, tlow);
67462306a36Sopenharmony_ci		i2c_writel(i2c_dev, val, I2C_INTERFACE_TIMING_0);
67562306a36Sopenharmony_ci	}
67662306a36Sopenharmony_ci
67762306a36Sopenharmony_ci	/*
67862306a36Sopenharmony_ci	 * Configure setup and hold times only when tsu_thd is non-zero.
67962306a36Sopenharmony_ci	 * Otherwise, preserve the chip default values.
68062306a36Sopenharmony_ci	 */
68162306a36Sopenharmony_ci	if (i2c_dev->hw->has_interface_timing_reg && tsu_thd)
68262306a36Sopenharmony_ci		i2c_writel(i2c_dev, tsu_thd, I2C_INTERFACE_TIMING_1);
68362306a36Sopenharmony_ci
68462306a36Sopenharmony_ci	clk_multiplier = (tlow + thigh + 2) * (non_hs_mode + 1);
68562306a36Sopenharmony_ci
68662306a36Sopenharmony_ci	err = clk_set_rate(i2c_dev->div_clk,
68762306a36Sopenharmony_ci			   t->bus_freq_hz * clk_multiplier);
68862306a36Sopenharmony_ci	if (err) {
68962306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "failed to set div-clk rate: %d\n", err);
69062306a36Sopenharmony_ci		return err;
69162306a36Sopenharmony_ci	}
69262306a36Sopenharmony_ci
69362306a36Sopenharmony_ci	if (!IS_DVC(i2c_dev) && !IS_VI(i2c_dev)) {
69462306a36Sopenharmony_ci		u32 sl_cfg = i2c_readl(i2c_dev, I2C_SL_CNFG);
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci		sl_cfg |= I2C_SL_CNFG_NACK | I2C_SL_CNFG_NEWSL;
69762306a36Sopenharmony_ci		i2c_writel(i2c_dev, sl_cfg, I2C_SL_CNFG);
69862306a36Sopenharmony_ci		i2c_writel(i2c_dev, 0xfc, I2C_SL_ADDR1);
69962306a36Sopenharmony_ci		i2c_writel(i2c_dev, 0x00, I2C_SL_ADDR2);
70062306a36Sopenharmony_ci	}
70162306a36Sopenharmony_ci
70262306a36Sopenharmony_ci	err = tegra_i2c_flush_fifos(i2c_dev);
70362306a36Sopenharmony_ci	if (err)
70462306a36Sopenharmony_ci		return err;
70562306a36Sopenharmony_ci
70662306a36Sopenharmony_ci	if (i2c_dev->multimaster_mode && i2c_dev->hw->has_slcg_override_reg)
70762306a36Sopenharmony_ci		i2c_writel(i2c_dev, I2C_MST_CORE_CLKEN_OVR, I2C_CLKEN_OVERRIDE);
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	err = tegra_i2c_wait_for_config_load(i2c_dev);
71062306a36Sopenharmony_ci	if (err)
71162306a36Sopenharmony_ci		return err;
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	return 0;
71462306a36Sopenharmony_ci}
71562306a36Sopenharmony_ci
71662306a36Sopenharmony_cistatic int tegra_i2c_disable_packet_mode(struct tegra_i2c_dev *i2c_dev)
71762306a36Sopenharmony_ci{
71862306a36Sopenharmony_ci	u32 cnfg;
71962306a36Sopenharmony_ci
72062306a36Sopenharmony_ci	/*
72162306a36Sopenharmony_ci	 * NACK interrupt is generated before the I2C controller generates
72262306a36Sopenharmony_ci	 * the STOP condition on the bus.  So, wait for 2 clock periods
72362306a36Sopenharmony_ci	 * before disabling the controller so that the STOP condition has
72462306a36Sopenharmony_ci	 * been delivered properly.
72562306a36Sopenharmony_ci	 */
72662306a36Sopenharmony_ci	udelay(DIV_ROUND_UP(2 * 1000000, i2c_dev->timings.bus_freq_hz));
72762306a36Sopenharmony_ci
72862306a36Sopenharmony_ci	cnfg = i2c_readl(i2c_dev, I2C_CNFG);
72962306a36Sopenharmony_ci	if (cnfg & I2C_CNFG_PACKET_MODE_EN)
73062306a36Sopenharmony_ci		i2c_writel(i2c_dev, cnfg & ~I2C_CNFG_PACKET_MODE_EN, I2C_CNFG);
73162306a36Sopenharmony_ci
73262306a36Sopenharmony_ci	return tegra_i2c_wait_for_config_load(i2c_dev);
73362306a36Sopenharmony_ci}
73462306a36Sopenharmony_ci
73562306a36Sopenharmony_cistatic int tegra_i2c_empty_rx_fifo(struct tegra_i2c_dev *i2c_dev)
73662306a36Sopenharmony_ci{
73762306a36Sopenharmony_ci	size_t buf_remaining = i2c_dev->msg_buf_remaining;
73862306a36Sopenharmony_ci	unsigned int words_to_transfer, rx_fifo_avail;
73962306a36Sopenharmony_ci	u8 *buf = i2c_dev->msg_buf;
74062306a36Sopenharmony_ci	u32 val;
74162306a36Sopenharmony_ci
74262306a36Sopenharmony_ci	/*
74362306a36Sopenharmony_ci	 * Catch overflow due to message fully sent before the check for
74462306a36Sopenharmony_ci	 * RX FIFO availability.
74562306a36Sopenharmony_ci	 */
74662306a36Sopenharmony_ci	if (WARN_ON_ONCE(!(i2c_dev->msg_buf_remaining)))
74762306a36Sopenharmony_ci		return -EINVAL;
74862306a36Sopenharmony_ci
74962306a36Sopenharmony_ci	if (i2c_dev->hw->has_mst_fifo) {
75062306a36Sopenharmony_ci		val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
75162306a36Sopenharmony_ci		rx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_RX, val);
75262306a36Sopenharmony_ci	} else {
75362306a36Sopenharmony_ci		val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
75462306a36Sopenharmony_ci		rx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_RX, val);
75562306a36Sopenharmony_ci	}
75662306a36Sopenharmony_ci
75762306a36Sopenharmony_ci	/* round down to exclude partial word at the end of buffer */
75862306a36Sopenharmony_ci	words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
75962306a36Sopenharmony_ci	if (words_to_transfer > rx_fifo_avail)
76062306a36Sopenharmony_ci		words_to_transfer = rx_fifo_avail;
76162306a36Sopenharmony_ci
76262306a36Sopenharmony_ci	i2c_readsl(i2c_dev, buf, I2C_RX_FIFO, words_to_transfer);
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	buf += words_to_transfer * BYTES_PER_FIFO_WORD;
76562306a36Sopenharmony_ci	buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
76662306a36Sopenharmony_ci	rx_fifo_avail -= words_to_transfer;
76762306a36Sopenharmony_ci
76862306a36Sopenharmony_ci	/*
76962306a36Sopenharmony_ci	 * If there is a partial word at the end of buffer, handle it
77062306a36Sopenharmony_ci	 * manually to prevent overwriting past the end of buffer.
77162306a36Sopenharmony_ci	 */
77262306a36Sopenharmony_ci	if (rx_fifo_avail > 0 && buf_remaining > 0) {
77362306a36Sopenharmony_ci		/*
77462306a36Sopenharmony_ci		 * buf_remaining > 3 check not needed as rx_fifo_avail == 0
77562306a36Sopenharmony_ci		 * when (words_to_transfer was > rx_fifo_avail) earlier
77662306a36Sopenharmony_ci		 * in this function.
77762306a36Sopenharmony_ci		 */
77862306a36Sopenharmony_ci		val = i2c_readl(i2c_dev, I2C_RX_FIFO);
77962306a36Sopenharmony_ci		val = cpu_to_le32(val);
78062306a36Sopenharmony_ci		memcpy(buf, &val, buf_remaining);
78162306a36Sopenharmony_ci		buf_remaining = 0;
78262306a36Sopenharmony_ci		rx_fifo_avail--;
78362306a36Sopenharmony_ci	}
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	/* RX FIFO must be drained, otherwise it's an Overflow case. */
78662306a36Sopenharmony_ci	if (WARN_ON_ONCE(rx_fifo_avail))
78762306a36Sopenharmony_ci		return -EINVAL;
78862306a36Sopenharmony_ci
78962306a36Sopenharmony_ci	i2c_dev->msg_buf_remaining = buf_remaining;
79062306a36Sopenharmony_ci	i2c_dev->msg_buf = buf;
79162306a36Sopenharmony_ci
79262306a36Sopenharmony_ci	return 0;
79362306a36Sopenharmony_ci}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_cistatic int tegra_i2c_fill_tx_fifo(struct tegra_i2c_dev *i2c_dev)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	size_t buf_remaining = i2c_dev->msg_buf_remaining;
79862306a36Sopenharmony_ci	unsigned int words_to_transfer, tx_fifo_avail;
79962306a36Sopenharmony_ci	u8 *buf = i2c_dev->msg_buf;
80062306a36Sopenharmony_ci	u32 val;
80162306a36Sopenharmony_ci
80262306a36Sopenharmony_ci	if (i2c_dev->hw->has_mst_fifo) {
80362306a36Sopenharmony_ci		val = i2c_readl(i2c_dev, I2C_MST_FIFO_STATUS);
80462306a36Sopenharmony_ci		tx_fifo_avail = FIELD_GET(I2C_MST_FIFO_STATUS_TX, val);
80562306a36Sopenharmony_ci	} else {
80662306a36Sopenharmony_ci		val = i2c_readl(i2c_dev, I2C_FIFO_STATUS);
80762306a36Sopenharmony_ci		tx_fifo_avail = FIELD_GET(I2C_FIFO_STATUS_TX, val);
80862306a36Sopenharmony_ci	}
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci	/* round down to exclude partial word at the end of buffer */
81162306a36Sopenharmony_ci	words_to_transfer = buf_remaining / BYTES_PER_FIFO_WORD;
81262306a36Sopenharmony_ci
81362306a36Sopenharmony_ci	/*
81462306a36Sopenharmony_ci	 * This hunk pushes 4 bytes at a time into the TX FIFO.
81562306a36Sopenharmony_ci	 *
81662306a36Sopenharmony_ci	 * It's very common to have < 4 bytes, hence there is no word
81762306a36Sopenharmony_ci	 * to push if we have less than 4 bytes to transfer.
81862306a36Sopenharmony_ci	 */
81962306a36Sopenharmony_ci	if (words_to_transfer) {
82062306a36Sopenharmony_ci		if (words_to_transfer > tx_fifo_avail)
82162306a36Sopenharmony_ci			words_to_transfer = tx_fifo_avail;
82262306a36Sopenharmony_ci
82362306a36Sopenharmony_ci		/*
82462306a36Sopenharmony_ci		 * Update state before writing to FIFO.  Note that this may
82562306a36Sopenharmony_ci		 * cause us to finish writing all bytes (AKA buf_remaining
82662306a36Sopenharmony_ci		 * goes to 0), hence we have a potential for an interrupt
82762306a36Sopenharmony_ci		 * (PACKET_XFER_COMPLETE is not maskable), but GIC interrupt
82862306a36Sopenharmony_ci		 * is disabled at this point.
82962306a36Sopenharmony_ci		 */
83062306a36Sopenharmony_ci		buf_remaining -= words_to_transfer * BYTES_PER_FIFO_WORD;
83162306a36Sopenharmony_ci		tx_fifo_avail -= words_to_transfer;
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ci		i2c_dev->msg_buf_remaining = buf_remaining;
83462306a36Sopenharmony_ci		i2c_dev->msg_buf = buf + words_to_transfer * BYTES_PER_FIFO_WORD;
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci		if (IS_VI(i2c_dev))
83762306a36Sopenharmony_ci			i2c_writesl_vi(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
83862306a36Sopenharmony_ci		else
83962306a36Sopenharmony_ci			i2c_writesl(i2c_dev, buf, I2C_TX_FIFO, words_to_transfer);
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_ci		buf += words_to_transfer * BYTES_PER_FIFO_WORD;
84262306a36Sopenharmony_ci	}
84362306a36Sopenharmony_ci
84462306a36Sopenharmony_ci	/*
84562306a36Sopenharmony_ci	 * If there is a partial word at the end of buffer, handle it manually
84662306a36Sopenharmony_ci	 * to prevent reading past the end of buffer, which could cross a page
84762306a36Sopenharmony_ci	 * boundary and fault.
84862306a36Sopenharmony_ci	 */
84962306a36Sopenharmony_ci	if (tx_fifo_avail > 0 && buf_remaining > 0) {
85062306a36Sopenharmony_ci		/*
85162306a36Sopenharmony_ci		 * buf_remaining > 3 check not needed as tx_fifo_avail == 0
85262306a36Sopenharmony_ci		 * when (words_to_transfer was > tx_fifo_avail) earlier
85362306a36Sopenharmony_ci		 * in this function for non-zero words_to_transfer.
85462306a36Sopenharmony_ci		 */
85562306a36Sopenharmony_ci		memcpy(&val, buf, buf_remaining);
85662306a36Sopenharmony_ci		val = le32_to_cpu(val);
85762306a36Sopenharmony_ci
85862306a36Sopenharmony_ci		i2c_dev->msg_buf_remaining = 0;
85962306a36Sopenharmony_ci		i2c_dev->msg_buf = NULL;
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci		i2c_writel(i2c_dev, val, I2C_TX_FIFO);
86262306a36Sopenharmony_ci	}
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_ci	return 0;
86562306a36Sopenharmony_ci}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_cistatic irqreturn_t tegra_i2c_isr(int irq, void *dev_id)
86862306a36Sopenharmony_ci{
86962306a36Sopenharmony_ci	const u32 status_err = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
87062306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = dev_id;
87162306a36Sopenharmony_ci	u32 status;
87262306a36Sopenharmony_ci
87362306a36Sopenharmony_ci	status = i2c_readl(i2c_dev, I2C_INT_STATUS);
87462306a36Sopenharmony_ci
87562306a36Sopenharmony_ci	if (status == 0) {
87662306a36Sopenharmony_ci		dev_warn(i2c_dev->dev, "IRQ status 0 %08x %08x %08x\n",
87762306a36Sopenharmony_ci			 i2c_readl(i2c_dev, I2C_PACKET_TRANSFER_STATUS),
87862306a36Sopenharmony_ci			 i2c_readl(i2c_dev, I2C_STATUS),
87962306a36Sopenharmony_ci			 i2c_readl(i2c_dev, I2C_CNFG));
88062306a36Sopenharmony_ci		i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
88162306a36Sopenharmony_ci		goto err;
88262306a36Sopenharmony_ci	}
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci	if (status & status_err) {
88562306a36Sopenharmony_ci		tegra_i2c_disable_packet_mode(i2c_dev);
88662306a36Sopenharmony_ci		if (status & I2C_INT_NO_ACK)
88762306a36Sopenharmony_ci			i2c_dev->msg_err |= I2C_ERR_NO_ACK;
88862306a36Sopenharmony_ci		if (status & I2C_INT_ARBITRATION_LOST)
88962306a36Sopenharmony_ci			i2c_dev->msg_err |= I2C_ERR_ARBITRATION_LOST;
89062306a36Sopenharmony_ci		goto err;
89162306a36Sopenharmony_ci	}
89262306a36Sopenharmony_ci
89362306a36Sopenharmony_ci	/*
89462306a36Sopenharmony_ci	 * I2C transfer is terminated during the bus clear, so skip
89562306a36Sopenharmony_ci	 * processing the other interrupts.
89662306a36Sopenharmony_ci	 */
89762306a36Sopenharmony_ci	if (i2c_dev->hw->supports_bus_clear && (status & I2C_INT_BUS_CLR_DONE))
89862306a36Sopenharmony_ci		goto err;
89962306a36Sopenharmony_ci
90062306a36Sopenharmony_ci	if (!i2c_dev->dma_mode) {
90162306a36Sopenharmony_ci		if (i2c_dev->msg_read && (status & I2C_INT_RX_FIFO_DATA_REQ)) {
90262306a36Sopenharmony_ci			if (tegra_i2c_empty_rx_fifo(i2c_dev)) {
90362306a36Sopenharmony_ci				/*
90462306a36Sopenharmony_ci				 * Overflow error condition: message fully sent,
90562306a36Sopenharmony_ci				 * with no XFER_COMPLETE interrupt but hardware
90662306a36Sopenharmony_ci				 * asks to transfer more.
90762306a36Sopenharmony_ci				 */
90862306a36Sopenharmony_ci				i2c_dev->msg_err |= I2C_ERR_RX_BUFFER_OVERFLOW;
90962306a36Sopenharmony_ci				goto err;
91062306a36Sopenharmony_ci			}
91162306a36Sopenharmony_ci		}
91262306a36Sopenharmony_ci
91362306a36Sopenharmony_ci		if (!i2c_dev->msg_read && (status & I2C_INT_TX_FIFO_DATA_REQ)) {
91462306a36Sopenharmony_ci			if (i2c_dev->msg_buf_remaining)
91562306a36Sopenharmony_ci				tegra_i2c_fill_tx_fifo(i2c_dev);
91662306a36Sopenharmony_ci			else
91762306a36Sopenharmony_ci				tegra_i2c_mask_irq(i2c_dev,
91862306a36Sopenharmony_ci						   I2C_INT_TX_FIFO_DATA_REQ);
91962306a36Sopenharmony_ci		}
92062306a36Sopenharmony_ci	}
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci	i2c_writel(i2c_dev, status, I2C_INT_STATUS);
92362306a36Sopenharmony_ci	if (IS_DVC(i2c_dev))
92462306a36Sopenharmony_ci		dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci	/*
92762306a36Sopenharmony_ci	 * During message read XFER_COMPLETE interrupt is triggered prior to
92862306a36Sopenharmony_ci	 * DMA completion and during message write XFER_COMPLETE interrupt is
92962306a36Sopenharmony_ci	 * triggered after DMA completion.
93062306a36Sopenharmony_ci	 *
93162306a36Sopenharmony_ci	 * PACKETS_XFER_COMPLETE indicates completion of all bytes of transfer,
93262306a36Sopenharmony_ci	 * so forcing msg_buf_remaining to 0 in DMA mode.
93362306a36Sopenharmony_ci	 */
93462306a36Sopenharmony_ci	if (status & I2C_INT_PACKET_XFER_COMPLETE) {
93562306a36Sopenharmony_ci		if (i2c_dev->dma_mode)
93662306a36Sopenharmony_ci			i2c_dev->msg_buf_remaining = 0;
93762306a36Sopenharmony_ci		/*
93862306a36Sopenharmony_ci		 * Underflow error condition: XFER_COMPLETE before message
93962306a36Sopenharmony_ci		 * fully sent.
94062306a36Sopenharmony_ci		 */
94162306a36Sopenharmony_ci		if (WARN_ON_ONCE(i2c_dev->msg_buf_remaining)) {
94262306a36Sopenharmony_ci			i2c_dev->msg_err |= I2C_ERR_UNKNOWN_INTERRUPT;
94362306a36Sopenharmony_ci			goto err;
94462306a36Sopenharmony_ci		}
94562306a36Sopenharmony_ci		complete(&i2c_dev->msg_complete);
94662306a36Sopenharmony_ci	}
94762306a36Sopenharmony_ci	goto done;
94862306a36Sopenharmony_cierr:
94962306a36Sopenharmony_ci	/* mask all interrupts on error */
95062306a36Sopenharmony_ci	tegra_i2c_mask_irq(i2c_dev,
95162306a36Sopenharmony_ci			   I2C_INT_NO_ACK |
95262306a36Sopenharmony_ci			   I2C_INT_ARBITRATION_LOST |
95362306a36Sopenharmony_ci			   I2C_INT_PACKET_XFER_COMPLETE |
95462306a36Sopenharmony_ci			   I2C_INT_TX_FIFO_DATA_REQ |
95562306a36Sopenharmony_ci			   I2C_INT_RX_FIFO_DATA_REQ);
95662306a36Sopenharmony_ci
95762306a36Sopenharmony_ci	if (i2c_dev->hw->supports_bus_clear)
95862306a36Sopenharmony_ci		tegra_i2c_mask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
95962306a36Sopenharmony_ci
96062306a36Sopenharmony_ci	i2c_writel(i2c_dev, status, I2C_INT_STATUS);
96162306a36Sopenharmony_ci
96262306a36Sopenharmony_ci	if (IS_DVC(i2c_dev))
96362306a36Sopenharmony_ci		dvc_writel(i2c_dev, DVC_STATUS_I2C_DONE_INTR, DVC_STATUS);
96462306a36Sopenharmony_ci
96562306a36Sopenharmony_ci	if (i2c_dev->dma_mode) {
96662306a36Sopenharmony_ci		dmaengine_terminate_async(i2c_dev->dma_chan);
96762306a36Sopenharmony_ci		complete(&i2c_dev->dma_complete);
96862306a36Sopenharmony_ci	}
96962306a36Sopenharmony_ci
97062306a36Sopenharmony_ci	complete(&i2c_dev->msg_complete);
97162306a36Sopenharmony_cidone:
97262306a36Sopenharmony_ci	return IRQ_HANDLED;
97362306a36Sopenharmony_ci}
97462306a36Sopenharmony_ci
97562306a36Sopenharmony_cistatic void tegra_i2c_config_fifo_trig(struct tegra_i2c_dev *i2c_dev,
97662306a36Sopenharmony_ci				       size_t len)
97762306a36Sopenharmony_ci{
97862306a36Sopenharmony_ci	struct dma_slave_config slv_config = {0};
97962306a36Sopenharmony_ci	u32 val, reg, dma_burst, reg_offset;
98062306a36Sopenharmony_ci	int err;
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ci	if (i2c_dev->hw->has_mst_fifo)
98362306a36Sopenharmony_ci		reg = I2C_MST_FIFO_CONTROL;
98462306a36Sopenharmony_ci	else
98562306a36Sopenharmony_ci		reg = I2C_FIFO_CONTROL;
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_ci	if (i2c_dev->dma_mode) {
98862306a36Sopenharmony_ci		if (len & 0xF)
98962306a36Sopenharmony_ci			dma_burst = 1;
99062306a36Sopenharmony_ci		else if (len & 0x10)
99162306a36Sopenharmony_ci			dma_burst = 4;
99262306a36Sopenharmony_ci		else
99362306a36Sopenharmony_ci			dma_burst = 8;
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_ci		if (i2c_dev->msg_read) {
99662306a36Sopenharmony_ci			reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_RX_FIFO);
99762306a36Sopenharmony_ci
99862306a36Sopenharmony_ci			slv_config.src_addr = i2c_dev->base_phys + reg_offset;
99962306a36Sopenharmony_ci			slv_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
100062306a36Sopenharmony_ci			slv_config.src_maxburst = dma_burst;
100162306a36Sopenharmony_ci
100262306a36Sopenharmony_ci			if (i2c_dev->hw->has_mst_fifo)
100362306a36Sopenharmony_ci				val = I2C_MST_FIFO_CONTROL_RX_TRIG(dma_burst);
100462306a36Sopenharmony_ci			else
100562306a36Sopenharmony_ci				val = I2C_FIFO_CONTROL_RX_TRIG(dma_burst);
100662306a36Sopenharmony_ci		} else {
100762306a36Sopenharmony_ci			reg_offset = tegra_i2c_reg_addr(i2c_dev, I2C_TX_FIFO);
100862306a36Sopenharmony_ci
100962306a36Sopenharmony_ci			slv_config.dst_addr = i2c_dev->base_phys + reg_offset;
101062306a36Sopenharmony_ci			slv_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
101162306a36Sopenharmony_ci			slv_config.dst_maxburst = dma_burst;
101262306a36Sopenharmony_ci
101362306a36Sopenharmony_ci			if (i2c_dev->hw->has_mst_fifo)
101462306a36Sopenharmony_ci				val = I2C_MST_FIFO_CONTROL_TX_TRIG(dma_burst);
101562306a36Sopenharmony_ci			else
101662306a36Sopenharmony_ci				val = I2C_FIFO_CONTROL_TX_TRIG(dma_burst);
101762306a36Sopenharmony_ci		}
101862306a36Sopenharmony_ci
101962306a36Sopenharmony_ci		slv_config.device_fc = true;
102062306a36Sopenharmony_ci		err = dmaengine_slave_config(i2c_dev->dma_chan, &slv_config);
102162306a36Sopenharmony_ci		if (err) {
102262306a36Sopenharmony_ci			dev_err(i2c_dev->dev, "DMA config failed: %d\n", err);
102362306a36Sopenharmony_ci			dev_err(i2c_dev->dev, "falling back to PIO\n");
102462306a36Sopenharmony_ci
102562306a36Sopenharmony_ci			tegra_i2c_release_dma(i2c_dev);
102662306a36Sopenharmony_ci			i2c_dev->dma_mode = false;
102762306a36Sopenharmony_ci		} else {
102862306a36Sopenharmony_ci			goto out;
102962306a36Sopenharmony_ci		}
103062306a36Sopenharmony_ci	}
103162306a36Sopenharmony_ci
103262306a36Sopenharmony_ci	if (i2c_dev->hw->has_mst_fifo)
103362306a36Sopenharmony_ci		val = I2C_MST_FIFO_CONTROL_TX_TRIG(8) |
103462306a36Sopenharmony_ci		      I2C_MST_FIFO_CONTROL_RX_TRIG(1);
103562306a36Sopenharmony_ci	else
103662306a36Sopenharmony_ci		val = I2C_FIFO_CONTROL_TX_TRIG(8) |
103762306a36Sopenharmony_ci		      I2C_FIFO_CONTROL_RX_TRIG(1);
103862306a36Sopenharmony_ciout:
103962306a36Sopenharmony_ci	i2c_writel(i2c_dev, val, reg);
104062306a36Sopenharmony_ci}
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_cistatic unsigned long tegra_i2c_poll_completion(struct tegra_i2c_dev *i2c_dev,
104362306a36Sopenharmony_ci					       struct completion *complete,
104462306a36Sopenharmony_ci					       unsigned int timeout_ms)
104562306a36Sopenharmony_ci{
104662306a36Sopenharmony_ci	ktime_t ktime = ktime_get();
104762306a36Sopenharmony_ci	ktime_t ktimeout = ktime_add_ms(ktime, timeout_ms);
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci	do {
105062306a36Sopenharmony_ci		u32 status = i2c_readl(i2c_dev, I2C_INT_STATUS);
105162306a36Sopenharmony_ci
105262306a36Sopenharmony_ci		if (status)
105362306a36Sopenharmony_ci			tegra_i2c_isr(i2c_dev->irq, i2c_dev);
105462306a36Sopenharmony_ci
105562306a36Sopenharmony_ci		if (completion_done(complete)) {
105662306a36Sopenharmony_ci			s64 delta = ktime_ms_delta(ktimeout, ktime);
105762306a36Sopenharmony_ci
105862306a36Sopenharmony_ci			return msecs_to_jiffies(delta) ?: 1;
105962306a36Sopenharmony_ci		}
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci		ktime = ktime_get();
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci	} while (ktime_before(ktime, ktimeout));
106462306a36Sopenharmony_ci
106562306a36Sopenharmony_ci	return 0;
106662306a36Sopenharmony_ci}
106762306a36Sopenharmony_ci
106862306a36Sopenharmony_cistatic unsigned long tegra_i2c_wait_completion(struct tegra_i2c_dev *i2c_dev,
106962306a36Sopenharmony_ci					       struct completion *complete,
107062306a36Sopenharmony_ci					       unsigned int timeout_ms)
107162306a36Sopenharmony_ci{
107262306a36Sopenharmony_ci	unsigned long ret;
107362306a36Sopenharmony_ci
107462306a36Sopenharmony_ci	if (i2c_dev->atomic_mode) {
107562306a36Sopenharmony_ci		ret = tegra_i2c_poll_completion(i2c_dev, complete, timeout_ms);
107662306a36Sopenharmony_ci	} else {
107762306a36Sopenharmony_ci		enable_irq(i2c_dev->irq);
107862306a36Sopenharmony_ci		ret = wait_for_completion_timeout(complete,
107962306a36Sopenharmony_ci						  msecs_to_jiffies(timeout_ms));
108062306a36Sopenharmony_ci		disable_irq(i2c_dev->irq);
108162306a36Sopenharmony_ci
108262306a36Sopenharmony_ci		/*
108362306a36Sopenharmony_ci		 * Under some rare circumstances (like running KASAN +
108462306a36Sopenharmony_ci		 * NFS root) CPU, which handles interrupt, may stuck in
108562306a36Sopenharmony_ci		 * uninterruptible state for a significant time.  In this
108662306a36Sopenharmony_ci		 * case we will get timeout if I2C transfer is running on
108762306a36Sopenharmony_ci		 * a sibling CPU, despite of IRQ being raised.
108862306a36Sopenharmony_ci		 *
108962306a36Sopenharmony_ci		 * In order to handle this rare condition, the IRQ status
109062306a36Sopenharmony_ci		 * needs to be checked after timeout.
109162306a36Sopenharmony_ci		 */
109262306a36Sopenharmony_ci		if (ret == 0)
109362306a36Sopenharmony_ci			ret = tegra_i2c_poll_completion(i2c_dev, complete, 0);
109462306a36Sopenharmony_ci	}
109562306a36Sopenharmony_ci
109662306a36Sopenharmony_ci	return ret;
109762306a36Sopenharmony_ci}
109862306a36Sopenharmony_ci
109962306a36Sopenharmony_cistatic int tegra_i2c_issue_bus_clear(struct i2c_adapter *adap)
110062306a36Sopenharmony_ci{
110162306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
110262306a36Sopenharmony_ci	u32 val, time_left;
110362306a36Sopenharmony_ci	int err;
110462306a36Sopenharmony_ci
110562306a36Sopenharmony_ci	reinit_completion(&i2c_dev->msg_complete);
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_ci	val = FIELD_PREP(I2C_BC_SCLK_THRESHOLD, 9) | I2C_BC_STOP_COND |
110862306a36Sopenharmony_ci	      I2C_BC_TERMINATE;
110962306a36Sopenharmony_ci	i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG);
111062306a36Sopenharmony_ci
111162306a36Sopenharmony_ci	err = tegra_i2c_wait_for_config_load(i2c_dev);
111262306a36Sopenharmony_ci	if (err)
111362306a36Sopenharmony_ci		return err;
111462306a36Sopenharmony_ci
111562306a36Sopenharmony_ci	val |= I2C_BC_ENABLE;
111662306a36Sopenharmony_ci	i2c_writel(i2c_dev, val, I2C_BUS_CLEAR_CNFG);
111762306a36Sopenharmony_ci	tegra_i2c_unmask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
111862306a36Sopenharmony_ci
111962306a36Sopenharmony_ci	time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete, 50);
112062306a36Sopenharmony_ci	tegra_i2c_mask_irq(i2c_dev, I2C_INT_BUS_CLR_DONE);
112162306a36Sopenharmony_ci
112262306a36Sopenharmony_ci	if (time_left == 0) {
112362306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "failed to clear bus\n");
112462306a36Sopenharmony_ci		return -ETIMEDOUT;
112562306a36Sopenharmony_ci	}
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ci	val = i2c_readl(i2c_dev, I2C_BUS_CLEAR_STATUS);
112862306a36Sopenharmony_ci	if (!(val & I2C_BC_STATUS)) {
112962306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "un-recovered arbitration lost\n");
113062306a36Sopenharmony_ci		return -EIO;
113162306a36Sopenharmony_ci	}
113262306a36Sopenharmony_ci
113362306a36Sopenharmony_ci	return -EAGAIN;
113462306a36Sopenharmony_ci}
113562306a36Sopenharmony_ci
113662306a36Sopenharmony_cistatic void tegra_i2c_push_packet_header(struct tegra_i2c_dev *i2c_dev,
113762306a36Sopenharmony_ci					 struct i2c_msg *msg,
113862306a36Sopenharmony_ci					 enum msg_end_type end_state)
113962306a36Sopenharmony_ci{
114062306a36Sopenharmony_ci	u32 *dma_buf = i2c_dev->dma_buf;
114162306a36Sopenharmony_ci	u32 packet_header;
114262306a36Sopenharmony_ci
114362306a36Sopenharmony_ci	packet_header = FIELD_PREP(PACKET_HEADER0_HEADER_SIZE, 0) |
114462306a36Sopenharmony_ci			FIELD_PREP(PACKET_HEADER0_PROTOCOL,
114562306a36Sopenharmony_ci				   PACKET_HEADER0_PROTOCOL_I2C) |
114662306a36Sopenharmony_ci			FIELD_PREP(PACKET_HEADER0_CONT_ID, i2c_dev->cont_id) |
114762306a36Sopenharmony_ci			FIELD_PREP(PACKET_HEADER0_PACKET_ID, 1);
114862306a36Sopenharmony_ci
114962306a36Sopenharmony_ci	if (i2c_dev->dma_mode && !i2c_dev->msg_read)
115062306a36Sopenharmony_ci		*dma_buf++ = packet_header;
115162306a36Sopenharmony_ci	else
115262306a36Sopenharmony_ci		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci	packet_header = i2c_dev->msg_len - 1;
115562306a36Sopenharmony_ci
115662306a36Sopenharmony_ci	if (i2c_dev->dma_mode && !i2c_dev->msg_read)
115762306a36Sopenharmony_ci		*dma_buf++ = packet_header;
115862306a36Sopenharmony_ci	else
115962306a36Sopenharmony_ci		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
116062306a36Sopenharmony_ci
116162306a36Sopenharmony_ci	packet_header = I2C_HEADER_IE_ENABLE;
116262306a36Sopenharmony_ci
116362306a36Sopenharmony_ci	if (end_state == MSG_END_CONTINUE)
116462306a36Sopenharmony_ci		packet_header |= I2C_HEADER_CONTINUE_XFER;
116562306a36Sopenharmony_ci	else if (end_state == MSG_END_REPEAT_START)
116662306a36Sopenharmony_ci		packet_header |= I2C_HEADER_REPEAT_START;
116762306a36Sopenharmony_ci
116862306a36Sopenharmony_ci	if (msg->flags & I2C_M_TEN) {
116962306a36Sopenharmony_ci		packet_header |= msg->addr;
117062306a36Sopenharmony_ci		packet_header |= I2C_HEADER_10BIT_ADDR;
117162306a36Sopenharmony_ci	} else {
117262306a36Sopenharmony_ci		packet_header |= msg->addr << I2C_HEADER_SLAVE_ADDR_SHIFT;
117362306a36Sopenharmony_ci	}
117462306a36Sopenharmony_ci
117562306a36Sopenharmony_ci	if (msg->flags & I2C_M_IGNORE_NAK)
117662306a36Sopenharmony_ci		packet_header |= I2C_HEADER_CONT_ON_NAK;
117762306a36Sopenharmony_ci
117862306a36Sopenharmony_ci	if (msg->flags & I2C_M_RD)
117962306a36Sopenharmony_ci		packet_header |= I2C_HEADER_READ;
118062306a36Sopenharmony_ci
118162306a36Sopenharmony_ci	if (i2c_dev->dma_mode && !i2c_dev->msg_read)
118262306a36Sopenharmony_ci		*dma_buf++ = packet_header;
118362306a36Sopenharmony_ci	else
118462306a36Sopenharmony_ci		i2c_writel(i2c_dev, packet_header, I2C_TX_FIFO);
118562306a36Sopenharmony_ci}
118662306a36Sopenharmony_ci
118762306a36Sopenharmony_cistatic int tegra_i2c_error_recover(struct tegra_i2c_dev *i2c_dev,
118862306a36Sopenharmony_ci				   struct i2c_msg *msg)
118962306a36Sopenharmony_ci{
119062306a36Sopenharmony_ci	if (i2c_dev->msg_err == I2C_ERR_NONE)
119162306a36Sopenharmony_ci		return 0;
119262306a36Sopenharmony_ci
119362306a36Sopenharmony_ci	tegra_i2c_init(i2c_dev);
119462306a36Sopenharmony_ci
119562306a36Sopenharmony_ci	/* start recovery upon arbitration loss in single master mode */
119662306a36Sopenharmony_ci	if (i2c_dev->msg_err == I2C_ERR_ARBITRATION_LOST) {
119762306a36Sopenharmony_ci		if (!i2c_dev->multimaster_mode)
119862306a36Sopenharmony_ci			return i2c_recover_bus(&i2c_dev->adapter);
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ci		return -EAGAIN;
120162306a36Sopenharmony_ci	}
120262306a36Sopenharmony_ci
120362306a36Sopenharmony_ci	if (i2c_dev->msg_err == I2C_ERR_NO_ACK) {
120462306a36Sopenharmony_ci		if (msg->flags & I2C_M_IGNORE_NAK)
120562306a36Sopenharmony_ci			return 0;
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci		return -EREMOTEIO;
120862306a36Sopenharmony_ci	}
120962306a36Sopenharmony_ci
121062306a36Sopenharmony_ci	return -EIO;
121162306a36Sopenharmony_ci}
121262306a36Sopenharmony_ci
121362306a36Sopenharmony_cistatic int tegra_i2c_xfer_msg(struct tegra_i2c_dev *i2c_dev,
121462306a36Sopenharmony_ci			      struct i2c_msg *msg,
121562306a36Sopenharmony_ci			      enum msg_end_type end_state)
121662306a36Sopenharmony_ci{
121762306a36Sopenharmony_ci	unsigned long time_left, xfer_time = 100;
121862306a36Sopenharmony_ci	size_t xfer_size;
121962306a36Sopenharmony_ci	u32 int_mask;
122062306a36Sopenharmony_ci	int err;
122162306a36Sopenharmony_ci
122262306a36Sopenharmony_ci	err = tegra_i2c_flush_fifos(i2c_dev);
122362306a36Sopenharmony_ci	if (err)
122462306a36Sopenharmony_ci		return err;
122562306a36Sopenharmony_ci
122662306a36Sopenharmony_ci	i2c_dev->msg_buf = msg->buf;
122762306a36Sopenharmony_ci	i2c_dev->msg_len = msg->len;
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	i2c_dev->msg_err = I2C_ERR_NONE;
123062306a36Sopenharmony_ci	i2c_dev->msg_read = !!(msg->flags & I2C_M_RD);
123162306a36Sopenharmony_ci	reinit_completion(&i2c_dev->msg_complete);
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_ci	/*
123462306a36Sopenharmony_ci	 * For SMBUS block read command, read only 1 byte in the first transfer.
123562306a36Sopenharmony_ci	 * Adjust that 1 byte for the next transfer in the msg buffer and msg
123662306a36Sopenharmony_ci	 * length.
123762306a36Sopenharmony_ci	 */
123862306a36Sopenharmony_ci	if (msg->flags & I2C_M_RECV_LEN) {
123962306a36Sopenharmony_ci		if (end_state == MSG_END_CONTINUE) {
124062306a36Sopenharmony_ci			i2c_dev->msg_len = 1;
124162306a36Sopenharmony_ci		} else {
124262306a36Sopenharmony_ci			i2c_dev->msg_buf += 1;
124362306a36Sopenharmony_ci			i2c_dev->msg_len -= 1;
124462306a36Sopenharmony_ci		}
124562306a36Sopenharmony_ci	}
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci	i2c_dev->msg_buf_remaining = i2c_dev->msg_len;
124862306a36Sopenharmony_ci
124962306a36Sopenharmony_ci	if (i2c_dev->msg_read)
125062306a36Sopenharmony_ci		xfer_size = i2c_dev->msg_len;
125162306a36Sopenharmony_ci	else
125262306a36Sopenharmony_ci		xfer_size = i2c_dev->msg_len + I2C_PACKET_HEADER_SIZE;
125362306a36Sopenharmony_ci
125462306a36Sopenharmony_ci	xfer_size = ALIGN(xfer_size, BYTES_PER_FIFO_WORD);
125562306a36Sopenharmony_ci
125662306a36Sopenharmony_ci	i2c_dev->dma_mode = xfer_size > I2C_PIO_MODE_PREFERRED_LEN &&
125762306a36Sopenharmony_ci			    i2c_dev->dma_buf && !i2c_dev->atomic_mode;
125862306a36Sopenharmony_ci
125962306a36Sopenharmony_ci	tegra_i2c_config_fifo_trig(i2c_dev, xfer_size);
126062306a36Sopenharmony_ci
126162306a36Sopenharmony_ci	/*
126262306a36Sopenharmony_ci	 * Transfer time in mSec = Total bits / transfer rate
126362306a36Sopenharmony_ci	 * Total bits = 9 bits per byte (including ACK bit) + Start & stop bits
126462306a36Sopenharmony_ci	 */
126562306a36Sopenharmony_ci	xfer_time += DIV_ROUND_CLOSEST(((xfer_size * 9) + 2) * MSEC_PER_SEC,
126662306a36Sopenharmony_ci				       i2c_dev->timings.bus_freq_hz);
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci	int_mask = I2C_INT_NO_ACK | I2C_INT_ARBITRATION_LOST;
126962306a36Sopenharmony_ci	tegra_i2c_unmask_irq(i2c_dev, int_mask);
127062306a36Sopenharmony_ci
127162306a36Sopenharmony_ci	if (i2c_dev->dma_mode) {
127262306a36Sopenharmony_ci		if (i2c_dev->msg_read) {
127362306a36Sopenharmony_ci			dma_sync_single_for_device(i2c_dev->dma_dev,
127462306a36Sopenharmony_ci						   i2c_dev->dma_phys,
127562306a36Sopenharmony_ci						   xfer_size, DMA_FROM_DEVICE);
127662306a36Sopenharmony_ci
127762306a36Sopenharmony_ci			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
127862306a36Sopenharmony_ci			if (err)
127962306a36Sopenharmony_ci				return err;
128062306a36Sopenharmony_ci		} else {
128162306a36Sopenharmony_ci			dma_sync_single_for_cpu(i2c_dev->dma_dev,
128262306a36Sopenharmony_ci						i2c_dev->dma_phys,
128362306a36Sopenharmony_ci						xfer_size, DMA_TO_DEVICE);
128462306a36Sopenharmony_ci		}
128562306a36Sopenharmony_ci	}
128662306a36Sopenharmony_ci
128762306a36Sopenharmony_ci	tegra_i2c_push_packet_header(i2c_dev, msg, end_state);
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci	if (!i2c_dev->msg_read) {
129062306a36Sopenharmony_ci		if (i2c_dev->dma_mode) {
129162306a36Sopenharmony_ci			memcpy(i2c_dev->dma_buf + I2C_PACKET_HEADER_SIZE,
129262306a36Sopenharmony_ci			       msg->buf, i2c_dev->msg_len);
129362306a36Sopenharmony_ci
129462306a36Sopenharmony_ci			dma_sync_single_for_device(i2c_dev->dma_dev,
129562306a36Sopenharmony_ci						   i2c_dev->dma_phys,
129662306a36Sopenharmony_ci						   xfer_size, DMA_TO_DEVICE);
129762306a36Sopenharmony_ci
129862306a36Sopenharmony_ci			err = tegra_i2c_dma_submit(i2c_dev, xfer_size);
129962306a36Sopenharmony_ci			if (err)
130062306a36Sopenharmony_ci				return err;
130162306a36Sopenharmony_ci		} else {
130262306a36Sopenharmony_ci			tegra_i2c_fill_tx_fifo(i2c_dev);
130362306a36Sopenharmony_ci		}
130462306a36Sopenharmony_ci	}
130562306a36Sopenharmony_ci
130662306a36Sopenharmony_ci	if (i2c_dev->hw->has_per_pkt_xfer_complete_irq)
130762306a36Sopenharmony_ci		int_mask |= I2C_INT_PACKET_XFER_COMPLETE;
130862306a36Sopenharmony_ci
130962306a36Sopenharmony_ci	if (!i2c_dev->dma_mode) {
131062306a36Sopenharmony_ci		if (msg->flags & I2C_M_RD)
131162306a36Sopenharmony_ci			int_mask |= I2C_INT_RX_FIFO_DATA_REQ;
131262306a36Sopenharmony_ci		else if (i2c_dev->msg_buf_remaining)
131362306a36Sopenharmony_ci			int_mask |= I2C_INT_TX_FIFO_DATA_REQ;
131462306a36Sopenharmony_ci	}
131562306a36Sopenharmony_ci
131662306a36Sopenharmony_ci	tegra_i2c_unmask_irq(i2c_dev, int_mask);
131762306a36Sopenharmony_ci	dev_dbg(i2c_dev->dev, "unmasked IRQ: %02x\n",
131862306a36Sopenharmony_ci		i2c_readl(i2c_dev, I2C_INT_MASK));
131962306a36Sopenharmony_ci
132062306a36Sopenharmony_ci	if (i2c_dev->dma_mode) {
132162306a36Sopenharmony_ci		time_left = tegra_i2c_wait_completion(i2c_dev,
132262306a36Sopenharmony_ci						      &i2c_dev->dma_complete,
132362306a36Sopenharmony_ci						      xfer_time);
132462306a36Sopenharmony_ci
132562306a36Sopenharmony_ci		/*
132662306a36Sopenharmony_ci		 * Synchronize DMA first, since dmaengine_terminate_sync()
132762306a36Sopenharmony_ci		 * performs synchronization after the transfer's termination
132862306a36Sopenharmony_ci		 * and we want to get a completion if transfer succeeded.
132962306a36Sopenharmony_ci		 */
133062306a36Sopenharmony_ci		dmaengine_synchronize(i2c_dev->dma_chan);
133162306a36Sopenharmony_ci		dmaengine_terminate_sync(i2c_dev->dma_chan);
133262306a36Sopenharmony_ci
133362306a36Sopenharmony_ci		if (!time_left && !completion_done(&i2c_dev->dma_complete)) {
133462306a36Sopenharmony_ci			dev_err(i2c_dev->dev, "DMA transfer timed out\n");
133562306a36Sopenharmony_ci			tegra_i2c_init(i2c_dev);
133662306a36Sopenharmony_ci			return -ETIMEDOUT;
133762306a36Sopenharmony_ci		}
133862306a36Sopenharmony_ci
133962306a36Sopenharmony_ci		if (i2c_dev->msg_read && i2c_dev->msg_err == I2C_ERR_NONE) {
134062306a36Sopenharmony_ci			dma_sync_single_for_cpu(i2c_dev->dma_dev,
134162306a36Sopenharmony_ci						i2c_dev->dma_phys,
134262306a36Sopenharmony_ci						xfer_size, DMA_FROM_DEVICE);
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci			memcpy(i2c_dev->msg_buf, i2c_dev->dma_buf, i2c_dev->msg_len);
134562306a36Sopenharmony_ci		}
134662306a36Sopenharmony_ci	}
134762306a36Sopenharmony_ci
134862306a36Sopenharmony_ci	time_left = tegra_i2c_wait_completion(i2c_dev, &i2c_dev->msg_complete,
134962306a36Sopenharmony_ci					      xfer_time);
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	tegra_i2c_mask_irq(i2c_dev, int_mask);
135262306a36Sopenharmony_ci
135362306a36Sopenharmony_ci	if (time_left == 0) {
135462306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "I2C transfer timed out\n");
135562306a36Sopenharmony_ci		tegra_i2c_init(i2c_dev);
135662306a36Sopenharmony_ci		return -ETIMEDOUT;
135762306a36Sopenharmony_ci	}
135862306a36Sopenharmony_ci
135962306a36Sopenharmony_ci	dev_dbg(i2c_dev->dev, "transfer complete: %lu %d %d\n",
136062306a36Sopenharmony_ci		time_left, completion_done(&i2c_dev->msg_complete),
136162306a36Sopenharmony_ci		i2c_dev->msg_err);
136262306a36Sopenharmony_ci
136362306a36Sopenharmony_ci	i2c_dev->dma_mode = false;
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	err = tegra_i2c_error_recover(i2c_dev, msg);
136662306a36Sopenharmony_ci	if (err)
136762306a36Sopenharmony_ci		return err;
136862306a36Sopenharmony_ci
136962306a36Sopenharmony_ci	return 0;
137062306a36Sopenharmony_ci}
137162306a36Sopenharmony_ci
137262306a36Sopenharmony_cistatic int tegra_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[],
137362306a36Sopenharmony_ci			  int num)
137462306a36Sopenharmony_ci{
137562306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
137662306a36Sopenharmony_ci	int i, ret;
137762306a36Sopenharmony_ci
137862306a36Sopenharmony_ci	ret = pm_runtime_get_sync(i2c_dev->dev);
137962306a36Sopenharmony_ci	if (ret < 0) {
138062306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "runtime resume failed %d\n", ret);
138162306a36Sopenharmony_ci		pm_runtime_put_noidle(i2c_dev->dev);
138262306a36Sopenharmony_ci		return ret;
138362306a36Sopenharmony_ci	}
138462306a36Sopenharmony_ci
138562306a36Sopenharmony_ci	for (i = 0; i < num; i++) {
138662306a36Sopenharmony_ci		enum msg_end_type end_type = MSG_END_STOP;
138762306a36Sopenharmony_ci
138862306a36Sopenharmony_ci		if (i < (num - 1)) {
138962306a36Sopenharmony_ci			/* check whether follow up message is coming */
139062306a36Sopenharmony_ci			if (msgs[i + 1].flags & I2C_M_NOSTART)
139162306a36Sopenharmony_ci				end_type = MSG_END_CONTINUE;
139262306a36Sopenharmony_ci			else
139362306a36Sopenharmony_ci				end_type = MSG_END_REPEAT_START;
139462306a36Sopenharmony_ci		}
139562306a36Sopenharmony_ci		/* If M_RECV_LEN use ContinueXfer to read the first byte */
139662306a36Sopenharmony_ci		if (msgs[i].flags & I2C_M_RECV_LEN) {
139762306a36Sopenharmony_ci			ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], MSG_END_CONTINUE);
139862306a36Sopenharmony_ci			if (ret)
139962306a36Sopenharmony_ci				break;
140062306a36Sopenharmony_ci			/* Set the msg length from first byte */
140162306a36Sopenharmony_ci			msgs[i].len += msgs[i].buf[0];
140262306a36Sopenharmony_ci			dev_dbg(i2c_dev->dev, "reading %d bytes\n", msgs[i].len);
140362306a36Sopenharmony_ci		}
140462306a36Sopenharmony_ci		ret = tegra_i2c_xfer_msg(i2c_dev, &msgs[i], end_type);
140562306a36Sopenharmony_ci		if (ret)
140662306a36Sopenharmony_ci			break;
140762306a36Sopenharmony_ci	}
140862306a36Sopenharmony_ci
140962306a36Sopenharmony_ci	pm_runtime_put(i2c_dev->dev);
141062306a36Sopenharmony_ci
141162306a36Sopenharmony_ci	return ret ?: i;
141262306a36Sopenharmony_ci}
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_cistatic int tegra_i2c_xfer_atomic(struct i2c_adapter *adap,
141562306a36Sopenharmony_ci				 struct i2c_msg msgs[], int num)
141662306a36Sopenharmony_ci{
141762306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
141862306a36Sopenharmony_ci	int ret;
141962306a36Sopenharmony_ci
142062306a36Sopenharmony_ci	i2c_dev->atomic_mode = true;
142162306a36Sopenharmony_ci	ret = tegra_i2c_xfer(adap, msgs, num);
142262306a36Sopenharmony_ci	i2c_dev->atomic_mode = false;
142362306a36Sopenharmony_ci
142462306a36Sopenharmony_ci	return ret;
142562306a36Sopenharmony_ci}
142662306a36Sopenharmony_ci
142762306a36Sopenharmony_cistatic u32 tegra_i2c_func(struct i2c_adapter *adap)
142862306a36Sopenharmony_ci{
142962306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = i2c_get_adapdata(adap);
143062306a36Sopenharmony_ci	u32 ret = I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
143162306a36Sopenharmony_ci		  I2C_FUNC_10BIT_ADDR | I2C_FUNC_PROTOCOL_MANGLING;
143262306a36Sopenharmony_ci
143362306a36Sopenharmony_ci	if (i2c_dev->hw->has_continue_xfer_support)
143462306a36Sopenharmony_ci		ret |= I2C_FUNC_NOSTART | I2C_FUNC_SMBUS_READ_BLOCK_DATA;
143562306a36Sopenharmony_ci
143662306a36Sopenharmony_ci	return ret;
143762306a36Sopenharmony_ci}
143862306a36Sopenharmony_ci
143962306a36Sopenharmony_cistatic const struct i2c_algorithm tegra_i2c_algo = {
144062306a36Sopenharmony_ci	.master_xfer		= tegra_i2c_xfer,
144162306a36Sopenharmony_ci	.master_xfer_atomic	= tegra_i2c_xfer_atomic,
144262306a36Sopenharmony_ci	.functionality		= tegra_i2c_func,
144362306a36Sopenharmony_ci};
144462306a36Sopenharmony_ci
144562306a36Sopenharmony_ci/* payload size is only 12 bit */
144662306a36Sopenharmony_cistatic const struct i2c_adapter_quirks tegra_i2c_quirks = {
144762306a36Sopenharmony_ci	.flags = I2C_AQ_NO_ZERO_LEN,
144862306a36Sopenharmony_ci	.max_read_len = SZ_4K,
144962306a36Sopenharmony_ci	.max_write_len = SZ_4K - I2C_PACKET_HEADER_SIZE,
145062306a36Sopenharmony_ci};
145162306a36Sopenharmony_ci
145262306a36Sopenharmony_cistatic const struct i2c_adapter_quirks tegra194_i2c_quirks = {
145362306a36Sopenharmony_ci	.flags = I2C_AQ_NO_ZERO_LEN,
145462306a36Sopenharmony_ci	.max_write_len = SZ_64K - I2C_PACKET_HEADER_SIZE,
145562306a36Sopenharmony_ci};
145662306a36Sopenharmony_ci
145762306a36Sopenharmony_cistatic struct i2c_bus_recovery_info tegra_i2c_recovery_info = {
145862306a36Sopenharmony_ci	.recover_bus = tegra_i2c_issue_bus_clear,
145962306a36Sopenharmony_ci};
146062306a36Sopenharmony_ci
146162306a36Sopenharmony_cistatic const struct tegra_i2c_hw_feature tegra20_i2c_hw = {
146262306a36Sopenharmony_ci	.has_continue_xfer_support = false,
146362306a36Sopenharmony_ci	.has_per_pkt_xfer_complete_irq = false,
146462306a36Sopenharmony_ci	.clk_divisor_hs_mode = 3,
146562306a36Sopenharmony_ci	.clk_divisor_std_mode = 0,
146662306a36Sopenharmony_ci	.clk_divisor_fast_mode = 0,
146762306a36Sopenharmony_ci	.clk_divisor_fast_plus_mode = 0,
146862306a36Sopenharmony_ci	.has_config_load_reg = false,
146962306a36Sopenharmony_ci	.has_multi_master_mode = false,
147062306a36Sopenharmony_ci	.has_slcg_override_reg = false,
147162306a36Sopenharmony_ci	.has_mst_fifo = false,
147262306a36Sopenharmony_ci	.quirks = &tegra_i2c_quirks,
147362306a36Sopenharmony_ci	.supports_bus_clear = false,
147462306a36Sopenharmony_ci	.has_apb_dma = true,
147562306a36Sopenharmony_ci	.tlow_std_mode = 0x4,
147662306a36Sopenharmony_ci	.thigh_std_mode = 0x2,
147762306a36Sopenharmony_ci	.tlow_fast_fastplus_mode = 0x4,
147862306a36Sopenharmony_ci	.thigh_fast_fastplus_mode = 0x2,
147962306a36Sopenharmony_ci	.setup_hold_time_std_mode = 0x0,
148062306a36Sopenharmony_ci	.setup_hold_time_fast_fast_plus_mode = 0x0,
148162306a36Sopenharmony_ci	.setup_hold_time_hs_mode = 0x0,
148262306a36Sopenharmony_ci	.has_interface_timing_reg = false,
148362306a36Sopenharmony_ci};
148462306a36Sopenharmony_ci
148562306a36Sopenharmony_cistatic const struct tegra_i2c_hw_feature tegra30_i2c_hw = {
148662306a36Sopenharmony_ci	.has_continue_xfer_support = true,
148762306a36Sopenharmony_ci	.has_per_pkt_xfer_complete_irq = false,
148862306a36Sopenharmony_ci	.clk_divisor_hs_mode = 3,
148962306a36Sopenharmony_ci	.clk_divisor_std_mode = 0,
149062306a36Sopenharmony_ci	.clk_divisor_fast_mode = 0,
149162306a36Sopenharmony_ci	.clk_divisor_fast_plus_mode = 0,
149262306a36Sopenharmony_ci	.has_config_load_reg = false,
149362306a36Sopenharmony_ci	.has_multi_master_mode = false,
149462306a36Sopenharmony_ci	.has_slcg_override_reg = false,
149562306a36Sopenharmony_ci	.has_mst_fifo = false,
149662306a36Sopenharmony_ci	.quirks = &tegra_i2c_quirks,
149762306a36Sopenharmony_ci	.supports_bus_clear = false,
149862306a36Sopenharmony_ci	.has_apb_dma = true,
149962306a36Sopenharmony_ci	.tlow_std_mode = 0x4,
150062306a36Sopenharmony_ci	.thigh_std_mode = 0x2,
150162306a36Sopenharmony_ci	.tlow_fast_fastplus_mode = 0x4,
150262306a36Sopenharmony_ci	.thigh_fast_fastplus_mode = 0x2,
150362306a36Sopenharmony_ci	.setup_hold_time_std_mode = 0x0,
150462306a36Sopenharmony_ci	.setup_hold_time_fast_fast_plus_mode = 0x0,
150562306a36Sopenharmony_ci	.setup_hold_time_hs_mode = 0x0,
150662306a36Sopenharmony_ci	.has_interface_timing_reg = false,
150762306a36Sopenharmony_ci};
150862306a36Sopenharmony_ci
150962306a36Sopenharmony_cistatic const struct tegra_i2c_hw_feature tegra114_i2c_hw = {
151062306a36Sopenharmony_ci	.has_continue_xfer_support = true,
151162306a36Sopenharmony_ci	.has_per_pkt_xfer_complete_irq = true,
151262306a36Sopenharmony_ci	.clk_divisor_hs_mode = 1,
151362306a36Sopenharmony_ci	.clk_divisor_std_mode = 0x19,
151462306a36Sopenharmony_ci	.clk_divisor_fast_mode = 0x19,
151562306a36Sopenharmony_ci	.clk_divisor_fast_plus_mode = 0x10,
151662306a36Sopenharmony_ci	.has_config_load_reg = false,
151762306a36Sopenharmony_ci	.has_multi_master_mode = false,
151862306a36Sopenharmony_ci	.has_slcg_override_reg = false,
151962306a36Sopenharmony_ci	.has_mst_fifo = false,
152062306a36Sopenharmony_ci	.quirks = &tegra_i2c_quirks,
152162306a36Sopenharmony_ci	.supports_bus_clear = true,
152262306a36Sopenharmony_ci	.has_apb_dma = true,
152362306a36Sopenharmony_ci	.tlow_std_mode = 0x4,
152462306a36Sopenharmony_ci	.thigh_std_mode = 0x2,
152562306a36Sopenharmony_ci	.tlow_fast_fastplus_mode = 0x4,
152662306a36Sopenharmony_ci	.thigh_fast_fastplus_mode = 0x2,
152762306a36Sopenharmony_ci	.setup_hold_time_std_mode = 0x0,
152862306a36Sopenharmony_ci	.setup_hold_time_fast_fast_plus_mode = 0x0,
152962306a36Sopenharmony_ci	.setup_hold_time_hs_mode = 0x0,
153062306a36Sopenharmony_ci	.has_interface_timing_reg = false,
153162306a36Sopenharmony_ci};
153262306a36Sopenharmony_ci
153362306a36Sopenharmony_cistatic const struct tegra_i2c_hw_feature tegra124_i2c_hw = {
153462306a36Sopenharmony_ci	.has_continue_xfer_support = true,
153562306a36Sopenharmony_ci	.has_per_pkt_xfer_complete_irq = true,
153662306a36Sopenharmony_ci	.clk_divisor_hs_mode = 1,
153762306a36Sopenharmony_ci	.clk_divisor_std_mode = 0x19,
153862306a36Sopenharmony_ci	.clk_divisor_fast_mode = 0x19,
153962306a36Sopenharmony_ci	.clk_divisor_fast_plus_mode = 0x10,
154062306a36Sopenharmony_ci	.has_config_load_reg = true,
154162306a36Sopenharmony_ci	.has_multi_master_mode = false,
154262306a36Sopenharmony_ci	.has_slcg_override_reg = true,
154362306a36Sopenharmony_ci	.has_mst_fifo = false,
154462306a36Sopenharmony_ci	.quirks = &tegra_i2c_quirks,
154562306a36Sopenharmony_ci	.supports_bus_clear = true,
154662306a36Sopenharmony_ci	.has_apb_dma = true,
154762306a36Sopenharmony_ci	.tlow_std_mode = 0x4,
154862306a36Sopenharmony_ci	.thigh_std_mode = 0x2,
154962306a36Sopenharmony_ci	.tlow_fast_fastplus_mode = 0x4,
155062306a36Sopenharmony_ci	.thigh_fast_fastplus_mode = 0x2,
155162306a36Sopenharmony_ci	.setup_hold_time_std_mode = 0x0,
155262306a36Sopenharmony_ci	.setup_hold_time_fast_fast_plus_mode = 0x0,
155362306a36Sopenharmony_ci	.setup_hold_time_hs_mode = 0x0,
155462306a36Sopenharmony_ci	.has_interface_timing_reg = true,
155562306a36Sopenharmony_ci};
155662306a36Sopenharmony_ci
155762306a36Sopenharmony_cistatic const struct tegra_i2c_hw_feature tegra210_i2c_hw = {
155862306a36Sopenharmony_ci	.has_continue_xfer_support = true,
155962306a36Sopenharmony_ci	.has_per_pkt_xfer_complete_irq = true,
156062306a36Sopenharmony_ci	.clk_divisor_hs_mode = 1,
156162306a36Sopenharmony_ci	.clk_divisor_std_mode = 0x19,
156262306a36Sopenharmony_ci	.clk_divisor_fast_mode = 0x19,
156362306a36Sopenharmony_ci	.clk_divisor_fast_plus_mode = 0x10,
156462306a36Sopenharmony_ci	.has_config_load_reg = true,
156562306a36Sopenharmony_ci	.has_multi_master_mode = false,
156662306a36Sopenharmony_ci	.has_slcg_override_reg = true,
156762306a36Sopenharmony_ci	.has_mst_fifo = false,
156862306a36Sopenharmony_ci	.quirks = &tegra_i2c_quirks,
156962306a36Sopenharmony_ci	.supports_bus_clear = true,
157062306a36Sopenharmony_ci	.has_apb_dma = true,
157162306a36Sopenharmony_ci	.tlow_std_mode = 0x4,
157262306a36Sopenharmony_ci	.thigh_std_mode = 0x2,
157362306a36Sopenharmony_ci	.tlow_fast_fastplus_mode = 0x4,
157462306a36Sopenharmony_ci	.thigh_fast_fastplus_mode = 0x2,
157562306a36Sopenharmony_ci	.setup_hold_time_std_mode = 0,
157662306a36Sopenharmony_ci	.setup_hold_time_fast_fast_plus_mode = 0,
157762306a36Sopenharmony_ci	.setup_hold_time_hs_mode = 0,
157862306a36Sopenharmony_ci	.has_interface_timing_reg = true,
157962306a36Sopenharmony_ci};
158062306a36Sopenharmony_ci
158162306a36Sopenharmony_cistatic const struct tegra_i2c_hw_feature tegra186_i2c_hw = {
158262306a36Sopenharmony_ci	.has_continue_xfer_support = true,
158362306a36Sopenharmony_ci	.has_per_pkt_xfer_complete_irq = true,
158462306a36Sopenharmony_ci	.clk_divisor_hs_mode = 1,
158562306a36Sopenharmony_ci	.clk_divisor_std_mode = 0x16,
158662306a36Sopenharmony_ci	.clk_divisor_fast_mode = 0x19,
158762306a36Sopenharmony_ci	.clk_divisor_fast_plus_mode = 0x10,
158862306a36Sopenharmony_ci	.has_config_load_reg = true,
158962306a36Sopenharmony_ci	.has_multi_master_mode = false,
159062306a36Sopenharmony_ci	.has_slcg_override_reg = true,
159162306a36Sopenharmony_ci	.has_mst_fifo = false,
159262306a36Sopenharmony_ci	.quirks = &tegra_i2c_quirks,
159362306a36Sopenharmony_ci	.supports_bus_clear = true,
159462306a36Sopenharmony_ci	.has_apb_dma = false,
159562306a36Sopenharmony_ci	.tlow_std_mode = 0x4,
159662306a36Sopenharmony_ci	.thigh_std_mode = 0x3,
159762306a36Sopenharmony_ci	.tlow_fast_fastplus_mode = 0x4,
159862306a36Sopenharmony_ci	.thigh_fast_fastplus_mode = 0x2,
159962306a36Sopenharmony_ci	.setup_hold_time_std_mode = 0,
160062306a36Sopenharmony_ci	.setup_hold_time_fast_fast_plus_mode = 0,
160162306a36Sopenharmony_ci	.setup_hold_time_hs_mode = 0,
160262306a36Sopenharmony_ci	.has_interface_timing_reg = true,
160362306a36Sopenharmony_ci};
160462306a36Sopenharmony_ci
160562306a36Sopenharmony_cistatic const struct tegra_i2c_hw_feature tegra194_i2c_hw = {
160662306a36Sopenharmony_ci	.has_continue_xfer_support = true,
160762306a36Sopenharmony_ci	.has_per_pkt_xfer_complete_irq = true,
160862306a36Sopenharmony_ci	.clk_divisor_hs_mode = 1,
160962306a36Sopenharmony_ci	.clk_divisor_std_mode = 0x4f,
161062306a36Sopenharmony_ci	.clk_divisor_fast_mode = 0x3c,
161162306a36Sopenharmony_ci	.clk_divisor_fast_plus_mode = 0x16,
161262306a36Sopenharmony_ci	.has_config_load_reg = true,
161362306a36Sopenharmony_ci	.has_multi_master_mode = true,
161462306a36Sopenharmony_ci	.has_slcg_override_reg = true,
161562306a36Sopenharmony_ci	.has_mst_fifo = true,
161662306a36Sopenharmony_ci	.quirks = &tegra194_i2c_quirks,
161762306a36Sopenharmony_ci	.supports_bus_clear = true,
161862306a36Sopenharmony_ci	.has_apb_dma = false,
161962306a36Sopenharmony_ci	.tlow_std_mode = 0x8,
162062306a36Sopenharmony_ci	.thigh_std_mode = 0x7,
162162306a36Sopenharmony_ci	.tlow_fast_fastplus_mode = 0x2,
162262306a36Sopenharmony_ci	.thigh_fast_fastplus_mode = 0x2,
162362306a36Sopenharmony_ci	.setup_hold_time_std_mode = 0x08080808,
162462306a36Sopenharmony_ci	.setup_hold_time_fast_fast_plus_mode = 0x02020202,
162562306a36Sopenharmony_ci	.setup_hold_time_hs_mode = 0x090909,
162662306a36Sopenharmony_ci	.has_interface_timing_reg = true,
162762306a36Sopenharmony_ci};
162862306a36Sopenharmony_ci
162962306a36Sopenharmony_cistatic const struct of_device_id tegra_i2c_of_match[] = {
163062306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra194-i2c", .data = &tegra194_i2c_hw, },
163162306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra186-i2c", .data = &tegra186_i2c_hw, },
163262306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
163362306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra210-i2c-vi", .data = &tegra210_i2c_hw, },
163462306a36Sopenharmony_ci#endif
163562306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra210-i2c", .data = &tegra210_i2c_hw, },
163662306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra124-i2c", .data = &tegra124_i2c_hw, },
163762306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra114-i2c", .data = &tegra114_i2c_hw, },
163862306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra30-i2c", .data = &tegra30_i2c_hw, },
163962306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra20-i2c", .data = &tegra20_i2c_hw, },
164062306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC)
164162306a36Sopenharmony_ci	{ .compatible = "nvidia,tegra20-i2c-dvc", .data = &tegra20_i2c_hw, },
164262306a36Sopenharmony_ci#endif
164362306a36Sopenharmony_ci	{},
164462306a36Sopenharmony_ci};
164562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, tegra_i2c_of_match);
164662306a36Sopenharmony_ci
164762306a36Sopenharmony_cistatic void tegra_i2c_parse_dt(struct tegra_i2c_dev *i2c_dev)
164862306a36Sopenharmony_ci{
164962306a36Sopenharmony_ci	struct device_node *np = i2c_dev->dev->of_node;
165062306a36Sopenharmony_ci	bool multi_mode;
165162306a36Sopenharmony_ci
165262306a36Sopenharmony_ci	i2c_parse_fw_timings(i2c_dev->dev, &i2c_dev->timings, true);
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_ci	multi_mode = device_property_read_bool(i2c_dev->dev, "multi-master");
165562306a36Sopenharmony_ci	i2c_dev->multimaster_mode = multi_mode;
165662306a36Sopenharmony_ci
165762306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_ARCH_TEGRA_2x_SOC) &&
165862306a36Sopenharmony_ci	    of_device_is_compatible(np, "nvidia,tegra20-i2c-dvc"))
165962306a36Sopenharmony_ci		i2c_dev->is_dvc = true;
166062306a36Sopenharmony_ci
166162306a36Sopenharmony_ci	if (IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC) &&
166262306a36Sopenharmony_ci	    of_device_is_compatible(np, "nvidia,tegra210-i2c-vi"))
166362306a36Sopenharmony_ci		i2c_dev->is_vi = true;
166462306a36Sopenharmony_ci}
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_cistatic int tegra_i2c_init_reset(struct tegra_i2c_dev *i2c_dev)
166762306a36Sopenharmony_ci{
166862306a36Sopenharmony_ci	if (ACPI_HANDLE(i2c_dev->dev))
166962306a36Sopenharmony_ci		return 0;
167062306a36Sopenharmony_ci
167162306a36Sopenharmony_ci	i2c_dev->rst = devm_reset_control_get_exclusive(i2c_dev->dev, "i2c");
167262306a36Sopenharmony_ci	if (IS_ERR(i2c_dev->rst))
167362306a36Sopenharmony_ci		return dev_err_probe(i2c_dev->dev, PTR_ERR(i2c_dev->rst),
167462306a36Sopenharmony_ci				      "failed to get reset control\n");
167562306a36Sopenharmony_ci
167662306a36Sopenharmony_ci	return 0;
167762306a36Sopenharmony_ci}
167862306a36Sopenharmony_ci
167962306a36Sopenharmony_cistatic int tegra_i2c_init_clocks(struct tegra_i2c_dev *i2c_dev)
168062306a36Sopenharmony_ci{
168162306a36Sopenharmony_ci	int err;
168262306a36Sopenharmony_ci
168362306a36Sopenharmony_ci	if (ACPI_HANDLE(i2c_dev->dev))
168462306a36Sopenharmony_ci		return 0;
168562306a36Sopenharmony_ci
168662306a36Sopenharmony_ci	i2c_dev->clocks[i2c_dev->nclocks++].id = "div-clk";
168762306a36Sopenharmony_ci
168862306a36Sopenharmony_ci	if (i2c_dev->hw == &tegra20_i2c_hw || i2c_dev->hw == &tegra30_i2c_hw)
168962306a36Sopenharmony_ci		i2c_dev->clocks[i2c_dev->nclocks++].id = "fast-clk";
169062306a36Sopenharmony_ci
169162306a36Sopenharmony_ci	if (IS_VI(i2c_dev))
169262306a36Sopenharmony_ci		i2c_dev->clocks[i2c_dev->nclocks++].id = "slow";
169362306a36Sopenharmony_ci
169462306a36Sopenharmony_ci	err = devm_clk_bulk_get(i2c_dev->dev, i2c_dev->nclocks,
169562306a36Sopenharmony_ci				i2c_dev->clocks);
169662306a36Sopenharmony_ci	if (err)
169762306a36Sopenharmony_ci		return err;
169862306a36Sopenharmony_ci
169962306a36Sopenharmony_ci	err = clk_bulk_prepare(i2c_dev->nclocks, i2c_dev->clocks);
170062306a36Sopenharmony_ci	if (err)
170162306a36Sopenharmony_ci		return err;
170262306a36Sopenharmony_ci
170362306a36Sopenharmony_ci	i2c_dev->div_clk = i2c_dev->clocks[0].clk;
170462306a36Sopenharmony_ci
170562306a36Sopenharmony_ci	if (!i2c_dev->multimaster_mode)
170662306a36Sopenharmony_ci		return 0;
170762306a36Sopenharmony_ci
170862306a36Sopenharmony_ci	err = clk_enable(i2c_dev->div_clk);
170962306a36Sopenharmony_ci	if (err) {
171062306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "failed to enable div-clk: %d\n", err);
171162306a36Sopenharmony_ci		goto unprepare_clocks;
171262306a36Sopenharmony_ci	}
171362306a36Sopenharmony_ci
171462306a36Sopenharmony_ci	return 0;
171562306a36Sopenharmony_ci
171662306a36Sopenharmony_ciunprepare_clocks:
171762306a36Sopenharmony_ci	clk_bulk_unprepare(i2c_dev->nclocks, i2c_dev->clocks);
171862306a36Sopenharmony_ci
171962306a36Sopenharmony_ci	return err;
172062306a36Sopenharmony_ci}
172162306a36Sopenharmony_ci
172262306a36Sopenharmony_cistatic void tegra_i2c_release_clocks(struct tegra_i2c_dev *i2c_dev)
172362306a36Sopenharmony_ci{
172462306a36Sopenharmony_ci	if (i2c_dev->multimaster_mode)
172562306a36Sopenharmony_ci		clk_disable(i2c_dev->div_clk);
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_ci	clk_bulk_unprepare(i2c_dev->nclocks, i2c_dev->clocks);
172862306a36Sopenharmony_ci}
172962306a36Sopenharmony_ci
173062306a36Sopenharmony_cistatic int tegra_i2c_init_hardware(struct tegra_i2c_dev *i2c_dev)
173162306a36Sopenharmony_ci{
173262306a36Sopenharmony_ci	int ret;
173362306a36Sopenharmony_ci
173462306a36Sopenharmony_ci	ret = pm_runtime_get_sync(i2c_dev->dev);
173562306a36Sopenharmony_ci	if (ret < 0)
173662306a36Sopenharmony_ci		dev_err(i2c_dev->dev, "runtime resume failed: %d\n", ret);
173762306a36Sopenharmony_ci	else
173862306a36Sopenharmony_ci		ret = tegra_i2c_init(i2c_dev);
173962306a36Sopenharmony_ci
174062306a36Sopenharmony_ci	pm_runtime_put_sync(i2c_dev->dev);
174162306a36Sopenharmony_ci
174262306a36Sopenharmony_ci	return ret;
174362306a36Sopenharmony_ci}
174462306a36Sopenharmony_ci
174562306a36Sopenharmony_cistatic int tegra_i2c_probe(struct platform_device *pdev)
174662306a36Sopenharmony_ci{
174762306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev;
174862306a36Sopenharmony_ci	struct resource *res;
174962306a36Sopenharmony_ci	int err;
175062306a36Sopenharmony_ci
175162306a36Sopenharmony_ci	i2c_dev = devm_kzalloc(&pdev->dev, sizeof(*i2c_dev), GFP_KERNEL);
175262306a36Sopenharmony_ci	if (!i2c_dev)
175362306a36Sopenharmony_ci		return -ENOMEM;
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_ci	platform_set_drvdata(pdev, i2c_dev);
175662306a36Sopenharmony_ci
175762306a36Sopenharmony_ci	init_completion(&i2c_dev->msg_complete);
175862306a36Sopenharmony_ci	init_completion(&i2c_dev->dma_complete);
175962306a36Sopenharmony_ci
176062306a36Sopenharmony_ci	i2c_dev->hw = device_get_match_data(&pdev->dev);
176162306a36Sopenharmony_ci	i2c_dev->cont_id = pdev->id;
176262306a36Sopenharmony_ci	i2c_dev->dev = &pdev->dev;
176362306a36Sopenharmony_ci
176462306a36Sopenharmony_ci	i2c_dev->base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
176562306a36Sopenharmony_ci	if (IS_ERR(i2c_dev->base))
176662306a36Sopenharmony_ci		return PTR_ERR(i2c_dev->base);
176762306a36Sopenharmony_ci
176862306a36Sopenharmony_ci	i2c_dev->base_phys = res->start;
176962306a36Sopenharmony_ci
177062306a36Sopenharmony_ci	err = platform_get_irq(pdev, 0);
177162306a36Sopenharmony_ci	if (err < 0)
177262306a36Sopenharmony_ci		return err;
177362306a36Sopenharmony_ci
177462306a36Sopenharmony_ci	i2c_dev->irq = err;
177562306a36Sopenharmony_ci
177662306a36Sopenharmony_ci	/* interrupt will be enabled during of transfer time */
177762306a36Sopenharmony_ci	irq_set_status_flags(i2c_dev->irq, IRQ_NOAUTOEN);
177862306a36Sopenharmony_ci
177962306a36Sopenharmony_ci	err = devm_request_threaded_irq(i2c_dev->dev, i2c_dev->irq,
178062306a36Sopenharmony_ci					NULL, tegra_i2c_isr,
178162306a36Sopenharmony_ci					IRQF_NO_SUSPEND | IRQF_ONESHOT,
178262306a36Sopenharmony_ci					dev_name(i2c_dev->dev), i2c_dev);
178362306a36Sopenharmony_ci	if (err)
178462306a36Sopenharmony_ci		return err;
178562306a36Sopenharmony_ci
178662306a36Sopenharmony_ci	tegra_i2c_parse_dt(i2c_dev);
178762306a36Sopenharmony_ci
178862306a36Sopenharmony_ci	err = tegra_i2c_init_reset(i2c_dev);
178962306a36Sopenharmony_ci	if (err)
179062306a36Sopenharmony_ci		return err;
179162306a36Sopenharmony_ci
179262306a36Sopenharmony_ci	err = tegra_i2c_init_clocks(i2c_dev);
179362306a36Sopenharmony_ci	if (err)
179462306a36Sopenharmony_ci		return err;
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci	err = tegra_i2c_init_dma(i2c_dev);
179762306a36Sopenharmony_ci	if (err)
179862306a36Sopenharmony_ci		goto release_clocks;
179962306a36Sopenharmony_ci
180062306a36Sopenharmony_ci	/*
180162306a36Sopenharmony_ci	 * VI I2C is in VE power domain which is not always ON and not
180262306a36Sopenharmony_ci	 * IRQ-safe.  Thus, IRQ-safe device shouldn't be attached to a
180362306a36Sopenharmony_ci	 * non IRQ-safe domain because this prevents powering off the power
180462306a36Sopenharmony_ci	 * domain.
180562306a36Sopenharmony_ci	 *
180662306a36Sopenharmony_ci	 * VI I2C device shouldn't be marked as IRQ-safe because VI I2C won't
180762306a36Sopenharmony_ci	 * be used for atomic transfers.
180862306a36Sopenharmony_ci	 */
180962306a36Sopenharmony_ci	if (!IS_VI(i2c_dev))
181062306a36Sopenharmony_ci		pm_runtime_irq_safe(i2c_dev->dev);
181162306a36Sopenharmony_ci
181262306a36Sopenharmony_ci	pm_runtime_enable(i2c_dev->dev);
181362306a36Sopenharmony_ci
181462306a36Sopenharmony_ci	err = tegra_i2c_init_hardware(i2c_dev);
181562306a36Sopenharmony_ci	if (err)
181662306a36Sopenharmony_ci		goto release_rpm;
181762306a36Sopenharmony_ci
181862306a36Sopenharmony_ci	i2c_set_adapdata(&i2c_dev->adapter, i2c_dev);
181962306a36Sopenharmony_ci	i2c_dev->adapter.dev.of_node = i2c_dev->dev->of_node;
182062306a36Sopenharmony_ci	i2c_dev->adapter.dev.parent = i2c_dev->dev;
182162306a36Sopenharmony_ci	i2c_dev->adapter.retries = 1;
182262306a36Sopenharmony_ci	i2c_dev->adapter.timeout = 6 * HZ;
182362306a36Sopenharmony_ci	i2c_dev->adapter.quirks = i2c_dev->hw->quirks;
182462306a36Sopenharmony_ci	i2c_dev->adapter.owner = THIS_MODULE;
182562306a36Sopenharmony_ci	i2c_dev->adapter.class = I2C_CLASS_DEPRECATED;
182662306a36Sopenharmony_ci	i2c_dev->adapter.algo = &tegra_i2c_algo;
182762306a36Sopenharmony_ci	i2c_dev->adapter.nr = pdev->id;
182862306a36Sopenharmony_ci	ACPI_COMPANION_SET(&i2c_dev->adapter.dev, ACPI_COMPANION(&pdev->dev));
182962306a36Sopenharmony_ci
183062306a36Sopenharmony_ci	if (i2c_dev->hw->supports_bus_clear)
183162306a36Sopenharmony_ci		i2c_dev->adapter.bus_recovery_info = &tegra_i2c_recovery_info;
183262306a36Sopenharmony_ci
183362306a36Sopenharmony_ci	strscpy(i2c_dev->adapter.name, dev_name(i2c_dev->dev),
183462306a36Sopenharmony_ci		sizeof(i2c_dev->adapter.name));
183562306a36Sopenharmony_ci
183662306a36Sopenharmony_ci	err = i2c_add_numbered_adapter(&i2c_dev->adapter);
183762306a36Sopenharmony_ci	if (err)
183862306a36Sopenharmony_ci		goto release_rpm;
183962306a36Sopenharmony_ci
184062306a36Sopenharmony_ci	return 0;
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_cirelease_rpm:
184362306a36Sopenharmony_ci	pm_runtime_disable(i2c_dev->dev);
184462306a36Sopenharmony_ci
184562306a36Sopenharmony_ci	tegra_i2c_release_dma(i2c_dev);
184662306a36Sopenharmony_cirelease_clocks:
184762306a36Sopenharmony_ci	tegra_i2c_release_clocks(i2c_dev);
184862306a36Sopenharmony_ci
184962306a36Sopenharmony_ci	return err;
185062306a36Sopenharmony_ci}
185162306a36Sopenharmony_ci
185262306a36Sopenharmony_cistatic void tegra_i2c_remove(struct platform_device *pdev)
185362306a36Sopenharmony_ci{
185462306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
185562306a36Sopenharmony_ci
185662306a36Sopenharmony_ci	i2c_del_adapter(&i2c_dev->adapter);
185762306a36Sopenharmony_ci	pm_runtime_force_suspend(i2c_dev->dev);
185862306a36Sopenharmony_ci
185962306a36Sopenharmony_ci	tegra_i2c_release_dma(i2c_dev);
186062306a36Sopenharmony_ci	tegra_i2c_release_clocks(i2c_dev);
186162306a36Sopenharmony_ci}
186262306a36Sopenharmony_ci
186362306a36Sopenharmony_cistatic int __maybe_unused tegra_i2c_runtime_resume(struct device *dev)
186462306a36Sopenharmony_ci{
186562306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
186662306a36Sopenharmony_ci	int err;
186762306a36Sopenharmony_ci
186862306a36Sopenharmony_ci	err = pinctrl_pm_select_default_state(dev);
186962306a36Sopenharmony_ci	if (err)
187062306a36Sopenharmony_ci		return err;
187162306a36Sopenharmony_ci
187262306a36Sopenharmony_ci	err = clk_bulk_enable(i2c_dev->nclocks, i2c_dev->clocks);
187362306a36Sopenharmony_ci	if (err)
187462306a36Sopenharmony_ci		return err;
187562306a36Sopenharmony_ci
187662306a36Sopenharmony_ci	/*
187762306a36Sopenharmony_ci	 * VI I2C device is attached to VE power domain which goes through
187862306a36Sopenharmony_ci	 * power ON/OFF during runtime PM resume/suspend, meaning that
187962306a36Sopenharmony_ci	 * controller needs to be re-initialized after power ON.
188062306a36Sopenharmony_ci	 */
188162306a36Sopenharmony_ci	if (IS_VI(i2c_dev)) {
188262306a36Sopenharmony_ci		err = tegra_i2c_init(i2c_dev);
188362306a36Sopenharmony_ci		if (err)
188462306a36Sopenharmony_ci			goto disable_clocks;
188562306a36Sopenharmony_ci	}
188662306a36Sopenharmony_ci
188762306a36Sopenharmony_ci	return 0;
188862306a36Sopenharmony_ci
188962306a36Sopenharmony_cidisable_clocks:
189062306a36Sopenharmony_ci	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
189162306a36Sopenharmony_ci
189262306a36Sopenharmony_ci	return err;
189362306a36Sopenharmony_ci}
189462306a36Sopenharmony_ci
189562306a36Sopenharmony_cistatic int __maybe_unused tegra_i2c_runtime_suspend(struct device *dev)
189662306a36Sopenharmony_ci{
189762306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
189862306a36Sopenharmony_ci
189962306a36Sopenharmony_ci	clk_bulk_disable(i2c_dev->nclocks, i2c_dev->clocks);
190062306a36Sopenharmony_ci
190162306a36Sopenharmony_ci	return pinctrl_pm_select_idle_state(dev);
190262306a36Sopenharmony_ci}
190362306a36Sopenharmony_ci
190462306a36Sopenharmony_cistatic int __maybe_unused tegra_i2c_suspend(struct device *dev)
190562306a36Sopenharmony_ci{
190662306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
190762306a36Sopenharmony_ci	int err;
190862306a36Sopenharmony_ci
190962306a36Sopenharmony_ci	i2c_mark_adapter_suspended(&i2c_dev->adapter);
191062306a36Sopenharmony_ci
191162306a36Sopenharmony_ci	if (!pm_runtime_status_suspended(dev)) {
191262306a36Sopenharmony_ci		err = tegra_i2c_runtime_suspend(dev);
191362306a36Sopenharmony_ci		if (err)
191462306a36Sopenharmony_ci			return err;
191562306a36Sopenharmony_ci	}
191662306a36Sopenharmony_ci
191762306a36Sopenharmony_ci	return 0;
191862306a36Sopenharmony_ci}
191962306a36Sopenharmony_ci
192062306a36Sopenharmony_cistatic int __maybe_unused tegra_i2c_resume(struct device *dev)
192162306a36Sopenharmony_ci{
192262306a36Sopenharmony_ci	struct tegra_i2c_dev *i2c_dev = dev_get_drvdata(dev);
192362306a36Sopenharmony_ci	int err;
192462306a36Sopenharmony_ci
192562306a36Sopenharmony_ci	/*
192662306a36Sopenharmony_ci	 * We need to ensure that clocks are enabled so that registers can be
192762306a36Sopenharmony_ci	 * restored in tegra_i2c_init().
192862306a36Sopenharmony_ci	 */
192962306a36Sopenharmony_ci	err = tegra_i2c_runtime_resume(dev);
193062306a36Sopenharmony_ci	if (err)
193162306a36Sopenharmony_ci		return err;
193262306a36Sopenharmony_ci
193362306a36Sopenharmony_ci	err = tegra_i2c_init(i2c_dev);
193462306a36Sopenharmony_ci	if (err)
193562306a36Sopenharmony_ci		return err;
193662306a36Sopenharmony_ci
193762306a36Sopenharmony_ci	/*
193862306a36Sopenharmony_ci	 * In case we are runtime suspended, disable clocks again so that we
193962306a36Sopenharmony_ci	 * don't unbalance the clock reference counts during the next runtime
194062306a36Sopenharmony_ci	 * resume transition.
194162306a36Sopenharmony_ci	 */
194262306a36Sopenharmony_ci	if (pm_runtime_status_suspended(dev)) {
194362306a36Sopenharmony_ci		err = tegra_i2c_runtime_suspend(dev);
194462306a36Sopenharmony_ci		if (err)
194562306a36Sopenharmony_ci			return err;
194662306a36Sopenharmony_ci	}
194762306a36Sopenharmony_ci
194862306a36Sopenharmony_ci	i2c_mark_adapter_resumed(&i2c_dev->adapter);
194962306a36Sopenharmony_ci
195062306a36Sopenharmony_ci	return 0;
195162306a36Sopenharmony_ci}
195262306a36Sopenharmony_ci
195362306a36Sopenharmony_cistatic const struct dev_pm_ops tegra_i2c_pm = {
195462306a36Sopenharmony_ci	SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(tegra_i2c_suspend, tegra_i2c_resume)
195562306a36Sopenharmony_ci	SET_RUNTIME_PM_OPS(tegra_i2c_runtime_suspend, tegra_i2c_runtime_resume,
195662306a36Sopenharmony_ci			   NULL)
195762306a36Sopenharmony_ci};
195862306a36Sopenharmony_ci
195962306a36Sopenharmony_cistatic const struct acpi_device_id tegra_i2c_acpi_match[] = {
196062306a36Sopenharmony_ci	{.id = "NVDA0101", .driver_data = (kernel_ulong_t)&tegra210_i2c_hw},
196162306a36Sopenharmony_ci	{.id = "NVDA0201", .driver_data = (kernel_ulong_t)&tegra186_i2c_hw},
196262306a36Sopenharmony_ci	{.id = "NVDA0301", .driver_data = (kernel_ulong_t)&tegra194_i2c_hw},
196362306a36Sopenharmony_ci	{ }
196462306a36Sopenharmony_ci};
196562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(acpi, tegra_i2c_acpi_match);
196662306a36Sopenharmony_ci
196762306a36Sopenharmony_cistatic struct platform_driver tegra_i2c_driver = {
196862306a36Sopenharmony_ci	.probe = tegra_i2c_probe,
196962306a36Sopenharmony_ci	.remove_new = tegra_i2c_remove,
197062306a36Sopenharmony_ci	.driver = {
197162306a36Sopenharmony_ci		.name = "tegra-i2c",
197262306a36Sopenharmony_ci		.of_match_table = tegra_i2c_of_match,
197362306a36Sopenharmony_ci		.acpi_match_table = tegra_i2c_acpi_match,
197462306a36Sopenharmony_ci		.pm = &tegra_i2c_pm,
197562306a36Sopenharmony_ci	},
197662306a36Sopenharmony_ci};
197762306a36Sopenharmony_cimodule_platform_driver(tegra_i2c_driver);
197862306a36Sopenharmony_ci
197962306a36Sopenharmony_ciMODULE_DESCRIPTION("NVIDIA Tegra I2C Bus Controller driver");
198062306a36Sopenharmony_ciMODULE_AUTHOR("Colin Cross");
198162306a36Sopenharmony_ciMODULE_LICENSE("GPL v2");
1982