1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2014-2015, The Linux Foundation. All rights reserved.
4  */
5 
6 #include "edp.h"
7 #include "edp.xml.h"
8 
9 #define AUX_CMD_FIFO_LEN	144
10 #define AUX_CMD_NATIVE_MAX	16
11 #define AUX_CMD_I2C_MAX		128
12 
13 #define EDP_INTR_AUX_I2C_ERR	\
14 	(EDP_INTERRUPT_REG_1_WRONG_ADDR | EDP_INTERRUPT_REG_1_TIMEOUT | \
15 	EDP_INTERRUPT_REG_1_NACK_DEFER | EDP_INTERRUPT_REG_1_WRONG_DATA_CNT | \
16 	EDP_INTERRUPT_REG_1_I2C_NACK | EDP_INTERRUPT_REG_1_I2C_DEFER)
17 #define EDP_INTR_TRANS_STATUS	\
18 	(EDP_INTERRUPT_REG_1_AUX_I2C_DONE | EDP_INTR_AUX_I2C_ERR)
19 
20 struct edp_aux {
21 	void __iomem *base;
22 	bool msg_err;
23 
24 	struct completion msg_comp;
25 
26 	/* To prevent the message transaction routine from reentry. */
27 	struct mutex msg_mutex;
28 
29 	struct drm_dp_aux drm_aux;
30 };
31 #define to_edp_aux(x) container_of(x, struct edp_aux, drm_aux)
32 
edp_msg_fifo_tx(struct edp_aux * aux,struct drm_dp_aux_msg * msg)33 static int edp_msg_fifo_tx(struct edp_aux *aux, struct drm_dp_aux_msg *msg)
34 {
35 	u32 data[4];
36 	u32 reg, len;
37 	bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
38 	bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
39 	u8 *msgdata = msg->buffer;
40 	int i;
41 
42 	if (read)
43 		len = 4;
44 	else
45 		len = msg->size + 4;
46 
47 	/*
48 	 * cmd fifo only has depth of 144 bytes
49 	 */
50 	if (len > AUX_CMD_FIFO_LEN)
51 		return -EINVAL;
52 
53 	/* Pack cmd and write to HW */
54 	data[0] = (msg->address >> 16) & 0xf;	/* addr[19:16] */
55 	if (read)
56 		data[0] |=  BIT(4);		/* R/W */
57 
58 	data[1] = (msg->address >> 8) & 0xff;	/* addr[15:8] */
59 	data[2] = msg->address & 0xff;		/* addr[7:0] */
60 	data[3] = (msg->size - 1) & 0xff;	/* len[7:0] */
61 
62 	for (i = 0; i < len; i++) {
63 		reg = (i < 4) ? data[i] : msgdata[i - 4];
64 		reg = EDP_AUX_DATA_DATA(reg); /* index = 0, write */
65 		if (i == 0)
66 			reg |= EDP_AUX_DATA_INDEX_WRITE;
67 		edp_write(aux->base + REG_EDP_AUX_DATA, reg);
68 	}
69 
70 	reg = 0; /* Transaction number is always 1 */
71 	if (!native) /* i2c */
72 		reg |= EDP_AUX_TRANS_CTRL_I2C;
73 
74 	reg |= EDP_AUX_TRANS_CTRL_GO;
75 	edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, reg);
76 
77 	return 0;
78 }
79 
edp_msg_fifo_rx(struct edp_aux * aux,struct drm_dp_aux_msg * msg)80 static int edp_msg_fifo_rx(struct edp_aux *aux, struct drm_dp_aux_msg *msg)
81 {
82 	u32 data;
83 	u8 *dp;
84 	int i;
85 	u32 len = msg->size;
86 
87 	edp_write(aux->base + REG_EDP_AUX_DATA,
88 		EDP_AUX_DATA_INDEX_WRITE | EDP_AUX_DATA_READ); /* index = 0 */
89 
90 	dp = msg->buffer;
91 
92 	/* discard first byte */
93 	data = edp_read(aux->base + REG_EDP_AUX_DATA);
94 	for (i = 0; i < len; i++) {
95 		data = edp_read(aux->base + REG_EDP_AUX_DATA);
96 		dp[i] = (u8)((data >> 8) & 0xff);
97 	}
98 
99 	return 0;
100 }
101 
102 /*
103  * This function does the real job to process an AUX transaction.
104  * It will call msm_edp_aux_ctrl() function to reset the AUX channel,
105  * if the waiting is timeout.
106  * The caller who triggers the transaction should avoid the
107  * msm_edp_aux_ctrl() running concurrently in other threads, i.e.
108  * start transaction only when AUX channel is fully enabled.
109  */
edp_aux_transfer(struct drm_dp_aux * drm_aux,struct drm_dp_aux_msg * msg)110 static ssize_t edp_aux_transfer(struct drm_dp_aux *drm_aux,
111 		struct drm_dp_aux_msg *msg)
112 {
113 	struct edp_aux *aux = to_edp_aux(drm_aux);
114 	ssize_t ret;
115 	unsigned long time_left;
116 	bool native = msg->request & (DP_AUX_NATIVE_WRITE & DP_AUX_NATIVE_READ);
117 	bool read = msg->request & (DP_AUX_I2C_READ & DP_AUX_NATIVE_READ);
118 
119 	/* Ignore address only message */
120 	if ((msg->size == 0) || (msg->buffer == NULL)) {
121 		msg->reply = native ?
122 			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
123 		return msg->size;
124 	}
125 
126 	/* msg sanity check */
127 	if ((native && (msg->size > AUX_CMD_NATIVE_MAX)) ||
128 		(msg->size > AUX_CMD_I2C_MAX)) {
129 		pr_err("%s: invalid msg: size(%zu), request(%x)\n",
130 			__func__, msg->size, msg->request);
131 		return -EINVAL;
132 	}
133 
134 	mutex_lock(&aux->msg_mutex);
135 
136 	aux->msg_err = false;
137 	reinit_completion(&aux->msg_comp);
138 
139 	ret = edp_msg_fifo_tx(aux, msg);
140 	if (ret < 0)
141 		goto unlock_exit;
142 
143 	DBG("wait_for_completion");
144 	time_left = wait_for_completion_timeout(&aux->msg_comp,
145 						msecs_to_jiffies(300));
146 	if (!time_left) {
147 		/*
148 		 * Clear GO and reset AUX channel
149 		 * to cancel the current transaction.
150 		 */
151 		edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
152 		msm_edp_aux_ctrl(aux, 1);
153 		pr_err("%s: aux timeout,\n", __func__);
154 		ret = -ETIMEDOUT;
155 		goto unlock_exit;
156 	}
157 	DBG("completion");
158 
159 	if (!aux->msg_err) {
160 		if (read) {
161 			ret = edp_msg_fifo_rx(aux, msg);
162 			if (ret < 0)
163 				goto unlock_exit;
164 		}
165 
166 		msg->reply = native ?
167 			DP_AUX_NATIVE_REPLY_ACK : DP_AUX_I2C_REPLY_ACK;
168 	} else {
169 		/* Reply defer to retry */
170 		msg->reply = native ?
171 			DP_AUX_NATIVE_REPLY_DEFER : DP_AUX_I2C_REPLY_DEFER;
172 		/*
173 		 * The sleep time in caller is not long enough to make sure
174 		 * our H/W completes transactions. Add more defer time here.
175 		 */
176 		msleep(100);
177 	}
178 
179 	/* Return requested size for success or retry */
180 	ret = msg->size;
181 
182 unlock_exit:
183 	mutex_unlock(&aux->msg_mutex);
184 	return ret;
185 }
186 
msm_edp_aux_init(struct device * dev,void __iomem * regbase,struct drm_dp_aux ** drm_aux)187 void *msm_edp_aux_init(struct device *dev, void __iomem *regbase,
188 	struct drm_dp_aux **drm_aux)
189 {
190 	struct edp_aux *aux = NULL;
191 	int ret;
192 
193 	DBG("");
194 	aux = devm_kzalloc(dev, sizeof(*aux), GFP_KERNEL);
195 	if (!aux)
196 		return NULL;
197 
198 	aux->base = regbase;
199 	mutex_init(&aux->msg_mutex);
200 	init_completion(&aux->msg_comp);
201 
202 	aux->drm_aux.name = "msm_edp_aux";
203 	aux->drm_aux.dev = dev;
204 	aux->drm_aux.transfer = edp_aux_transfer;
205 	ret = drm_dp_aux_register(&aux->drm_aux);
206 	if (ret) {
207 		pr_err("%s: failed to register drm aux: %d\n", __func__, ret);
208 		mutex_destroy(&aux->msg_mutex);
209 	}
210 
211 	if (drm_aux && aux)
212 		*drm_aux = &aux->drm_aux;
213 
214 	return aux;
215 }
216 
msm_edp_aux_destroy(struct device * dev,struct edp_aux * aux)217 void msm_edp_aux_destroy(struct device *dev, struct edp_aux *aux)
218 {
219 	if (aux) {
220 		drm_dp_aux_unregister(&aux->drm_aux);
221 		mutex_destroy(&aux->msg_mutex);
222 	}
223 }
224 
msm_edp_aux_irq(struct edp_aux * aux,u32 isr)225 irqreturn_t msm_edp_aux_irq(struct edp_aux *aux, u32 isr)
226 {
227 	if (isr & EDP_INTR_TRANS_STATUS) {
228 		DBG("isr=%x", isr);
229 		edp_write(aux->base + REG_EDP_AUX_TRANS_CTRL, 0);
230 
231 		if (isr & EDP_INTR_AUX_I2C_ERR)
232 			aux->msg_err = true;
233 		else
234 			aux->msg_err = false;
235 
236 		complete(&aux->msg_comp);
237 	}
238 
239 	return IRQ_HANDLED;
240 }
241 
msm_edp_aux_ctrl(struct edp_aux * aux,int enable)242 void msm_edp_aux_ctrl(struct edp_aux *aux, int enable)
243 {
244 	u32 data;
245 
246 	DBG("enable=%d", enable);
247 	data = edp_read(aux->base + REG_EDP_AUX_CTRL);
248 
249 	if (enable) {
250 		data |= EDP_AUX_CTRL_RESET;
251 		edp_write(aux->base + REG_EDP_AUX_CTRL, data);
252 		/* Make sure full reset */
253 		wmb();
254 		usleep_range(500, 1000);
255 
256 		data &= ~EDP_AUX_CTRL_RESET;
257 		data |= EDP_AUX_CTRL_ENABLE;
258 		edp_write(aux->base + REG_EDP_AUX_CTRL, data);
259 	} else {
260 		data &= ~EDP_AUX_CTRL_ENABLE;
261 		edp_write(aux->base + REG_EDP_AUX_CTRL, data);
262 	}
263 }
264 
265