blob: b89e8c77b3086bcf6634b17f8d85f92ed7443a08 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 */
13#include <linux/module.h>
14#include <linux/kernel.h>
15#include <linux/sched.h>
16#include <linux/time.h>
17#include <linux/init.h>
18#include <linux/interrupt.h>
19#include <linux/spinlock.h>
20#include <linux/hrtimer.h>
21#include <linux/clk.h>
22#include <linux/io.h>
23#include <linux/debugfs.h>
24#include <linux/semaphore.h>
25#include <linux/uaccess.h>
26#include <asm/system.h>
27#include <asm/mach-types.h>
28#include <mach/hardware.h>
29
30#include "mdp.h"
31#include "msm_fb.h"
32#ifdef CONFIG_FB_MSM_MDP40
33#include "mdp4.h"
34#endif
35#include "mddihosti.h"
36#include "tvenc.h"
37#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
38#include "hdmi_msm.h"
39#endif
40
41#define MDP_DEBUG_BUF 2048
42
43static uint32 mdp_offset;
44static uint32 mdp_count;
45
46static char debug_buf[MDP_DEBUG_BUF];
47
48/*
49 * MDP4
50 *
51 */
52
53static int mdp_offset_open(struct inode *inode, struct file *file)
54{
55 /* non-seekable */
56 file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
57 return 0;
58}
59
60static int mdp_offset_release(struct inode *inode, struct file *file)
61{
62 return 0;
63}
64
65static ssize_t mdp_offset_write(
66 struct file *file,
67 const char __user *buff,
68 size_t count,
69 loff_t *ppos)
70{
71 uint32 off, cnt;
72
73 if (count >= sizeof(debug_buf))
74 return -EFAULT;
75
76 if (copy_from_user(debug_buf, buff, count))
77 return -EFAULT;
78
79 debug_buf[count] = 0; /* end of string */
80
81 sscanf(debug_buf, "%x %d", &off, &cnt);
82
83 if (cnt <= 0)
84 cnt = 1;
85
86 mdp_offset = off;
87 mdp_count = cnt;
88
89 printk(KERN_INFO "%s: offset=%x cnt=%d\n", __func__,
90 mdp_offset, mdp_count);
91
92 return count;
93}
94
95static ssize_t mdp_offset_read(
96 struct file *file,
97 char __user *buff,
98 size_t count,
99 loff_t *ppos)
100{
101 int len = 0;
102
103
104 if (*ppos)
105 return 0; /* the end */
106
107 len = snprintf(debug_buf, sizeof(debug_buf), "0x%08x %d\n",
108 mdp_offset, mdp_count);
109 if (len < 0)
110 return 0;
111
112 if (copy_to_user(buff, debug_buf, len))
113 return -EFAULT;
114
115 *ppos += len; /* increase offset */
116
117 return len;
118}
119
120static const struct file_operations mdp_off_fops = {
121 .open = mdp_offset_open,
122 .release = mdp_offset_release,
123 .read = mdp_offset_read,
124 .write = mdp_offset_write,
125};
126
127static int mdp_reg_open(struct inode *inode, struct file *file)
128{
129 /* non-seekable */
130 file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
131 return 0;
132}
133
134static int mdp_reg_release(struct inode *inode, struct file *file)
135{
136 return 0;
137}
138
139static ssize_t mdp_reg_write(
140 struct file *file,
141 const char __user *buff,
142 size_t count,
143 loff_t *ppos)
144{
145 uint32 off, data;
146 int cnt;
147
148 if (count >= sizeof(debug_buf))
149 return -EFAULT;
150
151 if (copy_from_user(debug_buf, buff, count))
152 return -EFAULT;
153
154 debug_buf[count] = 0; /* end of string */
155
156 cnt = sscanf(debug_buf, "%x %x", &off, &data);
157
158 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
159 outpdw(MDP_BASE + off, data);
160 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
161
162 printk(KERN_INFO "%s: addr=%x data=%x\n", __func__, off, data);
163
164 return count;
165}
166
167static ssize_t mdp_reg_read(
168 struct file *file,
169 char __user *buff,
170 size_t count,
171 loff_t *ppos)
172{
173 int len = 0;
174 uint32 data;
175 int i, j, off, dlen, num;
176 char *bp, *cp;
177 int tot = 0;
178
179
180 if (*ppos)
181 return 0; /* the end */
182
183 j = 0;
184 num = 0;
185 bp = debug_buf;
186 cp = MDP_BASE + mdp_offset;
187 dlen = sizeof(debug_buf);
188 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
189 while (j++ < 8) {
190 len = snprintf(bp, dlen, "0x%08x: ", (int)cp);
191 tot += len;
192 bp += len;
193 dlen -= len;
194 off = 0;
195 i = 0;
196 while (i++ < 4) {
197 data = inpdw(cp + off);
198 len = snprintf(bp, dlen, "%08x ", data);
199 tot += len;
200 bp += len;
201 dlen -= len;
202 off += 4;
203 num++;
204 if (num >= mdp_count)
205 break;
206 }
207 *bp++ = '\n';
208 --dlen;
209 tot++;
210 cp += off;
211 if (num >= mdp_count)
212 break;
213 }
214 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
215 *bp = 0;
216 tot++;
217
218 if (copy_to_user(buff, debug_buf, tot))
219 return -EFAULT;
220
221 *ppos += tot; /* increase offset */
222
223 return tot;
224}
225
226
227static const struct file_operations mdp_reg_fops = {
228 .open = mdp_reg_open,
229 .release = mdp_reg_release,
230 .read = mdp_reg_read,
231 .write = mdp_reg_write,
232};
233
234#ifdef CONFIG_FB_MSM_MDP40
235static int mdp_stat_open(struct inode *inode, struct file *file)
236{
237 /* non-seekable */
238 file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
239 return 0;
240}
241
242static int mdp_stat_release(struct inode *inode, struct file *file)
243{
244 return 0;
245}
246
247static ssize_t mdp_stat_write(
248 struct file *file,
249 const char __user *buff,
250 size_t count,
251 loff_t *ppos)
252{
253 unsigned long flag;
254
255 if (count > sizeof(debug_buf))
256 return -EFAULT;
257
258 spin_lock_irqsave(&mdp_spin_lock, flag);
259 memset((char *)&mdp4_stat, 0 , sizeof(mdp4_stat)); /* reset */
260 spin_unlock_irqrestore(&mdp_spin_lock, flag);
261
262 return count;
263}
264
265static ssize_t mdp_stat_read(
266 struct file *file,
267 char __user *buff,
268 size_t count,
269 loff_t *ppos)
270{
271 int len = 0;
272 int tot = 0;
273 int dlen;
274 char *bp;
275 unsigned long flag;
276
277
278 if (*ppos)
279 return 0; /* the end */
280
281 bp = debug_buf;
282 dlen = sizeof(debug_buf);
283
284 spin_lock_irqsave(&mdp_spin_lock, flag);
285 len = snprintf(bp, dlen, "intr_total: %08lu\n",
286 mdp4_stat.intr_tot);
287 bp += len;
288 dlen -= len;
289 len = snprintf(bp, dlen, "intr_dma_p: %08lu\n",
290 mdp4_stat.intr_dma_p);
291 bp += len;
292 dlen -= len;
293 len = snprintf(bp, dlen, "intr_dma_s: %08lu\n",
294 mdp4_stat.intr_dma_s);
295 bp += len;
296 dlen -= len;
297 len = snprintf(bp, dlen, "intr_dma_e: %08lu\n",
298 mdp4_stat.intr_dma_e);
299 bp += len;
300 dlen -= len;
301 len = snprintf(bp, dlen, "intr_overlay0: %08lu\n",
302 mdp4_stat.intr_overlay0);
303 bp += len;
304 dlen -= len;
305 len = snprintf(bp, dlen, "intr_overlay1: %08lu\n",
306 mdp4_stat.intr_overlay1);
307 bp += len;
308 dlen -= len;
309 len = snprintf(bp, dlen, "unerrun_primary: %08lu\n",
310 mdp4_stat.intr_underrun_p);
311 bp += len;
312 dlen -= len;
313 len = snprintf(bp, dlen, "unerrun_external: %08lu\n\n",
314 mdp4_stat.intr_underrun_e);
315
316 bp += len;
317 dlen -= len;
318 len = snprintf(bp, dlen, "intr_dsi : %08lu\n\n",
319 mdp4_stat.intr_dsi);
320
321 bp += len;
322 dlen -= len;
323 spin_unlock_irqrestore(&mdp_spin_lock, flag);
324
325 len = snprintf(bp, dlen, "kickoff_mddi: %08lu\n",
326 mdp4_stat.kickoff_mddi);
327 bp += len;
328 dlen -= len;
329 len = snprintf(bp, dlen, "kickoff_lcdc: %08lu\n",
330 mdp4_stat.kickoff_lcdc);
331 bp += len;
332 dlen -= len;
333 len = snprintf(bp, dlen, "kickoff_dtv: %08lu\n",
334 mdp4_stat.kickoff_dtv);
335
336 bp += len;
337 dlen -= len;
338 len = snprintf(bp, dlen, "kickoff_atv: %08lu\n",
339 mdp4_stat.kickoff_atv);
340 bp += len;
341 dlen -= len;
342 len = snprintf(bp, dlen, "kickoff_dsi: %08lu\n\n",
343 mdp4_stat.kickoff_dsi);
344 bp += len;
345 dlen -= len;
346 len = snprintf(bp, dlen, "writeback: %08lu\n",
347 mdp4_stat.writeback);
348 bp += len;
349 dlen -= len;
350 len = snprintf(bp, dlen, "overlay0_set: %08lu\n",
351 mdp4_stat.overlay_set[0]);
352 bp += len;
353 dlen -= len;
354 len = snprintf(bp, dlen, "overlay0_unset: %08lu\n",
355 mdp4_stat.overlay_unset[0]);
356 bp += len;
357 dlen -= len;
358 len = snprintf(bp, dlen, "overlay0_play: %08lu\n",
359 mdp4_stat.overlay_play[0]);
360 bp += len;
361 dlen -= len;
362 len = snprintf(bp, dlen, "overlay1_set: %08lu\n",
363 mdp4_stat.overlay_set[1]);
364 bp += len;
365 dlen -= len;
366 len = snprintf(bp, dlen, "overlay1_unset: %08lu\n",
367 mdp4_stat.overlay_unset[1]);
368 bp += len;
369 dlen -= len;
370 len = snprintf(bp, dlen, "overlay1_play: %08lu\n\n",
371 mdp4_stat.overlay_play[1]);
372
373 bp += len;
374 dlen -= len;
375 len = snprintf(bp, dlen, "pipe_rgb1: %08lu\n", mdp4_stat.pipe[0]);
376 bp += len;
377 dlen -= len;
378 len = snprintf(bp, dlen, "pipe_rgb2: %08lu\n", mdp4_stat.pipe[1]);
379 bp += len;
380 dlen -= len;
381 len = snprintf(bp, dlen, "pipe_vg1: %08lu\n", mdp4_stat.pipe[2]);
382 bp += len;
383 dlen -= len;
384 len = snprintf(bp, dlen, "pipe_vg2: %08lu\n\n", mdp4_stat.pipe[3]);
385
386 bp += len;
387 dlen -= len;
388 len = snprintf(bp, dlen, "dsi_clkoff: %08lu\n\n", mdp4_stat.dsi_clkoff);
389
390 bp += len;
391 dlen -= len;
392 len = snprintf(bp, dlen, "err_mixer: %08lu\n", mdp4_stat.err_mixer);
393 bp += len;
394 dlen -= len;
395 len = snprintf(bp, dlen, "err_size: %08lu\n", mdp4_stat.err_size);
396 bp += len;
397 dlen -= len;
398 len = snprintf(bp, dlen, "err_scale: %08lu\n", mdp4_stat.err_scale);
399 bp += len;
400 dlen -= len;
401 len = snprintf(bp, dlen, "err_format: %08lu\n", mdp4_stat.err_format);
402 bp += len;
403 dlen -= len;
404
405 tot = (uint32)bp - (uint32)debug_buf;
406 *bp = 0;
407 tot++;
408
409 if (tot < 0)
410 return 0;
411 if (copy_to_user(buff, debug_buf, tot))
412 return -EFAULT;
413
414 *ppos += tot; /* increase offset */
415
416 return tot;
417}
418
419static const struct file_operations mdp_stat_fops = {
420 .open = mdp_stat_open,
421 .release = mdp_stat_release,
422 .read = mdp_stat_read,
423 .write = mdp_stat_write,
424};
425#endif
426
427/*
428 * MDDI
429 *
430 */
431
432struct mddi_reg {
433 char *name;
434 int off;
435};
436
437static struct mddi_reg mddi_regs_list[] = {
438 {"MDDI_CMD", MDDI_CMD}, /* 0x0000 */
439 {"MDDI_VERSION", MDDI_VERSION}, /* 0x0004 */
440 {"MDDI_PRI_PTR", MDDI_PRI_PTR}, /* 0x0008 */
441 {"MDDI_BPS", MDDI_BPS}, /* 0x0010 */
442 {"MDDI_SPM", MDDI_SPM}, /* 0x0014 */
443 {"MDDI_INT", MDDI_INT}, /* 0x0018 */
444 {"MDDI_INTEN", MDDI_INTEN}, /* 0x001c */
445 {"MDDI_REV_PTR", MDDI_REV_PTR}, /* 0x0020 */
446 {"MDDI_ REV_SIZE", MDDI_REV_SIZE},/* 0x0024 */
447 {"MDDI_STAT", MDDI_STAT}, /* 0x0028 */
448 {"MDDI_REV_RATE_DIV", MDDI_REV_RATE_DIV}, /* 0x002c */
449 {"MDDI_REV_CRC_ERR", MDDI_REV_CRC_ERR}, /* 0x0030 */
450 {"MDDI_TA1_LEN", MDDI_TA1_LEN}, /* 0x0034 */
451 {"MDDI_TA2_LEN", MDDI_TA2_LEN}, /* 0x0038 */
452 {"MDDI_TEST", MDDI_TEST}, /* 0x0040 */
453 {"MDDI_REV_PKT_CNT", MDDI_REV_PKT_CNT}, /* 0x0044 */
454 {"MDDI_DRIVE_HI", MDDI_DRIVE_HI},/* 0x0048 */
455 {"MDDI_DRIVE_LO", MDDI_DRIVE_LO}, /* 0x004c */
456 {"MDDI_DISP_WAKE", MDDI_DISP_WAKE},/* 0x0050 */
457 {"MDDI_REV_ENCAP_SZ", MDDI_REV_ENCAP_SZ}, /* 0x0054 */
458 {"MDDI_RTD_VAL", MDDI_RTD_VAL}, /* 0x0058 */
459 {"MDDI_PAD_CTL", MDDI_PAD_CTL}, /* 0x0068 */
460 {"MDDI_DRIVER_START_CNT", MDDI_DRIVER_START_CNT}, /* 0x006c */
461 {"MDDI_CORE_VER", MDDI_CORE_VER}, /* 0x008c */
462 {"MDDI_FIFO_ALLOC", MDDI_FIFO_ALLOC}, /* 0x0090 */
463 {"MDDI_PAD_IO_CTL", MDDI_PAD_IO_CTL}, /* 0x00a0 */
464 {"MDDI_PAD_CAL", MDDI_PAD_CAL}, /* 0x00a4 */
465 {0, 0}
466};
467
468static int mddi_reg_open(struct inode *inode, struct file *file)
469{
470 /* non-seekable */
471 file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
472 return 0;
473}
474
475static int mddi_reg_release(struct inode *inode, struct file *file)
476{
477 return 0;
478}
479
480static void mddi_reg_write(int ndx, uint32 off, uint32 data)
481{
482 char *base;
483
484 if (ndx)
485 base = (char *)msm_emdh_base;
486 else
487 base = (char *)msm_pmdh_base;
488
489 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
490 writel(data, base + off);
491 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
492
493 printk(KERN_INFO "%s: addr=%x data=%x\n",
494 __func__, (int)(base+off), (int)data);
495}
496
497static int mddi_reg_read(int ndx)
498{
499 struct mddi_reg *reg;
500 unsigned char *base;
501 int data;
502 char *bp;
503 int len = 0;
504 int tot = 0;
505 int dlen;
506
507 if (ndx)
508 base = msm_emdh_base;
509 else
510 base = msm_pmdh_base;
511
512 reg = mddi_regs_list;
513 bp = debug_buf;
514 dlen = sizeof(debug_buf);
515
516 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
517 while (reg->name) {
518 data = readl((u32)base + reg->off);
519 len = snprintf(bp, dlen, "%s:0x%08x\t\t= 0x%08x\n",
520 reg->name, reg->off, data);
521 tot += len;
522 bp += len;
523 dlen -= len;
524 reg++;
525 }
526 mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
527 *bp = 0;
528 tot++;
529
530 return tot;
531}
532
533static ssize_t pmdh_reg_write(
534 struct file *file,
535 const char __user *buff,
536 size_t count,
537 loff_t *ppos)
538{
539 uint32 off, data;
540 int cnt;
541
542 if (count >= sizeof(debug_buf))
543 return -EFAULT;
544
545 if (copy_from_user(debug_buf, buff, count))
546 return -EFAULT;
547
548 debug_buf[count] = 0; /* end of string */
549
550 cnt = sscanf(debug_buf, "%x %x", &off, &data);
551
552 mddi_reg_write(0, off, data);
553
554 return count;
555}
556
557static ssize_t pmdh_reg_read(
558 struct file *file,
559 char __user *buff,
560 size_t count,
561 loff_t *ppos)
562{
563 int tot = 0;
564
565 if (*ppos)
566 return 0; /* the end */
567
568 tot = mddi_reg_read(0); /* pmdh */
569
570 if (tot < 0)
571 return 0;
572 if (copy_to_user(buff, debug_buf, tot))
573 return -EFAULT;
574
575 *ppos += tot; /* increase offset */
576
577 return tot;
578}
579
580
581static const struct file_operations pmdh_fops = {
582 .open = mddi_reg_open,
583 .release = mddi_reg_release,
584 .read = pmdh_reg_read,
585 .write = pmdh_reg_write,
586};
587
588
589
590#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDDI)
591static int vsync_reg_open(struct inode *inode, struct file *file)
592{
593 /* non-seekable */
594 file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
595 return 0;
596}
597
598static int vsync_reg_release(struct inode *inode, struct file *file)
599{
600 return 0;
601}
602
603static ssize_t vsync_reg_write(
604 struct file *file,
605 const char __user *buff,
606 size_t count,
607 loff_t *ppos)
608{
609 uint32 enable;
610 int cnt;
611
612 if (count >= sizeof(debug_buf))
613 return -EFAULT;
614
615 if (copy_from_user(debug_buf, buff, count))
616 return -EFAULT;
617
618 debug_buf[count] = 0; /* end of string */
619
620 cnt = sscanf(debug_buf, "%x", &enable);
621
622 mdp_dmap_vsync_set(enable);
623
624 return count;
625}
626
627static ssize_t vsync_reg_read(
628 struct file *file,
629 char __user *buff,
630 size_t count,
631 loff_t *ppos)
632{
633 char *bp;
634 int len = 0;
635 int tot = 0;
636 int dlen;
637
638 if (*ppos)
639 return 0; /* the end */
640
641 bp = debug_buf;
642 dlen = sizeof(debug_buf);
643 len = snprintf(bp, dlen, "%x\n", mdp_dmap_vsync_get());
644 tot += len;
645 bp += len;
646 *bp = 0;
647 tot++;
648
649 if (copy_to_user(buff, debug_buf, tot))
650 return -EFAULT;
651
652 *ppos += tot; /* increase offset */
653
654 return tot;
655}
656
657
658static const struct file_operations vsync_fops = {
659 .open = vsync_reg_open,
660 .release = vsync_reg_release,
661 .read = vsync_reg_read,
662 .write = vsync_reg_write,
663};
664#endif
665
666static ssize_t emdh_reg_write(
667 struct file *file,
668 const char __user *buff,
669 size_t count,
670 loff_t *ppos)
671{
672 uint32 off, data;
673 int cnt;
674
675 if (count >= sizeof(debug_buf))
676 return -EFAULT;
677
678 if (copy_from_user(debug_buf, buff, count))
679 return -EFAULT;
680
681 debug_buf[count] = 0; /* end of string */
682
683 cnt = sscanf(debug_buf, "%x %x", &off, &data);
684
685 mddi_reg_write(1, off, data);
686
687 return count;
688}
689
690static ssize_t emdh_reg_read(
691 struct file *file,
692 char __user *buff,
693 size_t count,
694 loff_t *ppos)
695{
696 int tot = 0;
697
698 if (*ppos)
699 return 0; /* the end */
700
701 tot = mddi_reg_read(1); /* emdh */
702
703 if (tot < 0)
704 return 0;
705 if (copy_to_user(buff, debug_buf, tot))
706 return -EFAULT;
707
708 *ppos += tot; /* increase offset */
709
710 return tot;
711}
712
713static const struct file_operations emdh_fops = {
714 .open = mddi_reg_open,
715 .release = mddi_reg_release,
716 .read = emdh_reg_read,
717 .write = emdh_reg_write,
718};
719
720
721uint32 dbg_offset;
722uint32 dbg_count;
723char *dbg_base;
724
725
726static int dbg_open(struct inode *inode, struct file *file)
727{
728 /* non-seekable */
729 file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
730 return 0;
731}
732
733static int dbg_release(struct inode *inode, struct file *file)
734{
735 return 0;
736}
737
738static ssize_t dbg_base_write(
739 struct file *file,
740 const char __user *buff,
741 size_t count,
742 loff_t *ppos)
743{
744 return count;
745}
746
747static ssize_t dbg_base_read(
748 struct file *file,
749 char __user *buff,
750 size_t count,
751 loff_t *ppos)
752{
753 int len = 0;
754 int tot = 0;
755 int dlen;
756 char *bp;
757
758
759 if (*ppos)
760 return 0; /* the end */
761
762
763 bp = debug_buf;
764 dlen = sizeof(debug_buf);
765
766 len = snprintf(bp, dlen, "mdp_base : %08x\n",
767 (int)msm_mdp_base);
768 bp += len;
769 dlen -= len;
770 len = snprintf(bp, dlen, "mddi_base : %08x\n",
771 (int)msm_pmdh_base);
772 bp += len;
773 dlen -= len;
774 len = snprintf(bp, dlen, "emdh_base : %08x\n",
775 (int)msm_emdh_base);
776 bp += len;
777 dlen -= len;
778#ifdef CONFIG_FB_MSM_TVOUT
779 len = snprintf(bp, dlen, "tvenv_base: %08x\n",
780 (int)tvenc_base);
781 bp += len;
782 dlen -= len;
783#endif
784
785#ifdef CONFIG_FB_MSM_MIPI_DSI
786 len = snprintf(bp, dlen, "mipi_dsi_base: %08x\n",
787 (int)mipi_dsi_base);
788 bp += len;
789 dlen -= len;
790#endif
791
792 tot = (uint32)bp - (uint32)debug_buf;
793 *bp = 0;
794 tot++;
795
796 if (tot < 0)
797 return 0;
798 if (copy_to_user(buff, debug_buf, tot))
799 return -EFAULT;
800
801 *ppos += tot; /* increase offset */
802
803 return tot;
804}
805
806static const struct file_operations dbg_base_fops = {
807 .open = dbg_open,
808 .release = dbg_release,
809 .read = dbg_base_read,
810 .write = dbg_base_write,
811};
812
813static ssize_t dbg_offset_write(
814 struct file *file,
815 const char __user *buff,
816 size_t count,
817 loff_t *ppos)
818{
819 uint32 off, cnt, num, base;
820
821 if (count >= sizeof(debug_buf))
822 return -EFAULT;
823
824 if (copy_from_user(debug_buf, buff, count))
825 return -EFAULT;
826
827 debug_buf[count] = 0; /* end of string */
828
829 cnt = sscanf(debug_buf, "%x %d %x", &off, &num, &base);
830
831 if (cnt < 0)
832 cnt = 0;
833
834 if (cnt >= 1)
835 dbg_offset = off;
836 if (cnt >= 2)
837 dbg_count = num;
838 if (cnt >= 3)
839 dbg_base = (char *)base;
840
841 printk(KERN_INFO "%s: offset=%x cnt=%d base=%x\n", __func__,
842 dbg_offset, dbg_count, (int)dbg_base);
843
844 return count;
845}
846
847static ssize_t dbg_offset_read(
848 struct file *file,
849 char __user *buff,
850 size_t count,
851 loff_t *ppos)
852{
853 int len = 0;
854
855
856 if (*ppos)
857 return 0; /* the end */
858
859 len = snprintf(debug_buf, sizeof(debug_buf), "0x%08x %d 0x%08x\n",
860 dbg_offset, dbg_count, (int)dbg_base);
861 if (len < 0)
862 return 0;
863
864 if (copy_to_user(buff, debug_buf, len))
865 return -EFAULT;
866
867 *ppos += len; /* increase offset */
868
869 return len;
870}
871
872static const struct file_operations dbg_off_fops = {
873 .open = dbg_open,
874 .release = dbg_release,
875 .read = dbg_offset_read,
876 .write = dbg_offset_write,
877};
878
879
880static ssize_t dbg_reg_write(
881 struct file *file,
882 const char __user *buff,
883 size_t count,
884 loff_t *ppos)
885{
886 uint32 off, data;
887 int cnt;
888
889 if (count >= sizeof(debug_buf))
890 return -EFAULT;
891
892 if (copy_from_user(debug_buf, buff, count))
893 return -EFAULT;
894
895 debug_buf[count] = 0; /* end of string */
896
897 cnt = sscanf(debug_buf, "%x %x", &off, &data);
898
899 writel(data, dbg_base + off);
900
901 printk(KERN_INFO "%s: addr=%x data=%x\n",
902 __func__, (int)(dbg_base+off), (int)data);
903
904 return count;
905}
906
907static ssize_t dbg_reg_read(
908 struct file *file,
909 char __user *buff,
910 size_t count,
911 loff_t *ppos)
912{
913 int len = 0;
914 uint32 data;
915 int i, j, off, dlen, num;
916 char *bp, *cp;
917 int tot = 0;
918
919
920 if (*ppos)
921 return 0; /* the end */
922
923 if (dbg_base == 0)
924 return 0; /* nothing to read */
925
926 j = 0;
927 num = 0;
928 bp = debug_buf;
929 cp = (char *)(dbg_base + dbg_offset);
930 dlen = sizeof(debug_buf);
931 while (j++ < 16) {
932 len = snprintf(bp, dlen, "0x%08x: ", (int)cp);
933 tot += len;
934 bp += len;
935 dlen -= len;
936 off = 0;
937 i = 0;
938 while (i++ < 4) {
939 data = readl(cp + off);
940 len = snprintf(bp, dlen, "%08x ", data);
941 tot += len;
942 bp += len;
943 dlen -= len;
944 off += 4;
945 num++;
946 if (num >= dbg_count)
947 break;
948 }
949 data = readl((u32)cp + off);
950 *bp++ = '\n';
951 --dlen;
952 tot++;
953 cp += off;
954 if (num >= dbg_count)
955 break;
956 }
957 *bp = 0;
958 tot++;
959
960 if (copy_to_user(buff, debug_buf, tot))
961 return -EFAULT;
962
963 *ppos += tot; /* increase offset */
964
965 return tot;
966}
967
968
969static const struct file_operations dbg_reg_fops = {
970 .open = dbg_open,
971 .release = dbg_release,
972 .read = dbg_reg_read,
973 .write = dbg_reg_write,
974};
975
976#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
977static uint32 hdmi_offset;
978static uint32 hdmi_count;
979
980static int hdmi_open(struct inode *inode, struct file *file)
981{
982 /* non-seekable */
983 file->f_mode &= ~(FMODE_LSEEK | FMODE_PREAD | FMODE_PWRITE);
984 return 0;
985}
986
987static int hdmi_release(struct inode *inode, struct file *file)
988{
989 return 0;
990}
991
992static ssize_t hdmi_offset_write(
993 struct file *file,
994 const char __user *buff,
995 size_t count,
996 loff_t *ppos)
997{
998 uint32 off, cnt, num;
999
1000 if (count >= sizeof(debug_buf))
1001 return -EFAULT;
1002
1003 if (copy_from_user(debug_buf, buff, count))
1004 return -EFAULT;
1005
1006 debug_buf[count] = 0; /* end of string */
1007
1008 cnt = sscanf(debug_buf, "%x %d", &off, &num);
1009
1010 if (cnt < 0)
1011 cnt = 0;
1012
1013 if (cnt >= 1)
1014 hdmi_offset = off;
1015 if (cnt >= 2)
1016 hdmi_count = num;
1017
1018 printk(KERN_INFO "%s: offset=%x cnt=%d\n", __func__,
1019 hdmi_offset, hdmi_count);
1020
1021 return count;
1022}
1023
1024static ssize_t hdmi_offset_read(
1025 struct file *file,
1026 char __user *buff,
1027 size_t count,
1028 loff_t *ppos)
1029{
1030 int len = 0;
1031
1032
1033 if (*ppos)
1034 return 0; /* the end */
1035
1036 len = snprintf(debug_buf, sizeof(debug_buf), "0x%08x %d\n",
1037 hdmi_offset, hdmi_count);
1038 if (len < 0)
1039 return 0;
1040
1041 if (copy_to_user(buff, debug_buf, len))
1042 return -EFAULT;
1043
1044 *ppos += len; /* increase offset */
1045
1046 return len;
1047}
1048
1049static const struct file_operations hdmi_off_fops = {
1050 .open = hdmi_open,
1051 .release = hdmi_release,
1052 .read = hdmi_offset_read,
1053 .write = hdmi_offset_write,
1054};
1055
1056
1057static ssize_t hdmi_reg_write(
1058 struct file *file,
1059 const char __user *buff,
1060 size_t count,
1061 loff_t *ppos)
1062{
1063 uint32 off, data, base;
1064 int cnt;
1065
1066 if (count >= sizeof(debug_buf))
1067 return -EFAULT;
1068
1069 if (copy_from_user(debug_buf, buff, count))
1070 return -EFAULT;
1071
1072 base = hdmi_msm_get_io_base();
1073 if (base == 0)
1074 return -EFAULT;
1075
1076 debug_buf[count] = 0; /* end of string */
1077
1078 cnt = sscanf(debug_buf, "%x %x", &off, &data);
1079
1080 writel(data, base + off);
1081
1082 printk(KERN_INFO "%s: addr=%x data=%x\n",
1083 __func__, (int)(base+off), (int)data);
1084
1085 return count;
1086}
1087
1088static ssize_t hdmi_reg_read(
1089 struct file *file,
1090 char __user *buff,
1091 size_t count,
1092 loff_t *ppos)
1093{
1094 int len = 0;
1095 uint32 data;
1096 int i, j, off, dlen, num;
1097 char *bp, *cp;
1098 int tot = 0;
1099
1100
1101 if (*ppos)
1102 return 0; /* the end */
1103
1104 if (hdmi_msm_get_io_base() == 0)
1105 return 0; /* nothing to read */
1106
1107 j = 0;
1108 num = 0;
1109 bp = debug_buf;
1110 cp = (char *)(hdmi_msm_get_io_base() + hdmi_offset);
1111 dlen = sizeof(debug_buf);
1112 while (j++ < 16) {
1113 len = snprintf(bp, dlen, "0x%08x: ", (int)cp);
1114 tot += len;
1115 bp += len;
1116 dlen -= len;
1117 off = 0;
1118 i = 0;
1119 while (i++ < 4) {
1120 data = readl(cp + off);
1121 len = snprintf(bp, dlen, "%08x ", data);
1122 tot += len;
1123 bp += len;
1124 dlen -= len;
1125 off += 4;
1126 num++;
1127 if (num >= hdmi_count)
1128 break;
1129 }
1130 data = readl((u32)cp + off);
1131 *bp++ = '\n';
1132 --dlen;
1133 tot++;
1134 cp += off;
1135 if (num >= hdmi_count)
1136 break;
1137 }
1138 *bp = 0;
1139 tot++;
1140
1141 if (copy_to_user(buff, debug_buf, tot))
1142 return -EFAULT;
1143
1144 *ppos += tot; /* increase offset */
1145
1146 return tot;
1147}
1148
1149
1150static const struct file_operations hdmi_reg_fops = {
1151 .open = hdmi_open,
1152 .release = hdmi_release,
1153 .read = hdmi_reg_read,
1154 .write = hdmi_reg_write,
1155};
1156#endif
1157
1158/*
1159 * debugfs
1160 *
1161 */
1162
1163int mdp_debugfs_init(void)
1164{
1165 struct dentry *dent = debugfs_create_dir("mdp", NULL);
1166
1167 if (IS_ERR(dent)) {
1168 printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
1169 __FILE__, __LINE__, PTR_ERR(dent));
1170 return -1;
1171 }
1172
1173 if (debugfs_create_file("off", 0644, dent, 0, &mdp_off_fops)
1174 == NULL) {
1175 printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
1176 __FILE__, __LINE__);
1177 return -1;
1178 }
1179
1180 if (debugfs_create_file("reg", 0644, dent, 0, &mdp_reg_fops)
1181 == NULL) {
1182 printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
1183 __FILE__, __LINE__);
1184 return -1;
1185 }
1186
1187#ifdef CONFIG_FB_MSM_MDP40
1188 if (debugfs_create_file("stat", 0644, dent, 0, &mdp_stat_fops)
1189 == NULL) {
1190 printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
1191 __FILE__, __LINE__);
1192 return -1;
1193 }
1194#endif
1195
1196 dent = debugfs_create_dir("mddi", NULL);
1197
1198 if (IS_ERR(dent)) {
1199 printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
1200 __FILE__, __LINE__, PTR_ERR(dent));
1201 return -1;
1202 }
1203
1204 if (debugfs_create_file("reg", 0644, dent, 0, &pmdh_fops)
1205 == NULL) {
1206 printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
1207 __FILE__, __LINE__);
1208 return -1;
1209 }
1210
1211#if defined(CONFIG_FB_MSM_OVERLAY) && defined(CONFIG_FB_MSM_MDDI)
1212 if (debugfs_create_file("vsync", 0644, dent, 0, &vsync_fops)
1213 == NULL) {
1214 printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
1215 __FILE__, __LINE__);
1216 return -1;
1217 }
1218#endif
1219
1220 dent = debugfs_create_dir("emdh", NULL);
1221
1222 if (IS_ERR(dent)) {
1223 printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
1224 __FILE__, __LINE__, PTR_ERR(dent));
1225 return -1;
1226 }
1227
1228 if (debugfs_create_file("reg", 0644, dent, 0, &emdh_fops)
1229 == NULL) {
1230 printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
1231 __FILE__, __LINE__);
1232 return -1;
1233 }
1234
1235 dent = debugfs_create_dir("mdp-dbg", NULL);
1236
1237 if (IS_ERR(dent)) {
1238 printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
1239 __FILE__, __LINE__, PTR_ERR(dent));
1240 return -1;
1241 }
1242
1243 if (debugfs_create_file("base", 0644, dent, 0, &dbg_base_fops)
1244 == NULL) {
1245 printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
1246 __FILE__, __LINE__);
1247 return -1;
1248 }
1249
1250 if (debugfs_create_file("off", 0644, dent, 0, &dbg_off_fops)
1251 == NULL) {
1252 printk(KERN_ERR "%s(%d): debugfs_create_file: index fail\n",
1253 __FILE__, __LINE__);
1254 return -1;
1255 }
1256
1257 if (debugfs_create_file("reg", 0644, dent, 0, &dbg_reg_fops)
1258 == NULL) {
1259 printk(KERN_ERR "%s(%d): debugfs_create_file: debug fail\n",
1260 __FILE__, __LINE__);
1261 return -1;
1262 }
1263
1264#ifdef CONFIG_FB_MSM_HDMI_MSM_PANEL
1265 dent = debugfs_create_dir("hdmi", NULL);
1266
1267 if (IS_ERR(dent)) {
1268 printk(KERN_ERR "%s(%d): debugfs_create_dir fail, error %ld\n",
1269 __FILE__, __LINE__, PTR_ERR(dent));
1270 return PTR_ERR(dent);
1271 }
1272
1273 if (debugfs_create_file("off", 0644, dent, 0, &hdmi_off_fops)
1274 == NULL) {
1275 printk(KERN_ERR "%s(%d): debugfs_create_file: 'off' fail\n",
1276 __FILE__, __LINE__);
1277 return -ENOENT;
1278 }
1279
1280 if (debugfs_create_file("reg", 0644, dent, 0, &hdmi_reg_fops)
1281 == NULL) {
1282 printk(KERN_ERR "%s(%d): debugfs_create_file: 'reg' fail\n",
1283 __FILE__, __LINE__);
1284 return -ENOENT;
1285 }
1286#endif
1287
1288 return 0;
1289}