xref: /linux/drivers/i2c/busses/i2c-qcom-cci.c (revision 03c11eb3b16dc0058589751dfd91f254be2be613)
1e5175261SLoic Poulain // SPDX-License-Identifier: GPL-2.0
2e5175261SLoic Poulain // Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
3017b32e6SVladimir Zapolskiy // Copyright (c) 2017-2022 Linaro Limited.
4e5175261SLoic Poulain 
5e5175261SLoic Poulain #include <linux/clk.h>
6e5175261SLoic Poulain #include <linux/completion.h>
7e5175261SLoic Poulain #include <linux/i2c.h>
8e5175261SLoic Poulain #include <linux/io.h>
9e5175261SLoic Poulain #include <linux/interrupt.h>
10e5175261SLoic Poulain #include <linux/module.h>
11e5175261SLoic Poulain #include <linux/of.h>
12e5175261SLoic Poulain #include <linux/platform_device.h>
13e5175261SLoic Poulain #include <linux/pm_runtime.h>
14e5175261SLoic Poulain 
15e5175261SLoic Poulain #define CCI_HW_VERSION				0x0
16e5175261SLoic Poulain #define CCI_RESET_CMD				0x004
17e5175261SLoic Poulain #define CCI_RESET_CMD_MASK			0x0f73f3f7
18e5175261SLoic Poulain #define CCI_RESET_CMD_M0_MASK			0x000003f1
19e5175261SLoic Poulain #define CCI_RESET_CMD_M1_MASK			0x0003f001
20e5175261SLoic Poulain #define CCI_QUEUE_START				0x008
21e5175261SLoic Poulain #define CCI_HALT_REQ				0x034
22e5175261SLoic Poulain #define CCI_HALT_REQ_I2C_M0_Q0Q1		BIT(0)
23e5175261SLoic Poulain #define CCI_HALT_REQ_I2C_M1_Q0Q1		BIT(1)
24e5175261SLoic Poulain 
25e5175261SLoic Poulain #define CCI_I2C_Mm_SCL_CTL(m)			(0x100 + 0x100 * (m))
26e5175261SLoic Poulain #define CCI_I2C_Mm_SDA_CTL_0(m)			(0x104 + 0x100 * (m))
27e5175261SLoic Poulain #define CCI_I2C_Mm_SDA_CTL_1(m)			(0x108 + 0x100 * (m))
28e5175261SLoic Poulain #define CCI_I2C_Mm_SDA_CTL_2(m)			(0x10c + 0x100 * (m))
29e5175261SLoic Poulain #define CCI_I2C_Mm_MISC_CTL(m)			(0x110 + 0x100 * (m))
30e5175261SLoic Poulain 
31e5175261SLoic Poulain #define CCI_I2C_Mm_READ_DATA(m)			(0x118 + 0x100 * (m))
32e5175261SLoic Poulain #define CCI_I2C_Mm_READ_BUF_LEVEL(m)		(0x11c + 0x100 * (m))
33e5175261SLoic Poulain #define CCI_I2C_Mm_Qn_EXEC_WORD_CNT(m, n)	(0x300 + 0x200 * (m) + 0x100 * (n))
34e5175261SLoic Poulain #define CCI_I2C_Mm_Qn_CUR_WORD_CNT(m, n)	(0x304 + 0x200 * (m) + 0x100 * (n))
35e5175261SLoic Poulain #define CCI_I2C_Mm_Qn_CUR_CMD(m, n)		(0x308 + 0x200 * (m) + 0x100 * (n))
36e5175261SLoic Poulain #define CCI_I2C_Mm_Qn_REPORT_STATUS(m, n)	(0x30c + 0x200 * (m) + 0x100 * (n))
37e5175261SLoic Poulain #define CCI_I2C_Mm_Qn_LOAD_DATA(m, n)		(0x310 + 0x200 * (m) + 0x100 * (n))
38e5175261SLoic Poulain 
39e5175261SLoic Poulain #define CCI_IRQ_GLOBAL_CLEAR_CMD		0xc00
40e5175261SLoic Poulain #define CCI_IRQ_MASK_0				0xc04
41e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M0_RD_DONE		BIT(0)
42e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M0_Q0_REPORT		BIT(4)
43e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M0_Q1_REPORT		BIT(8)
44e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M1_RD_DONE		BIT(12)
45e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M1_Q0_REPORT		BIT(16)
46e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M1_Q1_REPORT		BIT(20)
47e5175261SLoic Poulain #define CCI_IRQ_MASK_0_RST_DONE_ACK		BIT(24)
48e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M0_Q0Q1_HALT_ACK	BIT(25)
49e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M1_Q0Q1_HALT_ACK	BIT(26)
50e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M0_ERROR		0x18000ee6
51e5175261SLoic Poulain #define CCI_IRQ_MASK_0_I2C_M1_ERROR		0x60ee6000
52e5175261SLoic Poulain #define CCI_IRQ_CLEAR_0				0xc08
53e5175261SLoic Poulain #define CCI_IRQ_STATUS_0			0xc0c
54e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M0_RD_DONE		BIT(0)
55e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT	BIT(4)
56e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT	BIT(8)
57e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M1_RD_DONE		BIT(12)
58e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT	BIT(16)
59e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT	BIT(20)
60e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_RST_DONE_ACK		BIT(24)
61e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK	BIT(25)
62e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK	BIT(26)
63e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR	BIT(27)
64e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR	BIT(28)
65e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR	BIT(29)
66e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR	BIT(30)
67e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M0_ERROR		0x18000ee6
68e5175261SLoic Poulain #define CCI_IRQ_STATUS_0_I2C_M1_ERROR		0x60ee6000
69e5175261SLoic Poulain 
70e5175261SLoic Poulain #define CCI_TIMEOUT	(msecs_to_jiffies(100))
71e5175261SLoic Poulain #define NUM_MASTERS	2
72e5175261SLoic Poulain #define NUM_QUEUES	2
73e5175261SLoic Poulain 
74e5175261SLoic Poulain /* Max number of resources + 1 for a NULL terminator */
75e5175261SLoic Poulain #define CCI_RES_MAX	6
76e5175261SLoic Poulain 
77e5175261SLoic Poulain #define CCI_I2C_SET_PARAM	1
78e5175261SLoic Poulain #define CCI_I2C_REPORT		8
79e5175261SLoic Poulain #define CCI_I2C_WRITE		9
80e5175261SLoic Poulain #define CCI_I2C_READ		10
81e5175261SLoic Poulain 
82e5175261SLoic Poulain #define CCI_I2C_REPORT_IRQ_EN	BIT(8)
83e5175261SLoic Poulain 
84e5175261SLoic Poulain enum {
85e5175261SLoic Poulain 	I2C_MODE_STANDARD,
86e5175261SLoic Poulain 	I2C_MODE_FAST,
87e5175261SLoic Poulain 	I2C_MODE_FAST_PLUS,
88e5175261SLoic Poulain };
89e5175261SLoic Poulain 
90e5175261SLoic Poulain enum cci_i2c_queue_t {
91e5175261SLoic Poulain 	QUEUE_0,
92e5175261SLoic Poulain 	QUEUE_1
93e5175261SLoic Poulain };
94e5175261SLoic Poulain 
95e5175261SLoic Poulain struct hw_params {
96e5175261SLoic Poulain 	u16 thigh; /* HIGH period of the SCL clock in clock ticks */
97e5175261SLoic Poulain 	u16 tlow; /* LOW period of the SCL clock */
98e5175261SLoic Poulain 	u16 tsu_sto; /* set-up time for STOP condition */
99e5175261SLoic Poulain 	u16 tsu_sta; /* set-up time for a repeated START condition */
100e5175261SLoic Poulain 	u16 thd_dat; /* data hold time */
101e5175261SLoic Poulain 	u16 thd_sta; /* hold time (repeated) START condition */
102e5175261SLoic Poulain 	u16 tbuf; /* bus free time between a STOP and START condition */
103e5175261SLoic Poulain 	u8 scl_stretch_en;
104e5175261SLoic Poulain 	u16 trdhld;
105e5175261SLoic Poulain 	u16 tsp; /* pulse width of spikes suppressed by the input filter */
106e5175261SLoic Poulain };
107e5175261SLoic Poulain 
108e5175261SLoic Poulain struct cci;
109e5175261SLoic Poulain 
110e5175261SLoic Poulain struct cci_master {
111e5175261SLoic Poulain 	struct i2c_adapter adap;
112e5175261SLoic Poulain 	u16 master;
113e5175261SLoic Poulain 	u8 mode;
114e5175261SLoic Poulain 	int status;
115e5175261SLoic Poulain 	struct completion irq_complete;
116e5175261SLoic Poulain 	struct cci *cci;
117e5175261SLoic Poulain };
118e5175261SLoic Poulain 
119e5175261SLoic Poulain struct cci_data {
120e5175261SLoic Poulain 	unsigned int num_masters;
121e5175261SLoic Poulain 	struct i2c_adapter_quirks quirks;
122e5175261SLoic Poulain 	u16 queue_size[NUM_QUEUES];
123e5175261SLoic Poulain 	unsigned long cci_clk_rate;
124e5175261SLoic Poulain 	struct hw_params params[3];
125e5175261SLoic Poulain };
126e5175261SLoic Poulain 
127e5175261SLoic Poulain struct cci {
128e5175261SLoic Poulain 	struct device *dev;
129e5175261SLoic Poulain 	void __iomem *base;
130e5175261SLoic Poulain 	unsigned int irq;
131e5175261SLoic Poulain 	const struct cci_data *data;
132e5175261SLoic Poulain 	struct clk_bulk_data *clocks;
133e5175261SLoic Poulain 	int nclocks;
134e5175261SLoic Poulain 	struct cci_master master[NUM_MASTERS];
135e5175261SLoic Poulain };
136e5175261SLoic Poulain 
cci_isr(int irq,void * dev)137e5175261SLoic Poulain static irqreturn_t cci_isr(int irq, void *dev)
138e5175261SLoic Poulain {
139e5175261SLoic Poulain 	struct cci *cci = dev;
140e5175261SLoic Poulain 	u32 val, reset = 0;
141e5175261SLoic Poulain 	int ret = IRQ_NONE;
142e5175261SLoic Poulain 
143e5175261SLoic Poulain 	val = readl(cci->base + CCI_IRQ_STATUS_0);
144e5175261SLoic Poulain 	writel(val, cci->base + CCI_IRQ_CLEAR_0);
145e5175261SLoic Poulain 	writel(0x1, cci->base + CCI_IRQ_GLOBAL_CLEAR_CMD);
146e5175261SLoic Poulain 
147e5175261SLoic Poulain 	if (val & CCI_IRQ_STATUS_0_RST_DONE_ACK) {
148e5175261SLoic Poulain 		complete(&cci->master[0].irq_complete);
149e5175261SLoic Poulain 		if (cci->master[1].master)
150e5175261SLoic Poulain 			complete(&cci->master[1].irq_complete);
151e5175261SLoic Poulain 		ret = IRQ_HANDLED;
152e5175261SLoic Poulain 	}
153e5175261SLoic Poulain 
154e5175261SLoic Poulain 	if (val & CCI_IRQ_STATUS_0_I2C_M0_RD_DONE ||
155e5175261SLoic Poulain 			val & CCI_IRQ_STATUS_0_I2C_M0_Q0_REPORT ||
156e5175261SLoic Poulain 			val & CCI_IRQ_STATUS_0_I2C_M0_Q1_REPORT) {
157e5175261SLoic Poulain 		cci->master[0].status = 0;
158e5175261SLoic Poulain 		complete(&cci->master[0].irq_complete);
159e5175261SLoic Poulain 		ret = IRQ_HANDLED;
160e5175261SLoic Poulain 	}
161e5175261SLoic Poulain 
162e5175261SLoic Poulain 	if (val & CCI_IRQ_STATUS_0_I2C_M1_RD_DONE ||
163e5175261SLoic Poulain 			val & CCI_IRQ_STATUS_0_I2C_M1_Q0_REPORT ||
164e5175261SLoic Poulain 			val & CCI_IRQ_STATUS_0_I2C_M1_Q1_REPORT) {
165e5175261SLoic Poulain 		cci->master[1].status = 0;
166e5175261SLoic Poulain 		complete(&cci->master[1].irq_complete);
167e5175261SLoic Poulain 		ret = IRQ_HANDLED;
168e5175261SLoic Poulain 	}
169e5175261SLoic Poulain 
170e5175261SLoic Poulain 	if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M0_Q0Q1_HALT_ACK)) {
171e5175261SLoic Poulain 		reset = CCI_RESET_CMD_M0_MASK;
172e5175261SLoic Poulain 		ret = IRQ_HANDLED;
173e5175261SLoic Poulain 	}
174e5175261SLoic Poulain 
175e5175261SLoic Poulain 	if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M1_Q0Q1_HALT_ACK)) {
176e5175261SLoic Poulain 		reset = CCI_RESET_CMD_M1_MASK;
177e5175261SLoic Poulain 		ret = IRQ_HANDLED;
178e5175261SLoic Poulain 	}
179e5175261SLoic Poulain 
180e5175261SLoic Poulain 	if (unlikely(reset))
181e5175261SLoic Poulain 		writel(reset, cci->base + CCI_RESET_CMD);
182e5175261SLoic Poulain 
183e5175261SLoic Poulain 	if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M0_ERROR)) {
184e5175261SLoic Poulain 		if (val & CCI_IRQ_STATUS_0_I2C_M0_Q0_NACK_ERR ||
185e5175261SLoic Poulain 			val & CCI_IRQ_STATUS_0_I2C_M0_Q1_NACK_ERR)
186e5175261SLoic Poulain 			cci->master[0].status = -ENXIO;
187e5175261SLoic Poulain 		else
188e5175261SLoic Poulain 			cci->master[0].status = -EIO;
189e5175261SLoic Poulain 
190e5175261SLoic Poulain 		writel(CCI_HALT_REQ_I2C_M0_Q0Q1, cci->base + CCI_HALT_REQ);
191e5175261SLoic Poulain 		ret = IRQ_HANDLED;
192e5175261SLoic Poulain 	}
193e5175261SLoic Poulain 
194e5175261SLoic Poulain 	if (unlikely(val & CCI_IRQ_STATUS_0_I2C_M1_ERROR)) {
195e5175261SLoic Poulain 		if (val & CCI_IRQ_STATUS_0_I2C_M1_Q0_NACK_ERR ||
196e5175261SLoic Poulain 			val & CCI_IRQ_STATUS_0_I2C_M1_Q1_NACK_ERR)
19714718b3eSRobert Foss 			cci->master[1].status = -ENXIO;
198e5175261SLoic Poulain 		else
19914718b3eSRobert Foss 			cci->master[1].status = -EIO;
200e5175261SLoic Poulain 
201e5175261SLoic Poulain 		writel(CCI_HALT_REQ_I2C_M1_Q0Q1, cci->base + CCI_HALT_REQ);
202e5175261SLoic Poulain 		ret = IRQ_HANDLED;
203e5175261SLoic Poulain 	}
204e5175261SLoic Poulain 
205e5175261SLoic Poulain 	return ret;
206e5175261SLoic Poulain }
207e5175261SLoic Poulain 
cci_halt(struct cci * cci,u8 master_num)208e5175261SLoic Poulain static int cci_halt(struct cci *cci, u8 master_num)
209e5175261SLoic Poulain {
210e5175261SLoic Poulain 	struct cci_master *master;
211e5175261SLoic Poulain 	u32 val;
212e5175261SLoic Poulain 
213e5175261SLoic Poulain 	if (master_num >= cci->data->num_masters) {
214e5175261SLoic Poulain 		dev_err(cci->dev, "Unsupported master idx (%u)\n", master_num);
215e5175261SLoic Poulain 		return -EINVAL;
216e5175261SLoic Poulain 	}
217e5175261SLoic Poulain 
218e5175261SLoic Poulain 	val = BIT(master_num);
219e5175261SLoic Poulain 	master = &cci->master[master_num];
220e5175261SLoic Poulain 
221e5175261SLoic Poulain 	reinit_completion(&master->irq_complete);
222e5175261SLoic Poulain 	writel(val, cci->base + CCI_HALT_REQ);
223e5175261SLoic Poulain 
224e5175261SLoic Poulain 	if (!wait_for_completion_timeout(&master->irq_complete, CCI_TIMEOUT)) {
225e5175261SLoic Poulain 		dev_err(cci->dev, "CCI halt timeout\n");
226e5175261SLoic Poulain 		return -ETIMEDOUT;
227e5175261SLoic Poulain 	}
228e5175261SLoic Poulain 
229e5175261SLoic Poulain 	return 0;
230e5175261SLoic Poulain }
231e5175261SLoic Poulain 
cci_reset(struct cci * cci)232e5175261SLoic Poulain static int cci_reset(struct cci *cci)
233e5175261SLoic Poulain {
234e5175261SLoic Poulain 	/*
235e5175261SLoic Poulain 	 * we reset the whole controller, here and for implicity use
236e5175261SLoic Poulain 	 * master[0].xxx for waiting on it.
237e5175261SLoic Poulain 	 */
238e5175261SLoic Poulain 	reinit_completion(&cci->master[0].irq_complete);
239e5175261SLoic Poulain 	writel(CCI_RESET_CMD_MASK, cci->base + CCI_RESET_CMD);
240e5175261SLoic Poulain 
241e5175261SLoic Poulain 	if (!wait_for_completion_timeout(&cci->master[0].irq_complete,
242e5175261SLoic Poulain 					 CCI_TIMEOUT)) {
243e5175261SLoic Poulain 		dev_err(cci->dev, "CCI reset timeout\n");
244e5175261SLoic Poulain 		return -ETIMEDOUT;
245e5175261SLoic Poulain 	}
246e5175261SLoic Poulain 
247e5175261SLoic Poulain 	return 0;
248e5175261SLoic Poulain }
249e5175261SLoic Poulain 
cci_init(struct cci * cci)250e5175261SLoic Poulain static int cci_init(struct cci *cci)
251e5175261SLoic Poulain {
252e5175261SLoic Poulain 	u32 val = CCI_IRQ_MASK_0_I2C_M0_RD_DONE |
253e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M0_Q0_REPORT |
254e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M0_Q1_REPORT |
255e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M1_RD_DONE |
256e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M1_Q0_REPORT |
257e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M1_Q1_REPORT |
258e5175261SLoic Poulain 			CCI_IRQ_MASK_0_RST_DONE_ACK |
259e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M0_Q0Q1_HALT_ACK |
260e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M1_Q0Q1_HALT_ACK |
261e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M0_ERROR |
262e5175261SLoic Poulain 			CCI_IRQ_MASK_0_I2C_M1_ERROR;
263e5175261SLoic Poulain 	int i;
264e5175261SLoic Poulain 
265e5175261SLoic Poulain 	writel(val, cci->base + CCI_IRQ_MASK_0);
266e5175261SLoic Poulain 
267e5175261SLoic Poulain 	for (i = 0; i < cci->data->num_masters; i++) {
268e5175261SLoic Poulain 		int mode = cci->master[i].mode;
269e5175261SLoic Poulain 		const struct hw_params *hw;
270e5175261SLoic Poulain 
271e5175261SLoic Poulain 		if (!cci->master[i].cci)
272e5175261SLoic Poulain 			continue;
273e5175261SLoic Poulain 
274e5175261SLoic Poulain 		hw = &cci->data->params[mode];
275e5175261SLoic Poulain 
276e5175261SLoic Poulain 		val = hw->thigh << 16 | hw->tlow;
277e5175261SLoic Poulain 		writel(val, cci->base + CCI_I2C_Mm_SCL_CTL(i));
278e5175261SLoic Poulain 
279e5175261SLoic Poulain 		val = hw->tsu_sto << 16 | hw->tsu_sta;
280e5175261SLoic Poulain 		writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_0(i));
281e5175261SLoic Poulain 
282e5175261SLoic Poulain 		val = hw->thd_dat << 16 | hw->thd_sta;
283e5175261SLoic Poulain 		writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_1(i));
284e5175261SLoic Poulain 
285e5175261SLoic Poulain 		val = hw->tbuf;
286e5175261SLoic Poulain 		writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_2(i));
287e5175261SLoic Poulain 
288e5175261SLoic Poulain 		val = hw->scl_stretch_en << 8 | hw->trdhld << 4 | hw->tsp;
289e5175261SLoic Poulain 		writel(val, cci->base + CCI_I2C_Mm_MISC_CTL(i));
290e5175261SLoic Poulain 	}
291e5175261SLoic Poulain 
292e5175261SLoic Poulain 	return 0;
293e5175261SLoic Poulain }
294e5175261SLoic Poulain 
cci_run_queue(struct cci * cci,u8 master,u8 queue)295e5175261SLoic Poulain static int cci_run_queue(struct cci *cci, u8 master, u8 queue)
296e5175261SLoic Poulain {
297e5175261SLoic Poulain 	u32 val;
298e5175261SLoic Poulain 
299e5175261SLoic Poulain 	val = readl(cci->base + CCI_I2C_Mm_Qn_CUR_WORD_CNT(master, queue));
300e5175261SLoic Poulain 	writel(val, cci->base + CCI_I2C_Mm_Qn_EXEC_WORD_CNT(master, queue));
301e5175261SLoic Poulain 
302e5175261SLoic Poulain 	reinit_completion(&cci->master[master].irq_complete);
303e5175261SLoic Poulain 	val = BIT(master * 2 + queue);
304e5175261SLoic Poulain 	writel(val, cci->base + CCI_QUEUE_START);
305e5175261SLoic Poulain 
306e5175261SLoic Poulain 	if (!wait_for_completion_timeout(&cci->master[master].irq_complete,
307e5175261SLoic Poulain 					 CCI_TIMEOUT)) {
308e5175261SLoic Poulain 		dev_err(cci->dev, "master %d queue %d timeout\n",
309e5175261SLoic Poulain 			master, queue);
310e5175261SLoic Poulain 		cci_reset(cci);
311e5175261SLoic Poulain 		cci_init(cci);
312e5175261SLoic Poulain 		return -ETIMEDOUT;
313e5175261SLoic Poulain 	}
314e5175261SLoic Poulain 
315e5175261SLoic Poulain 	return cci->master[master].status;
316e5175261SLoic Poulain }
317e5175261SLoic Poulain 
cci_validate_queue(struct cci * cci,u8 master,u8 queue)318e5175261SLoic Poulain static int cci_validate_queue(struct cci *cci, u8 master, u8 queue)
319e5175261SLoic Poulain {
320e5175261SLoic Poulain 	u32 val;
321e5175261SLoic Poulain 
322e5175261SLoic Poulain 	val = readl(cci->base + CCI_I2C_Mm_Qn_CUR_WORD_CNT(master, queue));
323e5175261SLoic Poulain 	if (val == cci->data->queue_size[queue])
324e5175261SLoic Poulain 		return -EINVAL;
325e5175261SLoic Poulain 
326e5175261SLoic Poulain 	if (!val)
327e5175261SLoic Poulain 		return 0;
328e5175261SLoic Poulain 
329e5175261SLoic Poulain 	val = CCI_I2C_REPORT | CCI_I2C_REPORT_IRQ_EN;
330e5175261SLoic Poulain 	writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
331e5175261SLoic Poulain 
332e5175261SLoic Poulain 	return cci_run_queue(cci, master, queue);
333e5175261SLoic Poulain }
334e5175261SLoic Poulain 
cci_i2c_read(struct cci * cci,u16 master,u16 addr,u8 * buf,u16 len)335e5175261SLoic Poulain static int cci_i2c_read(struct cci *cci, u16 master,
336e5175261SLoic Poulain 			u16 addr, u8 *buf, u16 len)
337e5175261SLoic Poulain {
338e5175261SLoic Poulain 	u32 val, words_read, words_exp;
339e5175261SLoic Poulain 	u8 queue = QUEUE_1;
340e5175261SLoic Poulain 	int i, index = 0, ret;
341e5175261SLoic Poulain 	bool first = true;
342e5175261SLoic Poulain 
343e5175261SLoic Poulain 	/*
344e5175261SLoic Poulain 	 * Call validate queue to make sure queue is empty before starting.
345e5175261SLoic Poulain 	 * This is to avoid overflow / underflow of queue.
346e5175261SLoic Poulain 	 */
347e5175261SLoic Poulain 	ret = cci_validate_queue(cci, master, queue);
348e5175261SLoic Poulain 	if (ret < 0)
349e5175261SLoic Poulain 		return ret;
350e5175261SLoic Poulain 
351e5175261SLoic Poulain 	val = CCI_I2C_SET_PARAM | (addr & 0x7f) << 4;
352e5175261SLoic Poulain 	writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
353e5175261SLoic Poulain 
354e5175261SLoic Poulain 	val = CCI_I2C_READ | len << 4;
355e5175261SLoic Poulain 	writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
356e5175261SLoic Poulain 
357e5175261SLoic Poulain 	ret = cci_run_queue(cci, master, queue);
358e5175261SLoic Poulain 	if (ret < 0)
359e5175261SLoic Poulain 		return ret;
360e5175261SLoic Poulain 
361e5175261SLoic Poulain 	words_read = readl(cci->base + CCI_I2C_Mm_READ_BUF_LEVEL(master));
362e5175261SLoic Poulain 	words_exp = len / 4 + 1;
363e5175261SLoic Poulain 	if (words_read != words_exp) {
364e5175261SLoic Poulain 		dev_err(cci->dev, "words read = %d, words expected = %d\n",
365e5175261SLoic Poulain 			words_read, words_exp);
366e5175261SLoic Poulain 		return -EIO;
367e5175261SLoic Poulain 	}
368e5175261SLoic Poulain 
369e5175261SLoic Poulain 	do {
370e5175261SLoic Poulain 		val = readl(cci->base + CCI_I2C_Mm_READ_DATA(master));
371e5175261SLoic Poulain 
372e5175261SLoic Poulain 		for (i = 0; i < 4 && index < len; i++) {
373e5175261SLoic Poulain 			if (first) {
374e5175261SLoic Poulain 				/* The LS byte of this register represents the
375e5175261SLoic Poulain 				 * first byte read from the slave during a read
376e5175261SLoic Poulain 				 * access.
377e5175261SLoic Poulain 				 */
378e5175261SLoic Poulain 				first = false;
379e5175261SLoic Poulain 				continue;
380e5175261SLoic Poulain 			}
381e5175261SLoic Poulain 			buf[index++] = (val >> (i * 8)) & 0xff;
382e5175261SLoic Poulain 		}
383e5175261SLoic Poulain 	} while (--words_read);
384e5175261SLoic Poulain 
385e5175261SLoic Poulain 	return 0;
386e5175261SLoic Poulain }
387e5175261SLoic Poulain 
cci_i2c_write(struct cci * cci,u16 master,u16 addr,u8 * buf,u16 len)388e5175261SLoic Poulain static int cci_i2c_write(struct cci *cci, u16 master,
389e5175261SLoic Poulain 			 u16 addr, u8 *buf, u16 len)
390e5175261SLoic Poulain {
391e5175261SLoic Poulain 	u8 queue = QUEUE_0;
392e5175261SLoic Poulain 	u8 load[12] = { 0 };
393e5175261SLoic Poulain 	int i = 0, j, ret;
394e5175261SLoic Poulain 	u32 val;
395e5175261SLoic Poulain 
396e5175261SLoic Poulain 	/*
397e5175261SLoic Poulain 	 * Call validate queue to make sure queue is empty before starting.
398e5175261SLoic Poulain 	 * This is to avoid overflow / underflow of queue.
399e5175261SLoic Poulain 	 */
400e5175261SLoic Poulain 	ret = cci_validate_queue(cci, master, queue);
401e5175261SLoic Poulain 	if (ret < 0)
402e5175261SLoic Poulain 		return ret;
403e5175261SLoic Poulain 
404e5175261SLoic Poulain 	val = CCI_I2C_SET_PARAM | (addr & 0x7f) << 4;
405e5175261SLoic Poulain 	writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
406e5175261SLoic Poulain 
407e5175261SLoic Poulain 	load[i++] = CCI_I2C_WRITE | len << 4;
408e5175261SLoic Poulain 
409e5175261SLoic Poulain 	for (j = 0; j < len; j++)
410e5175261SLoic Poulain 		load[i++] = buf[j];
411e5175261SLoic Poulain 
412e5175261SLoic Poulain 	for (j = 0; j < i; j += 4) {
413e5175261SLoic Poulain 		val = load[j];
414e5175261SLoic Poulain 		val |= load[j + 1] << 8;
415e5175261SLoic Poulain 		val |= load[j + 2] << 16;
416e5175261SLoic Poulain 		val |= load[j + 3] << 24;
417e5175261SLoic Poulain 		writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
418e5175261SLoic Poulain 	}
419e5175261SLoic Poulain 
420e5175261SLoic Poulain 	val = CCI_I2C_REPORT | CCI_I2C_REPORT_IRQ_EN;
421e5175261SLoic Poulain 	writel(val, cci->base + CCI_I2C_Mm_Qn_LOAD_DATA(master, queue));
422e5175261SLoic Poulain 
423e5175261SLoic Poulain 	return cci_run_queue(cci, master, queue);
424e5175261SLoic Poulain }
425e5175261SLoic Poulain 
cci_xfer(struct i2c_adapter * adap,struct i2c_msg msgs[],int num)426e5175261SLoic Poulain static int cci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
427e5175261SLoic Poulain {
428e5175261SLoic Poulain 	struct cci_master *cci_master = i2c_get_adapdata(adap);
429e5175261SLoic Poulain 	struct cci *cci = cci_master->cci;
430e5175261SLoic Poulain 	int i, ret;
431e5175261SLoic Poulain 
432e5175261SLoic Poulain 	ret = pm_runtime_get_sync(cci->dev);
433e5175261SLoic Poulain 	if (ret < 0)
434e5175261SLoic Poulain 		goto err;
435e5175261SLoic Poulain 
436e5175261SLoic Poulain 	for (i = 0; i < num; i++) {
437e5175261SLoic Poulain 		if (msgs[i].flags & I2C_M_RD)
438e5175261SLoic Poulain 			ret = cci_i2c_read(cci, cci_master->master,
439e5175261SLoic Poulain 					   msgs[i].addr, msgs[i].buf,
440e5175261SLoic Poulain 					   msgs[i].len);
441e5175261SLoic Poulain 		else
442e5175261SLoic Poulain 			ret = cci_i2c_write(cci, cci_master->master,
443e5175261SLoic Poulain 					    msgs[i].addr, msgs[i].buf,
444e5175261SLoic Poulain 					    msgs[i].len);
445e5175261SLoic Poulain 
446e5175261SLoic Poulain 		if (ret < 0)
447e5175261SLoic Poulain 			break;
448e5175261SLoic Poulain 	}
449e5175261SLoic Poulain 
450e5175261SLoic Poulain 	if (!ret)
451e5175261SLoic Poulain 		ret = num;
452e5175261SLoic Poulain 
453e5175261SLoic Poulain err:
454e5175261SLoic Poulain 	pm_runtime_mark_last_busy(cci->dev);
455e5175261SLoic Poulain 	pm_runtime_put_autosuspend(cci->dev);
456e5175261SLoic Poulain 
457e5175261SLoic Poulain 	return ret;
458e5175261SLoic Poulain }
459e5175261SLoic Poulain 
cci_func(struct i2c_adapter * adap)460e5175261SLoic Poulain static u32 cci_func(struct i2c_adapter *adap)
461e5175261SLoic Poulain {
462e5175261SLoic Poulain 	return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
463e5175261SLoic Poulain }
464e5175261SLoic Poulain 
465e5175261SLoic Poulain static const struct i2c_algorithm cci_algo = {
466e5175261SLoic Poulain 	.master_xfer	= cci_xfer,
467e5175261SLoic Poulain 	.functionality	= cci_func,
468e5175261SLoic Poulain };
469e5175261SLoic Poulain 
cci_enable_clocks(struct cci * cci)470e5175261SLoic Poulain static int cci_enable_clocks(struct cci *cci)
471e5175261SLoic Poulain {
472e5175261SLoic Poulain 	return clk_bulk_prepare_enable(cci->nclocks, cci->clocks);
473e5175261SLoic Poulain }
474e5175261SLoic Poulain 
cci_disable_clocks(struct cci * cci)475e5175261SLoic Poulain static void cci_disable_clocks(struct cci *cci)
476e5175261SLoic Poulain {
477e5175261SLoic Poulain 	clk_bulk_disable_unprepare(cci->nclocks, cci->clocks);
478e5175261SLoic Poulain }
479e5175261SLoic Poulain 
cci_suspend_runtime(struct device * dev)480e5175261SLoic Poulain static int __maybe_unused cci_suspend_runtime(struct device *dev)
481e5175261SLoic Poulain {
482e5175261SLoic Poulain 	struct cci *cci = dev_get_drvdata(dev);
483e5175261SLoic Poulain 
484e5175261SLoic Poulain 	cci_disable_clocks(cci);
485e5175261SLoic Poulain 	return 0;
486e5175261SLoic Poulain }
487e5175261SLoic Poulain 
cci_resume_runtime(struct device * dev)488e5175261SLoic Poulain static int __maybe_unused cci_resume_runtime(struct device *dev)
489e5175261SLoic Poulain {
490e5175261SLoic Poulain 	struct cci *cci = dev_get_drvdata(dev);
491e5175261SLoic Poulain 	int ret;
492e5175261SLoic Poulain 
493e5175261SLoic Poulain 	ret = cci_enable_clocks(cci);
494e5175261SLoic Poulain 	if (ret)
495e5175261SLoic Poulain 		return ret;
496e5175261SLoic Poulain 
497e5175261SLoic Poulain 	cci_init(cci);
498e5175261SLoic Poulain 	return 0;
499e5175261SLoic Poulain }
500e5175261SLoic Poulain 
cci_suspend(struct device * dev)501e5175261SLoic Poulain static int __maybe_unused cci_suspend(struct device *dev)
502e5175261SLoic Poulain {
503e5175261SLoic Poulain 	if (!pm_runtime_suspended(dev))
504e5175261SLoic Poulain 		return cci_suspend_runtime(dev);
505e5175261SLoic Poulain 
506e5175261SLoic Poulain 	return 0;
507e5175261SLoic Poulain }
508e5175261SLoic Poulain 
cci_resume(struct device * dev)509e5175261SLoic Poulain static int __maybe_unused cci_resume(struct device *dev)
510e5175261SLoic Poulain {
511e5175261SLoic Poulain 	cci_resume_runtime(dev);
512e5175261SLoic Poulain 	pm_runtime_mark_last_busy(dev);
513e5175261SLoic Poulain 	pm_request_autosuspend(dev);
514e5175261SLoic Poulain 
515e5175261SLoic Poulain 	return 0;
516e5175261SLoic Poulain }
517e5175261SLoic Poulain 
518e5175261SLoic Poulain static const struct dev_pm_ops qcom_cci_pm = {
519e5175261SLoic Poulain 	SET_SYSTEM_SLEEP_PM_OPS(cci_suspend, cci_resume)
520e5175261SLoic Poulain 	SET_RUNTIME_PM_OPS(cci_suspend_runtime, cci_resume_runtime, NULL)
521e5175261SLoic Poulain };
522e5175261SLoic Poulain 
cci_probe(struct platform_device * pdev)523e5175261SLoic Poulain static int cci_probe(struct platform_device *pdev)
524e5175261SLoic Poulain {
525e5175261SLoic Poulain 	struct device *dev = &pdev->dev;
526e5175261SLoic Poulain 	unsigned long cci_clk_rate = 0;
527e5175261SLoic Poulain 	struct device_node *child;
528e5175261SLoic Poulain 	struct resource *r;
529e5175261SLoic Poulain 	struct cci *cci;
530e5175261SLoic Poulain 	int ret, i;
531e5175261SLoic Poulain 	u32 val;
532e5175261SLoic Poulain 
533e5175261SLoic Poulain 	cci = devm_kzalloc(dev, sizeof(*cci), GFP_KERNEL);
534e5175261SLoic Poulain 	if (!cci)
535e5175261SLoic Poulain 		return -ENOMEM;
536e5175261SLoic Poulain 
537e5175261SLoic Poulain 	cci->dev = dev;
538e5175261SLoic Poulain 	platform_set_drvdata(pdev, cci);
539e5175261SLoic Poulain 	cci->data = device_get_match_data(dev);
540e5175261SLoic Poulain 	if (!cci->data)
541e5175261SLoic Poulain 		return -ENOENT;
542e5175261SLoic Poulain 
543e5175261SLoic Poulain 	for_each_available_child_of_node(dev->of_node, child) {
544f24bc86aSVladimir Zapolskiy 		struct cci_master *master;
545e5175261SLoic Poulain 		u32 idx;
546e5175261SLoic Poulain 
547e5175261SLoic Poulain 		ret = of_property_read_u32(child, "reg", &idx);
548e5175261SLoic Poulain 		if (ret) {
549e5175261SLoic Poulain 			dev_err(dev, "%pOF invalid 'reg' property", child);
550e5175261SLoic Poulain 			continue;
551e5175261SLoic Poulain 		}
552e5175261SLoic Poulain 
553e5175261SLoic Poulain 		if (idx >= cci->data->num_masters) {
554e5175261SLoic Poulain 			dev_err(dev, "%pOF invalid 'reg' value: %u (max is %u)",
555e5175261SLoic Poulain 				child, idx, cci->data->num_masters - 1);
556e5175261SLoic Poulain 			continue;
557e5175261SLoic Poulain 		}
558e5175261SLoic Poulain 
559f24bc86aSVladimir Zapolskiy 		master = &cci->master[idx];
560f24bc86aSVladimir Zapolskiy 		master->adap.quirks = &cci->data->quirks;
561f24bc86aSVladimir Zapolskiy 		master->adap.algo = &cci_algo;
562f24bc86aSVladimir Zapolskiy 		master->adap.dev.parent = dev;
563f24bc86aSVladimir Zapolskiy 		master->adap.dev.of_node = of_node_get(child);
564f24bc86aSVladimir Zapolskiy 		master->master = idx;
565f24bc86aSVladimir Zapolskiy 		master->cci = cci;
566e5175261SLoic Poulain 
567f24bc86aSVladimir Zapolskiy 		i2c_set_adapdata(&master->adap, master);
568f24bc86aSVladimir Zapolskiy 		snprintf(master->adap.name, sizeof(master->adap.name), "Qualcomm-CCI");
569e5175261SLoic Poulain 
570f24bc86aSVladimir Zapolskiy 		master->mode = I2C_MODE_STANDARD;
571e5175261SLoic Poulain 		ret = of_property_read_u32(child, "clock-frequency", &val);
572e5175261SLoic Poulain 		if (!ret) {
573fd6ddaa0SAndy Shevchenko 			if (val == I2C_MAX_FAST_MODE_FREQ)
574f24bc86aSVladimir Zapolskiy 				master->mode = I2C_MODE_FAST;
575fd6ddaa0SAndy Shevchenko 			else if (val == I2C_MAX_FAST_MODE_PLUS_FREQ)
576f24bc86aSVladimir Zapolskiy 				master->mode = I2C_MODE_FAST_PLUS;
577e5175261SLoic Poulain 		}
578e5175261SLoic Poulain 
579f24bc86aSVladimir Zapolskiy 		init_completion(&master->irq_complete);
580e5175261SLoic Poulain 	}
581e5175261SLoic Poulain 
582e5175261SLoic Poulain 	/* Memory */
583e5175261SLoic Poulain 
584fdbd6954SMd Sadre Alam 	cci->base = devm_platform_get_and_ioremap_resource(pdev, 0, &r);
585e5175261SLoic Poulain 	if (IS_ERR(cci->base))
586e5175261SLoic Poulain 		return PTR_ERR(cci->base);
587e5175261SLoic Poulain 
588e5175261SLoic Poulain 	/* Clocks */
589e5175261SLoic Poulain 
590e5175261SLoic Poulain 	ret = devm_clk_bulk_get_all(dev, &cci->clocks);
591*7f2e65a8SHarshit Mogalapalli 	if (ret < 0)
592605efbf4SLiao Chang 		return dev_err_probe(dev, ret, "failed to get clocks\n");
593*7f2e65a8SHarshit Mogalapalli 	else if (!ret)
594*7f2e65a8SHarshit Mogalapalli 		return dev_err_probe(dev, -EINVAL, "not enough clocks in DT\n");
595e5175261SLoic Poulain 	cci->nclocks = ret;
596e5175261SLoic Poulain 
597e5175261SLoic Poulain 	/* Retrieve CCI clock rate */
598e5175261SLoic Poulain 	for (i = 0; i < cci->nclocks; i++) {
599e5175261SLoic Poulain 		if (!strcmp(cci->clocks[i].id, "cci")) {
600e5175261SLoic Poulain 			cci_clk_rate = clk_get_rate(cci->clocks[i].clk);
601e5175261SLoic Poulain 			break;
602e5175261SLoic Poulain 		}
603e5175261SLoic Poulain 	}
604e5175261SLoic Poulain 
605e5175261SLoic Poulain 	if (cci_clk_rate != cci->data->cci_clk_rate) {
606e5175261SLoic Poulain 		/* cci clock set by the bootloader or via assigned clock rate
607e5175261SLoic Poulain 		 * in DT.
608e5175261SLoic Poulain 		 */
609e5175261SLoic Poulain 		dev_warn(dev, "Found %lu cci clk rate while %lu was expected\n",
610e5175261SLoic Poulain 			 cci_clk_rate, cci->data->cci_clk_rate);
611e5175261SLoic Poulain 	}
612e5175261SLoic Poulain 
613e5175261SLoic Poulain 	ret = cci_enable_clocks(cci);
614e5175261SLoic Poulain 	if (ret < 0)
615e5175261SLoic Poulain 		return ret;
616e5175261SLoic Poulain 
617e5175261SLoic Poulain 	/* Interrupt */
618e5175261SLoic Poulain 
619e5175261SLoic Poulain 	ret = platform_get_irq(pdev, 0);
620e5175261SLoic Poulain 	if (ret < 0)
621e5175261SLoic Poulain 		goto disable_clocks;
622e5175261SLoic Poulain 	cci->irq = ret;
623e5175261SLoic Poulain 
624e5175261SLoic Poulain 	ret = devm_request_irq(dev, cci->irq, cci_isr, 0, dev_name(dev), cci);
625e5175261SLoic Poulain 	if (ret < 0) {
626e5175261SLoic Poulain 		dev_err(dev, "request_irq failed, ret: %d\n", ret);
627e5175261SLoic Poulain 		goto disable_clocks;
628e5175261SLoic Poulain 	}
629e5175261SLoic Poulain 
630e5175261SLoic Poulain 	val = readl(cci->base + CCI_HW_VERSION);
631e5175261SLoic Poulain 	dev_dbg(dev, "CCI HW version = 0x%08x", val);
632e5175261SLoic Poulain 
633e5175261SLoic Poulain 	ret = cci_reset(cci);
634e5175261SLoic Poulain 	if (ret < 0)
635e5175261SLoic Poulain 		goto error;
636e5175261SLoic Poulain 
637e5175261SLoic Poulain 	ret = cci_init(cci);
638e5175261SLoic Poulain 	if (ret < 0)
639e5175261SLoic Poulain 		goto error;
640e5175261SLoic Poulain 
64161775d54SBryan O'Donoghue 	pm_runtime_set_autosuspend_delay(dev, MSEC_PER_SEC);
64261775d54SBryan O'Donoghue 	pm_runtime_use_autosuspend(dev);
64361775d54SBryan O'Donoghue 	pm_runtime_set_active(dev);
64461775d54SBryan O'Donoghue 	pm_runtime_enable(dev);
64561775d54SBryan O'Donoghue 
646e5175261SLoic Poulain 	for (i = 0; i < cci->data->num_masters; i++) {
647e5175261SLoic Poulain 		if (!cci->master[i].cci)
648e5175261SLoic Poulain 			continue;
649e5175261SLoic Poulain 
650e5175261SLoic Poulain 		ret = i2c_add_adapter(&cci->master[i].adap);
65102a4a696SVladimir Zapolskiy 		if (ret < 0) {
65202a4a696SVladimir Zapolskiy 			of_node_put(cci->master[i].adap.dev.of_node);
653e5175261SLoic Poulain 			goto error_i2c;
654e5175261SLoic Poulain 		}
65502a4a696SVladimir Zapolskiy 	}
656e5175261SLoic Poulain 
657e5175261SLoic Poulain 	return 0;
658e5175261SLoic Poulain 
659e5175261SLoic Poulain error_i2c:
66061775d54SBryan O'Donoghue 	pm_runtime_disable(dev);
66161775d54SBryan O'Donoghue 	pm_runtime_dont_use_autosuspend(dev);
66261775d54SBryan O'Donoghue 
663a0d48505SVladimir Zapolskiy 	for (--i ; i >= 0; i--) {
66402a4a696SVladimir Zapolskiy 		if (cci->master[i].cci) {
665e5175261SLoic Poulain 			i2c_del_adapter(&cci->master[i].adap);
66602a4a696SVladimir Zapolskiy 			of_node_put(cci->master[i].adap.dev.of_node);
66702a4a696SVladimir Zapolskiy 		}
668e5175261SLoic Poulain 	}
669e5175261SLoic Poulain error:
670e5175261SLoic Poulain 	disable_irq(cci->irq);
671e5175261SLoic Poulain disable_clocks:
672e5175261SLoic Poulain 	cci_disable_clocks(cci);
673e5175261SLoic Poulain 
674e5175261SLoic Poulain 	return ret;
675e5175261SLoic Poulain }
676e5175261SLoic Poulain 
cci_remove(struct platform_device * pdev)677e190a0c3SUwe Kleine-König static void cci_remove(struct platform_device *pdev)
678e5175261SLoic Poulain {
679e5175261SLoic Poulain 	struct cci *cci = platform_get_drvdata(pdev);
680e5175261SLoic Poulain 	int i;
681e5175261SLoic Poulain 
682e5175261SLoic Poulain 	for (i = 0; i < cci->data->num_masters; i++) {
68302a4a696SVladimir Zapolskiy 		if (cci->master[i].cci) {
684e5175261SLoic Poulain 			i2c_del_adapter(&cci->master[i].adap);
68502a4a696SVladimir Zapolskiy 			of_node_put(cci->master[i].adap.dev.of_node);
68602a4a696SVladimir Zapolskiy 		}
687e5175261SLoic Poulain 		cci_halt(cci, i);
688e5175261SLoic Poulain 	}
689e5175261SLoic Poulain 
690e5175261SLoic Poulain 	disable_irq(cci->irq);
691e5175261SLoic Poulain 	pm_runtime_disable(&pdev->dev);
692e5175261SLoic Poulain 	pm_runtime_set_suspended(&pdev->dev);
693e5175261SLoic Poulain }
694e5175261SLoic Poulain 
695e5175261SLoic Poulain static const struct cci_data cci_v1_data = {
696e5175261SLoic Poulain 	.num_masters = 1,
697e5175261SLoic Poulain 	.queue_size = { 64, 16 },
698e5175261SLoic Poulain 	.quirks = {
699e5175261SLoic Poulain 		.max_write_len = 10,
700e5175261SLoic Poulain 		.max_read_len = 12,
701e5175261SLoic Poulain 	},
702e5175261SLoic Poulain 	.cci_clk_rate =  19200000,
703e5175261SLoic Poulain 	.params[I2C_MODE_STANDARD] = {
704e5175261SLoic Poulain 		.thigh = 78,
705e5175261SLoic Poulain 		.tlow = 114,
706e5175261SLoic Poulain 		.tsu_sto = 28,
707e5175261SLoic Poulain 		.tsu_sta = 28,
708e5175261SLoic Poulain 		.thd_dat = 10,
709e5175261SLoic Poulain 		.thd_sta = 77,
710e5175261SLoic Poulain 		.tbuf = 118,
711e5175261SLoic Poulain 		.scl_stretch_en = 0,
712e5175261SLoic Poulain 		.trdhld = 6,
713e5175261SLoic Poulain 		.tsp = 1
714e5175261SLoic Poulain 	},
715e5175261SLoic Poulain 	.params[I2C_MODE_FAST] = {
716e5175261SLoic Poulain 		.thigh = 20,
717e5175261SLoic Poulain 		.tlow = 28,
718e5175261SLoic Poulain 		.tsu_sto = 21,
719e5175261SLoic Poulain 		.tsu_sta = 21,
720e5175261SLoic Poulain 		.thd_dat = 13,
721e5175261SLoic Poulain 		.thd_sta = 18,
722e5175261SLoic Poulain 		.tbuf = 32,
723e5175261SLoic Poulain 		.scl_stretch_en = 0,
724e5175261SLoic Poulain 		.trdhld = 6,
725e5175261SLoic Poulain 		.tsp = 3
726e5175261SLoic Poulain 	},
727e5175261SLoic Poulain };
728e5175261SLoic Poulain 
7294c0ad47bSMatti Lehtimäki static const struct cci_data cci_v1_5_data = {
7304c0ad47bSMatti Lehtimäki 	.num_masters = 2,
7314c0ad47bSMatti Lehtimäki 	.queue_size = { 64, 16 },
7324c0ad47bSMatti Lehtimäki 	.quirks = {
7334c0ad47bSMatti Lehtimäki 		.max_write_len = 10,
7344c0ad47bSMatti Lehtimäki 		.max_read_len = 12,
7354c0ad47bSMatti Lehtimäki 	},
7364c0ad47bSMatti Lehtimäki 	.cci_clk_rate =  19200000,
7374c0ad47bSMatti Lehtimäki 	.params[I2C_MODE_STANDARD] = {
7384c0ad47bSMatti Lehtimäki 		.thigh = 78,
7394c0ad47bSMatti Lehtimäki 		.tlow = 114,
7404c0ad47bSMatti Lehtimäki 		.tsu_sto = 28,
7414c0ad47bSMatti Lehtimäki 		.tsu_sta = 28,
7424c0ad47bSMatti Lehtimäki 		.thd_dat = 10,
7434c0ad47bSMatti Lehtimäki 		.thd_sta = 77,
7444c0ad47bSMatti Lehtimäki 		.tbuf = 118,
7454c0ad47bSMatti Lehtimäki 		.scl_stretch_en = 0,
7464c0ad47bSMatti Lehtimäki 		.trdhld = 6,
7474c0ad47bSMatti Lehtimäki 		.tsp = 1
7484c0ad47bSMatti Lehtimäki 	},
7494c0ad47bSMatti Lehtimäki 	.params[I2C_MODE_FAST] = {
7504c0ad47bSMatti Lehtimäki 		.thigh = 20,
7514c0ad47bSMatti Lehtimäki 		.tlow = 28,
7524c0ad47bSMatti Lehtimäki 		.tsu_sto = 21,
7534c0ad47bSMatti Lehtimäki 		.tsu_sta = 21,
7544c0ad47bSMatti Lehtimäki 		.thd_dat = 13,
7554c0ad47bSMatti Lehtimäki 		.thd_sta = 18,
7564c0ad47bSMatti Lehtimäki 		.tbuf = 32,
7574c0ad47bSMatti Lehtimäki 		.scl_stretch_en = 0,
7584c0ad47bSMatti Lehtimäki 		.trdhld = 6,
7594c0ad47bSMatti Lehtimäki 		.tsp = 3
7604c0ad47bSMatti Lehtimäki 	},
7614c0ad47bSMatti Lehtimäki };
7624c0ad47bSMatti Lehtimäki 
763e5175261SLoic Poulain static const struct cci_data cci_v2_data = {
764e5175261SLoic Poulain 	.num_masters = 2,
765e5175261SLoic Poulain 	.queue_size = { 64, 16 },
766e5175261SLoic Poulain 	.quirks = {
767e5175261SLoic Poulain 		.max_write_len = 11,
768e5175261SLoic Poulain 		.max_read_len = 12,
769e5175261SLoic Poulain 	},
770e5175261SLoic Poulain 	.cci_clk_rate =  37500000,
771e5175261SLoic Poulain 	.params[I2C_MODE_STANDARD] = {
772e5175261SLoic Poulain 		.thigh = 201,
773e5175261SLoic Poulain 		.tlow = 174,
774e5175261SLoic Poulain 		.tsu_sto = 204,
775e5175261SLoic Poulain 		.tsu_sta = 231,
776e5175261SLoic Poulain 		.thd_dat = 22,
777e5175261SLoic Poulain 		.thd_sta = 162,
778e5175261SLoic Poulain 		.tbuf = 227,
779e5175261SLoic Poulain 		.scl_stretch_en = 0,
780e5175261SLoic Poulain 		.trdhld = 6,
781e5175261SLoic Poulain 		.tsp = 3
782e5175261SLoic Poulain 	},
783e5175261SLoic Poulain 	.params[I2C_MODE_FAST] = {
784e5175261SLoic Poulain 		.thigh = 38,
785e5175261SLoic Poulain 		.tlow = 56,
786e5175261SLoic Poulain 		.tsu_sto = 40,
787e5175261SLoic Poulain 		.tsu_sta = 40,
788e5175261SLoic Poulain 		.thd_dat = 22,
789e5175261SLoic Poulain 		.thd_sta = 35,
790e5175261SLoic Poulain 		.tbuf = 62,
791e5175261SLoic Poulain 		.scl_stretch_en = 0,
792e5175261SLoic Poulain 		.trdhld = 6,
793e5175261SLoic Poulain 		.tsp = 3
794e5175261SLoic Poulain 	},
795e5175261SLoic Poulain 	.params[I2C_MODE_FAST_PLUS] = {
796e5175261SLoic Poulain 		.thigh = 16,
797e5175261SLoic Poulain 		.tlow = 22,
798e5175261SLoic Poulain 		.tsu_sto = 17,
799e5175261SLoic Poulain 		.tsu_sta = 18,
800e5175261SLoic Poulain 		.thd_dat = 16,
801e5175261SLoic Poulain 		.thd_sta = 15,
802e5175261SLoic Poulain 		.tbuf = 24,
803e5175261SLoic Poulain 		.scl_stretch_en = 0,
804e5175261SLoic Poulain 		.trdhld = 3,
805e5175261SLoic Poulain 		.tsp = 3
806e5175261SLoic Poulain 	},
807e5175261SLoic Poulain };
808e5175261SLoic Poulain 
809e5175261SLoic Poulain static const struct of_device_id cci_dt_match[] = {
810d046bd13SRayyan Ansari 	{ .compatible = "qcom,msm8226-cci", .data = &cci_v1_data},
8114c0ad47bSMatti Lehtimäki 	{ .compatible = "qcom,msm8974-cci", .data = &cci_v1_5_data},
812e5175261SLoic Poulain 	{ .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
813816e7faeSKonrad Dybcio 
814816e7faeSKonrad Dybcio 
815816e7faeSKonrad Dybcio 	/*
816816e7faeSKonrad Dybcio 	 * Legacy compatibles kept for backwards compatibility.
817816e7faeSKonrad Dybcio 	 * Do not add any new ones unless they introduce a new config
818816e7faeSKonrad Dybcio 	 */
819816e7faeSKonrad Dybcio 	{ .compatible = "qcom,msm8916-cci", .data = &cci_v1_data},
820e5175261SLoic Poulain 	{ .compatible = "qcom,sdm845-cci", .data = &cci_v2_data},
821e653312bSJonathan Marek 	{ .compatible = "qcom,sm8250-cci", .data = &cci_v2_data},
822017b32e6SVladimir Zapolskiy 	{ .compatible = "qcom,sm8450-cci", .data = &cci_v2_data},
823e5175261SLoic Poulain 	{}
824e5175261SLoic Poulain };
825e5175261SLoic Poulain MODULE_DEVICE_TABLE(of, cci_dt_match);
826e5175261SLoic Poulain 
827e5175261SLoic Poulain static struct platform_driver qcom_cci_driver = {
828e5175261SLoic Poulain 	.probe  = cci_probe,
829e190a0c3SUwe Kleine-König 	.remove_new = cci_remove,
830e5175261SLoic Poulain 	.driver = {
831e5175261SLoic Poulain 		.name = "i2c-qcom-cci",
832e5175261SLoic Poulain 		.of_match_table = cci_dt_match,
833e5175261SLoic Poulain 		.pm = &qcom_cci_pm,
834e5175261SLoic Poulain 	},
835e5175261SLoic Poulain };
836e5175261SLoic Poulain 
837e5175261SLoic Poulain module_platform_driver(qcom_cci_driver);
838e5175261SLoic Poulain 
839e5175261SLoic Poulain MODULE_DESCRIPTION("Qualcomm Camera Control Interface driver");
840e5175261SLoic Poulain MODULE_AUTHOR("Todor Tomov <todor.tomov@linaro.org>");
841e5175261SLoic Poulain MODULE_AUTHOR("Loic Poulain <loic.poulain@linaro.org>");
842e5175261SLoic Poulain MODULE_LICENSE("GPL v2");
843