Loading...
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
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
20struct 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
33static 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
80static 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 */
110static 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
182unlock_exit:
183 mutex_unlock(&aux->msg_mutex);
184 return ret;
185}
186
187void *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
217void 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
225irqreturn_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
242void 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