blob: f40abf9365e8ed221ed2435eb6e0147000c27ef9 [file] [log] [blame]
Kuogee Hsiehad69c3c2013-08-01 14:34:29 -07001/* Copyright (c) 2013, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions
5 * are met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above copyright
9 * notice, this list of conditions and the following disclaimer in
10 * the documentation and/or other materials provided with the
11 * distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
22 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
23 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
25 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
26 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 */
29
30#include "edp.h"
31
32extern struct edp_aux_ctrl edpctrl;
33
34extern int edp_hpd_done;
35extern int edp_video_ready;
36
37/*
38 * edp buffer operation
39 */
40char *edp_buf_init(struct edp_buf *eb, char *buf, int size)
41{
42 eb->start = buf;
43 eb->size = size;
44 eb->data = eb->start;
45 eb->end = eb->start + eb->size;
46 eb->len = 0;
47 eb->trans_num = 0;
48 eb->i2c = 0;
49 return eb->data;
50}
51
52static char *edp_buf_reset(struct edp_buf *eb)
53{
54 eb->data = eb->start;
55 eb->len = 0;
56 eb->trans_num = 0;
57 eb->i2c = 0;
58 return eb->data;
59}
60
61static char *edp_buf_push(struct edp_buf *eb, int len)
62{
63 eb->data += len;
64 eb->len += len;
65 return eb->data;
66}
67
68static int edp_buf_trailing(struct edp_buf *eb)
69{
70 return (int)(eb->end - eb->data);
71}
72
73/*
74 * edp aux edp_buf_add_cmd:
75 * NO native and i2c command mix allowed
76 */
77static int edp_buf_add_cmd(struct edp_buf *eb, struct edp_cmd *cmd)
78{
79 char data;
80 char *bp, *cp;
81 int i, len;
82
83 if (cmd->read) /* read */
84 len = 4;
85 else
86 len = cmd->len + 4;
87
88 if (edp_buf_trailing(eb) < len)
89 return 0;
90
91 /*
92 * cmd fifo only has depth of 144 bytes
93 * limit buf length to 128 bytes here
94 */
95 if ((eb->len + len) > 128)
96 return 0;
97
98 bp = eb->data;
99 data = cmd->addr >> 16;
100 data &= 0x0f; /* 4 addr bits */
101 if (cmd->read)
102 data |= BIT(4);
103 *bp++ = data;
104 *bp++ = cmd->addr >> 8;
105 *bp++ = cmd->addr;
106 *bp++ = cmd->len - 1;
107
108 if (!cmd->read) { /* write */
109 cp = cmd->datap;
110 for (i = 0; i < cmd->len; i++)
111 *bp++ = *cp++;
112 }
113 edp_buf_push(eb, len);
114
115 if (cmd->i2c)
116 eb->i2c++;
117
118 eb->trans_num++; /* Increase transaction number */
119
120 return cmd->len - 1;
121}
122
123static int edp_cmd_fifo_tx(struct edp_buf *tp)
124{
125 int data;
126 char *dp;
127 int len, cnt;
128
129 len = tp->len; /* total byte to cmd fifo */
130 if (len == 0)
131 return 0;
132
133 cnt = 0;
134 dp = tp->start;
135
136 while (cnt < len) {
137 data = *dp; /* data byte */
138 data <<= 8;
139 data &= 0x00ff00; /* index = 0, write */
140 if (cnt == 0)
141 data |= BIT(31); /* INDEX_WRITE */
142 dprintf(SPEW, "%s: data=%x\n",__func__, data);
143 edp_write(EDP_BASE + EDP_AUX_DATA, data);
144 cnt++;
145 dp++;
146 }
147
148 data = (tp->trans_num - 1);
149 if (tp->i2c)
150 data |= BIT(8); /* I2C */
151
152 data |= BIT(9); /* GO */
153 dprintf(SPEW, "%s: data=%x\n",__func__, data);
154 edp_write(EDP_BASE + EDP_AUX_TRANS_CTRL, data);
155
156 return tp->len;
157}
158
159static int edp_cmd_fifo_rx(struct edp_buf *rp, int len)
160{
161 int data;
162 char *dp;
163 int i;
164
165 data = 0; /* index = 0 */
166 data |= BIT(31); /* INDEX_WRITE */
167 data |= BIT(0); /* read */
168 edp_write(EDP_BASE + EDP_AUX_DATA, data);
169
170 dp = rp->data;
171
172 /* discard first byte */
173 data = edp_read(EDP_BASE + EDP_AUX_DATA);
174 for (i = 0; i < len; i++) {
175 data = edp_read(EDP_BASE + EDP_AUX_DATA);
176 dprintf(SPEW, "%s: data=%x\n", __func__, data);
177 *dp++ = (char)((data >> 8) & 0xff);
178 }
179
180 rp->len = len;
181 return len;
182}
183
184
185void edp_aux_native_handler(unsigned int isr)
186{
187
188 dprintf(SPEW, "%s: isr=%x\n", __func__, isr);
189
190 if (isr & EDP_INTR_AUX_I2C_DONE)
191 edpctrl.aux_error_num = EDP_AUX_ERR_NONE;
192 else if (isr & EDP_INTR_WRONG_ADDR)
193 edpctrl.aux_error_num = EDP_AUX_ERR_ADDR;
194 else if (isr & EDP_INTR_TIMEOUT)
195 edpctrl.aux_error_num = EDP_AUX_ERR_TOUT;
196 if (isr & EDP_INTR_NACK_DEFER)
197 edpctrl.aux_error_num = EDP_AUX_ERR_NACK;
198}
199
200void edp_aux_i2c_handler(unsigned int isr)
201{
202
203 dprintf(SPEW, "%s: isr=%x\n", __func__, isr);
204
205 if (isr & EDP_INTR_AUX_I2C_DONE) {
206 if (isr & (EDP_INTR_I2C_NACK | EDP_INTR_I2C_DEFER))
207 edpctrl.aux_error_num = EDP_AUX_ERR_NACK;
208 else
209 edpctrl.aux_error_num = EDP_AUX_ERR_NONE;
210 } else {
211 if (isr & EDP_INTR_WRONG_ADDR)
212 edpctrl.aux_error_num = EDP_AUX_ERR_ADDR;
213 else if (isr & EDP_INTR_TIMEOUT)
214 edpctrl.aux_error_num = EDP_AUX_ERR_TOUT;
215 if (isr & EDP_INTR_NACK_DEFER)
216 edpctrl.aux_error_num = EDP_AUX_ERR_NACK;
217 if (isr & EDP_INTR_I2C_NACK)
218 edpctrl.aux_error_num = EDP_AUX_ERR_NACK;
219 if (isr & EDP_INTR_I2C_DEFER)
220 edpctrl.aux_error_num = EDP_AUX_ERR_NACK;
221 }
222}
223
224void mdss_edp_irq_enable(void)
225{
226 edp_write(EDP_BASE + 0x308, EDP_INTR_MASK1);
227 edp_write(EDP_BASE + 0x30c, EDP_INTR_MASK2);
228}
229
230void mdss_edp_irq_disable(void)
231{
232 edp_write(EDP_BASE + 0x308, 0);
233 edp_write(EDP_BASE + 0x30c, 0);
234}
235
236int edp_isr_read(unsigned int *isr1, unsigned int *isr2)
237{
238 unsigned int data1, data2, mask1, mask2;
239 unsigned int ack;
240
241 data1 = edp_read(EDP_BASE + 0x308);
242 data2 = edp_read(EDP_BASE + 0x30c);
243
244 if (data1 == 0 && data2 == 0)
245 return 0;
246
247 mask1 = data1 & EDP_INTR_MASK1;
248 mask2 = data2 & EDP_INTR_MASK2;
249
250 data1 &= ~mask1; /* remove masks bit */
251 data2 &= ~mask2;
252
253 dprintf(SPEW, "%s: isr=%x mask=%x isr2=%x mask2=%x\n",
254 __func__, data1, mask1, data2, mask2);
255
256 if (data1 == 0 && data2 == 0) /* no irq set */
257 return 0;
258
259 ack = data1 & EDP_INTR_STATUS1;
260 ack <<= 1; /* ack bits */
261 ack |= mask1;
262 edp_write(EDP_BASE + 0x308, ack);
263
264 ack = data2 & EDP_INTR_STATUS2;
265 ack <<= 1; /* ack bits */
266 ack |= mask2;
267 edp_write(EDP_BASE + 0x30c, ack);
268
269 if (data1 & EDP_INTR_HPD) {
270 edp_hpd_done++;
271 dprintf(INFO, "%s: got EDP_INTR_HOD\n", __func__);
272 data1 &= ~EDP_INTR_HPD;
273 }
274
275 if (data2 & EDP_INTR_READY_FOR_VIDEO) {
276 edp_video_ready++;
277 dprintf(INFO, "%s: got EDP_INTR_READY_FOR_VIDEO\n", __func__);
278 data2 &= ~EDP_INTR_READY_FOR_VIDEO;
279 }
280
281 if (data1 == 0 && data2 == 0) /* only hpd set */
282 return 0;
283
284 *isr1 = data1;
285 *isr2 = data2;
286
287 return 1;
288}
289
290void edp_isr_poll(void)
291{
292 int cnt;
293 unsigned int isr1, isr2;
294
295 isr1 = 0;
296 isr2 = 0;
297
298 /* one second loop here to cover
299 * the worst case for i2c edid 128 bytes read
300 */
301 cnt = 1000;
302 while(cnt--) {
303 if (edp_isr_read(&isr1, &isr2))
304 break;
305 udelay(1000);
306 }
307
308 if(cnt <= 0) {
309 dprintf(INFO, "%s: NO isr\n", __func__);
310 return;
311 }
312
313 dprintf(SPEW, "%s: isr1=%x isr2=%x\n", __func__, isr1, isr2);
314
315 if (isr2 & EDP_INTR_READY_FOR_VIDEO) {
316 }
317
318 if (isr1 && edpctrl.aux_cmd_busy) {
319 /* clear EDP_AUX_TRANS_CTRL */
320 edp_write(EDP_BASE + 0x318, 0);
321 /* read EDP_INTERRUPT_TRANS_NUM */
322 edpctrl.aux_trans_num = edp_read(EDP_BASE + 0x310);
323
324 if (edpctrl.aux_cmd_i2c)
325 edp_aux_i2c_handler(isr1);
326 else
327 edp_aux_native_handler(isr1);
328 }
329}
330
331int edp_aux_write_cmds(struct edp_aux_ctrl *ep,
332 struct edp_cmd *cmd)
333{
334 struct edp_cmd *cm;
335 struct edp_buf *tp;
336 int len, ret;
337
338 ep->aux_cmd_busy = 1;
339
340 tp = &ep->txp;
341 edp_buf_reset(tp);
342
343 cm = cmd;
344 while (cm) {
345 dprintf(SPEW, "%s: i2c=%d read=%d addr=%x len=%d next=%d\n",
346 __func__, cm->i2c, cm->read, cm->addr, cm->len, cm->next);
347 ret = edp_buf_add_cmd(tp, cm);
348 if (ret <= 0)
349 break;
350 if (cm->next == 0)
351 break;
352 cm++;
353 }
354
355 if (tp->i2c)
356 ep->aux_cmd_i2c = 1;
357 else
358 ep->aux_cmd_i2c = 0;
359
360 len = edp_cmd_fifo_tx(&ep->txp);
361
362 edp_isr_poll();
363
364 if (ep->aux_error_num == EDP_AUX_ERR_NONE)
365 ret = len;
366 else
367 ret = ep->aux_error_num;
368
369 ep->aux_cmd_busy = 0;
370 return ret;
371}
372
373int edp_aux_read_cmds(struct edp_aux_ctrl *ep,
374 struct edp_cmd *cmds)
375{
376 struct edp_cmd *cm;
377 struct edp_buf *tp;
378 struct edp_buf *rp;
379 int len, ret;
380
381 ep->aux_cmd_busy = 1;
382
383 tp = &ep->txp;
384 rp = &ep->rxp;
385 edp_buf_reset(tp);
386 edp_buf_reset(rp);
387
388 cm = cmds;
389 len = 0;
390 while (cm) {
391 dprintf(SPEW, "%s: i2c=%d read=%d addr=%x len=%d next=%d\n",
392 __func__, cm->i2c, cm->read, cm->addr, cm->len, cm->next);
393 ret = edp_buf_add_cmd(tp, cm);
394 len += cm->len;
395 if (ret <= 0)
396 break;
397 if (cm->next == 0)
398 break;
399 cm++;
400 }
401
402 if (tp->i2c)
403 ep->aux_cmd_i2c = 1;
404 else
405 ep->aux_cmd_i2c = 0;
406{
407 unsigned int isr1, isr2;
408
409 isr1 = edp_read(EDP_BASE + 0x308);
410 isr2 = edp_read(EDP_BASE + 0x30c);
411
412 if (isr1 != EDP_INTR_MASK1)
413 dprintf(INFO, "%s: BEFORE: isr1=%x isr2=%x\n", __func__, isr1, isr2);
414}
415
416 edp_cmd_fifo_tx(tp);
417
418 edp_isr_poll();
419
420 if (ep->aux_error_num == EDP_AUX_ERR_NONE)
421 ret = edp_cmd_fifo_rx(rp, len);
422 else
423 ret = ep->aux_error_num;
424
425 ep->aux_cmd_busy = 0;
426
427 return ret;
428}
429
430
431int edp_aux_write_buf(struct edp_aux_ctrl *ep, int addr,
432 char *buf, int len, int i2c)
433{
434 struct edp_cmd cmd;
435
436 cmd.read = 0;
437 cmd.i2c = i2c;
438 cmd.addr = addr;
439 cmd.datap = buf;
440 cmd.len = len & 0x0ff;
441 cmd.next = 0;
442
443 return edp_aux_write_cmds(ep, &cmd);
444}
445
446int edp_aux_read_buf(struct edp_aux_ctrl *ep, int addr,
447 int len, int i2c)
448{
449 struct edp_cmd cmd;
450
451 cmd.read = 1;
452 cmd.i2c = i2c;
453 cmd.addr = addr;
454 cmd.datap = NULL;
455 cmd.len = len & 0x0ff;
456 cmd.next = 0;
457
458 return edp_aux_read_cmds(ep, &cmd);
459}