Linux Audio

Check our new training course

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