aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_pipe_crc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_pipe_crc.c')
-rw-r--r--drivers/gpu/drm/i915/intel_pipe_crc.c445
1 files changed, 0 insertions, 445 deletions
diff --git a/drivers/gpu/drm/i915/intel_pipe_crc.c b/drivers/gpu/drm/i915/intel_pipe_crc.c
index 39a4e4edda07..849e1b69ba73 100644
--- a/drivers/gpu/drm/i915/intel_pipe_crc.c
+++ b/drivers/gpu/drm/i915/intel_pipe_crc.c
@@ -30,160 +30,6 @@
30#include <linux/debugfs.h> 30#include <linux/debugfs.h>
31#include "intel_drv.h" 31#include "intel_drv.h"
32 32
33struct pipe_crc_info {
34 const char *name;
35 struct drm_i915_private *dev_priv;
36 enum pipe pipe;
37};
38
39static int i915_pipe_crc_open(struct inode *inode, struct file *filep)
40{
41 struct pipe_crc_info *info = inode->i_private;
42 struct drm_i915_private *dev_priv = info->dev_priv;
43 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
44
45 if (info->pipe >= INTEL_INFO(dev_priv)->num_pipes)
46 return -ENODEV;
47
48 spin_lock_irq(&pipe_crc->lock);
49
50 if (pipe_crc->opened) {
51 spin_unlock_irq(&pipe_crc->lock);
52 return -EBUSY; /* already open */
53 }
54
55 pipe_crc->opened = true;
56 filep->private_data = inode->i_private;
57
58 spin_unlock_irq(&pipe_crc->lock);
59
60 return 0;
61}
62
63static int i915_pipe_crc_release(struct inode *inode, struct file *filep)
64{
65 struct pipe_crc_info *info = inode->i_private;
66 struct drm_i915_private *dev_priv = info->dev_priv;
67 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
68
69 spin_lock_irq(&pipe_crc->lock);
70 pipe_crc->opened = false;
71 spin_unlock_irq(&pipe_crc->lock);
72
73 return 0;
74}
75
76/* (6 fields, 8 chars each, space separated (5) + '\n') */
77#define PIPE_CRC_LINE_LEN (6 * 8 + 5 + 1)
78/* account for \'0' */
79#define PIPE_CRC_BUFFER_LEN (PIPE_CRC_LINE_LEN + 1)
80
81static int pipe_crc_data_count(struct intel_pipe_crc *pipe_crc)
82{
83 lockdep_assert_held(&pipe_crc->lock);
84 return CIRC_CNT(pipe_crc->head, pipe_crc->tail,
85 INTEL_PIPE_CRC_ENTRIES_NR);
86}
87
88static ssize_t
89i915_pipe_crc_read(struct file *filep, char __user *user_buf, size_t count,
90 loff_t *pos)
91{
92 struct pipe_crc_info *info = filep->private_data;
93 struct drm_i915_private *dev_priv = info->dev_priv;
94 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[info->pipe];
95 char buf[PIPE_CRC_BUFFER_LEN];
96 int n_entries;
97 ssize_t bytes_read;
98
99 /*
100 * Don't allow user space to provide buffers not big enough to hold
101 * a line of data.
102 */
103 if (count < PIPE_CRC_LINE_LEN)
104 return -EINVAL;
105
106 if (pipe_crc->source == INTEL_PIPE_CRC_SOURCE_NONE)
107 return 0;
108
109 /* nothing to read */
110 spin_lock_irq(&pipe_crc->lock);
111 while (pipe_crc_data_count(pipe_crc) == 0) {
112 int ret;
113
114 if (filep->f_flags & O_NONBLOCK) {
115 spin_unlock_irq(&pipe_crc->lock);
116 return -EAGAIN;
117 }
118
119 ret = wait_event_interruptible_lock_irq(pipe_crc->wq,
120 pipe_crc_data_count(pipe_crc), pipe_crc->lock);
121 if (ret) {
122 spin_unlock_irq(&pipe_crc->lock);
123 return ret;
124 }
125 }
126
127 /* We now have one or more entries to read */
128 n_entries = count / PIPE_CRC_LINE_LEN;
129
130 bytes_read = 0;
131 while (n_entries > 0) {
132 struct intel_pipe_crc_entry *entry =
133 &pipe_crc->entries[pipe_crc->tail];
134
135 if (CIRC_CNT(pipe_crc->head, pipe_crc->tail,
136 INTEL_PIPE_CRC_ENTRIES_NR) < 1)
137 break;
138
139 BUILD_BUG_ON_NOT_POWER_OF_2(INTEL_PIPE_CRC_ENTRIES_NR);
140 pipe_crc->tail = (pipe_crc->tail + 1) &
141 (INTEL_PIPE_CRC_ENTRIES_NR - 1);
142
143 bytes_read += snprintf(buf, PIPE_CRC_BUFFER_LEN,
144 "%8u %8x %8x %8x %8x %8x\n",
145 entry->frame, entry->crc[0],
146 entry->crc[1], entry->crc[2],
147 entry->crc[3], entry->crc[4]);
148
149 spin_unlock_irq(&pipe_crc->lock);
150
151 if (copy_to_user(user_buf, buf, PIPE_CRC_LINE_LEN))
152 return -EFAULT;
153
154 user_buf += PIPE_CRC_LINE_LEN;
155 n_entries--;
156
157 spin_lock_irq(&pipe_crc->lock);
158 }
159
160 spin_unlock_irq(&pipe_crc->lock);
161
162 return bytes_read;
163}
164
165static const struct file_operations i915_pipe_crc_fops = {
166 .owner = THIS_MODULE,
167 .open = i915_pipe_crc_open,
168 .read = i915_pipe_crc_read,
169 .release = i915_pipe_crc_release,
170};
171
172static struct pipe_crc_info i915_pipe_crc_data[I915_MAX_PIPES] = {
173 {
174 .name = "i915_pipe_A_crc",
175 .pipe = PIPE_A,
176 },
177 {
178 .name = "i915_pipe_B_crc",
179 .pipe = PIPE_B,
180 },
181 {
182 .name = "i915_pipe_C_crc",
183 .pipe = PIPE_C,
184 },
185};
186
187static const char * const pipe_crc_sources[] = { 33static const char * const pipe_crc_sources[] = {
188 "none", 34 "none",
189 "plane1", 35 "plane1",
@@ -197,29 +43,6 @@ static const char * const pipe_crc_sources[] = {
197 "auto", 43 "auto",
198}; 44};
199 45
200static const char *pipe_crc_source_name(enum intel_pipe_crc_source source)
201{
202 BUILD_BUG_ON(ARRAY_SIZE(pipe_crc_sources) != INTEL_PIPE_CRC_SOURCE_MAX);
203 return pipe_crc_sources[source];
204}
205
206static int display_crc_ctl_show(struct seq_file *m, void *data)
207{
208 struct drm_i915_private *dev_priv = m->private;
209 enum pipe pipe;
210
211 for_each_pipe(dev_priv, pipe)
212 seq_printf(m, "%c %s\n", pipe_name(pipe),
213 pipe_crc_source_name(dev_priv->pipe_crc[pipe].source));
214
215 return 0;
216}
217
218static int display_crc_ctl_open(struct inode *inode, struct file *file)
219{
220 return single_open(file, display_crc_ctl_show, inode->i_private);
221}
222
223static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source, 46static int i8xx_pipe_crc_ctl_reg(enum intel_pipe_crc_source *source,
224 uint32_t *val) 47 uint32_t *val)
225{ 48{
@@ -616,177 +439,6 @@ static int get_new_crc_ctl_reg(struct drm_i915_private *dev_priv,
616 return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val, set_wa); 439 return ivb_pipe_crc_ctl_reg(dev_priv, pipe, source, val, set_wa);
617} 440}
618 441
619static int pipe_crc_set_source(struct drm_i915_private *dev_priv,
620 enum pipe pipe,
621 enum intel_pipe_crc_source source)
622{
623 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
624 enum intel_display_power_domain power_domain;
625 u32 val = 0; /* shut up gcc */
626 int ret;
627
628 if (pipe_crc->source == source)
629 return 0;
630
631 /* forbid changing the source without going back to 'none' */
632 if (pipe_crc->source && source)
633 return -EINVAL;
634
635 power_domain = POWER_DOMAIN_PIPE(pipe);
636 if (!intel_display_power_get_if_enabled(dev_priv, power_domain)) {
637 DRM_DEBUG_KMS("Trying to capture CRC while pipe is off\n");
638 return -EIO;
639 }
640
641 ret = get_new_crc_ctl_reg(dev_priv, pipe, &source, &val, true);
642 if (ret != 0)
643 goto out;
644
645 /* none -> real source transition */
646 if (source) {
647 struct intel_pipe_crc_entry *entries;
648
649 DRM_DEBUG_DRIVER("collecting CRCs for pipe %c, %s\n",
650 pipe_name(pipe), pipe_crc_source_name(source));
651
652 entries = kcalloc(INTEL_PIPE_CRC_ENTRIES_NR,
653 sizeof(pipe_crc->entries[0]),
654 GFP_KERNEL);
655 if (!entries) {
656 ret = -ENOMEM;
657 goto out;
658 }
659
660 spin_lock_irq(&pipe_crc->lock);
661 kfree(pipe_crc->entries);
662 pipe_crc->entries = entries;
663 pipe_crc->head = 0;
664 pipe_crc->tail = 0;
665 spin_unlock_irq(&pipe_crc->lock);
666 }
667
668 pipe_crc->source = source;
669
670 I915_WRITE(PIPE_CRC_CTL(pipe), val);
671 POSTING_READ(PIPE_CRC_CTL(pipe));
672
673 /* real source -> none transition */
674 if (!source) {
675 struct intel_pipe_crc_entry *entries;
676 struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv,
677 pipe);
678
679 DRM_DEBUG_DRIVER("stopping CRCs for pipe %c\n",
680 pipe_name(pipe));
681
682 drm_modeset_lock(&crtc->base.mutex, NULL);
683 if (crtc->base.state->active)
684 intel_wait_for_vblank(dev_priv, pipe);
685 drm_modeset_unlock(&crtc->base.mutex);
686
687 spin_lock_irq(&pipe_crc->lock);
688 entries = pipe_crc->entries;
689 pipe_crc->entries = NULL;
690 pipe_crc->head = 0;
691 pipe_crc->tail = 0;
692 spin_unlock_irq(&pipe_crc->lock);
693
694 kfree(entries);
695
696 if (IS_G4X(dev_priv))
697 g4x_undo_pipe_scramble_reset(dev_priv, pipe);
698 else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
699 vlv_undo_pipe_scramble_reset(dev_priv, pipe);
700 else if ((IS_HASWELL(dev_priv) ||
701 IS_BROADWELL(dev_priv)) && pipe == PIPE_A)
702 hsw_pipe_A_crc_wa(dev_priv, false);
703 }
704
705 ret = 0;
706
707out:
708 intel_display_power_put(dev_priv, power_domain);
709
710 return ret;
711}
712
713/*
714 * Parse pipe CRC command strings:
715 * command: wsp* object wsp+ name wsp+ source wsp*
716 * object: 'pipe'
717 * name: (A | B | C)
718 * source: (none | plane1 | plane2 | pf)
719 * wsp: (#0x20 | #0x9 | #0xA)+
720 *
721 * eg.:
722 * "pipe A plane1" -> Start CRC computations on plane1 of pipe A
723 * "pipe A none" -> Stop CRC
724 */
725static int display_crc_ctl_tokenize(char *buf, char *words[], int max_words)
726{
727 int n_words = 0;
728
729 while (*buf) {
730 char *end;
731
732 /* skip leading white space */
733 buf = skip_spaces(buf);
734 if (!*buf)
735 break; /* end of buffer */
736
737 /* find end of word */
738 for (end = buf; *end && !isspace(*end); end++)
739 ;
740
741 if (n_words == max_words) {
742 DRM_DEBUG_DRIVER("too many words, allowed <= %d\n",
743 max_words);
744 return -EINVAL; /* ran out of words[] before bytes */
745 }
746
747 if (*end)
748 *end++ = '\0';
749 words[n_words++] = buf;
750 buf = end;
751 }
752
753 return n_words;
754}
755
756enum intel_pipe_crc_object {
757 PIPE_CRC_OBJECT_PIPE,
758};
759
760static const char * const pipe_crc_objects[] = {
761 "pipe",
762};
763
764static int
765display_crc_ctl_parse_object(const char *buf, enum intel_pipe_crc_object *o)
766{
767 int i;
768
769 i = match_string(pipe_crc_objects, ARRAY_SIZE(pipe_crc_objects), buf);
770 if (i < 0)
771 return i;
772
773 *o = i;
774 return 0;
775}
776
777static int display_crc_ctl_parse_pipe(struct drm_i915_private *dev_priv,
778 const char *buf, enum pipe *pipe)
779{
780 const char name = buf[0];
781
782 if (name < 'A' || name >= pipe_name(INTEL_INFO(dev_priv)->num_pipes))
783 return -EINVAL;
784
785 *pipe = name - 'A';
786
787 return 0;
788}
789
790static int 442static int
791display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s) 443display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s)
792{ 444{
@@ -805,81 +457,6 @@ display_crc_ctl_parse_source(const char *buf, enum intel_pipe_crc_source *s)
805 return 0; 457 return 0;
806} 458}
807 459
808static int display_crc_ctl_parse(struct drm_i915_private *dev_priv,
809 char *buf, size_t len)
810{
811#define N_WORDS 3
812 int n_words;
813 char *words[N_WORDS];
814 enum pipe pipe;
815 enum intel_pipe_crc_object object;
816 enum intel_pipe_crc_source source;
817
818 n_words = display_crc_ctl_tokenize(buf, words, N_WORDS);
819 if (n_words != N_WORDS) {
820 DRM_DEBUG_DRIVER("tokenize failed, a command is %d words\n",
821 N_WORDS);
822 return -EINVAL;
823 }
824
825 if (display_crc_ctl_parse_object(words[0], &object) < 0) {
826 DRM_DEBUG_DRIVER("unknown object %s\n", words[0]);
827 return -EINVAL;
828 }
829
830 if (display_crc_ctl_parse_pipe(dev_priv, words[1], &pipe) < 0) {
831 DRM_DEBUG_DRIVER("unknown pipe %s\n", words[1]);
832 return -EINVAL;
833 }
834
835 if (display_crc_ctl_parse_source(words[2], &source) < 0) {
836 DRM_DEBUG_DRIVER("unknown source %s\n", words[2]);
837 return -EINVAL;
838 }
839
840 return pipe_crc_set_source(dev_priv, pipe, source);
841}
842
843static ssize_t display_crc_ctl_write(struct file *file, const char __user *ubuf,
844 size_t len, loff_t *offp)
845{
846 struct seq_file *m = file->private_data;
847 struct drm_i915_private *dev_priv = m->private;
848 char *tmpbuf;
849 int ret;
850
851 if (len == 0)
852 return 0;
853
854 if (len > PAGE_SIZE - 1) {
855 DRM_DEBUG_DRIVER("expected <%lu bytes into pipe crc control\n",
856 PAGE_SIZE);
857 return -E2BIG;
858 }
859
860 tmpbuf = memdup_user_nul(ubuf, len);
861 if (IS_ERR(tmpbuf))
862 return PTR_ERR(tmpbuf);
863
864 ret = display_crc_ctl_parse(dev_priv, tmpbuf, len);
865
866 kfree(tmpbuf);
867 if (ret < 0)
868 return ret;
869
870 *offp += len;
871 return len;
872}
873
874const struct file_operations i915_display_crc_ctl_fops = {
875 .owner = THIS_MODULE,
876 .open = display_crc_ctl_open,
877 .read = seq_read,
878 .llseek = seq_lseek,
879 .release = single_release,
880 .write = display_crc_ctl_write
881};
882
883void intel_display_crc_init(struct drm_i915_private *dev_priv) 460void intel_display_crc_init(struct drm_i915_private *dev_priv)
884{ 461{
885 enum pipe pipe; 462 enum pipe pipe;
@@ -887,30 +464,8 @@ void intel_display_crc_init(struct drm_i915_private *dev_priv)
887 for_each_pipe(dev_priv, pipe) { 464 for_each_pipe(dev_priv, pipe) {
888 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe]; 465 struct intel_pipe_crc *pipe_crc = &dev_priv->pipe_crc[pipe];
889 466
890 pipe_crc->opened = false;
891 spin_lock_init(&pipe_crc->lock); 467 spin_lock_init(&pipe_crc->lock);
892 init_waitqueue_head(&pipe_crc->wq);
893 }
894}
895
896int intel_pipe_crc_create(struct drm_minor *minor)
897{
898 struct drm_i915_private *dev_priv = to_i915(minor->dev);
899 struct dentry *ent;
900 int i;
901
902 for (i = 0; i < ARRAY_SIZE(i915_pipe_crc_data); i++) {
903 struct pipe_crc_info *info = &i915_pipe_crc_data[i];
904
905 info->dev_priv = dev_priv;
906 ent = debugfs_create_file(info->name, S_IRUGO,
907 minor->debugfs_root, info,
908 &i915_pipe_crc_fops);
909 if (!ent)
910 return -ENOMEM;
911 } 468 }
912
913 return 0;
914} 469}
915 470
916int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name, 471int intel_crtc_set_crc_source(struct drm_crtc *crtc, const char *source_name,