| @@ -1,1502 +1,1506 @@ | | | @@ -1,1502 +1,1506 @@ |
1 | /* | | 1 | /* |
2 | * Copyright © 2006-2007 Intel Corporation | | 2 | * Copyright © 2006-2007 Intel Corporation |
3 | * | | 3 | * |
4 | * Permission is hereby granted, free of charge, to any person obtaining a | | 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | * copy of this software and associated documentation files (the "Software"), | | 5 | * copy of this software and associated documentation files (the "Software"), |
6 | * to deal in the Software without restriction, including without limitation | | 6 | * to deal in the Software without restriction, including without limitation |
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | | 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, |
8 | * and/or sell copies of the Software, and to permit persons to whom the | | 8 | * and/or sell copies of the Software, and to permit persons to whom the |
9 | * Software is furnished to do so, subject to the following conditions: | | 9 | * Software is furnished to do so, subject to the following conditions: |
10 | * | | 10 | * |
11 | * The above copyright notice and this permission notice (including the next | | 11 | * The above copyright notice and this permission notice (including the next |
12 | * paragraph) shall be included in all copies or substantial portions of the | | 12 | * paragraph) shall be included in all copies or substantial portions of the |
13 | * Software. | | 13 | * Software. |
14 | * | | 14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | | 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | | 16 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | | 17 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | | 18 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | | 19 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | | 20 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
21 | * DEALINGS IN THE SOFTWARE. | | 21 | * DEALINGS IN THE SOFTWARE. |
22 | * | | 22 | * |
23 | * Authors: | | 23 | * Authors: |
24 | * Eric Anholt <eric@anholt.net> | | 24 | * Eric Anholt <eric@anholt.net> |
25 | */ | | 25 | */ |
26 | | | 26 | |
27 | #include <linux/dmi.h> | | 27 | #include <linux/dmi.h> |
28 | #include <linux/module.h> | | 28 | #include <linux/module.h> |
29 | #include <linux/input.h> | | 29 | #include <linux/input.h> |
30 | #include <linux/i2c.h> | | 30 | #include <linux/i2c.h> |
31 | #include <linux/kernel.h> | | 31 | #include <linux/kernel.h> |
32 | #include <linux/slab.h> | | 32 | #include <linux/slab.h> |
33 | #include <linux/vgaarb.h> | | 33 | #include <linux/vgaarb.h> |
34 | #include <drm/drm_edid.h> | | 34 | #include <drm/drm_edid.h> |
35 | #include <drm/drmP.h> | | 35 | #include <drm/drmP.h> |
36 | #include "intel_drv.h" | | 36 | #include "intel_drv.h" |
37 | #include <drm/i915_drm.h> | | 37 | #include <drm/i915_drm.h> |
38 | #include "i915_drv.h" | | 38 | #include "i915_drv.h" |
39 | #include "i915_trace.h" | | 39 | #include "i915_trace.h" |
40 | #include <drm/drm_dp_helper.h> | | 40 | #include <drm/drm_dp_helper.h> |
41 | #include <drm/drm_crtc_helper.h> | | 41 | #include <drm/drm_crtc_helper.h> |
42 | #include <linux/dma_remapping.h> | | 42 | #include <linux/dma_remapping.h> |
43 | | | 43 | |
44 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type); | | 44 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type); |
45 | static void intel_increase_pllclock(struct drm_crtc *crtc); | | 45 | static void intel_increase_pllclock(struct drm_crtc *crtc); |
46 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); | | 46 | static void intel_crtc_update_cursor(struct drm_crtc *crtc, bool on); |
47 | | | 47 | |
48 | typedef struct { | | 48 | typedef struct { |
49 | /* given values */ | | 49 | /* given values */ |
50 | int n; | | 50 | int n; |
51 | int m1, m2; | | 51 | int m1, m2; |
52 | int p1, p2; | | 52 | int p1, p2; |
53 | /* derived values */ | | 53 | /* derived values */ |
54 | int dot; | | 54 | int dot; |
55 | int vco; | | 55 | int vco; |
56 | int m; | | 56 | int m; |
57 | int p; | | 57 | int p; |
58 | } intel_clock_t; | | 58 | } intel_clock_t; |
59 | | | 59 | |
60 | typedef struct { | | 60 | typedef struct { |
61 | int min, max; | | 61 | int min, max; |
62 | } intel_range_t; | | 62 | } intel_range_t; |
63 | | | 63 | |
64 | typedef struct { | | 64 | typedef struct { |
65 | int dot_limit; | | 65 | int dot_limit; |
66 | int p2_slow, p2_fast; | | 66 | int p2_slow, p2_fast; |
67 | } intel_p2_t; | | 67 | } intel_p2_t; |
68 | | | 68 | |
69 | #define INTEL_P2_NUM 2 | | 69 | #define INTEL_P2_NUM 2 |
70 | typedef struct intel_limit intel_limit_t; | | 70 | typedef struct intel_limit intel_limit_t; |
71 | struct intel_limit { | | 71 | struct intel_limit { |
72 | intel_range_t dot, vco, n, m, m1, m2, p, p1; | | 72 | intel_range_t dot, vco, n, m, m1, m2, p, p1; |
73 | intel_p2_t p2; | | 73 | intel_p2_t p2; |
74 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, | | 74 | bool (* find_pll)(const intel_limit_t *, struct drm_crtc *, |
75 | int, int, intel_clock_t *, intel_clock_t *); | | 75 | int, int, intel_clock_t *, intel_clock_t *); |
76 | }; | | 76 | }; |
77 | | | 77 | |
78 | /* FDI */ | | 78 | /* FDI */ |
79 | #define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */ | | 79 | #define IRONLAKE_FDI_FREQ 2700000 /* in kHz for mode->clock */ |
80 | | | 80 | |
81 | int | | 81 | int |
82 | intel_pch_rawclk(struct drm_device *dev) | | 82 | intel_pch_rawclk(struct drm_device *dev) |
83 | { | | 83 | { |
84 | struct drm_i915_private *dev_priv = dev->dev_private; | | 84 | struct drm_i915_private *dev_priv = dev->dev_private; |
85 | | | 85 | |
86 | WARN_ON(!HAS_PCH_SPLIT(dev)); | | 86 | WARN_ON(!HAS_PCH_SPLIT(dev)); |
87 | | | 87 | |
88 | return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK; | | 88 | return I915_READ(PCH_RAWCLK_FREQ) & RAWCLK_FREQ_MASK; |
89 | } | | 89 | } |
90 | | | 90 | |
91 | static bool | | 91 | static bool |
92 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | | 92 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
93 | int target, int refclk, intel_clock_t *match_clock, | | 93 | int target, int refclk, intel_clock_t *match_clock, |
94 | intel_clock_t *best_clock); | | 94 | intel_clock_t *best_clock); |
95 | static bool | | 95 | static bool |
96 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | | 96 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
97 | int target, int refclk, intel_clock_t *match_clock, | | 97 | int target, int refclk, intel_clock_t *match_clock, |
98 | intel_clock_t *best_clock); | | 98 | intel_clock_t *best_clock); |
99 | | | 99 | |
100 | static bool | | 100 | static bool |
101 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, | | 101 | intel_find_pll_g4x_dp(const intel_limit_t *, struct drm_crtc *crtc, |
102 | int target, int refclk, intel_clock_t *match_clock, | | 102 | int target, int refclk, intel_clock_t *match_clock, |
103 | intel_clock_t *best_clock); | | 103 | intel_clock_t *best_clock); |
104 | static bool | | 104 | static bool |
105 | intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, | | 105 | intel_find_pll_ironlake_dp(const intel_limit_t *, struct drm_crtc *crtc, |
106 | int target, int refclk, intel_clock_t *match_clock, | | 106 | int target, int refclk, intel_clock_t *match_clock, |
107 | intel_clock_t *best_clock); | | 107 | intel_clock_t *best_clock); |
108 | | | 108 | |
109 | static bool | | 109 | static bool |
110 | intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, | | 110 | intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, |
111 | int target, int refclk, intel_clock_t *match_clock, | | 111 | int target, int refclk, intel_clock_t *match_clock, |
112 | intel_clock_t *best_clock); | | 112 | intel_clock_t *best_clock); |
113 | | | 113 | |
114 | static inline u32 /* units of 100MHz */ | | 114 | static inline u32 /* units of 100MHz */ |
115 | intel_fdi_link_freq(struct drm_device *dev) | | 115 | intel_fdi_link_freq(struct drm_device *dev) |
116 | { | | 116 | { |
117 | if (IS_GEN5(dev)) { | | 117 | if (IS_GEN5(dev)) { |
118 | struct drm_i915_private *dev_priv = dev->dev_private; | | 118 | struct drm_i915_private *dev_priv = dev->dev_private; |
119 | return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2; | | 119 | return (I915_READ(FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK) + 2; |
120 | } else | | 120 | } else |
121 | return 27; | | 121 | return 27; |
122 | } | | 122 | } |
123 | | | 123 | |
124 | static const intel_limit_t intel_limits_i8xx_dvo = { | | 124 | static const intel_limit_t intel_limits_i8xx_dvo = { |
125 | .dot = { .min = 25000, .max = 350000 }, | | 125 | .dot = { .min = 25000, .max = 350000 }, |
126 | .vco = { .min = 930000, .max = 1400000 }, | | 126 | .vco = { .min = 930000, .max = 1400000 }, |
127 | .n = { .min = 3, .max = 16 }, | | 127 | .n = { .min = 3, .max = 16 }, |
128 | .m = { .min = 96, .max = 140 }, | | 128 | .m = { .min = 96, .max = 140 }, |
129 | .m1 = { .min = 18, .max = 26 }, | | 129 | .m1 = { .min = 18, .max = 26 }, |
130 | .m2 = { .min = 6, .max = 16 }, | | 130 | .m2 = { .min = 6, .max = 16 }, |
131 | .p = { .min = 4, .max = 128 }, | | 131 | .p = { .min = 4, .max = 128 }, |
132 | .p1 = { .min = 2, .max = 33 }, | | 132 | .p1 = { .min = 2, .max = 33 }, |
133 | .p2 = { .dot_limit = 165000, | | 133 | .p2 = { .dot_limit = 165000, |
134 | .p2_slow = 4, .p2_fast = 2 }, | | 134 | .p2_slow = 4, .p2_fast = 2 }, |
135 | .find_pll = intel_find_best_PLL, | | 135 | .find_pll = intel_find_best_PLL, |
136 | }; | | 136 | }; |
137 | | | 137 | |
138 | static const intel_limit_t intel_limits_i8xx_lvds = { | | 138 | static const intel_limit_t intel_limits_i8xx_lvds = { |
139 | .dot = { .min = 25000, .max = 350000 }, | | 139 | .dot = { .min = 25000, .max = 350000 }, |
140 | .vco = { .min = 930000, .max = 1400000 }, | | 140 | .vco = { .min = 930000, .max = 1400000 }, |
141 | .n = { .min = 3, .max = 16 }, | | 141 | .n = { .min = 3, .max = 16 }, |
142 | .m = { .min = 96, .max = 140 }, | | 142 | .m = { .min = 96, .max = 140 }, |
143 | .m1 = { .min = 18, .max = 26 }, | | 143 | .m1 = { .min = 18, .max = 26 }, |
144 | .m2 = { .min = 6, .max = 16 }, | | 144 | .m2 = { .min = 6, .max = 16 }, |
145 | .p = { .min = 4, .max = 128 }, | | 145 | .p = { .min = 4, .max = 128 }, |
146 | .p1 = { .min = 1, .max = 6 }, | | 146 | .p1 = { .min = 1, .max = 6 }, |
147 | .p2 = { .dot_limit = 165000, | | 147 | .p2 = { .dot_limit = 165000, |
148 | .p2_slow = 14, .p2_fast = 7 }, | | 148 | .p2_slow = 14, .p2_fast = 7 }, |
149 | .find_pll = intel_find_best_PLL, | | 149 | .find_pll = intel_find_best_PLL, |
150 | }; | | 150 | }; |
151 | | | 151 | |
152 | static const intel_limit_t intel_limits_i9xx_sdvo = { | | 152 | static const intel_limit_t intel_limits_i9xx_sdvo = { |
153 | .dot = { .min = 20000, .max = 400000 }, | | 153 | .dot = { .min = 20000, .max = 400000 }, |
154 | .vco = { .min = 1400000, .max = 2800000 }, | | 154 | .vco = { .min = 1400000, .max = 2800000 }, |
155 | .n = { .min = 1, .max = 6 }, | | 155 | .n = { .min = 1, .max = 6 }, |
156 | .m = { .min = 70, .max = 120 }, | | 156 | .m = { .min = 70, .max = 120 }, |
157 | .m1 = { .min = 10, .max = 22 }, | | 157 | .m1 = { .min = 10, .max = 22 }, |
158 | .m2 = { .min = 5, .max = 9 }, | | 158 | .m2 = { .min = 5, .max = 9 }, |
159 | .p = { .min = 5, .max = 80 }, | | 159 | .p = { .min = 5, .max = 80 }, |
160 | .p1 = { .min = 1, .max = 8 }, | | 160 | .p1 = { .min = 1, .max = 8 }, |
161 | .p2 = { .dot_limit = 200000, | | 161 | .p2 = { .dot_limit = 200000, |
162 | .p2_slow = 10, .p2_fast = 5 }, | | 162 | .p2_slow = 10, .p2_fast = 5 }, |
163 | .find_pll = intel_find_best_PLL, | | 163 | .find_pll = intel_find_best_PLL, |
164 | }; | | 164 | }; |
165 | | | 165 | |
166 | static const intel_limit_t intel_limits_i9xx_lvds = { | | 166 | static const intel_limit_t intel_limits_i9xx_lvds = { |
167 | .dot = { .min = 20000, .max = 400000 }, | | 167 | .dot = { .min = 20000, .max = 400000 }, |
168 | .vco = { .min = 1400000, .max = 2800000 }, | | 168 | .vco = { .min = 1400000, .max = 2800000 }, |
169 | .n = { .min = 1, .max = 6 }, | | 169 | .n = { .min = 1, .max = 6 }, |
170 | .m = { .min = 70, .max = 120 }, | | 170 | .m = { .min = 70, .max = 120 }, |
171 | .m1 = { .min = 10, .max = 22 }, | | 171 | .m1 = { .min = 10, .max = 22 }, |
172 | .m2 = { .min = 5, .max = 9 }, | | 172 | .m2 = { .min = 5, .max = 9 }, |
173 | .p = { .min = 7, .max = 98 }, | | 173 | .p = { .min = 7, .max = 98 }, |
174 | .p1 = { .min = 1, .max = 8 }, | | 174 | .p1 = { .min = 1, .max = 8 }, |
175 | .p2 = { .dot_limit = 112000, | | 175 | .p2 = { .dot_limit = 112000, |
176 | .p2_slow = 14, .p2_fast = 7 }, | | 176 | .p2_slow = 14, .p2_fast = 7 }, |
177 | .find_pll = intel_find_best_PLL, | | 177 | .find_pll = intel_find_best_PLL, |
178 | }; | | 178 | }; |
179 | | | 179 | |
180 | | | 180 | |
181 | static const intel_limit_t intel_limits_g4x_sdvo = { | | 181 | static const intel_limit_t intel_limits_g4x_sdvo = { |
182 | .dot = { .min = 25000, .max = 270000 }, | | 182 | .dot = { .min = 25000, .max = 270000 }, |
183 | .vco = { .min = 1750000, .max = 3500000}, | | 183 | .vco = { .min = 1750000, .max = 3500000}, |
184 | .n = { .min = 1, .max = 4 }, | | 184 | .n = { .min = 1, .max = 4 }, |
185 | .m = { .min = 104, .max = 138 }, | | 185 | .m = { .min = 104, .max = 138 }, |
186 | .m1 = { .min = 17, .max = 23 }, | | 186 | .m1 = { .min = 17, .max = 23 }, |
187 | .m2 = { .min = 5, .max = 11 }, | | 187 | .m2 = { .min = 5, .max = 11 }, |
188 | .p = { .min = 10, .max = 30 }, | | 188 | .p = { .min = 10, .max = 30 }, |
189 | .p1 = { .min = 1, .max = 3}, | | 189 | .p1 = { .min = 1, .max = 3}, |
190 | .p2 = { .dot_limit = 270000, | | 190 | .p2 = { .dot_limit = 270000, |
191 | .p2_slow = 10, | | 191 | .p2_slow = 10, |
192 | .p2_fast = 10 | | 192 | .p2_fast = 10 |
193 | }, | | 193 | }, |
194 | .find_pll = intel_g4x_find_best_PLL, | | 194 | .find_pll = intel_g4x_find_best_PLL, |
195 | }; | | 195 | }; |
196 | | | 196 | |
197 | static const intel_limit_t intel_limits_g4x_hdmi = { | | 197 | static const intel_limit_t intel_limits_g4x_hdmi = { |
198 | .dot = { .min = 22000, .max = 400000 }, | | 198 | .dot = { .min = 22000, .max = 400000 }, |
199 | .vco = { .min = 1750000, .max = 3500000}, | | 199 | .vco = { .min = 1750000, .max = 3500000}, |
200 | .n = { .min = 1, .max = 4 }, | | 200 | .n = { .min = 1, .max = 4 }, |
201 | .m = { .min = 104, .max = 138 }, | | 201 | .m = { .min = 104, .max = 138 }, |
202 | .m1 = { .min = 16, .max = 23 }, | | 202 | .m1 = { .min = 16, .max = 23 }, |
203 | .m2 = { .min = 5, .max = 11 }, | | 203 | .m2 = { .min = 5, .max = 11 }, |
204 | .p = { .min = 5, .max = 80 }, | | 204 | .p = { .min = 5, .max = 80 }, |
205 | .p1 = { .min = 1, .max = 8}, | | 205 | .p1 = { .min = 1, .max = 8}, |
206 | .p2 = { .dot_limit = 165000, | | 206 | .p2 = { .dot_limit = 165000, |
207 | .p2_slow = 10, .p2_fast = 5 }, | | 207 | .p2_slow = 10, .p2_fast = 5 }, |
208 | .find_pll = intel_g4x_find_best_PLL, | | 208 | .find_pll = intel_g4x_find_best_PLL, |
209 | }; | | 209 | }; |
210 | | | 210 | |
211 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { | | 211 | static const intel_limit_t intel_limits_g4x_single_channel_lvds = { |
212 | .dot = { .min = 20000, .max = 115000 }, | | 212 | .dot = { .min = 20000, .max = 115000 }, |
213 | .vco = { .min = 1750000, .max = 3500000 }, | | 213 | .vco = { .min = 1750000, .max = 3500000 }, |
214 | .n = { .min = 1, .max = 3 }, | | 214 | .n = { .min = 1, .max = 3 }, |
215 | .m = { .min = 104, .max = 138 }, | | 215 | .m = { .min = 104, .max = 138 }, |
216 | .m1 = { .min = 17, .max = 23 }, | | 216 | .m1 = { .min = 17, .max = 23 }, |
217 | .m2 = { .min = 5, .max = 11 }, | | 217 | .m2 = { .min = 5, .max = 11 }, |
218 | .p = { .min = 28, .max = 112 }, | | 218 | .p = { .min = 28, .max = 112 }, |
219 | .p1 = { .min = 2, .max = 8 }, | | 219 | .p1 = { .min = 2, .max = 8 }, |
220 | .p2 = { .dot_limit = 0, | | 220 | .p2 = { .dot_limit = 0, |
221 | .p2_slow = 14, .p2_fast = 14 | | 221 | .p2_slow = 14, .p2_fast = 14 |
222 | }, | | 222 | }, |
223 | .find_pll = intel_g4x_find_best_PLL, | | 223 | .find_pll = intel_g4x_find_best_PLL, |
224 | }; | | 224 | }; |
225 | | | 225 | |
226 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { | | 226 | static const intel_limit_t intel_limits_g4x_dual_channel_lvds = { |
227 | .dot = { .min = 80000, .max = 224000 }, | | 227 | .dot = { .min = 80000, .max = 224000 }, |
228 | .vco = { .min = 1750000, .max = 3500000 }, | | 228 | .vco = { .min = 1750000, .max = 3500000 }, |
229 | .n = { .min = 1, .max = 3 }, | | 229 | .n = { .min = 1, .max = 3 }, |
230 | .m = { .min = 104, .max = 138 }, | | 230 | .m = { .min = 104, .max = 138 }, |
231 | .m1 = { .min = 17, .max = 23 }, | | 231 | .m1 = { .min = 17, .max = 23 }, |
232 | .m2 = { .min = 5, .max = 11 }, | | 232 | .m2 = { .min = 5, .max = 11 }, |
233 | .p = { .min = 14, .max = 42 }, | | 233 | .p = { .min = 14, .max = 42 }, |
234 | .p1 = { .min = 2, .max = 6 }, | | 234 | .p1 = { .min = 2, .max = 6 }, |
235 | .p2 = { .dot_limit = 0, | | 235 | .p2 = { .dot_limit = 0, |
236 | .p2_slow = 7, .p2_fast = 7 | | 236 | .p2_slow = 7, .p2_fast = 7 |
237 | }, | | 237 | }, |
238 | .find_pll = intel_g4x_find_best_PLL, | | 238 | .find_pll = intel_g4x_find_best_PLL, |
239 | }; | | 239 | }; |
240 | | | 240 | |
241 | static const intel_limit_t intel_limits_g4x_display_port = { | | 241 | static const intel_limit_t intel_limits_g4x_display_port = { |
242 | .dot = { .min = 161670, .max = 227000 }, | | 242 | .dot = { .min = 161670, .max = 227000 }, |
243 | .vco = { .min = 1750000, .max = 3500000}, | | 243 | .vco = { .min = 1750000, .max = 3500000}, |
244 | .n = { .min = 1, .max = 2 }, | | 244 | .n = { .min = 1, .max = 2 }, |
245 | .m = { .min = 97, .max = 108 }, | | 245 | .m = { .min = 97, .max = 108 }, |
246 | .m1 = { .min = 0x10, .max = 0x12 }, | | 246 | .m1 = { .min = 0x10, .max = 0x12 }, |
247 | .m2 = { .min = 0x05, .max = 0x06 }, | | 247 | .m2 = { .min = 0x05, .max = 0x06 }, |
248 | .p = { .min = 10, .max = 20 }, | | 248 | .p = { .min = 10, .max = 20 }, |
249 | .p1 = { .min = 1, .max = 2}, | | 249 | .p1 = { .min = 1, .max = 2}, |
250 | .p2 = { .dot_limit = 0, | | 250 | .p2 = { .dot_limit = 0, |
251 | .p2_slow = 10, .p2_fast = 10 }, | | 251 | .p2_slow = 10, .p2_fast = 10 }, |
252 | .find_pll = intel_find_pll_g4x_dp, | | 252 | .find_pll = intel_find_pll_g4x_dp, |
253 | }; | | 253 | }; |
254 | | | 254 | |
255 | static const intel_limit_t intel_limits_pineview_sdvo = { | | 255 | static const intel_limit_t intel_limits_pineview_sdvo = { |
256 | .dot = { .min = 20000, .max = 400000}, | | 256 | .dot = { .min = 20000, .max = 400000}, |
257 | .vco = { .min = 1700000, .max = 3500000 }, | | 257 | .vco = { .min = 1700000, .max = 3500000 }, |
258 | /* Pineview's Ncounter is a ring counter */ | | 258 | /* Pineview's Ncounter is a ring counter */ |
259 | .n = { .min = 3, .max = 6 }, | | 259 | .n = { .min = 3, .max = 6 }, |
260 | .m = { .min = 2, .max = 256 }, | | 260 | .m = { .min = 2, .max = 256 }, |
261 | /* Pineview only has one combined m divider, which we treat as m2. */ | | 261 | /* Pineview only has one combined m divider, which we treat as m2. */ |
262 | .m1 = { .min = 0, .max = 0 }, | | 262 | .m1 = { .min = 0, .max = 0 }, |
263 | .m2 = { .min = 0, .max = 254 }, | | 263 | .m2 = { .min = 0, .max = 254 }, |
264 | .p = { .min = 5, .max = 80 }, | | 264 | .p = { .min = 5, .max = 80 }, |
265 | .p1 = { .min = 1, .max = 8 }, | | 265 | .p1 = { .min = 1, .max = 8 }, |
266 | .p2 = { .dot_limit = 200000, | | 266 | .p2 = { .dot_limit = 200000, |
267 | .p2_slow = 10, .p2_fast = 5 }, | | 267 | .p2_slow = 10, .p2_fast = 5 }, |
268 | .find_pll = intel_find_best_PLL, | | 268 | .find_pll = intel_find_best_PLL, |
269 | }; | | 269 | }; |
270 | | | 270 | |
271 | static const intel_limit_t intel_limits_pineview_lvds = { | | 271 | static const intel_limit_t intel_limits_pineview_lvds = { |
272 | .dot = { .min = 20000, .max = 400000 }, | | 272 | .dot = { .min = 20000, .max = 400000 }, |
273 | .vco = { .min = 1700000, .max = 3500000 }, | | 273 | .vco = { .min = 1700000, .max = 3500000 }, |
274 | .n = { .min = 3, .max = 6 }, | | 274 | .n = { .min = 3, .max = 6 }, |
275 | .m = { .min = 2, .max = 256 }, | | 275 | .m = { .min = 2, .max = 256 }, |
276 | .m1 = { .min = 0, .max = 0 }, | | 276 | .m1 = { .min = 0, .max = 0 }, |
277 | .m2 = { .min = 0, .max = 254 }, | | 277 | .m2 = { .min = 0, .max = 254 }, |
278 | .p = { .min = 7, .max = 112 }, | | 278 | .p = { .min = 7, .max = 112 }, |
279 | .p1 = { .min = 1, .max = 8 }, | | 279 | .p1 = { .min = 1, .max = 8 }, |
280 | .p2 = { .dot_limit = 112000, | | 280 | .p2 = { .dot_limit = 112000, |
281 | .p2_slow = 14, .p2_fast = 14 }, | | 281 | .p2_slow = 14, .p2_fast = 14 }, |
282 | .find_pll = intel_find_best_PLL, | | 282 | .find_pll = intel_find_best_PLL, |
283 | }; | | 283 | }; |
284 | | | 284 | |
285 | /* Ironlake / Sandybridge | | 285 | /* Ironlake / Sandybridge |
286 | * | | 286 | * |
287 | * We calculate clock using (register_value + 2) for N/M1/M2, so here | | 287 | * We calculate clock using (register_value + 2) for N/M1/M2, so here |
288 | * the range value for them is (actual_value - 2). | | 288 | * the range value for them is (actual_value - 2). |
289 | */ | | 289 | */ |
290 | static const intel_limit_t intel_limits_ironlake_dac = { | | 290 | static const intel_limit_t intel_limits_ironlake_dac = { |
291 | .dot = { .min = 25000, .max = 350000 }, | | 291 | .dot = { .min = 25000, .max = 350000 }, |
292 | .vco = { .min = 1760000, .max = 3510000 }, | | 292 | .vco = { .min = 1760000, .max = 3510000 }, |
293 | .n = { .min = 1, .max = 5 }, | | 293 | .n = { .min = 1, .max = 5 }, |
294 | .m = { .min = 79, .max = 127 }, | | 294 | .m = { .min = 79, .max = 127 }, |
295 | .m1 = { .min = 12, .max = 22 }, | | 295 | .m1 = { .min = 12, .max = 22 }, |
296 | .m2 = { .min = 5, .max = 9 }, | | 296 | .m2 = { .min = 5, .max = 9 }, |
297 | .p = { .min = 5, .max = 80 }, | | 297 | .p = { .min = 5, .max = 80 }, |
298 | .p1 = { .min = 1, .max = 8 }, | | 298 | .p1 = { .min = 1, .max = 8 }, |
299 | .p2 = { .dot_limit = 225000, | | 299 | .p2 = { .dot_limit = 225000, |
300 | .p2_slow = 10, .p2_fast = 5 }, | | 300 | .p2_slow = 10, .p2_fast = 5 }, |
301 | .find_pll = intel_g4x_find_best_PLL, | | 301 | .find_pll = intel_g4x_find_best_PLL, |
302 | }; | | 302 | }; |
303 | | | 303 | |
304 | static const intel_limit_t intel_limits_ironlake_single_lvds = { | | 304 | static const intel_limit_t intel_limits_ironlake_single_lvds = { |
305 | .dot = { .min = 25000, .max = 350000 }, | | 305 | .dot = { .min = 25000, .max = 350000 }, |
306 | .vco = { .min = 1760000, .max = 3510000 }, | | 306 | .vco = { .min = 1760000, .max = 3510000 }, |
307 | .n = { .min = 1, .max = 3 }, | | 307 | .n = { .min = 1, .max = 3 }, |
308 | .m = { .min = 79, .max = 118 }, | | 308 | .m = { .min = 79, .max = 118 }, |
309 | .m1 = { .min = 12, .max = 22 }, | | 309 | .m1 = { .min = 12, .max = 22 }, |
310 | .m2 = { .min = 5, .max = 9 }, | | 310 | .m2 = { .min = 5, .max = 9 }, |
311 | .p = { .min = 28, .max = 112 }, | | 311 | .p = { .min = 28, .max = 112 }, |
312 | .p1 = { .min = 2, .max = 8 }, | | 312 | .p1 = { .min = 2, .max = 8 }, |
313 | .p2 = { .dot_limit = 225000, | | 313 | .p2 = { .dot_limit = 225000, |
314 | .p2_slow = 14, .p2_fast = 14 }, | | 314 | .p2_slow = 14, .p2_fast = 14 }, |
315 | .find_pll = intel_g4x_find_best_PLL, | | 315 | .find_pll = intel_g4x_find_best_PLL, |
316 | }; | | 316 | }; |
317 | | | 317 | |
318 | static const intel_limit_t intel_limits_ironlake_dual_lvds = { | | 318 | static const intel_limit_t intel_limits_ironlake_dual_lvds = { |
319 | .dot = { .min = 25000, .max = 350000 }, | | 319 | .dot = { .min = 25000, .max = 350000 }, |
320 | .vco = { .min = 1760000, .max = 3510000 }, | | 320 | .vco = { .min = 1760000, .max = 3510000 }, |
321 | .n = { .min = 1, .max = 3 }, | | 321 | .n = { .min = 1, .max = 3 }, |
322 | .m = { .min = 79, .max = 127 }, | | 322 | .m = { .min = 79, .max = 127 }, |
323 | .m1 = { .min = 12, .max = 22 }, | | 323 | .m1 = { .min = 12, .max = 22 }, |
324 | .m2 = { .min = 5, .max = 9 }, | | 324 | .m2 = { .min = 5, .max = 9 }, |
325 | .p = { .min = 14, .max = 56 }, | | 325 | .p = { .min = 14, .max = 56 }, |
326 | .p1 = { .min = 2, .max = 8 }, | | 326 | .p1 = { .min = 2, .max = 8 }, |
327 | .p2 = { .dot_limit = 225000, | | 327 | .p2 = { .dot_limit = 225000, |
328 | .p2_slow = 7, .p2_fast = 7 }, | | 328 | .p2_slow = 7, .p2_fast = 7 }, |
329 | .find_pll = intel_g4x_find_best_PLL, | | 329 | .find_pll = intel_g4x_find_best_PLL, |
330 | }; | | 330 | }; |
331 | | | 331 | |
332 | /* LVDS 100mhz refclk limits. */ | | 332 | /* LVDS 100mhz refclk limits. */ |
333 | static const intel_limit_t intel_limits_ironlake_single_lvds_100m = { | | 333 | static const intel_limit_t intel_limits_ironlake_single_lvds_100m = { |
334 | .dot = { .min = 25000, .max = 350000 }, | | 334 | .dot = { .min = 25000, .max = 350000 }, |
335 | .vco = { .min = 1760000, .max = 3510000 }, | | 335 | .vco = { .min = 1760000, .max = 3510000 }, |
336 | .n = { .min = 1, .max = 2 }, | | 336 | .n = { .min = 1, .max = 2 }, |
337 | .m = { .min = 79, .max = 126 }, | | 337 | .m = { .min = 79, .max = 126 }, |
338 | .m1 = { .min = 12, .max = 22 }, | | 338 | .m1 = { .min = 12, .max = 22 }, |
339 | .m2 = { .min = 5, .max = 9 }, | | 339 | .m2 = { .min = 5, .max = 9 }, |
340 | .p = { .min = 28, .max = 112 }, | | 340 | .p = { .min = 28, .max = 112 }, |
341 | .p1 = { .min = 2, .max = 8 }, | | 341 | .p1 = { .min = 2, .max = 8 }, |
342 | .p2 = { .dot_limit = 225000, | | 342 | .p2 = { .dot_limit = 225000, |
343 | .p2_slow = 14, .p2_fast = 14 }, | | 343 | .p2_slow = 14, .p2_fast = 14 }, |
344 | .find_pll = intel_g4x_find_best_PLL, | | 344 | .find_pll = intel_g4x_find_best_PLL, |
345 | }; | | 345 | }; |
346 | | | 346 | |
347 | static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { | | 347 | static const intel_limit_t intel_limits_ironlake_dual_lvds_100m = { |
348 | .dot = { .min = 25000, .max = 350000 }, | | 348 | .dot = { .min = 25000, .max = 350000 }, |
349 | .vco = { .min = 1760000, .max = 3510000 }, | | 349 | .vco = { .min = 1760000, .max = 3510000 }, |
350 | .n = { .min = 1, .max = 3 }, | | 350 | .n = { .min = 1, .max = 3 }, |
351 | .m = { .min = 79, .max = 126 }, | | 351 | .m = { .min = 79, .max = 126 }, |
352 | .m1 = { .min = 12, .max = 22 }, | | 352 | .m1 = { .min = 12, .max = 22 }, |
353 | .m2 = { .min = 5, .max = 9 }, | | 353 | .m2 = { .min = 5, .max = 9 }, |
354 | .p = { .min = 14, .max = 42 }, | | 354 | .p = { .min = 14, .max = 42 }, |
355 | .p1 = { .min = 2, .max = 6 }, | | 355 | .p1 = { .min = 2, .max = 6 }, |
356 | .p2 = { .dot_limit = 225000, | | 356 | .p2 = { .dot_limit = 225000, |
357 | .p2_slow = 7, .p2_fast = 7 }, | | 357 | .p2_slow = 7, .p2_fast = 7 }, |
358 | .find_pll = intel_g4x_find_best_PLL, | | 358 | .find_pll = intel_g4x_find_best_PLL, |
359 | }; | | 359 | }; |
360 | | | 360 | |
361 | static const intel_limit_t intel_limits_ironlake_display_port = { | | 361 | static const intel_limit_t intel_limits_ironlake_display_port = { |
362 | .dot = { .min = 25000, .max = 350000 }, | | 362 | .dot = { .min = 25000, .max = 350000 }, |
363 | .vco = { .min = 1760000, .max = 3510000}, | | 363 | .vco = { .min = 1760000, .max = 3510000}, |
364 | .n = { .min = 1, .max = 2 }, | | 364 | .n = { .min = 1, .max = 2 }, |
365 | .m = { .min = 81, .max = 90 }, | | 365 | .m = { .min = 81, .max = 90 }, |
366 | .m1 = { .min = 12, .max = 22 }, | | 366 | .m1 = { .min = 12, .max = 22 }, |
367 | .m2 = { .min = 5, .max = 9 }, | | 367 | .m2 = { .min = 5, .max = 9 }, |
368 | .p = { .min = 10, .max = 20 }, | | 368 | .p = { .min = 10, .max = 20 }, |
369 | .p1 = { .min = 1, .max = 2}, | | 369 | .p1 = { .min = 1, .max = 2}, |
370 | .p2 = { .dot_limit = 0, | | 370 | .p2 = { .dot_limit = 0, |
371 | .p2_slow = 10, .p2_fast = 10 }, | | 371 | .p2_slow = 10, .p2_fast = 10 }, |
372 | .find_pll = intel_find_pll_ironlake_dp, | | 372 | .find_pll = intel_find_pll_ironlake_dp, |
373 | }; | | 373 | }; |
374 | | | 374 | |
375 | static const intel_limit_t intel_limits_vlv_dac = { | | 375 | static const intel_limit_t intel_limits_vlv_dac = { |
376 | .dot = { .min = 25000, .max = 270000 }, | | 376 | .dot = { .min = 25000, .max = 270000 }, |
377 | .vco = { .min = 4000000, .max = 6000000 }, | | 377 | .vco = { .min = 4000000, .max = 6000000 }, |
378 | .n = { .min = 1, .max = 7 }, | | 378 | .n = { .min = 1, .max = 7 }, |
379 | .m = { .min = 22, .max = 450 }, /* guess */ | | 379 | .m = { .min = 22, .max = 450 }, /* guess */ |
380 | .m1 = { .min = 2, .max = 3 }, | | 380 | .m1 = { .min = 2, .max = 3 }, |
381 | .m2 = { .min = 11, .max = 156 }, | | 381 | .m2 = { .min = 11, .max = 156 }, |
382 | .p = { .min = 10, .max = 30 }, | | 382 | .p = { .min = 10, .max = 30 }, |
383 | .p1 = { .min = 2, .max = 3 }, | | 383 | .p1 = { .min = 2, .max = 3 }, |
384 | .p2 = { .dot_limit = 270000, | | 384 | .p2 = { .dot_limit = 270000, |
385 | .p2_slow = 2, .p2_fast = 20 }, | | 385 | .p2_slow = 2, .p2_fast = 20 }, |
386 | .find_pll = intel_vlv_find_best_pll, | | 386 | .find_pll = intel_vlv_find_best_pll, |
387 | }; | | 387 | }; |
388 | | | 388 | |
389 | static const intel_limit_t intel_limits_vlv_hdmi = { | | 389 | static const intel_limit_t intel_limits_vlv_hdmi = { |
390 | .dot = { .min = 20000, .max = 165000 }, | | 390 | .dot = { .min = 20000, .max = 165000 }, |
391 | .vco = { .min = 4000000, .max = 5994000}, | | 391 | .vco = { .min = 4000000, .max = 5994000}, |
392 | .n = { .min = 1, .max = 7 }, | | 392 | .n = { .min = 1, .max = 7 }, |
393 | .m = { .min = 60, .max = 300 }, /* guess */ | | 393 | .m = { .min = 60, .max = 300 }, /* guess */ |
394 | .m1 = { .min = 2, .max = 3 }, | | 394 | .m1 = { .min = 2, .max = 3 }, |
395 | .m2 = { .min = 11, .max = 156 }, | | 395 | .m2 = { .min = 11, .max = 156 }, |
396 | .p = { .min = 10, .max = 30 }, | | 396 | .p = { .min = 10, .max = 30 }, |
397 | .p1 = { .min = 2, .max = 3 }, | | 397 | .p1 = { .min = 2, .max = 3 }, |
398 | .p2 = { .dot_limit = 270000, | | 398 | .p2 = { .dot_limit = 270000, |
399 | .p2_slow = 2, .p2_fast = 20 }, | | 399 | .p2_slow = 2, .p2_fast = 20 }, |
400 | .find_pll = intel_vlv_find_best_pll, | | 400 | .find_pll = intel_vlv_find_best_pll, |
401 | }; | | 401 | }; |
402 | | | 402 | |
403 | static const intel_limit_t intel_limits_vlv_dp = { | | 403 | static const intel_limit_t intel_limits_vlv_dp = { |
404 | .dot = { .min = 25000, .max = 270000 }, | | 404 | .dot = { .min = 25000, .max = 270000 }, |
405 | .vco = { .min = 4000000, .max = 6000000 }, | | 405 | .vco = { .min = 4000000, .max = 6000000 }, |
406 | .n = { .min = 1, .max = 7 }, | | 406 | .n = { .min = 1, .max = 7 }, |
407 | .m = { .min = 22, .max = 450 }, | | 407 | .m = { .min = 22, .max = 450 }, |
408 | .m1 = { .min = 2, .max = 3 }, | | 408 | .m1 = { .min = 2, .max = 3 }, |
409 | .m2 = { .min = 11, .max = 156 }, | | 409 | .m2 = { .min = 11, .max = 156 }, |
410 | .p = { .min = 10, .max = 30 }, | | 410 | .p = { .min = 10, .max = 30 }, |
411 | .p1 = { .min = 2, .max = 3 }, | | 411 | .p1 = { .min = 2, .max = 3 }, |
412 | .p2 = { .dot_limit = 270000, | | 412 | .p2 = { .dot_limit = 270000, |
413 | .p2_slow = 2, .p2_fast = 20 }, | | 413 | .p2_slow = 2, .p2_fast = 20 }, |
414 | .find_pll = intel_vlv_find_best_pll, | | 414 | .find_pll = intel_vlv_find_best_pll, |
415 | }; | | 415 | }; |
416 | | | 416 | |
417 | u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) | | 417 | u32 intel_dpio_read(struct drm_i915_private *dev_priv, int reg) |
418 | { | | 418 | { |
419 | unsigned long flags; | | 419 | unsigned long flags; |
420 | u32 val = 0; | | 420 | u32 val = 0; |
421 | | | 421 | |
422 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); | | 422 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); |
423 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { | | 423 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { |
424 | DRM_ERROR("DPIO idle wait timed out\n"); | | 424 | DRM_ERROR("DPIO idle wait timed out\n"); |
425 | goto out_unlock; | | 425 | goto out_unlock; |
426 | } | | 426 | } |
427 | | | 427 | |
428 | I915_WRITE(DPIO_REG, reg); | | 428 | I915_WRITE(DPIO_REG, reg); |
429 | I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_READ | DPIO_PORTID | | | 429 | I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_READ | DPIO_PORTID | |
430 | DPIO_BYTE); | | 430 | DPIO_BYTE); |
431 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { | | 431 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { |
432 | DRM_ERROR("DPIO read wait timed out\n"); | | 432 | DRM_ERROR("DPIO read wait timed out\n"); |
433 | goto out_unlock; | | 433 | goto out_unlock; |
434 | } | | 434 | } |
435 | val = I915_READ(DPIO_DATA); | | 435 | val = I915_READ(DPIO_DATA); |
436 | | | 436 | |
437 | out_unlock: | | 437 | out_unlock: |
438 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); | | 438 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); |
439 | return val; | | 439 | return val; |
440 | } | | 440 | } |
441 | | | 441 | |
442 | static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, | | 442 | static void intel_dpio_write(struct drm_i915_private *dev_priv, int reg, |
443 | u32 val) | | 443 | u32 val) |
444 | { | | 444 | { |
445 | unsigned long flags; | | 445 | unsigned long flags; |
446 | | | 446 | |
447 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); | | 447 | spin_lock_irqsave(&dev_priv->dpio_lock, flags); |
448 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { | | 448 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) { |
449 | DRM_ERROR("DPIO idle wait timed out\n"); | | 449 | DRM_ERROR("DPIO idle wait timed out\n"); |
450 | goto out_unlock; | | 450 | goto out_unlock; |
451 | } | | 451 | } |
452 | | | 452 | |
453 | I915_WRITE(DPIO_DATA, val); | | 453 | I915_WRITE(DPIO_DATA, val); |
454 | I915_WRITE(DPIO_REG, reg); | | 454 | I915_WRITE(DPIO_REG, reg); |
455 | I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID | | | 455 | I915_WRITE(DPIO_PKT, DPIO_RID | DPIO_OP_WRITE | DPIO_PORTID | |
456 | DPIO_BYTE); | | 456 | DPIO_BYTE); |
457 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) | | 457 | if (wait_for_atomic_us((I915_READ(DPIO_PKT) & DPIO_BUSY) == 0, 100)) |
458 | DRM_ERROR("DPIO write wait timed out\n"); | | 458 | DRM_ERROR("DPIO write wait timed out\n"); |
459 | | | 459 | |
460 | out_unlock: | | 460 | out_unlock: |
461 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); | | 461 | spin_unlock_irqrestore(&dev_priv->dpio_lock, flags); |
462 | } | | 462 | } |
463 | | | 463 | |
464 | static void vlv_init_dpio(struct drm_device *dev) | | 464 | static void vlv_init_dpio(struct drm_device *dev) |
465 | { | | 465 | { |
466 | struct drm_i915_private *dev_priv = dev->dev_private; | | 466 | struct drm_i915_private *dev_priv = dev->dev_private; |
467 | | | 467 | |
468 | /* Reset the DPIO config */ | | 468 | /* Reset the DPIO config */ |
469 | I915_WRITE(DPIO_CTL, 0); | | 469 | I915_WRITE(DPIO_CTL, 0); |
470 | POSTING_READ(DPIO_CTL); | | 470 | POSTING_READ(DPIO_CTL); |
471 | I915_WRITE(DPIO_CTL, 1); | | 471 | I915_WRITE(DPIO_CTL, 1); |
472 | POSTING_READ(DPIO_CTL); | | 472 | POSTING_READ(DPIO_CTL); |
473 | } | | 473 | } |
474 | | | 474 | |
| | | 475 | #ifndef __NetBSD__ /* XXX dmi hack */ |
475 | static int intel_dual_link_lvds_callback(const struct dmi_system_id *id) | | 476 | static int intel_dual_link_lvds_callback(const struct dmi_system_id *id) |
476 | { | | 477 | { |
477 | DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident); | | 478 | DRM_INFO("Forcing lvds to dual link mode on %s\n", id->ident); |
478 | return 1; | | 479 | return 1; |
479 | } | | 480 | } |
480 | | | 481 | |
481 | static const struct dmi_system_id intel_dual_link_lvds[] = { | | 482 | static const struct dmi_system_id intel_dual_link_lvds[] = { |
482 | { | | 483 | { |
483 | .callback = intel_dual_link_lvds_callback, | | 484 | .callback = intel_dual_link_lvds_callback, |
484 | .ident = "Apple MacBook Pro (Core i5/i7 Series)", | | 485 | .ident = "Apple MacBook Pro (Core i5/i7 Series)", |
485 | .matches = { | | 486 | .matches = { |
486 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), | | 487 | DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."), |
487 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"), | | 488 | DMI_MATCH(DMI_PRODUCT_NAME, "MacBookPro8,2"), |
488 | }, | | 489 | }, |
489 | }, | | 490 | }, |
490 | { } /* terminating entry */ | | 491 | { } /* terminating entry */ |
491 | }; | | 492 | }; |
| | | 493 | #endif |
492 | | | 494 | |
493 | static bool is_dual_link_lvds(struct drm_i915_private *dev_priv, | | 495 | static bool is_dual_link_lvds(struct drm_i915_private *dev_priv, |
494 | unsigned int reg) | | 496 | unsigned int reg) |
495 | { | | 497 | { |
496 | unsigned int val; | | 498 | unsigned int val; |
497 | | | 499 | |
498 | /* use the module option value if specified */ | | 500 | /* use the module option value if specified */ |
499 | if (i915_lvds_channel_mode > 0) | | 501 | if (i915_lvds_channel_mode > 0) |
500 | return i915_lvds_channel_mode == 2; | | 502 | return i915_lvds_channel_mode == 2; |
501 | | | 503 | |
| | | 504 | #ifndef __NetBSD__ /* XXX dmi hack */ |
502 | if (dmi_check_system(intel_dual_link_lvds)) | | 505 | if (dmi_check_system(intel_dual_link_lvds)) |
503 | return true; | | 506 | return true; |
| | | 507 | #endif |
504 | | | 508 | |
505 | if (dev_priv->lvds_val) | | 509 | if (dev_priv->lvds_val) |
506 | val = dev_priv->lvds_val; | | 510 | val = dev_priv->lvds_val; |
507 | else { | | 511 | else { |
508 | /* BIOS should set the proper LVDS register value at boot, but | | 512 | /* BIOS should set the proper LVDS register value at boot, but |
509 | * in reality, it doesn't set the value when the lid is closed; | | 513 | * in reality, it doesn't set the value when the lid is closed; |
510 | * we need to check "the value to be set" in VBT when LVDS | | 514 | * we need to check "the value to be set" in VBT when LVDS |
511 | * register is uninitialized. | | 515 | * register is uninitialized. |
512 | */ | | 516 | */ |
513 | val = I915_READ(reg); | | 517 | val = I915_READ(reg); |
514 | if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) | | 518 | if (!(val & ~(LVDS_PIPE_MASK | LVDS_DETECTED))) |
515 | val = dev_priv->bios_lvds_val; | | 519 | val = dev_priv->bios_lvds_val; |
516 | dev_priv->lvds_val = val; | | 520 | dev_priv->lvds_val = val; |
517 | } | | 521 | } |
518 | return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP; | | 522 | return (val & LVDS_CLKB_POWER_MASK) == LVDS_CLKB_POWER_UP; |
519 | } | | 523 | } |
520 | | | 524 | |
521 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, | | 525 | static const intel_limit_t *intel_ironlake_limit(struct drm_crtc *crtc, |
522 | int refclk) | | 526 | int refclk) |
523 | { | | 527 | { |
524 | struct drm_device *dev = crtc->dev; | | 528 | struct drm_device *dev = crtc->dev; |
525 | struct drm_i915_private *dev_priv = dev->dev_private; | | 529 | struct drm_i915_private *dev_priv = dev->dev_private; |
526 | const intel_limit_t *limit; | | 530 | const intel_limit_t *limit; |
527 | | | 531 | |
528 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | | 532 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
529 | if (is_dual_link_lvds(dev_priv, PCH_LVDS)) { | | 533 | if (is_dual_link_lvds(dev_priv, PCH_LVDS)) { |
530 | /* LVDS dual channel */ | | 534 | /* LVDS dual channel */ |
531 | if (refclk == 100000) | | 535 | if (refclk == 100000) |
532 | limit = &intel_limits_ironlake_dual_lvds_100m; | | 536 | limit = &intel_limits_ironlake_dual_lvds_100m; |
533 | else | | 537 | else |
534 | limit = &intel_limits_ironlake_dual_lvds; | | 538 | limit = &intel_limits_ironlake_dual_lvds; |
535 | } else { | | 539 | } else { |
536 | if (refclk == 100000) | | 540 | if (refclk == 100000) |
537 | limit = &intel_limits_ironlake_single_lvds_100m; | | 541 | limit = &intel_limits_ironlake_single_lvds_100m; |
538 | else | | 542 | else |
539 | limit = &intel_limits_ironlake_single_lvds; | | 543 | limit = &intel_limits_ironlake_single_lvds; |
540 | } | | 544 | } |
541 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || | | 545 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT) || |
542 | intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) | | 546 | intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP)) |
543 | limit = &intel_limits_ironlake_display_port; | | 547 | limit = &intel_limits_ironlake_display_port; |
544 | else | | 548 | else |
545 | limit = &intel_limits_ironlake_dac; | | 549 | limit = &intel_limits_ironlake_dac; |
546 | | | 550 | |
547 | return limit; | | 551 | return limit; |
548 | } | | 552 | } |
549 | | | 553 | |
550 | static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) | | 554 | static const intel_limit_t *intel_g4x_limit(struct drm_crtc *crtc) |
551 | { | | 555 | { |
552 | struct drm_device *dev = crtc->dev; | | 556 | struct drm_device *dev = crtc->dev; |
553 | struct drm_i915_private *dev_priv = dev->dev_private; | | 557 | struct drm_i915_private *dev_priv = dev->dev_private; |
554 | const intel_limit_t *limit; | | 558 | const intel_limit_t *limit; |
555 | | | 559 | |
556 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | | 560 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
557 | if (is_dual_link_lvds(dev_priv, LVDS)) | | 561 | if (is_dual_link_lvds(dev_priv, LVDS)) |
558 | /* LVDS with dual channel */ | | 562 | /* LVDS with dual channel */ |
559 | limit = &intel_limits_g4x_dual_channel_lvds; | | 563 | limit = &intel_limits_g4x_dual_channel_lvds; |
560 | else | | 564 | else |
561 | /* LVDS with dual channel */ | | 565 | /* LVDS with dual channel */ |
562 | limit = &intel_limits_g4x_single_channel_lvds; | | 566 | limit = &intel_limits_g4x_single_channel_lvds; |
563 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || | | 567 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI) || |
564 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { | | 568 | intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) { |
565 | limit = &intel_limits_g4x_hdmi; | | 569 | limit = &intel_limits_g4x_hdmi; |
566 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { | | 570 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_SDVO)) { |
567 | limit = &intel_limits_g4x_sdvo; | | 571 | limit = &intel_limits_g4x_sdvo; |
568 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { | | 572 | } else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_DISPLAYPORT)) { |
569 | limit = &intel_limits_g4x_display_port; | | 573 | limit = &intel_limits_g4x_display_port; |
570 | } else /* The option is for other outputs */ | | 574 | } else /* The option is for other outputs */ |
571 | limit = &intel_limits_i9xx_sdvo; | | 575 | limit = &intel_limits_i9xx_sdvo; |
572 | | | 576 | |
573 | return limit; | | 577 | return limit; |
574 | } | | 578 | } |
575 | | | 579 | |
576 | static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) | | 580 | static const intel_limit_t *intel_limit(struct drm_crtc *crtc, int refclk) |
577 | { | | 581 | { |
578 | struct drm_device *dev = crtc->dev; | | 582 | struct drm_device *dev = crtc->dev; |
579 | const intel_limit_t *limit; | | 583 | const intel_limit_t *limit; |
580 | | | 584 | |
581 | if (HAS_PCH_SPLIT(dev)) | | 585 | if (HAS_PCH_SPLIT(dev)) |
582 | limit = intel_ironlake_limit(crtc, refclk); | | 586 | limit = intel_ironlake_limit(crtc, refclk); |
583 | else if (IS_G4X(dev)) { | | 587 | else if (IS_G4X(dev)) { |
584 | limit = intel_g4x_limit(crtc); | | 588 | limit = intel_g4x_limit(crtc); |
585 | } else if (IS_PINEVIEW(dev)) { | | 589 | } else if (IS_PINEVIEW(dev)) { |
586 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | | 590 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
587 | limit = &intel_limits_pineview_lvds; | | 591 | limit = &intel_limits_pineview_lvds; |
588 | else | | 592 | else |
589 | limit = &intel_limits_pineview_sdvo; | | 593 | limit = &intel_limits_pineview_sdvo; |
590 | } else if (IS_VALLEYVIEW(dev)) { | | 594 | } else if (IS_VALLEYVIEW(dev)) { |
591 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) | | 595 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_ANALOG)) |
592 | limit = &intel_limits_vlv_dac; | | 596 | limit = &intel_limits_vlv_dac; |
593 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) | | 597 | else if (intel_pipe_has_type(crtc, INTEL_OUTPUT_HDMI)) |
594 | limit = &intel_limits_vlv_hdmi; | | 598 | limit = &intel_limits_vlv_hdmi; |
595 | else | | 599 | else |
596 | limit = &intel_limits_vlv_dp; | | 600 | limit = &intel_limits_vlv_dp; |
597 | } else if (!IS_GEN2(dev)) { | | 601 | } else if (!IS_GEN2(dev)) { |
598 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | | 602 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
599 | limit = &intel_limits_i9xx_lvds; | | 603 | limit = &intel_limits_i9xx_lvds; |
600 | else | | 604 | else |
601 | limit = &intel_limits_i9xx_sdvo; | | 605 | limit = &intel_limits_i9xx_sdvo; |
602 | } else { | | 606 | } else { |
603 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) | | 607 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) |
604 | limit = &intel_limits_i8xx_lvds; | | 608 | limit = &intel_limits_i8xx_lvds; |
605 | else | | 609 | else |
606 | limit = &intel_limits_i8xx_dvo; | | 610 | limit = &intel_limits_i8xx_dvo; |
607 | } | | 611 | } |
608 | return limit; | | 612 | return limit; |
609 | } | | 613 | } |
610 | | | 614 | |
611 | /* m1 is reserved as 0 in Pineview, n is a ring counter */ | | 615 | /* m1 is reserved as 0 in Pineview, n is a ring counter */ |
612 | static void pineview_clock(int refclk, intel_clock_t *clock) | | 616 | static void pineview_clock(int refclk, intel_clock_t *clock) |
613 | { | | 617 | { |
614 | clock->m = clock->m2 + 2; | | 618 | clock->m = clock->m2 + 2; |
615 | clock->p = clock->p1 * clock->p2; | | 619 | clock->p = clock->p1 * clock->p2; |
616 | clock->vco = refclk * clock->m / clock->n; | | 620 | clock->vco = refclk * clock->m / clock->n; |
617 | clock->dot = clock->vco / clock->p; | | 621 | clock->dot = clock->vco / clock->p; |
618 | } | | 622 | } |
619 | | | 623 | |
620 | static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock) | | 624 | static void intel_clock(struct drm_device *dev, int refclk, intel_clock_t *clock) |
621 | { | | 625 | { |
622 | if (IS_PINEVIEW(dev)) { | | 626 | if (IS_PINEVIEW(dev)) { |
623 | pineview_clock(refclk, clock); | | 627 | pineview_clock(refclk, clock); |
624 | return; | | 628 | return; |
625 | } | | 629 | } |
626 | clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); | | 630 | clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2); |
627 | clock->p = clock->p1 * clock->p2; | | 631 | clock->p = clock->p1 * clock->p2; |
628 | clock->vco = refclk * clock->m / (clock->n + 2); | | 632 | clock->vco = refclk * clock->m / (clock->n + 2); |
629 | clock->dot = clock->vco / clock->p; | | 633 | clock->dot = clock->vco / clock->p; |
630 | } | | 634 | } |
631 | | | 635 | |
632 | /** | | 636 | /** |
633 | * Returns whether any output on the specified pipe is of the specified type | | 637 | * Returns whether any output on the specified pipe is of the specified type |
634 | */ | | 638 | */ |
635 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type) | | 639 | bool intel_pipe_has_type(struct drm_crtc *crtc, int type) |
636 | { | | 640 | { |
637 | struct drm_device *dev = crtc->dev; | | 641 | struct drm_device *dev = crtc->dev; |
638 | struct intel_encoder *encoder; | | 642 | struct intel_encoder *encoder; |
639 | | | 643 | |
640 | for_each_encoder_on_crtc(dev, crtc, encoder) | | 644 | for_each_encoder_on_crtc(dev, crtc, encoder) |
641 | if (encoder->type == type) | | 645 | if (encoder->type == type) |
642 | return true; | | 646 | return true; |
643 | | | 647 | |
644 | return false; | | 648 | return false; |
645 | } | | 649 | } |
646 | | | 650 | |
647 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) | | 651 | #define INTELPllInvalid(s) do { /* DRM_DEBUG(s); */ return false; } while (0) |
648 | /** | | 652 | /** |
649 | * Returns whether the given set of divisors are valid for a given refclk with | | 653 | * Returns whether the given set of divisors are valid for a given refclk with |
650 | * the given connectors. | | 654 | * the given connectors. |
651 | */ | | 655 | */ |
652 | | | 656 | |
653 | static bool intel_PLL_is_valid(struct drm_device *dev, | | 657 | static bool intel_PLL_is_valid(struct drm_device *dev, |
654 | const intel_limit_t *limit, | | 658 | const intel_limit_t *limit, |
655 | const intel_clock_t *clock) | | 659 | const intel_clock_t *clock) |
656 | { | | 660 | { |
657 | if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) | | 661 | if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1) |
658 | INTELPllInvalid("p1 out of range\n"); | | 662 | INTELPllInvalid("p1 out of range\n"); |
659 | if (clock->p < limit->p.min || limit->p.max < clock->p) | | 663 | if (clock->p < limit->p.min || limit->p.max < clock->p) |
660 | INTELPllInvalid("p out of range\n"); | | 664 | INTELPllInvalid("p out of range\n"); |
661 | if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2) | | 665 | if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2) |
662 | INTELPllInvalid("m2 out of range\n"); | | 666 | INTELPllInvalid("m2 out of range\n"); |
663 | if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) | | 667 | if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1) |
664 | INTELPllInvalid("m1 out of range\n"); | | 668 | INTELPllInvalid("m1 out of range\n"); |
665 | if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev)) | | 669 | if (clock->m1 <= clock->m2 && !IS_PINEVIEW(dev)) |
666 | INTELPllInvalid("m1 <= m2\n"); | | 670 | INTELPllInvalid("m1 <= m2\n"); |
667 | if (clock->m < limit->m.min || limit->m.max < clock->m) | | 671 | if (clock->m < limit->m.min || limit->m.max < clock->m) |
668 | INTELPllInvalid("m out of range\n"); | | 672 | INTELPllInvalid("m out of range\n"); |
669 | if (clock->n < limit->n.min || limit->n.max < clock->n) | | 673 | if (clock->n < limit->n.min || limit->n.max < clock->n) |
670 | INTELPllInvalid("n out of range\n"); | | 674 | INTELPllInvalid("n out of range\n"); |
671 | if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) | | 675 | if (clock->vco < limit->vco.min || limit->vco.max < clock->vco) |
672 | INTELPllInvalid("vco out of range\n"); | | 676 | INTELPllInvalid("vco out of range\n"); |
673 | /* XXX: We may need to be checking "Dot clock" depending on the multiplier, | | 677 | /* XXX: We may need to be checking "Dot clock" depending on the multiplier, |
674 | * connector, etc., rather than just a single range. | | 678 | * connector, etc., rather than just a single range. |
675 | */ | | 679 | */ |
676 | if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) | | 680 | if (clock->dot < limit->dot.min || limit->dot.max < clock->dot) |
677 | INTELPllInvalid("dot out of range\n"); | | 681 | INTELPllInvalid("dot out of range\n"); |
678 | | | 682 | |
679 | return true; | | 683 | return true; |
680 | } | | 684 | } |
681 | | | 685 | |
682 | static bool | | 686 | static bool |
683 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | | 687 | intel_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
684 | int target, int refclk, intel_clock_t *match_clock, | | 688 | int target, int refclk, intel_clock_t *match_clock, |
685 | intel_clock_t *best_clock) | | 689 | intel_clock_t *best_clock) |
686 | | | 690 | |
687 | { | | 691 | { |
688 | struct drm_device *dev = crtc->dev; | | 692 | struct drm_device *dev = crtc->dev; |
689 | struct drm_i915_private *dev_priv = dev->dev_private; | | 693 | struct drm_i915_private *dev_priv = dev->dev_private; |
690 | intel_clock_t clock; | | 694 | intel_clock_t clock; |
691 | int err = target; | | 695 | int err = target; |
692 | | | 696 | |
693 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && | | 697 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) && |
694 | (I915_READ(LVDS)) != 0) { | | 698 | (I915_READ(LVDS)) != 0) { |
695 | /* | | 699 | /* |
696 | * For LVDS, if the panel is on, just rely on its current | | 700 | * For LVDS, if the panel is on, just rely on its current |
697 | * settings for dual-channel. We haven't figured out how to | | 701 | * settings for dual-channel. We haven't figured out how to |
698 | * reliably set up different single/dual channel state, if we | | 702 | * reliably set up different single/dual channel state, if we |
699 | * even can. | | 703 | * even can. |
700 | */ | | 704 | */ |
701 | if (is_dual_link_lvds(dev_priv, LVDS)) | | 705 | if (is_dual_link_lvds(dev_priv, LVDS)) |
702 | clock.p2 = limit->p2.p2_fast; | | 706 | clock.p2 = limit->p2.p2_fast; |
703 | else | | 707 | else |
704 | clock.p2 = limit->p2.p2_slow; | | 708 | clock.p2 = limit->p2.p2_slow; |
705 | } else { | | 709 | } else { |
706 | if (target < limit->p2.dot_limit) | | 710 | if (target < limit->p2.dot_limit) |
707 | clock.p2 = limit->p2.p2_slow; | | 711 | clock.p2 = limit->p2.p2_slow; |
708 | else | | 712 | else |
709 | clock.p2 = limit->p2.p2_fast; | | 713 | clock.p2 = limit->p2.p2_fast; |
710 | } | | 714 | } |
711 | | | 715 | |
712 | memset(best_clock, 0, sizeof(*best_clock)); | | 716 | memset(best_clock, 0, sizeof(*best_clock)); |
713 | | | 717 | |
714 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; | | 718 | for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max; |
715 | clock.m1++) { | | 719 | clock.m1++) { |
716 | for (clock.m2 = limit->m2.min; | | 720 | for (clock.m2 = limit->m2.min; |
717 | clock.m2 <= limit->m2.max; clock.m2++) { | | 721 | clock.m2 <= limit->m2.max; clock.m2++) { |
718 | /* m1 is always 0 in Pineview */ | | 722 | /* m1 is always 0 in Pineview */ |
719 | if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev)) | | 723 | if (clock.m2 >= clock.m1 && !IS_PINEVIEW(dev)) |
720 | break; | | 724 | break; |
721 | for (clock.n = limit->n.min; | | 725 | for (clock.n = limit->n.min; |
722 | clock.n <= limit->n.max; clock.n++) { | | 726 | clock.n <= limit->n.max; clock.n++) { |
723 | for (clock.p1 = limit->p1.min; | | 727 | for (clock.p1 = limit->p1.min; |
724 | clock.p1 <= limit->p1.max; clock.p1++) { | | 728 | clock.p1 <= limit->p1.max; clock.p1++) { |
725 | int this_err; | | 729 | int this_err; |
726 | | | 730 | |
727 | intel_clock(dev, refclk, &clock); | | 731 | intel_clock(dev, refclk, &clock); |
728 | if (!intel_PLL_is_valid(dev, limit, | | 732 | if (!intel_PLL_is_valid(dev, limit, |
729 | &clock)) | | 733 | &clock)) |
730 | continue; | | 734 | continue; |
731 | if (match_clock && | | 735 | if (match_clock && |
732 | clock.p != match_clock->p) | | 736 | clock.p != match_clock->p) |
733 | continue; | | 737 | continue; |
734 | | | 738 | |
735 | this_err = abs(clock.dot - target); | | 739 | this_err = abs(clock.dot - target); |
736 | if (this_err < err) { | | 740 | if (this_err < err) { |
737 | *best_clock = clock; | | 741 | *best_clock = clock; |
738 | err = this_err; | | 742 | err = this_err; |
739 | } | | 743 | } |
740 | } | | 744 | } |
741 | } | | 745 | } |
742 | } | | 746 | } |
743 | } | | 747 | } |
744 | | | 748 | |
745 | return (err != target); | | 749 | return (err != target); |
746 | } | | 750 | } |
747 | | | 751 | |
748 | static bool | | 752 | static bool |
749 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, | | 753 | intel_g4x_find_best_PLL(const intel_limit_t *limit, struct drm_crtc *crtc, |
750 | int target, int refclk, intel_clock_t *match_clock, | | 754 | int target, int refclk, intel_clock_t *match_clock, |
751 | intel_clock_t *best_clock) | | 755 | intel_clock_t *best_clock) |
752 | { | | 756 | { |
753 | struct drm_device *dev = crtc->dev; | | 757 | struct drm_device *dev = crtc->dev; |
754 | struct drm_i915_private *dev_priv = dev->dev_private; | | 758 | struct drm_i915_private *dev_priv = dev->dev_private; |
755 | intel_clock_t clock; | | 759 | intel_clock_t clock; |
756 | int max_n; | | 760 | int max_n; |
757 | bool found; | | 761 | bool found; |
758 | /* approximately equals target * 0.00585 */ | | 762 | /* approximately equals target * 0.00585 */ |
759 | int err_most = (target >> 8) + (target >> 9); | | 763 | int err_most = (target >> 8) + (target >> 9); |
760 | found = false; | | 764 | found = false; |
761 | | | 765 | |
762 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { | | 766 | if (intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS)) { |
763 | int lvds_reg; | | 767 | int lvds_reg; |
764 | | | 768 | |
765 | if (HAS_PCH_SPLIT(dev)) | | 769 | if (HAS_PCH_SPLIT(dev)) |
766 | lvds_reg = PCH_LVDS; | | 770 | lvds_reg = PCH_LVDS; |
767 | else | | 771 | else |
768 | lvds_reg = LVDS; | | 772 | lvds_reg = LVDS; |
769 | if ((I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) == | | 773 | if ((I915_READ(lvds_reg) & LVDS_CLKB_POWER_MASK) == |
770 | LVDS_CLKB_POWER_UP) | | 774 | LVDS_CLKB_POWER_UP) |
771 | clock.p2 = limit->p2.p2_fast; | | 775 | clock.p2 = limit->p2.p2_fast; |
772 | else | | 776 | else |
773 | clock.p2 = limit->p2.p2_slow; | | 777 | clock.p2 = limit->p2.p2_slow; |
774 | } else { | | 778 | } else { |
775 | if (target < limit->p2.dot_limit) | | 779 | if (target < limit->p2.dot_limit) |
776 | clock.p2 = limit->p2.p2_slow; | | 780 | clock.p2 = limit->p2.p2_slow; |
777 | else | | 781 | else |
778 | clock.p2 = limit->p2.p2_fast; | | 782 | clock.p2 = limit->p2.p2_fast; |
779 | } | | 783 | } |
780 | | | 784 | |
781 | memset(best_clock, 0, sizeof(*best_clock)); | | 785 | memset(best_clock, 0, sizeof(*best_clock)); |
782 | max_n = limit->n.max; | | 786 | max_n = limit->n.max; |
783 | /* based on hardware requirement, prefer smaller n to precision */ | | 787 | /* based on hardware requirement, prefer smaller n to precision */ |
784 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { | | 788 | for (clock.n = limit->n.min; clock.n <= max_n; clock.n++) { |
785 | /* based on hardware requirement, prefere larger m1,m2 */ | | 789 | /* based on hardware requirement, prefere larger m1,m2 */ |
786 | for (clock.m1 = limit->m1.max; | | 790 | for (clock.m1 = limit->m1.max; |
787 | clock.m1 >= limit->m1.min; clock.m1--) { | | 791 | clock.m1 >= limit->m1.min; clock.m1--) { |
788 | for (clock.m2 = limit->m2.max; | | 792 | for (clock.m2 = limit->m2.max; |
789 | clock.m2 >= limit->m2.min; clock.m2--) { | | 793 | clock.m2 >= limit->m2.min; clock.m2--) { |
790 | for (clock.p1 = limit->p1.max; | | 794 | for (clock.p1 = limit->p1.max; |
791 | clock.p1 >= limit->p1.min; clock.p1--) { | | 795 | clock.p1 >= limit->p1.min; clock.p1--) { |
792 | int this_err; | | 796 | int this_err; |
793 | | | 797 | |
794 | intel_clock(dev, refclk, &clock); | | 798 | intel_clock(dev, refclk, &clock); |
795 | if (!intel_PLL_is_valid(dev, limit, | | 799 | if (!intel_PLL_is_valid(dev, limit, |
796 | &clock)) | | 800 | &clock)) |
797 | continue; | | 801 | continue; |
798 | if (match_clock && | | 802 | if (match_clock && |
799 | clock.p != match_clock->p) | | 803 | clock.p != match_clock->p) |
800 | continue; | | 804 | continue; |
801 | | | 805 | |
802 | this_err = abs(clock.dot - target); | | 806 | this_err = abs(clock.dot - target); |
803 | if (this_err < err_most) { | | 807 | if (this_err < err_most) { |
804 | *best_clock = clock; | | 808 | *best_clock = clock; |
805 | err_most = this_err; | | 809 | err_most = this_err; |
806 | max_n = clock.n; | | 810 | max_n = clock.n; |
807 | found = true; | | 811 | found = true; |
808 | } | | 812 | } |
809 | } | | 813 | } |
810 | } | | 814 | } |
811 | } | | 815 | } |
812 | } | | 816 | } |
813 | return found; | | 817 | return found; |
814 | } | | 818 | } |
815 | | | 819 | |
816 | static bool | | 820 | static bool |
817 | intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | | 821 | intel_find_pll_ironlake_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
818 | int target, int refclk, intel_clock_t *match_clock, | | 822 | int target, int refclk, intel_clock_t *match_clock, |
819 | intel_clock_t *best_clock) | | 823 | intel_clock_t *best_clock) |
820 | { | | 824 | { |
821 | struct drm_device *dev = crtc->dev; | | 825 | struct drm_device *dev = crtc->dev; |
822 | intel_clock_t clock; | | 826 | intel_clock_t clock; |
823 | | | 827 | |
824 | if (target < 200000) { | | 828 | if (target < 200000) { |
825 | clock.n = 1; | | 829 | clock.n = 1; |
826 | clock.p1 = 2; | | 830 | clock.p1 = 2; |
827 | clock.p2 = 10; | | 831 | clock.p2 = 10; |
828 | clock.m1 = 12; | | 832 | clock.m1 = 12; |
829 | clock.m2 = 9; | | 833 | clock.m2 = 9; |
830 | } else { | | 834 | } else { |
831 | clock.n = 2; | | 835 | clock.n = 2; |
832 | clock.p1 = 1; | | 836 | clock.p1 = 1; |
833 | clock.p2 = 10; | | 837 | clock.p2 = 10; |
834 | clock.m1 = 14; | | 838 | clock.m1 = 14; |
835 | clock.m2 = 8; | | 839 | clock.m2 = 8; |
836 | } | | 840 | } |
837 | intel_clock(dev, refclk, &clock); | | 841 | intel_clock(dev, refclk, &clock); |
838 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | | 842 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
839 | return true; | | 843 | return true; |
840 | } | | 844 | } |
841 | | | 845 | |
842 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ | | 846 | /* DisplayPort has only two frequencies, 162MHz and 270MHz */ |
843 | static bool | | 847 | static bool |
844 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, | | 848 | intel_find_pll_g4x_dp(const intel_limit_t *limit, struct drm_crtc *crtc, |
845 | int target, int refclk, intel_clock_t *match_clock, | | 849 | int target, int refclk, intel_clock_t *match_clock, |
846 | intel_clock_t *best_clock) | | 850 | intel_clock_t *best_clock) |
847 | { | | 851 | { |
848 | intel_clock_t clock; | | 852 | intel_clock_t clock; |
849 | if (target < 200000) { | | 853 | if (target < 200000) { |
850 | clock.p1 = 2; | | 854 | clock.p1 = 2; |
851 | clock.p2 = 10; | | 855 | clock.p2 = 10; |
852 | clock.n = 2; | | 856 | clock.n = 2; |
853 | clock.m1 = 23; | | 857 | clock.m1 = 23; |
854 | clock.m2 = 8; | | 858 | clock.m2 = 8; |
855 | } else { | | 859 | } else { |
856 | clock.p1 = 1; | | 860 | clock.p1 = 1; |
857 | clock.p2 = 10; | | 861 | clock.p2 = 10; |
858 | clock.n = 1; | | 862 | clock.n = 1; |
859 | clock.m1 = 14; | | 863 | clock.m1 = 14; |
860 | clock.m2 = 2; | | 864 | clock.m2 = 2; |
861 | } | | 865 | } |
862 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); | | 866 | clock.m = 5 * (clock.m1 + 2) + (clock.m2 + 2); |
863 | clock.p = (clock.p1 * clock.p2); | | 867 | clock.p = (clock.p1 * clock.p2); |
864 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; | | 868 | clock.dot = 96000 * clock.m / (clock.n + 2) / clock.p; |
865 | clock.vco = 0; | | 869 | clock.vco = 0; |
866 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); | | 870 | memcpy(best_clock, &clock, sizeof(intel_clock_t)); |
867 | return true; | | 871 | return true; |
868 | } | | 872 | } |
869 | static bool | | 873 | static bool |
870 | intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, | | 874 | intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, |
871 | int target, int refclk, intel_clock_t *match_clock, | | 875 | int target, int refclk, intel_clock_t *match_clock, |
872 | intel_clock_t *best_clock) | | 876 | intel_clock_t *best_clock) |
873 | { | | 877 | { |
874 | u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2; | | 878 | u32 p1, p2, m1, m2, vco, bestn, bestm1, bestm2, bestp1, bestp2; |
875 | u32 m, n, fastclk; | | 879 | u32 m, n, fastclk; |
876 | u32 updrate, minupdate, fracbits, p; | | 880 | u32 updrate, minupdate, fracbits, p; |
877 | unsigned long bestppm, ppm, absppm; | | 881 | unsigned long bestppm, ppm, absppm; |
878 | int dotclk, flag; | | 882 | int dotclk, flag; |
879 | | | 883 | |
880 | flag = 0; | | 884 | flag = 0; |
881 | dotclk = target * 1000; | | 885 | dotclk = target * 1000; |
882 | bestppm = 1000000; | | 886 | bestppm = 1000000; |
883 | ppm = absppm = 0; | | 887 | ppm = absppm = 0; |
884 | fastclk = dotclk / (2*100); | | 888 | fastclk = dotclk / (2*100); |
885 | updrate = 0; | | 889 | updrate = 0; |
886 | minupdate = 19200; | | 890 | minupdate = 19200; |
887 | fracbits = 1; | | 891 | fracbits = 1; |
888 | n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0; | | 892 | n = p = p1 = p2 = m = m1 = m2 = vco = bestn = 0; |
889 | bestm1 = bestm2 = bestp1 = bestp2 = 0; | | 893 | bestm1 = bestm2 = bestp1 = bestp2 = 0; |
890 | | | 894 | |
891 | /* based on hardware requirement, prefer smaller n to precision */ | | 895 | /* based on hardware requirement, prefer smaller n to precision */ |
892 | for (n = limit->n.min; n <= ((refclk) / minupdate); n++) { | | 896 | for (n = limit->n.min; n <= ((refclk) / minupdate); n++) { |
893 | updrate = refclk / n; | | 897 | updrate = refclk / n; |
894 | for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) { | | 898 | for (p1 = limit->p1.max; p1 > limit->p1.min; p1--) { |
895 | for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) { | | 899 | for (p2 = limit->p2.p2_fast+1; p2 > 0; p2--) { |
896 | if (p2 > 10) | | 900 | if (p2 > 10) |
897 | p2 = p2 - 1; | | 901 | p2 = p2 - 1; |
898 | p = p1 * p2; | | 902 | p = p1 * p2; |
899 | /* based on hardware requirement, prefer bigger m1,m2 values */ | | 903 | /* based on hardware requirement, prefer bigger m1,m2 values */ |
900 | for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) { | | 904 | for (m1 = limit->m1.min; m1 <= limit->m1.max; m1++) { |
901 | m2 = (((2*(fastclk * p * n / m1 )) + | | 905 | m2 = (((2*(fastclk * p * n / m1 )) + |
902 | refclk) / (2*refclk)); | | 906 | refclk) / (2*refclk)); |
903 | m = m1 * m2; | | 907 | m = m1 * m2; |
904 | vco = updrate * m; | | 908 | vco = updrate * m; |
905 | if (vco >= limit->vco.min && vco < limit->vco.max) { | | 909 | if (vco >= limit->vco.min && vco < limit->vco.max) { |
906 | ppm = 1000000 * ((vco / p) - fastclk) / fastclk; | | 910 | ppm = 1000000 * ((vco / p) - fastclk) / fastclk; |
907 | absppm = (ppm > 0) ? ppm : (-ppm); | | 911 | absppm = (ppm > 0) ? ppm : (-ppm); |
908 | if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) { | | 912 | if (absppm < 100 && ((p1 * p2) > (bestp1 * bestp2))) { |
909 | bestppm = 0; | | 913 | bestppm = 0; |
910 | flag = 1; | | 914 | flag = 1; |
911 | } | | 915 | } |
912 | if (absppm < bestppm - 10) { | | 916 | if (absppm < bestppm - 10) { |
913 | bestppm = absppm; | | 917 | bestppm = absppm; |
914 | flag = 1; | | 918 | flag = 1; |
915 | } | | 919 | } |
916 | if (flag) { | | 920 | if (flag) { |
917 | bestn = n; | | 921 | bestn = n; |
918 | bestm1 = m1; | | 922 | bestm1 = m1; |
919 | bestm2 = m2; | | 923 | bestm2 = m2; |
920 | bestp1 = p1; | | 924 | bestp1 = p1; |
921 | bestp2 = p2; | | 925 | bestp2 = p2; |
922 | flag = 0; | | 926 | flag = 0; |
923 | } | | 927 | } |
924 | } | | 928 | } |
925 | } | | 929 | } |
926 | } | | 930 | } |
927 | } | | 931 | } |
928 | } | | 932 | } |
929 | best_clock->n = bestn; | | 933 | best_clock->n = bestn; |
930 | best_clock->m1 = bestm1; | | 934 | best_clock->m1 = bestm1; |
931 | best_clock->m2 = bestm2; | | 935 | best_clock->m2 = bestm2; |
932 | best_clock->p1 = bestp1; | | 936 | best_clock->p1 = bestp1; |
933 | best_clock->p2 = bestp2; | | 937 | best_clock->p2 = bestp2; |
934 | | | 938 | |
935 | return true; | | 939 | return true; |
936 | } | | 940 | } |
937 | | | 941 | |
938 | enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, | | 942 | enum transcoder intel_pipe_to_cpu_transcoder(struct drm_i915_private *dev_priv, |
939 | enum pipe pipe) | | 943 | enum pipe pipe) |
940 | { | | 944 | { |
941 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; | | 945 | struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe]; |
942 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | | 946 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
943 | | | 947 | |
944 | return intel_crtc->cpu_transcoder; | | 948 | return intel_crtc->cpu_transcoder; |
945 | } | | 949 | } |
946 | | | 950 | |
947 | static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe) | | 951 | static void ironlake_wait_for_vblank(struct drm_device *dev, int pipe) |
948 | { | | 952 | { |
949 | struct drm_i915_private *dev_priv = dev->dev_private; | | 953 | struct drm_i915_private *dev_priv = dev->dev_private; |
950 | u32 frame, frame_reg = PIPEFRAME(pipe); | | 954 | u32 frame, frame_reg = PIPEFRAME(pipe); |
951 | | | 955 | |
952 | frame = I915_READ(frame_reg); | | 956 | frame = I915_READ(frame_reg); |
953 | | | 957 | |
954 | if (wait_for(I915_READ_NOTRACE(frame_reg) != frame, 50)) | | 958 | if (wait_for(I915_READ_NOTRACE(frame_reg) != frame, 50)) |
955 | DRM_DEBUG_KMS("vblank wait timed out\n"); | | 959 | DRM_DEBUG_KMS("vblank wait timed out\n"); |
956 | } | | 960 | } |
957 | | | 961 | |
958 | /** | | 962 | /** |
959 | * intel_wait_for_vblank - wait for vblank on a given pipe | | 963 | * intel_wait_for_vblank - wait for vblank on a given pipe |
960 | * @dev: drm device | | 964 | * @dev: drm device |
961 | * @pipe: pipe to wait for | | 965 | * @pipe: pipe to wait for |
962 | * | | 966 | * |
963 | * Wait for vblank to occur on a given pipe. Needed for various bits of | | 967 | * Wait for vblank to occur on a given pipe. Needed for various bits of |
964 | * mode setting code. | | 968 | * mode setting code. |
965 | */ | | 969 | */ |
966 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) | | 970 | void intel_wait_for_vblank(struct drm_device *dev, int pipe) |
967 | { | | 971 | { |
968 | struct drm_i915_private *dev_priv = dev->dev_private; | | 972 | struct drm_i915_private *dev_priv = dev->dev_private; |
969 | int pipestat_reg = PIPESTAT(pipe); | | 973 | int pipestat_reg = PIPESTAT(pipe); |
970 | | | 974 | |
971 | if (INTEL_INFO(dev)->gen >= 5) { | | 975 | if (INTEL_INFO(dev)->gen >= 5) { |
972 | ironlake_wait_for_vblank(dev, pipe); | | 976 | ironlake_wait_for_vblank(dev, pipe); |
973 | return; | | 977 | return; |
974 | } | | 978 | } |
975 | | | 979 | |
976 | /* Clear existing vblank status. Note this will clear any other | | 980 | /* Clear existing vblank status. Note this will clear any other |
977 | * sticky status fields as well. | | 981 | * sticky status fields as well. |
978 | * | | 982 | * |
979 | * This races with i915_driver_irq_handler() with the result | | 983 | * This races with i915_driver_irq_handler() with the result |
980 | * that either function could miss a vblank event. Here it is not | | 984 | * that either function could miss a vblank event. Here it is not |
981 | * fatal, as we will either wait upon the next vblank interrupt or | | 985 | * fatal, as we will either wait upon the next vblank interrupt or |
982 | * timeout. Generally speaking intel_wait_for_vblank() is only | | 986 | * timeout. Generally speaking intel_wait_for_vblank() is only |
983 | * called during modeset at which time the GPU should be idle and | | 987 | * called during modeset at which time the GPU should be idle and |
984 | * should *not* be performing page flips and thus not waiting on | | 988 | * should *not* be performing page flips and thus not waiting on |
985 | * vblanks... | | 989 | * vblanks... |
986 | * Currently, the result of us stealing a vblank from the irq | | 990 | * Currently, the result of us stealing a vblank from the irq |
987 | * handler is that a single frame will be skipped during swapbuffers. | | 991 | * handler is that a single frame will be skipped during swapbuffers. |
988 | */ | | 992 | */ |
989 | I915_WRITE(pipestat_reg, | | 993 | I915_WRITE(pipestat_reg, |
990 | I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); | | 994 | I915_READ(pipestat_reg) | PIPE_VBLANK_INTERRUPT_STATUS); |
991 | | | 995 | |
992 | /* Wait for vblank interrupt bit to set */ | | 996 | /* Wait for vblank interrupt bit to set */ |
993 | if (wait_for(I915_READ(pipestat_reg) & | | 997 | if (wait_for(I915_READ(pipestat_reg) & |
994 | PIPE_VBLANK_INTERRUPT_STATUS, | | 998 | PIPE_VBLANK_INTERRUPT_STATUS, |
995 | 50)) | | 999 | 50)) |
996 | DRM_DEBUG_KMS("vblank wait timed out\n"); | | 1000 | DRM_DEBUG_KMS("vblank wait timed out\n"); |
997 | } | | 1001 | } |
998 | | | 1002 | |
999 | /* | | 1003 | /* |
1000 | * intel_wait_for_pipe_off - wait for pipe to turn off | | 1004 | * intel_wait_for_pipe_off - wait for pipe to turn off |
1001 | * @dev: drm device | | 1005 | * @dev: drm device |
1002 | * @pipe: pipe to wait for | | 1006 | * @pipe: pipe to wait for |
1003 | * | | 1007 | * |
1004 | * After disabling a pipe, we can't wait for vblank in the usual way, | | 1008 | * After disabling a pipe, we can't wait for vblank in the usual way, |
1005 | * spinning on the vblank interrupt status bit, since we won't actually | | 1009 | * spinning on the vblank interrupt status bit, since we won't actually |
1006 | * see an interrupt when the pipe is disabled. | | 1010 | * see an interrupt when the pipe is disabled. |
1007 | * | | 1011 | * |
1008 | * On Gen4 and above: | | 1012 | * On Gen4 and above: |
1009 | * wait for the pipe register state bit to turn off | | 1013 | * wait for the pipe register state bit to turn off |
1010 | * | | 1014 | * |
1011 | * Otherwise: | | 1015 | * Otherwise: |
1012 | * wait for the display line value to settle (it usually | | 1016 | * wait for the display line value to settle (it usually |
1013 | * ends up stopping at the start of the next frame). | | 1017 | * ends up stopping at the start of the next frame). |
1014 | * | | 1018 | * |
1015 | */ | | 1019 | */ |
1016 | void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) | | 1020 | void intel_wait_for_pipe_off(struct drm_device *dev, int pipe) |
1017 | { | | 1021 | { |
1018 | struct drm_i915_private *dev_priv = dev->dev_private; | | 1022 | struct drm_i915_private *dev_priv = dev->dev_private; |
1019 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, | | 1023 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
1020 | pipe); | | 1024 | pipe); |
1021 | | | 1025 | |
1022 | if (INTEL_INFO(dev)->gen >= 4) { | | 1026 | if (INTEL_INFO(dev)->gen >= 4) { |
1023 | int reg = PIPECONF(cpu_transcoder); | | 1027 | int reg = PIPECONF(cpu_transcoder); |
1024 | | | 1028 | |
1025 | /* Wait for the Pipe State to go off */ | | 1029 | /* Wait for the Pipe State to go off */ |
1026 | if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, | | 1030 | if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0, |
1027 | 100)) | | 1031 | 100)) |
1028 | WARN(1, "pipe_off wait timed out\n"); | | 1032 | WARN(1, "pipe_off wait timed out\n"); |
1029 | } else { | | 1033 | } else { |
1030 | u32 last_line, line_mask; | | 1034 | u32 last_line, line_mask; |
1031 | int reg = PIPEDSL(pipe); | | 1035 | int reg = PIPEDSL(pipe); |
1032 | unsigned long timeout = jiffies + msecs_to_jiffies(100); | | 1036 | unsigned long timeout = jiffies + msecs_to_jiffies(100); |
1033 | | | 1037 | |
1034 | if (IS_GEN2(dev)) | | 1038 | if (IS_GEN2(dev)) |
1035 | line_mask = DSL_LINEMASK_GEN2; | | 1039 | line_mask = DSL_LINEMASK_GEN2; |
1036 | else | | 1040 | else |
1037 | line_mask = DSL_LINEMASK_GEN3; | | 1041 | line_mask = DSL_LINEMASK_GEN3; |
1038 | | | 1042 | |
1039 | /* Wait for the display line to settle */ | | 1043 | /* Wait for the display line to settle */ |
1040 | do { | | 1044 | do { |
1041 | last_line = I915_READ(reg) & line_mask; | | 1045 | last_line = I915_READ(reg) & line_mask; |
1042 | mdelay(5); | | 1046 | mdelay(5); |
1043 | } while (((I915_READ(reg) & line_mask) != last_line) && | | 1047 | } while (((I915_READ(reg) & line_mask) != last_line) && |
1044 | time_after(timeout, jiffies)); | | 1048 | time_after(timeout, jiffies)); |
1045 | if (time_after(jiffies, timeout)) | | 1049 | if (time_after(jiffies, timeout)) |
1046 | WARN(1, "pipe_off wait timed out\n"); | | 1050 | WARN(1, "pipe_off wait timed out\n"); |
1047 | } | | 1051 | } |
1048 | } | | 1052 | } |
1049 | | | 1053 | |
1050 | static const char *state_string(bool enabled) | | 1054 | static const char *state_string(bool enabled) |
1051 | { | | 1055 | { |
1052 | return enabled ? "on" : "off"; | | 1056 | return enabled ? "on" : "off"; |
1053 | } | | 1057 | } |
1054 | | | 1058 | |
1055 | /* Only for pre-ILK configs */ | | 1059 | /* Only for pre-ILK configs */ |
1056 | static void assert_pll(struct drm_i915_private *dev_priv, | | 1060 | static void assert_pll(struct drm_i915_private *dev_priv, |
1057 | enum pipe pipe, bool state) | | 1061 | enum pipe pipe, bool state) |
1058 | { | | 1062 | { |
1059 | int reg; | | 1063 | int reg; |
1060 | u32 val; | | 1064 | u32 val; |
1061 | bool cur_state; | | 1065 | bool cur_state; |
1062 | | | 1066 | |
1063 | reg = DPLL(pipe); | | 1067 | reg = DPLL(pipe); |
1064 | val = I915_READ(reg); | | 1068 | val = I915_READ(reg); |
1065 | cur_state = !!(val & DPLL_VCO_ENABLE); | | 1069 | cur_state = !!(val & DPLL_VCO_ENABLE); |
1066 | WARN(cur_state != state, | | 1070 | WARN(cur_state != state, |
1067 | "PLL state assertion failure (expected %s, current %s)\n", | | 1071 | "PLL state assertion failure (expected %s, current %s)\n", |
1068 | state_string(state), state_string(cur_state)); | | 1072 | state_string(state), state_string(cur_state)); |
1069 | } | | 1073 | } |
1070 | #define assert_pll_enabled(d, p) assert_pll(d, p, true) | | 1074 | #define assert_pll_enabled(d, p) assert_pll(d, p, true) |
1071 | #define assert_pll_disabled(d, p) assert_pll(d, p, false) | | 1075 | #define assert_pll_disabled(d, p) assert_pll(d, p, false) |
1072 | | | 1076 | |
1073 | /* For ILK+ */ | | 1077 | /* For ILK+ */ |
1074 | static void assert_pch_pll(struct drm_i915_private *dev_priv, | | 1078 | static void assert_pch_pll(struct drm_i915_private *dev_priv, |
1075 | struct intel_pch_pll *pll, | | 1079 | struct intel_pch_pll *pll, |
1076 | struct intel_crtc *crtc, | | 1080 | struct intel_crtc *crtc, |
1077 | bool state) | | 1081 | bool state) |
1078 | { | | 1082 | { |
1079 | u32 val; | | 1083 | u32 val; |
1080 | bool cur_state; | | 1084 | bool cur_state; |
1081 | | | 1085 | |
1082 | if (HAS_PCH_LPT(dev_priv->dev)) { | | 1086 | if (HAS_PCH_LPT(dev_priv->dev)) { |
1083 | DRM_DEBUG_DRIVER("LPT detected: skipping PCH PLL test\n"); | | 1087 | DRM_DEBUG_DRIVER("LPT detected: skipping PCH PLL test\n"); |
1084 | return; | | 1088 | return; |
1085 | } | | 1089 | } |
1086 | | | 1090 | |
1087 | if (WARN (!pll, | | 1091 | if (WARN (!pll, |
1088 | "asserting PCH PLL %s with no PLL\n", state_string(state))) | | 1092 | "asserting PCH PLL %s with no PLL\n", state_string(state))) |
1089 | return; | | 1093 | return; |
1090 | | | 1094 | |
1091 | val = I915_READ(pll->pll_reg); | | 1095 | val = I915_READ(pll->pll_reg); |
1092 | cur_state = !!(val & DPLL_VCO_ENABLE); | | 1096 | cur_state = !!(val & DPLL_VCO_ENABLE); |
1093 | WARN(cur_state != state, | | 1097 | WARN(cur_state != state, |
1094 | "PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n", | | 1098 | "PCH PLL state for reg %x assertion failure (expected %s, current %s), val=%08x\n", |
1095 | pll->pll_reg, state_string(state), state_string(cur_state), val); | | 1099 | pll->pll_reg, state_string(state), state_string(cur_state), val); |
1096 | | | 1100 | |
1097 | /* Make sure the selected PLL is correctly attached to the transcoder */ | | 1101 | /* Make sure the selected PLL is correctly attached to the transcoder */ |
1098 | if (crtc && HAS_PCH_CPT(dev_priv->dev)) { | | 1102 | if (crtc && HAS_PCH_CPT(dev_priv->dev)) { |
1099 | u32 pch_dpll; | | 1103 | u32 pch_dpll; |
1100 | | | 1104 | |
1101 | pch_dpll = I915_READ(PCH_DPLL_SEL); | | 1105 | pch_dpll = I915_READ(PCH_DPLL_SEL); |
1102 | cur_state = pll->pll_reg == _PCH_DPLL_B; | | 1106 | cur_state = pll->pll_reg == _PCH_DPLL_B; |
1103 | if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state, | | 1107 | if (!WARN(((pch_dpll >> (4 * crtc->pipe)) & 1) != cur_state, |
1104 | "PLL[%d] not attached to this transcoder %d: %08x\n", | | 1108 | "PLL[%d] not attached to this transcoder %d: %08x\n", |
1105 | cur_state, crtc->pipe, pch_dpll)) { | | 1109 | cur_state, crtc->pipe, pch_dpll)) { |
1106 | cur_state = !!(val >> (4*crtc->pipe + 3)); | | 1110 | cur_state = !!(val >> (4*crtc->pipe + 3)); |
1107 | WARN(cur_state != state, | | 1111 | WARN(cur_state != state, |
1108 | "PLL[%d] not %s on this transcoder %d: %08x\n", | | 1112 | "PLL[%d] not %s on this transcoder %d: %08x\n", |
1109 | pll->pll_reg == _PCH_DPLL_B, | | 1113 | pll->pll_reg == _PCH_DPLL_B, |
1110 | state_string(state), | | 1114 | state_string(state), |
1111 | crtc->pipe, | | 1115 | crtc->pipe, |
1112 | val); | | 1116 | val); |
1113 | } | | 1117 | } |
1114 | } | | 1118 | } |
1115 | } | | 1119 | } |
1116 | #define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true) | | 1120 | #define assert_pch_pll_enabled(d, p, c) assert_pch_pll(d, p, c, true) |
1117 | #define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false) | | 1121 | #define assert_pch_pll_disabled(d, p, c) assert_pch_pll(d, p, c, false) |
1118 | | | 1122 | |
1119 | static void assert_fdi_tx(struct drm_i915_private *dev_priv, | | 1123 | static void assert_fdi_tx(struct drm_i915_private *dev_priv, |
1120 | enum pipe pipe, bool state) | | 1124 | enum pipe pipe, bool state) |
1121 | { | | 1125 | { |
1122 | int reg; | | 1126 | int reg; |
1123 | u32 val; | | 1127 | u32 val; |
1124 | bool cur_state; | | 1128 | bool cur_state; |
1125 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, | | 1129 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
1126 | pipe); | | 1130 | pipe); |
1127 | | | 1131 | |
1128 | if (IS_HASWELL(dev_priv->dev)) { | | 1132 | if (IS_HASWELL(dev_priv->dev)) { |
1129 | /* On Haswell, DDI is used instead of FDI_TX_CTL */ | | 1133 | /* On Haswell, DDI is used instead of FDI_TX_CTL */ |
1130 | reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); | | 1134 | reg = TRANS_DDI_FUNC_CTL(cpu_transcoder); |
1131 | val = I915_READ(reg); | | 1135 | val = I915_READ(reg); |
1132 | cur_state = !!(val & TRANS_DDI_FUNC_ENABLE); | | 1136 | cur_state = !!(val & TRANS_DDI_FUNC_ENABLE); |
1133 | } else { | | 1137 | } else { |
1134 | reg = FDI_TX_CTL(pipe); | | 1138 | reg = FDI_TX_CTL(pipe); |
1135 | val = I915_READ(reg); | | 1139 | val = I915_READ(reg); |
1136 | cur_state = !!(val & FDI_TX_ENABLE); | | 1140 | cur_state = !!(val & FDI_TX_ENABLE); |
1137 | } | | 1141 | } |
1138 | WARN(cur_state != state, | | 1142 | WARN(cur_state != state, |
1139 | "FDI TX state assertion failure (expected %s, current %s)\n", | | 1143 | "FDI TX state assertion failure (expected %s, current %s)\n", |
1140 | state_string(state), state_string(cur_state)); | | 1144 | state_string(state), state_string(cur_state)); |
1141 | } | | 1145 | } |
1142 | #define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true) | | 1146 | #define assert_fdi_tx_enabled(d, p) assert_fdi_tx(d, p, true) |
1143 | #define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false) | | 1147 | #define assert_fdi_tx_disabled(d, p) assert_fdi_tx(d, p, false) |
1144 | | | 1148 | |
1145 | static void assert_fdi_rx(struct drm_i915_private *dev_priv, | | 1149 | static void assert_fdi_rx(struct drm_i915_private *dev_priv, |
1146 | enum pipe pipe, bool state) | | 1150 | enum pipe pipe, bool state) |
1147 | { | | 1151 | { |
1148 | int reg; | | 1152 | int reg; |
1149 | u32 val; | | 1153 | u32 val; |
1150 | bool cur_state; | | 1154 | bool cur_state; |
1151 | | | 1155 | |
1152 | reg = FDI_RX_CTL(pipe); | | 1156 | reg = FDI_RX_CTL(pipe); |
1153 | val = I915_READ(reg); | | 1157 | val = I915_READ(reg); |
1154 | cur_state = !!(val & FDI_RX_ENABLE); | | 1158 | cur_state = !!(val & FDI_RX_ENABLE); |
1155 | WARN(cur_state != state, | | 1159 | WARN(cur_state != state, |
1156 | "FDI RX state assertion failure (expected %s, current %s)\n", | | 1160 | "FDI RX state assertion failure (expected %s, current %s)\n", |
1157 | state_string(state), state_string(cur_state)); | | 1161 | state_string(state), state_string(cur_state)); |
1158 | } | | 1162 | } |
1159 | #define assert_fdi_rx_enabled(d, p) assert_fdi_rx(d, p, true) | | 1163 | #define assert_fdi_rx_enabled(d, p) assert_fdi_rx(d, p, true) |
1160 | #define assert_fdi_rx_disabled(d, p) assert_fdi_rx(d, p, false) | | 1164 | #define assert_fdi_rx_disabled(d, p) assert_fdi_rx(d, p, false) |
1161 | | | 1165 | |
1162 | static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, | | 1166 | static void assert_fdi_tx_pll_enabled(struct drm_i915_private *dev_priv, |
1163 | enum pipe pipe) | | 1167 | enum pipe pipe) |
1164 | { | | 1168 | { |
1165 | int reg; | | 1169 | int reg; |
1166 | u32 val; | | 1170 | u32 val; |
1167 | | | 1171 | |
1168 | /* ILK FDI PLL is always enabled */ | | 1172 | /* ILK FDI PLL is always enabled */ |
1169 | if (dev_priv->info->gen == 5) | | 1173 | if (dev_priv->info->gen == 5) |
1170 | return; | | 1174 | return; |
1171 | | | 1175 | |
1172 | /* On Haswell, DDI ports are responsible for the FDI PLL setup */ | | 1176 | /* On Haswell, DDI ports are responsible for the FDI PLL setup */ |
1173 | if (IS_HASWELL(dev_priv->dev)) | | 1177 | if (IS_HASWELL(dev_priv->dev)) |
1174 | return; | | 1178 | return; |
1175 | | | 1179 | |
1176 | reg = FDI_TX_CTL(pipe); | | 1180 | reg = FDI_TX_CTL(pipe); |
1177 | val = I915_READ(reg); | | 1181 | val = I915_READ(reg); |
1178 | WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n"); | | 1182 | WARN(!(val & FDI_TX_PLL_ENABLE), "FDI TX PLL assertion failure, should be active but is disabled\n"); |
1179 | } | | 1183 | } |
1180 | | | 1184 | |
1181 | static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv, | | 1185 | static void assert_fdi_rx_pll_enabled(struct drm_i915_private *dev_priv, |
1182 | enum pipe pipe) | | 1186 | enum pipe pipe) |
1183 | { | | 1187 | { |
1184 | int reg; | | 1188 | int reg; |
1185 | u32 val; | | 1189 | u32 val; |
1186 | | | 1190 | |
1187 | reg = FDI_RX_CTL(pipe); | | 1191 | reg = FDI_RX_CTL(pipe); |
1188 | val = I915_READ(reg); | | 1192 | val = I915_READ(reg); |
1189 | WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n"); | | 1193 | WARN(!(val & FDI_RX_PLL_ENABLE), "FDI RX PLL assertion failure, should be active but is disabled\n"); |
1190 | } | | 1194 | } |
1191 | | | 1195 | |
1192 | static void assert_panel_unlocked(struct drm_i915_private *dev_priv, | | 1196 | static void assert_panel_unlocked(struct drm_i915_private *dev_priv, |
1193 | enum pipe pipe) | | 1197 | enum pipe pipe) |
1194 | { | | 1198 | { |
1195 | int pp_reg, lvds_reg; | | 1199 | int pp_reg, lvds_reg; |
1196 | u32 val; | | 1200 | u32 val; |
1197 | enum pipe panel_pipe = PIPE_A; | | 1201 | enum pipe panel_pipe = PIPE_A; |
1198 | bool locked = true; | | 1202 | bool locked = true; |
1199 | | | 1203 | |
1200 | if (HAS_PCH_SPLIT(dev_priv->dev)) { | | 1204 | if (HAS_PCH_SPLIT(dev_priv->dev)) { |
1201 | pp_reg = PCH_PP_CONTROL; | | 1205 | pp_reg = PCH_PP_CONTROL; |
1202 | lvds_reg = PCH_LVDS; | | 1206 | lvds_reg = PCH_LVDS; |
1203 | } else { | | 1207 | } else { |
1204 | pp_reg = PP_CONTROL; | | 1208 | pp_reg = PP_CONTROL; |
1205 | lvds_reg = LVDS; | | 1209 | lvds_reg = LVDS; |
1206 | } | | 1210 | } |
1207 | | | 1211 | |
1208 | val = I915_READ(pp_reg); | | 1212 | val = I915_READ(pp_reg); |
1209 | if (!(val & PANEL_POWER_ON) || | | 1213 | if (!(val & PANEL_POWER_ON) || |
1210 | ((val & PANEL_UNLOCK_REGS) == PANEL_UNLOCK_REGS)) | | 1214 | ((val & PANEL_UNLOCK_REGS) == PANEL_UNLOCK_REGS)) |
1211 | locked = false; | | 1215 | locked = false; |
1212 | | | 1216 | |
1213 | if (I915_READ(lvds_reg) & LVDS_PIPEB_SELECT) | | 1217 | if (I915_READ(lvds_reg) & LVDS_PIPEB_SELECT) |
1214 | panel_pipe = PIPE_B; | | 1218 | panel_pipe = PIPE_B; |
1215 | | | 1219 | |
1216 | WARN(panel_pipe == pipe && locked, | | 1220 | WARN(panel_pipe == pipe && locked, |
1217 | "panel assertion failure, pipe %c regs locked\n", | | 1221 | "panel assertion failure, pipe %c regs locked\n", |
1218 | pipe_name(pipe)); | | 1222 | pipe_name(pipe)); |
1219 | } | | 1223 | } |
1220 | | | 1224 | |
1221 | void assert_pipe(struct drm_i915_private *dev_priv, | | 1225 | void assert_pipe(struct drm_i915_private *dev_priv, |
1222 | enum pipe pipe, bool state) | | 1226 | enum pipe pipe, bool state) |
1223 | { | | 1227 | { |
1224 | int reg; | | 1228 | int reg; |
1225 | u32 val; | | 1229 | u32 val; |
1226 | bool cur_state; | | 1230 | bool cur_state; |
1227 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, | | 1231 | enum transcoder cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, |
1228 | pipe); | | 1232 | pipe); |
1229 | | | 1233 | |
1230 | /* if we need the pipe A quirk it must be always on */ | | 1234 | /* if we need the pipe A quirk it must be always on */ |
1231 | if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) | | 1235 | if (pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) |
1232 | state = true; | | 1236 | state = true; |
1233 | | | 1237 | |
1234 | reg = PIPECONF(cpu_transcoder); | | 1238 | reg = PIPECONF(cpu_transcoder); |
1235 | val = I915_READ(reg); | | 1239 | val = I915_READ(reg); |
1236 | cur_state = !!(val & PIPECONF_ENABLE); | | 1240 | cur_state = !!(val & PIPECONF_ENABLE); |
1237 | WARN(cur_state != state, | | 1241 | WARN(cur_state != state, |
1238 | "pipe %c assertion failure (expected %s, current %s)\n", | | 1242 | "pipe %c assertion failure (expected %s, current %s)\n", |
1239 | pipe_name(pipe), state_string(state), state_string(cur_state)); | | 1243 | pipe_name(pipe), state_string(state), state_string(cur_state)); |
1240 | } | | 1244 | } |
1241 | | | 1245 | |
1242 | static void assert_plane(struct drm_i915_private *dev_priv, | | 1246 | static void assert_plane(struct drm_i915_private *dev_priv, |
1243 | enum plane plane, bool state) | | 1247 | enum plane plane, bool state) |
1244 | { | | 1248 | { |
1245 | int reg; | | 1249 | int reg; |
1246 | u32 val; | | 1250 | u32 val; |
1247 | bool cur_state; | | 1251 | bool cur_state; |
1248 | | | 1252 | |
1249 | reg = DSPCNTR(plane); | | 1253 | reg = DSPCNTR(plane); |
1250 | val = I915_READ(reg); | | 1254 | val = I915_READ(reg); |
1251 | cur_state = !!(val & DISPLAY_PLANE_ENABLE); | | 1255 | cur_state = !!(val & DISPLAY_PLANE_ENABLE); |
1252 | WARN(cur_state != state, | | 1256 | WARN(cur_state != state, |
1253 | "plane %c assertion failure (expected %s, current %s)\n", | | 1257 | "plane %c assertion failure (expected %s, current %s)\n", |
1254 | plane_name(plane), state_string(state), state_string(cur_state)); | | 1258 | plane_name(plane), state_string(state), state_string(cur_state)); |
1255 | } | | 1259 | } |
1256 | | | 1260 | |
1257 | #define assert_plane_enabled(d, p) assert_plane(d, p, true) | | 1261 | #define assert_plane_enabled(d, p) assert_plane(d, p, true) |
1258 | #define assert_plane_disabled(d, p) assert_plane(d, p, false) | | 1262 | #define assert_plane_disabled(d, p) assert_plane(d, p, false) |
1259 | | | 1263 | |
1260 | static void assert_planes_disabled(struct drm_i915_private *dev_priv, | | 1264 | static void assert_planes_disabled(struct drm_i915_private *dev_priv, |
1261 | enum pipe pipe) | | 1265 | enum pipe pipe) |
1262 | { | | 1266 | { |
1263 | int reg, i; | | 1267 | int reg, i; |
1264 | u32 val; | | 1268 | u32 val; |
1265 | int cur_pipe; | | 1269 | int cur_pipe; |
1266 | | | 1270 | |
1267 | /* Planes are fixed to pipes on ILK+ */ | | 1271 | /* Planes are fixed to pipes on ILK+ */ |
1268 | if (HAS_PCH_SPLIT(dev_priv->dev)) { | | 1272 | if (HAS_PCH_SPLIT(dev_priv->dev)) { |
1269 | reg = DSPCNTR(pipe); | | 1273 | reg = DSPCNTR(pipe); |
1270 | val = I915_READ(reg); | | 1274 | val = I915_READ(reg); |
1271 | WARN((val & DISPLAY_PLANE_ENABLE), | | 1275 | WARN((val & DISPLAY_PLANE_ENABLE), |
1272 | "plane %c assertion failure, should be disabled but not\n", | | 1276 | "plane %c assertion failure, should be disabled but not\n", |
1273 | plane_name(pipe)); | | 1277 | plane_name(pipe)); |
1274 | return; | | 1278 | return; |
1275 | } | | 1279 | } |
1276 | | | 1280 | |
1277 | /* Need to check both planes against the pipe */ | | 1281 | /* Need to check both planes against the pipe */ |
1278 | for (i = 0; i < 2; i++) { | | 1282 | for (i = 0; i < 2; i++) { |
1279 | reg = DSPCNTR(i); | | 1283 | reg = DSPCNTR(i); |
1280 | val = I915_READ(reg); | | 1284 | val = I915_READ(reg); |
1281 | cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> | | 1285 | cur_pipe = (val & DISPPLANE_SEL_PIPE_MASK) >> |
1282 | DISPPLANE_SEL_PIPE_SHIFT; | | 1286 | DISPPLANE_SEL_PIPE_SHIFT; |
1283 | WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe, | | 1287 | WARN((val & DISPLAY_PLANE_ENABLE) && pipe == cur_pipe, |
1284 | "plane %c assertion failure, should be off on pipe %c but is still active\n", | | 1288 | "plane %c assertion failure, should be off on pipe %c but is still active\n", |
1285 | plane_name(i), pipe_name(pipe)); | | 1289 | plane_name(i), pipe_name(pipe)); |
1286 | } | | 1290 | } |
1287 | } | | 1291 | } |
1288 | | | 1292 | |
1289 | static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) | | 1293 | static void assert_pch_refclk_enabled(struct drm_i915_private *dev_priv) |
1290 | { | | 1294 | { |
1291 | u32 val; | | 1295 | u32 val; |
1292 | bool enabled; | | 1296 | bool enabled; |
1293 | | | 1297 | |
1294 | if (HAS_PCH_LPT(dev_priv->dev)) { | | 1298 | if (HAS_PCH_LPT(dev_priv->dev)) { |
1295 | DRM_DEBUG_DRIVER("LPT does not has PCH refclk, skipping check\n"); | | 1299 | DRM_DEBUG_DRIVER("LPT does not has PCH refclk, skipping check\n"); |
1296 | return; | | 1300 | return; |
1297 | } | | 1301 | } |
1298 | | | 1302 | |
1299 | val = I915_READ(PCH_DREF_CONTROL); | | 1303 | val = I915_READ(PCH_DREF_CONTROL); |
1300 | enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | | | 1304 | enabled = !!(val & (DREF_SSC_SOURCE_MASK | DREF_NONSPREAD_SOURCE_MASK | |
1301 | DREF_SUPERSPREAD_SOURCE_MASK)); | | 1305 | DREF_SUPERSPREAD_SOURCE_MASK)); |
1302 | WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); | | 1306 | WARN(!enabled, "PCH refclk assertion failure, should be active but is disabled\n"); |
1303 | } | | 1307 | } |
1304 | | | 1308 | |
1305 | static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, | | 1309 | static void assert_transcoder_disabled(struct drm_i915_private *dev_priv, |
1306 | enum pipe pipe) | | 1310 | enum pipe pipe) |
1307 | { | | 1311 | { |
1308 | int reg; | | 1312 | int reg; |
1309 | u32 val; | | 1313 | u32 val; |
1310 | bool enabled; | | 1314 | bool enabled; |
1311 | | | 1315 | |
1312 | reg = TRANSCONF(pipe); | | 1316 | reg = TRANSCONF(pipe); |
1313 | val = I915_READ(reg); | | 1317 | val = I915_READ(reg); |
1314 | enabled = !!(val & TRANS_ENABLE); | | 1318 | enabled = !!(val & TRANS_ENABLE); |
1315 | WARN(enabled, | | 1319 | WARN(enabled, |
1316 | "transcoder assertion failed, should be off on pipe %c but is still active\n", | | 1320 | "transcoder assertion failed, should be off on pipe %c but is still active\n", |
1317 | pipe_name(pipe)); | | 1321 | pipe_name(pipe)); |
1318 | } | | 1322 | } |
1319 | | | 1323 | |
1320 | static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, | | 1324 | static bool dp_pipe_enabled(struct drm_i915_private *dev_priv, |
1321 | enum pipe pipe, u32 port_sel, u32 val) | | 1325 | enum pipe pipe, u32 port_sel, u32 val) |
1322 | { | | 1326 | { |
1323 | if ((val & DP_PORT_EN) == 0) | | 1327 | if ((val & DP_PORT_EN) == 0) |
1324 | return false; | | 1328 | return false; |
1325 | | | 1329 | |
1326 | if (HAS_PCH_CPT(dev_priv->dev)) { | | 1330 | if (HAS_PCH_CPT(dev_priv->dev)) { |
1327 | u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe); | | 1331 | u32 trans_dp_ctl_reg = TRANS_DP_CTL(pipe); |
1328 | u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg); | | 1332 | u32 trans_dp_ctl = I915_READ(trans_dp_ctl_reg); |
1329 | if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel) | | 1333 | if ((trans_dp_ctl & TRANS_DP_PORT_SEL_MASK) != port_sel) |
1330 | return false; | | 1334 | return false; |
1331 | } else { | | 1335 | } else { |
1332 | if ((val & DP_PIPE_MASK) != (pipe << 30)) | | 1336 | if ((val & DP_PIPE_MASK) != (pipe << 30)) |
1333 | return false; | | 1337 | return false; |
1334 | } | | 1338 | } |
1335 | return true; | | 1339 | return true; |
1336 | } | | 1340 | } |
1337 | | | 1341 | |
1338 | static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv, | | 1342 | static bool hdmi_pipe_enabled(struct drm_i915_private *dev_priv, |
1339 | enum pipe pipe, u32 val) | | 1343 | enum pipe pipe, u32 val) |
1340 | { | | 1344 | { |
1341 | if ((val & PORT_ENABLE) == 0) | | 1345 | if ((val & PORT_ENABLE) == 0) |
1342 | return false; | | 1346 | return false; |
1343 | | | 1347 | |
1344 | if (HAS_PCH_CPT(dev_priv->dev)) { | | 1348 | if (HAS_PCH_CPT(dev_priv->dev)) { |
1345 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) | | 1349 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) |
1346 | return false; | | 1350 | return false; |
1347 | } else { | | 1351 | } else { |
1348 | if ((val & TRANSCODER_MASK) != TRANSCODER(pipe)) | | 1352 | if ((val & TRANSCODER_MASK) != TRANSCODER(pipe)) |
1349 | return false; | | 1353 | return false; |
1350 | } | | 1354 | } |
1351 | return true; | | 1355 | return true; |
1352 | } | | 1356 | } |
1353 | | | 1357 | |
1354 | static bool lvds_pipe_enabled(struct drm_i915_private *dev_priv, | | 1358 | static bool lvds_pipe_enabled(struct drm_i915_private *dev_priv, |
1355 | enum pipe pipe, u32 val) | | 1359 | enum pipe pipe, u32 val) |
1356 | { | | 1360 | { |
1357 | if ((val & LVDS_PORT_EN) == 0) | | 1361 | if ((val & LVDS_PORT_EN) == 0) |
1358 | return false; | | 1362 | return false; |
1359 | | | 1363 | |
1360 | if (HAS_PCH_CPT(dev_priv->dev)) { | | 1364 | if (HAS_PCH_CPT(dev_priv->dev)) { |
1361 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) | | 1365 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) |
1362 | return false; | | 1366 | return false; |
1363 | } else { | | 1367 | } else { |
1364 | if ((val & LVDS_PIPE_MASK) != LVDS_PIPE(pipe)) | | 1368 | if ((val & LVDS_PIPE_MASK) != LVDS_PIPE(pipe)) |
1365 | return false; | | 1369 | return false; |
1366 | } | | 1370 | } |
1367 | return true; | | 1371 | return true; |
1368 | } | | 1372 | } |
1369 | | | 1373 | |
1370 | static bool adpa_pipe_enabled(struct drm_i915_private *dev_priv, | | 1374 | static bool adpa_pipe_enabled(struct drm_i915_private *dev_priv, |
1371 | enum pipe pipe, u32 val) | | 1375 | enum pipe pipe, u32 val) |
1372 | { | | 1376 | { |
1373 | if ((val & ADPA_DAC_ENABLE) == 0) | | 1377 | if ((val & ADPA_DAC_ENABLE) == 0) |
1374 | return false; | | 1378 | return false; |
1375 | if (HAS_PCH_CPT(dev_priv->dev)) { | | 1379 | if (HAS_PCH_CPT(dev_priv->dev)) { |
1376 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) | | 1380 | if ((val & PORT_TRANS_SEL_MASK) != PORT_TRANS_SEL_CPT(pipe)) |
1377 | return false; | | 1381 | return false; |
1378 | } else { | | 1382 | } else { |
1379 | if ((val & ADPA_PIPE_SELECT_MASK) != ADPA_PIPE_SELECT(pipe)) | | 1383 | if ((val & ADPA_PIPE_SELECT_MASK) != ADPA_PIPE_SELECT(pipe)) |
1380 | return false; | | 1384 | return false; |
1381 | } | | 1385 | } |
1382 | return true; | | 1386 | return true; |
1383 | } | | 1387 | } |
1384 | | | 1388 | |
1385 | static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, | | 1389 | static void assert_pch_dp_disabled(struct drm_i915_private *dev_priv, |
1386 | enum pipe pipe, int reg, u32 port_sel) | | 1390 | enum pipe pipe, int reg, u32 port_sel) |
1387 | { | | 1391 | { |
1388 | u32 val = I915_READ(reg); | | 1392 | u32 val = I915_READ(reg); |
1389 | WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), | | 1393 | WARN(dp_pipe_enabled(dev_priv, pipe, port_sel, val), |
1390 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", | | 1394 | "PCH DP (0x%08x) enabled on transcoder %c, should be disabled\n", |
1391 | reg, pipe_name(pipe)); | | 1395 | reg, pipe_name(pipe)); |
1392 | | | 1396 | |
1393 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 | | 1397 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & DP_PORT_EN) == 0 |
1394 | && (val & DP_PIPEB_SELECT), | | 1398 | && (val & DP_PIPEB_SELECT), |
1395 | "IBX PCH dp port still using transcoder B\n"); | | 1399 | "IBX PCH dp port still using transcoder B\n"); |
1396 | } | | 1400 | } |
1397 | | | 1401 | |
1398 | static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, | | 1402 | static void assert_pch_hdmi_disabled(struct drm_i915_private *dev_priv, |
1399 | enum pipe pipe, int reg) | | 1403 | enum pipe pipe, int reg) |
1400 | { | | 1404 | { |
1401 | u32 val = I915_READ(reg); | | 1405 | u32 val = I915_READ(reg); |
1402 | WARN(hdmi_pipe_enabled(dev_priv, pipe, val), | | 1406 | WARN(hdmi_pipe_enabled(dev_priv, pipe, val), |
1403 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", | | 1407 | "PCH HDMI (0x%08x) enabled on transcoder %c, should be disabled\n", |
1404 | reg, pipe_name(pipe)); | | 1408 | reg, pipe_name(pipe)); |
1405 | | | 1409 | |
1406 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 | | 1410 | WARN(HAS_PCH_IBX(dev_priv->dev) && (val & PORT_ENABLE) == 0 |
1407 | && (val & SDVO_PIPE_B_SELECT), | | 1411 | && (val & SDVO_PIPE_B_SELECT), |
1408 | "IBX PCH hdmi port still using transcoder B\n"); | | 1412 | "IBX PCH hdmi port still using transcoder B\n"); |
1409 | } | | 1413 | } |
1410 | | | 1414 | |
1411 | static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, | | 1415 | static void assert_pch_ports_disabled(struct drm_i915_private *dev_priv, |
1412 | enum pipe pipe) | | 1416 | enum pipe pipe) |
1413 | { | | 1417 | { |
1414 | int reg; | | 1418 | int reg; |
1415 | u32 val; | | 1419 | u32 val; |
1416 | | | 1420 | |
1417 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); | | 1421 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_B, TRANS_DP_PORT_SEL_B); |
1418 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); | | 1422 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_C, TRANS_DP_PORT_SEL_C); |
1419 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); | | 1423 | assert_pch_dp_disabled(dev_priv, pipe, PCH_DP_D, TRANS_DP_PORT_SEL_D); |
1420 | | | 1424 | |
1421 | reg = PCH_ADPA; | | 1425 | reg = PCH_ADPA; |
1422 | val = I915_READ(reg); | | 1426 | val = I915_READ(reg); |
1423 | WARN(adpa_pipe_enabled(dev_priv, pipe, val), | | 1427 | WARN(adpa_pipe_enabled(dev_priv, pipe, val), |
1424 | "PCH VGA enabled on transcoder %c, should be disabled\n", | | 1428 | "PCH VGA enabled on transcoder %c, should be disabled\n", |
1425 | pipe_name(pipe)); | | 1429 | pipe_name(pipe)); |
1426 | | | 1430 | |
1427 | reg = PCH_LVDS; | | 1431 | reg = PCH_LVDS; |
1428 | val = I915_READ(reg); | | 1432 | val = I915_READ(reg); |
1429 | WARN(lvds_pipe_enabled(dev_priv, pipe, val), | | 1433 | WARN(lvds_pipe_enabled(dev_priv, pipe, val), |
1430 | "PCH LVDS enabled on transcoder %c, should be disabled\n", | | 1434 | "PCH LVDS enabled on transcoder %c, should be disabled\n", |
1431 | pipe_name(pipe)); | | 1435 | pipe_name(pipe)); |
1432 | | | 1436 | |
1433 | assert_pch_hdmi_disabled(dev_priv, pipe, HDMIB); | | 1437 | assert_pch_hdmi_disabled(dev_priv, pipe, HDMIB); |
1434 | assert_pch_hdmi_disabled(dev_priv, pipe, HDMIC); | | 1438 | assert_pch_hdmi_disabled(dev_priv, pipe, HDMIC); |
1435 | assert_pch_hdmi_disabled(dev_priv, pipe, HDMID); | | 1439 | assert_pch_hdmi_disabled(dev_priv, pipe, HDMID); |
1436 | } | | 1440 | } |
1437 | | | 1441 | |
1438 | /** | | 1442 | /** |
1439 | * intel_enable_pll - enable a PLL | | 1443 | * intel_enable_pll - enable a PLL |
1440 | * @dev_priv: i915 private structure | | 1444 | * @dev_priv: i915 private structure |
1441 | * @pipe: pipe PLL to enable | | 1445 | * @pipe: pipe PLL to enable |
1442 | * | | 1446 | * |
1443 | * Enable @pipe's PLL so we can start pumping pixels from a plane. Check to | | 1447 | * Enable @pipe's PLL so we can start pumping pixels from a plane. Check to |
1444 | * make sure the PLL reg is writable first though, since the panel write | | 1448 | * make sure the PLL reg is writable first though, since the panel write |
1445 | * protect mechanism may be enabled. | | 1449 | * protect mechanism may be enabled. |
1446 | * | | 1450 | * |
1447 | * Note! This is for pre-ILK only. | | 1451 | * Note! This is for pre-ILK only. |
1448 | * | | 1452 | * |
1449 | * Unfortunately needed by dvo_ns2501 since the dvo depends on it running. | | 1453 | * Unfortunately needed by dvo_ns2501 since the dvo depends on it running. |
1450 | */ | | 1454 | */ |
1451 | static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) | | 1455 | static void intel_enable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) |
1452 | { | | 1456 | { |
1453 | int reg; | | 1457 | int reg; |
1454 | u32 val; | | 1458 | u32 val; |
1455 | | | 1459 | |
1456 | /* No really, not for ILK+ */ | | 1460 | /* No really, not for ILK+ */ |
1457 | BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5); | | 1461 | BUG_ON(!IS_VALLEYVIEW(dev_priv->dev) && dev_priv->info->gen >= 5); |
1458 | | | 1462 | |
1459 | /* PLL is protected by panel, make sure we can write it */ | | 1463 | /* PLL is protected by panel, make sure we can write it */ |
1460 | if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) | | 1464 | if (IS_MOBILE(dev_priv->dev) && !IS_I830(dev_priv->dev)) |
1461 | assert_panel_unlocked(dev_priv, pipe); | | 1465 | assert_panel_unlocked(dev_priv, pipe); |
1462 | | | 1466 | |
1463 | reg = DPLL(pipe); | | 1467 | reg = DPLL(pipe); |
1464 | val = I915_READ(reg); | | 1468 | val = I915_READ(reg); |
1465 | val |= DPLL_VCO_ENABLE; | | 1469 | val |= DPLL_VCO_ENABLE; |
1466 | | | 1470 | |
1467 | /* We do this three times for luck */ | | 1471 | /* We do this three times for luck */ |
1468 | I915_WRITE(reg, val); | | 1472 | I915_WRITE(reg, val); |
1469 | POSTING_READ(reg); | | 1473 | POSTING_READ(reg); |
1470 | udelay(150); /* wait for warmup */ | | 1474 | udelay(150); /* wait for warmup */ |
1471 | I915_WRITE(reg, val); | | 1475 | I915_WRITE(reg, val); |
1472 | POSTING_READ(reg); | | 1476 | POSTING_READ(reg); |
1473 | udelay(150); /* wait for warmup */ | | 1477 | udelay(150); /* wait for warmup */ |
1474 | I915_WRITE(reg, val); | | 1478 | I915_WRITE(reg, val); |
1475 | POSTING_READ(reg); | | 1479 | POSTING_READ(reg); |
1476 | udelay(150); /* wait for warmup */ | | 1480 | udelay(150); /* wait for warmup */ |
1477 | } | | 1481 | } |
1478 | | | 1482 | |
1479 | /** | | 1483 | /** |
1480 | * intel_disable_pll - disable a PLL | | 1484 | * intel_disable_pll - disable a PLL |
1481 | * @dev_priv: i915 private structure | | 1485 | * @dev_priv: i915 private structure |
1482 | * @pipe: pipe PLL to disable | | 1486 | * @pipe: pipe PLL to disable |
1483 | * | | 1487 | * |
1484 | * Disable the PLL for @pipe, making sure the pipe is off first. | | 1488 | * Disable the PLL for @pipe, making sure the pipe is off first. |
1485 | * | | 1489 | * |
1486 | * Note! This is for pre-ILK only. | | 1490 | * Note! This is for pre-ILK only. |
1487 | */ | | 1491 | */ |
1488 | static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) | | 1492 | static void intel_disable_pll(struct drm_i915_private *dev_priv, enum pipe pipe) |
1489 | { | | 1493 | { |
1490 | int reg; | | 1494 | int reg; |
1491 | u32 val; | | 1495 | u32 val; |
1492 | | | 1496 | |
1493 | /* Don't disable pipe A or pipe A PLLs if needed */ | | 1497 | /* Don't disable pipe A or pipe A PLLs if needed */ |
1494 | if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) | | 1498 | if (pipe == PIPE_A && (dev_priv->quirks & QUIRK_PIPEA_FORCE)) |
1495 | return; | | 1499 | return; |
1496 | | | 1500 | |
1497 | /* Make sure the pipe isn't still relying on us */ | | 1501 | /* Make sure the pipe isn't still relying on us */ |
1498 | assert_pipe_disabled(dev_priv, pipe); | | 1502 | assert_pipe_disabled(dev_priv, pipe); |
1499 | | | 1503 | |
1500 | reg = DPLL(pipe); | | 1504 | reg = DPLL(pipe); |
1501 | val = I915_READ(reg); | | 1505 | val = I915_READ(reg); |
1502 | val &= ~DPLL_VCO_ENABLE; | | 1506 | val &= ~DPLL_VCO_ENABLE; |
| @@ -7801,1718 +7805,1722 @@ intel_modeset_update_state(struct drm_de | | | @@ -7801,1718 +7805,1722 @@ intel_modeset_update_state(struct drm_de |
7801 | } | | 7805 | } |
7802 | | | 7806 | |
7803 | #define for_each_intel_crtc_masked(dev, mask, intel_crtc) \ | | 7807 | #define for_each_intel_crtc_masked(dev, mask, intel_crtc) \ |
7804 | list_for_each_entry((intel_crtc), \ | | 7808 | list_for_each_entry((intel_crtc), \ |
7805 | &(dev)->mode_config.crtc_list, \ | | 7809 | &(dev)->mode_config.crtc_list, \ |
7806 | base.head) \ | | 7810 | base.head) \ |
7807 | if (mask & (1 <<(intel_crtc)->pipe)) \ | | 7811 | if (mask & (1 <<(intel_crtc)->pipe)) \ |
7808 | | | 7812 | |
7809 | void | | 7813 | void |
7810 | intel_modeset_check_state(struct drm_device *dev) | | 7814 | intel_modeset_check_state(struct drm_device *dev) |
7811 | { | | 7815 | { |
7812 | struct intel_crtc *crtc; | | 7816 | struct intel_crtc *crtc; |
7813 | struct intel_encoder *encoder; | | 7817 | struct intel_encoder *encoder; |
7814 | struct intel_connector *connector; | | 7818 | struct intel_connector *connector; |
7815 | | | 7819 | |
7816 | list_for_each_entry(connector, &dev->mode_config.connector_list, | | 7820 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
7817 | base.head) { | | 7821 | base.head) { |
7818 | /* This also checks the encoder/connector hw state with the | | 7822 | /* This also checks the encoder/connector hw state with the |
7819 | * ->get_hw_state callbacks. */ | | 7823 | * ->get_hw_state callbacks. */ |
7820 | intel_connector_check_state(connector); | | 7824 | intel_connector_check_state(connector); |
7821 | | | 7825 | |
7822 | WARN(&connector->new_encoder->base != connector->base.encoder, | | 7826 | WARN(&connector->new_encoder->base != connector->base.encoder, |
7823 | "connector's staged encoder doesn't match current encoder\n"); | | 7827 | "connector's staged encoder doesn't match current encoder\n"); |
7824 | } | | 7828 | } |
7825 | | | 7829 | |
7826 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | | 7830 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
7827 | base.head) { | | 7831 | base.head) { |
7828 | bool enabled = false; | | 7832 | bool enabled = false; |
7829 | bool active = false; | | 7833 | bool active = false; |
7830 | enum pipe pipe, tracked_pipe; | | 7834 | enum pipe pipe, tracked_pipe; |
7831 | | | 7835 | |
7832 | DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", | | 7836 | DRM_DEBUG_KMS("[ENCODER:%d:%s]\n", |
7833 | encoder->base.base.id, | | 7837 | encoder->base.base.id, |
7834 | drm_get_encoder_name(&encoder->base)); | | 7838 | drm_get_encoder_name(&encoder->base)); |
7835 | | | 7839 | |
7836 | WARN(&encoder->new_crtc->base != encoder->base.crtc, | | 7840 | WARN(&encoder->new_crtc->base != encoder->base.crtc, |
7837 | "encoder's stage crtc doesn't match current crtc\n"); | | 7841 | "encoder's stage crtc doesn't match current crtc\n"); |
7838 | WARN(encoder->connectors_active && !encoder->base.crtc, | | 7842 | WARN(encoder->connectors_active && !encoder->base.crtc, |
7839 | "encoder's active_connectors set, but no crtc\n"); | | 7843 | "encoder's active_connectors set, but no crtc\n"); |
7840 | | | 7844 | |
7841 | list_for_each_entry(connector, &dev->mode_config.connector_list, | | 7845 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
7842 | base.head) { | | 7846 | base.head) { |
7843 | if (connector->base.encoder != &encoder->base) | | 7847 | if (connector->base.encoder != &encoder->base) |
7844 | continue; | | 7848 | continue; |
7845 | enabled = true; | | 7849 | enabled = true; |
7846 | if (connector->base.dpms != DRM_MODE_DPMS_OFF) | | 7850 | if (connector->base.dpms != DRM_MODE_DPMS_OFF) |
7847 | active = true; | | 7851 | active = true; |
7848 | } | | 7852 | } |
7849 | WARN(!!encoder->base.crtc != enabled, | | 7853 | WARN(!!encoder->base.crtc != enabled, |
7850 | "encoder's enabled state mismatch " | | 7854 | "encoder's enabled state mismatch " |
7851 | "(expected %i, found %i)\n", | | 7855 | "(expected %i, found %i)\n", |
7852 | !!encoder->base.crtc, enabled); | | 7856 | !!encoder->base.crtc, enabled); |
7853 | WARN(active && !encoder->base.crtc, | | 7857 | WARN(active && !encoder->base.crtc, |
7854 | "active encoder with no crtc\n"); | | 7858 | "active encoder with no crtc\n"); |
7855 | | | 7859 | |
7856 | WARN(encoder->connectors_active != active, | | 7860 | WARN(encoder->connectors_active != active, |
7857 | "encoder's computed active state doesn't match tracked active state " | | 7861 | "encoder's computed active state doesn't match tracked active state " |
7858 | "(expected %i, found %i)\n", active, encoder->connectors_active); | | 7862 | "(expected %i, found %i)\n", active, encoder->connectors_active); |
7859 | | | 7863 | |
7860 | active = encoder->get_hw_state(encoder, &pipe); | | 7864 | active = encoder->get_hw_state(encoder, &pipe); |
7861 | WARN(active != encoder->connectors_active, | | 7865 | WARN(active != encoder->connectors_active, |
7862 | "encoder's hw state doesn't match sw tracking " | | 7866 | "encoder's hw state doesn't match sw tracking " |
7863 | "(expected %i, found %i)\n", | | 7867 | "(expected %i, found %i)\n", |
7864 | encoder->connectors_active, active); | | 7868 | encoder->connectors_active, active); |
7865 | | | 7869 | |
7866 | if (!encoder->base.crtc) | | 7870 | if (!encoder->base.crtc) |
7867 | continue; | | 7871 | continue; |
7868 | | | 7872 | |
7869 | tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe; | | 7873 | tracked_pipe = to_intel_crtc(encoder->base.crtc)->pipe; |
7870 | WARN(active && pipe != tracked_pipe, | | 7874 | WARN(active && pipe != tracked_pipe, |
7871 | "active encoder's pipe doesn't match" | | 7875 | "active encoder's pipe doesn't match" |
7872 | "(expected %i, found %i)\n", | | 7876 | "(expected %i, found %i)\n", |
7873 | tracked_pipe, pipe); | | 7877 | tracked_pipe, pipe); |
7874 | | | 7878 | |
7875 | } | | 7879 | } |
7876 | | | 7880 | |
7877 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, | | 7881 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, |
7878 | base.head) { | | 7882 | base.head) { |
7879 | bool enabled = false; | | 7883 | bool enabled = false; |
7880 | bool active = false; | | 7884 | bool active = false; |
7881 | | | 7885 | |
7882 | DRM_DEBUG_KMS("[CRTC:%d]\n", | | 7886 | DRM_DEBUG_KMS("[CRTC:%d]\n", |
7883 | crtc->base.base.id); | | 7887 | crtc->base.base.id); |
7884 | | | 7888 | |
7885 | WARN(crtc->active && !crtc->base.enabled, | | 7889 | WARN(crtc->active && !crtc->base.enabled, |
7886 | "active crtc, but not enabled in sw tracking\n"); | | 7890 | "active crtc, but not enabled in sw tracking\n"); |
7887 | | | 7891 | |
7888 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | | 7892 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
7889 | base.head) { | | 7893 | base.head) { |
7890 | if (encoder->base.crtc != &crtc->base) | | 7894 | if (encoder->base.crtc != &crtc->base) |
7891 | continue; | | 7895 | continue; |
7892 | enabled = true; | | 7896 | enabled = true; |
7893 | if (encoder->connectors_active) | | 7897 | if (encoder->connectors_active) |
7894 | active = true; | | 7898 | active = true; |
7895 | } | | 7899 | } |
7896 | WARN(active != crtc->active, | | 7900 | WARN(active != crtc->active, |
7897 | "crtc's computed active state doesn't match tracked active state " | | 7901 | "crtc's computed active state doesn't match tracked active state " |
7898 | "(expected %i, found %i)\n", active, crtc->active); | | 7902 | "(expected %i, found %i)\n", active, crtc->active); |
7899 | WARN(enabled != crtc->base.enabled, | | 7903 | WARN(enabled != crtc->base.enabled, |
7900 | "crtc's computed enabled state doesn't match tracked enabled state " | | 7904 | "crtc's computed enabled state doesn't match tracked enabled state " |
7901 | "(expected %i, found %i)\n", enabled, crtc->base.enabled); | | 7905 | "(expected %i, found %i)\n", enabled, crtc->base.enabled); |
7902 | | | 7906 | |
7903 | assert_pipe(dev->dev_private, crtc->pipe, crtc->active); | | 7907 | assert_pipe(dev->dev_private, crtc->pipe, crtc->active); |
7904 | } | | 7908 | } |
7905 | } | | 7909 | } |
7906 | | | 7910 | |
7907 | bool intel_set_mode(struct drm_crtc *crtc, | | 7911 | bool intel_set_mode(struct drm_crtc *crtc, |
7908 | struct drm_display_mode *mode, | | 7912 | struct drm_display_mode *mode, |
7909 | int x, int y, struct drm_framebuffer *fb) | | 7913 | int x, int y, struct drm_framebuffer *fb) |
7910 | { | | 7914 | { |
7911 | struct drm_device *dev = crtc->dev; | | 7915 | struct drm_device *dev = crtc->dev; |
7912 | drm_i915_private_t *dev_priv = dev->dev_private; | | 7916 | drm_i915_private_t *dev_priv = dev->dev_private; |
7913 | struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode; | | 7917 | struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode; |
7914 | struct intel_crtc *intel_crtc; | | 7918 | struct intel_crtc *intel_crtc; |
7915 | unsigned disable_pipes, prepare_pipes, modeset_pipes; | | 7919 | unsigned disable_pipes, prepare_pipes, modeset_pipes; |
7916 | bool ret = true; | | 7920 | bool ret = true; |
7917 | | | 7921 | |
7918 | intel_modeset_affected_pipes(crtc, &modeset_pipes, | | 7922 | intel_modeset_affected_pipes(crtc, &modeset_pipes, |
7919 | &prepare_pipes, &disable_pipes); | | 7923 | &prepare_pipes, &disable_pipes); |
7920 | | | 7924 | |
7921 | DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n", | | 7925 | DRM_DEBUG_KMS("set mode pipe masks: modeset: %x, prepare: %x, disable: %x\n", |
7922 | modeset_pipes, prepare_pipes, disable_pipes); | | 7926 | modeset_pipes, prepare_pipes, disable_pipes); |
7923 | | | 7927 | |
7924 | for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc) | | 7928 | for_each_intel_crtc_masked(dev, disable_pipes, intel_crtc) |
7925 | intel_crtc_disable(&intel_crtc->base); | | 7929 | intel_crtc_disable(&intel_crtc->base); |
7926 | | | 7930 | |
7927 | saved_hwmode = crtc->hwmode; | | 7931 | saved_hwmode = crtc->hwmode; |
7928 | saved_mode = crtc->mode; | | 7932 | saved_mode = crtc->mode; |
7929 | | | 7933 | |
7930 | /* Hack: Because we don't (yet) support global modeset on multiple | | 7934 | /* Hack: Because we don't (yet) support global modeset on multiple |
7931 | * crtcs, we don't keep track of the new mode for more than one crtc. | | 7935 | * crtcs, we don't keep track of the new mode for more than one crtc. |
7932 | * Hence simply check whether any bit is set in modeset_pipes in all the | | 7936 | * Hence simply check whether any bit is set in modeset_pipes in all the |
7933 | * pieces of code that are not yet converted to deal with mutliple crtcs | | 7937 | * pieces of code that are not yet converted to deal with mutliple crtcs |
7934 | * changing their mode at the same time. */ | | 7938 | * changing their mode at the same time. */ |
7935 | adjusted_mode = NULL; | | 7939 | adjusted_mode = NULL; |
7936 | if (modeset_pipes) { | | 7940 | if (modeset_pipes) { |
7937 | adjusted_mode = intel_modeset_adjusted_mode(crtc, mode); | | 7941 | adjusted_mode = intel_modeset_adjusted_mode(crtc, mode); |
7938 | if (IS_ERR(adjusted_mode)) { | | 7942 | if (IS_ERR(adjusted_mode)) { |
7939 | return false; | | 7943 | return false; |
7940 | } | | 7944 | } |
7941 | } | | 7945 | } |
7942 | | | 7946 | |
7943 | for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) { | | 7947 | for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) { |
7944 | if (intel_crtc->base.enabled) | | 7948 | if (intel_crtc->base.enabled) |
7945 | dev_priv->display.crtc_disable(&intel_crtc->base); | | 7949 | dev_priv->display.crtc_disable(&intel_crtc->base); |
7946 | } | | 7950 | } |
7947 | | | 7951 | |
7948 | /* crtc->mode is already used by the ->mode_set callbacks, hence we need | | 7952 | /* crtc->mode is already used by the ->mode_set callbacks, hence we need |
7949 | * to set it here already despite that we pass it down the callchain. | | 7953 | * to set it here already despite that we pass it down the callchain. |
7950 | */ | | 7954 | */ |
7951 | if (modeset_pipes) | | 7955 | if (modeset_pipes) |
7952 | crtc->mode = *mode; | | 7956 | crtc->mode = *mode; |
7953 | | | 7957 | |
7954 | /* Only after disabling all output pipelines that will be changed can we | | 7958 | /* Only after disabling all output pipelines that will be changed can we |
7955 | * update the the output configuration. */ | | 7959 | * update the the output configuration. */ |
7956 | intel_modeset_update_state(dev, prepare_pipes); | | 7960 | intel_modeset_update_state(dev, prepare_pipes); |
7957 | | | 7961 | |
7958 | if (dev_priv->display.modeset_global_resources) | | 7962 | if (dev_priv->display.modeset_global_resources) |
7959 | dev_priv->display.modeset_global_resources(dev); | | 7963 | dev_priv->display.modeset_global_resources(dev); |
7960 | | | 7964 | |
7961 | /* Set up the DPLL and any encoders state that needs to adjust or depend | | 7965 | /* Set up the DPLL and any encoders state that needs to adjust or depend |
7962 | * on the DPLL. | | 7966 | * on the DPLL. |
7963 | */ | | 7967 | */ |
7964 | for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) { | | 7968 | for_each_intel_crtc_masked(dev, modeset_pipes, intel_crtc) { |
7965 | ret = !intel_crtc_mode_set(&intel_crtc->base, | | 7969 | ret = !intel_crtc_mode_set(&intel_crtc->base, |
7966 | mode, adjusted_mode, | | 7970 | mode, adjusted_mode, |
7967 | x, y, fb); | | 7971 | x, y, fb); |
7968 | if (!ret) | | 7972 | if (!ret) |
7969 | goto done; | | 7973 | goto done; |
7970 | } | | 7974 | } |
7971 | | | 7975 | |
7972 | /* Now enable the clocks, plane, pipe, and connectors that we set up. */ | | 7976 | /* Now enable the clocks, plane, pipe, and connectors that we set up. */ |
7973 | for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) | | 7977 | for_each_intel_crtc_masked(dev, prepare_pipes, intel_crtc) |
7974 | dev_priv->display.crtc_enable(&intel_crtc->base); | | 7978 | dev_priv->display.crtc_enable(&intel_crtc->base); |
7975 | | | 7979 | |
7976 | if (modeset_pipes) { | | 7980 | if (modeset_pipes) { |
7977 | /* Store real post-adjustment hardware mode. */ | | 7981 | /* Store real post-adjustment hardware mode. */ |
7978 | crtc->hwmode = *adjusted_mode; | | 7982 | crtc->hwmode = *adjusted_mode; |
7979 | | | 7983 | |
7980 | /* Calculate and store various constants which | | 7984 | /* Calculate and store various constants which |
7981 | * are later needed by vblank and swap-completion | | 7985 | * are later needed by vblank and swap-completion |
7982 | * timestamping. They are derived from true hwmode. | | 7986 | * timestamping. They are derived from true hwmode. |
7983 | */ | | 7987 | */ |
7984 | drm_calc_timestamping_constants(crtc); | | 7988 | drm_calc_timestamping_constants(crtc); |
7985 | } | | 7989 | } |
7986 | | | 7990 | |
7987 | /* FIXME: add subpixel order */ | | 7991 | /* FIXME: add subpixel order */ |
7988 | done: | | 7992 | done: |
7989 | drm_mode_destroy(dev, adjusted_mode); | | 7993 | drm_mode_destroy(dev, adjusted_mode); |
7990 | if (!ret && crtc->enabled) { | | 7994 | if (!ret && crtc->enabled) { |
7991 | crtc->hwmode = saved_hwmode; | | 7995 | crtc->hwmode = saved_hwmode; |
7992 | crtc->mode = saved_mode; | | 7996 | crtc->mode = saved_mode; |
7993 | } else { | | 7997 | } else { |
7994 | intel_modeset_check_state(dev); | | 7998 | intel_modeset_check_state(dev); |
7995 | } | | 7999 | } |
7996 | | | 8000 | |
7997 | return ret; | | 8001 | return ret; |
7998 | } | | 8002 | } |
7999 | | | 8003 | |
8000 | #undef for_each_intel_crtc_masked | | 8004 | #undef for_each_intel_crtc_masked |
8001 | | | 8005 | |
8002 | static void intel_set_config_free(struct intel_set_config *config) | | 8006 | static void intel_set_config_free(struct intel_set_config *config) |
8003 | { | | 8007 | { |
8004 | if (!config) | | 8008 | if (!config) |
8005 | return; | | 8009 | return; |
8006 | | | 8010 | |
8007 | kfree(config->save_connector_encoders); | | 8011 | kfree(config->save_connector_encoders); |
8008 | kfree(config->save_encoder_crtcs); | | 8012 | kfree(config->save_encoder_crtcs); |
8009 | kfree(config); | | 8013 | kfree(config); |
8010 | } | | 8014 | } |
8011 | | | 8015 | |
8012 | static int intel_set_config_save_state(struct drm_device *dev, | | 8016 | static int intel_set_config_save_state(struct drm_device *dev, |
8013 | struct intel_set_config *config) | | 8017 | struct intel_set_config *config) |
8014 | { | | 8018 | { |
8015 | struct drm_encoder *encoder; | | 8019 | struct drm_encoder *encoder; |
8016 | struct drm_connector *connector; | | 8020 | struct drm_connector *connector; |
8017 | int count; | | 8021 | int count; |
8018 | | | 8022 | |
8019 | config->save_encoder_crtcs = | | 8023 | config->save_encoder_crtcs = |
8020 | kcalloc(dev->mode_config.num_encoder, | | 8024 | kcalloc(dev->mode_config.num_encoder, |
8021 | sizeof(struct drm_crtc *), GFP_KERNEL); | | 8025 | sizeof(struct drm_crtc *), GFP_KERNEL); |
8022 | if (!config->save_encoder_crtcs) | | 8026 | if (!config->save_encoder_crtcs) |
8023 | return -ENOMEM; | | 8027 | return -ENOMEM; |
8024 | | | 8028 | |
8025 | config->save_connector_encoders = | | 8029 | config->save_connector_encoders = |
8026 | kcalloc(dev->mode_config.num_connector, | | 8030 | kcalloc(dev->mode_config.num_connector, |
8027 | sizeof(struct drm_encoder *), GFP_KERNEL); | | 8031 | sizeof(struct drm_encoder *), GFP_KERNEL); |
8028 | if (!config->save_connector_encoders) | | 8032 | if (!config->save_connector_encoders) |
8029 | return -ENOMEM; | | 8033 | return -ENOMEM; |
8030 | | | 8034 | |
8031 | /* Copy data. Note that driver private data is not affected. | | 8035 | /* Copy data. Note that driver private data is not affected. |
8032 | * Should anything bad happen only the expected state is | | 8036 | * Should anything bad happen only the expected state is |
8033 | * restored, not the drivers personal bookkeeping. | | 8037 | * restored, not the drivers personal bookkeeping. |
8034 | */ | | 8038 | */ |
8035 | count = 0; | | 8039 | count = 0; |
8036 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | | 8040 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
8037 | config->save_encoder_crtcs[count++] = encoder->crtc; | | 8041 | config->save_encoder_crtcs[count++] = encoder->crtc; |
8038 | } | | 8042 | } |
8039 | | | 8043 | |
8040 | count = 0; | | 8044 | count = 0; |
8041 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { | | 8045 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
8042 | config->save_connector_encoders[count++] = connector->encoder; | | 8046 | config->save_connector_encoders[count++] = connector->encoder; |
8043 | } | | 8047 | } |
8044 | | | 8048 | |
8045 | return 0; | | 8049 | return 0; |
8046 | } | | 8050 | } |
8047 | | | 8051 | |
8048 | static void intel_set_config_restore_state(struct drm_device *dev, | | 8052 | static void intel_set_config_restore_state(struct drm_device *dev, |
8049 | struct intel_set_config *config) | | 8053 | struct intel_set_config *config) |
8050 | { | | 8054 | { |
8051 | struct intel_encoder *encoder; | | 8055 | struct intel_encoder *encoder; |
8052 | struct intel_connector *connector; | | 8056 | struct intel_connector *connector; |
8053 | int count; | | 8057 | int count; |
8054 | | | 8058 | |
8055 | count = 0; | | 8059 | count = 0; |
8056 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { | | 8060 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { |
8057 | encoder->new_crtc = | | 8061 | encoder->new_crtc = |
8058 | to_intel_crtc(config->save_encoder_crtcs[count++]); | | 8062 | to_intel_crtc(config->save_encoder_crtcs[count++]); |
8059 | } | | 8063 | } |
8060 | | | 8064 | |
8061 | count = 0; | | 8065 | count = 0; |
8062 | list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) { | | 8066 | list_for_each_entry(connector, &dev->mode_config.connector_list, base.head) { |
8063 | connector->new_encoder = | | 8067 | connector->new_encoder = |
8064 | to_intel_encoder(config->save_connector_encoders[count++]); | | 8068 | to_intel_encoder(config->save_connector_encoders[count++]); |
8065 | } | | 8069 | } |
8066 | } | | 8070 | } |
8067 | | | 8071 | |
8068 | static void | | 8072 | static void |
8069 | intel_set_config_compute_mode_changes(struct drm_mode_set *set, | | 8073 | intel_set_config_compute_mode_changes(struct drm_mode_set *set, |
8070 | struct intel_set_config *config) | | 8074 | struct intel_set_config *config) |
8071 | { | | 8075 | { |
8072 | | | 8076 | |
8073 | /* We should be able to check here if the fb has the same properties | | 8077 | /* We should be able to check here if the fb has the same properties |
8074 | * and then just flip_or_move it */ | | 8078 | * and then just flip_or_move it */ |
8075 | if (set->crtc->fb != set->fb) { | | 8079 | if (set->crtc->fb != set->fb) { |
8076 | /* If we have no fb then treat it as a full mode set */ | | 8080 | /* If we have no fb then treat it as a full mode set */ |
8077 | if (set->crtc->fb == NULL) { | | 8081 | if (set->crtc->fb == NULL) { |
8078 | DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); | | 8082 | DRM_DEBUG_KMS("crtc has no fb, full mode set\n"); |
8079 | config->mode_changed = true; | | 8083 | config->mode_changed = true; |
8080 | } else if (set->fb == NULL) { | | 8084 | } else if (set->fb == NULL) { |
8081 | config->mode_changed = true; | | 8085 | config->mode_changed = true; |
8082 | } else if (set->fb->depth != set->crtc->fb->depth) { | | 8086 | } else if (set->fb->depth != set->crtc->fb->depth) { |
8083 | config->mode_changed = true; | | 8087 | config->mode_changed = true; |
8084 | } else if (set->fb->bits_per_pixel != | | 8088 | } else if (set->fb->bits_per_pixel != |
8085 | set->crtc->fb->bits_per_pixel) { | | 8089 | set->crtc->fb->bits_per_pixel) { |
8086 | config->mode_changed = true; | | 8090 | config->mode_changed = true; |
8087 | } else | | 8091 | } else |
8088 | config->fb_changed = true; | | 8092 | config->fb_changed = true; |
8089 | } | | 8093 | } |
8090 | | | 8094 | |
8091 | if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y)) | | 8095 | if (set->fb && (set->x != set->crtc->x || set->y != set->crtc->y)) |
8092 | config->fb_changed = true; | | 8096 | config->fb_changed = true; |
8093 | | | 8097 | |
8094 | if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { | | 8098 | if (set->mode && !drm_mode_equal(set->mode, &set->crtc->mode)) { |
8095 | DRM_DEBUG_KMS("modes are different, full mode set\n"); | | 8099 | DRM_DEBUG_KMS("modes are different, full mode set\n"); |
8096 | drm_mode_debug_printmodeline(&set->crtc->mode); | | 8100 | drm_mode_debug_printmodeline(&set->crtc->mode); |
8097 | drm_mode_debug_printmodeline(set->mode); | | 8101 | drm_mode_debug_printmodeline(set->mode); |
8098 | config->mode_changed = true; | | 8102 | config->mode_changed = true; |
8099 | } | | 8103 | } |
8100 | } | | 8104 | } |
8101 | | | 8105 | |
8102 | static int | | 8106 | static int |
8103 | intel_modeset_stage_output_state(struct drm_device *dev, | | 8107 | intel_modeset_stage_output_state(struct drm_device *dev, |
8104 | struct drm_mode_set *set, | | 8108 | struct drm_mode_set *set, |
8105 | struct intel_set_config *config) | | 8109 | struct intel_set_config *config) |
8106 | { | | 8110 | { |
8107 | struct drm_crtc *new_crtc; | | 8111 | struct drm_crtc *new_crtc; |
8108 | struct intel_connector *connector; | | 8112 | struct intel_connector *connector; |
8109 | struct intel_encoder *encoder; | | 8113 | struct intel_encoder *encoder; |
8110 | int count, ro; | | 8114 | int count, ro; |
8111 | | | 8115 | |
8112 | /* The upper layers ensure that we either disabl a crtc or have a list | | 8116 | /* The upper layers ensure that we either disabl a crtc or have a list |
8113 | * of connectors. For paranoia, double-check this. */ | | 8117 | * of connectors. For paranoia, double-check this. */ |
8114 | WARN_ON(!set->fb && (set->num_connectors != 0)); | | 8118 | WARN_ON(!set->fb && (set->num_connectors != 0)); |
8115 | WARN_ON(set->fb && (set->num_connectors == 0)); | | 8119 | WARN_ON(set->fb && (set->num_connectors == 0)); |
8116 | | | 8120 | |
8117 | count = 0; | | 8121 | count = 0; |
8118 | list_for_each_entry(connector, &dev->mode_config.connector_list, | | 8122 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
8119 | base.head) { | | 8123 | base.head) { |
8120 | /* Otherwise traverse passed in connector list and get encoders | | 8124 | /* Otherwise traverse passed in connector list and get encoders |
8121 | * for them. */ | | 8125 | * for them. */ |
8122 | for (ro = 0; ro < set->num_connectors; ro++) { | | 8126 | for (ro = 0; ro < set->num_connectors; ro++) { |
8123 | if (set->connectors[ro] == &connector->base) { | | 8127 | if (set->connectors[ro] == &connector->base) { |
8124 | connector->new_encoder = connector->encoder; | | 8128 | connector->new_encoder = connector->encoder; |
8125 | break; | | 8129 | break; |
8126 | } | | 8130 | } |
8127 | } | | 8131 | } |
8128 | | | 8132 | |
8129 | /* If we disable the crtc, disable all its connectors. Also, if | | 8133 | /* If we disable the crtc, disable all its connectors. Also, if |
8130 | * the connector is on the changing crtc but not on the new | | 8134 | * the connector is on the changing crtc but not on the new |
8131 | * connector list, disable it. */ | | 8135 | * connector list, disable it. */ |
8132 | if ((!set->fb || ro == set->num_connectors) && | | 8136 | if ((!set->fb || ro == set->num_connectors) && |
8133 | connector->base.encoder && | | 8137 | connector->base.encoder && |
8134 | connector->base.encoder->crtc == set->crtc) { | | 8138 | connector->base.encoder->crtc == set->crtc) { |
8135 | connector->new_encoder = NULL; | | 8139 | connector->new_encoder = NULL; |
8136 | | | 8140 | |
8137 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n", | | 8141 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [NOCRTC]\n", |
8138 | connector->base.base.id, | | 8142 | connector->base.base.id, |
8139 | drm_get_connector_name(&connector->base)); | | 8143 | drm_get_connector_name(&connector->base)); |
8140 | } | | 8144 | } |
8141 | | | 8145 | |
8142 | | | 8146 | |
8143 | if (&connector->new_encoder->base != connector->base.encoder) { | | 8147 | if (&connector->new_encoder->base != connector->base.encoder) { |
8144 | DRM_DEBUG_KMS("encoder changed, full mode switch\n"); | | 8148 | DRM_DEBUG_KMS("encoder changed, full mode switch\n"); |
8145 | config->mode_changed = true; | | 8149 | config->mode_changed = true; |
8146 | } | | 8150 | } |
8147 | } | | 8151 | } |
8148 | /* connector->new_encoder is now updated for all connectors. */ | | 8152 | /* connector->new_encoder is now updated for all connectors. */ |
8149 | | | 8153 | |
8150 | /* Update crtc of enabled connectors. */ | | 8154 | /* Update crtc of enabled connectors. */ |
8151 | count = 0; | | 8155 | count = 0; |
8152 | list_for_each_entry(connector, &dev->mode_config.connector_list, | | 8156 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
8153 | base.head) { | | 8157 | base.head) { |
8154 | if (!connector->new_encoder) | | 8158 | if (!connector->new_encoder) |
8155 | continue; | | 8159 | continue; |
8156 | | | 8160 | |
8157 | new_crtc = connector->new_encoder->base.crtc; | | 8161 | new_crtc = connector->new_encoder->base.crtc; |
8158 | | | 8162 | |
8159 | for (ro = 0; ro < set->num_connectors; ro++) { | | 8163 | for (ro = 0; ro < set->num_connectors; ro++) { |
8160 | if (set->connectors[ro] == &connector->base) | | 8164 | if (set->connectors[ro] == &connector->base) |
8161 | new_crtc = set->crtc; | | 8165 | new_crtc = set->crtc; |
8162 | } | | 8166 | } |
8163 | | | 8167 | |
8164 | /* Make sure the new CRTC will work with the encoder */ | | 8168 | /* Make sure the new CRTC will work with the encoder */ |
8165 | if (!intel_encoder_crtc_ok(&connector->new_encoder->base, | | 8169 | if (!intel_encoder_crtc_ok(&connector->new_encoder->base, |
8166 | new_crtc)) { | | 8170 | new_crtc)) { |
8167 | return -EINVAL; | | 8171 | return -EINVAL; |
8168 | } | | 8172 | } |
8169 | connector->encoder->new_crtc = to_intel_crtc(new_crtc); | | 8173 | connector->encoder->new_crtc = to_intel_crtc(new_crtc); |
8170 | | | 8174 | |
8171 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n", | | 8175 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] to [CRTC:%d]\n", |
8172 | connector->base.base.id, | | 8176 | connector->base.base.id, |
8173 | drm_get_connector_name(&connector->base), | | 8177 | drm_get_connector_name(&connector->base), |
8174 | new_crtc->base.id); | | 8178 | new_crtc->base.id); |
8175 | } | | 8179 | } |
8176 | | | 8180 | |
8177 | /* Check for any encoders that needs to be disabled. */ | | 8181 | /* Check for any encoders that needs to be disabled. */ |
8178 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | | 8182 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
8179 | base.head) { | | 8183 | base.head) { |
8180 | list_for_each_entry(connector, | | 8184 | list_for_each_entry(connector, |
8181 | &dev->mode_config.connector_list, | | 8185 | &dev->mode_config.connector_list, |
8182 | base.head) { | | 8186 | base.head) { |
8183 | if (connector->new_encoder == encoder) { | | 8187 | if (connector->new_encoder == encoder) { |
8184 | WARN_ON(!connector->new_encoder->new_crtc); | | 8188 | WARN_ON(!connector->new_encoder->new_crtc); |
8185 | | | 8189 | |
8186 | goto next_encoder; | | 8190 | goto next_encoder; |
8187 | } | | 8191 | } |
8188 | } | | 8192 | } |
8189 | encoder->new_crtc = NULL; | | 8193 | encoder->new_crtc = NULL; |
8190 | next_encoder: | | 8194 | next_encoder: |
8191 | /* Only now check for crtc changes so we don't miss encoders | | 8195 | /* Only now check for crtc changes so we don't miss encoders |
8192 | * that will be disabled. */ | | 8196 | * that will be disabled. */ |
8193 | if (&encoder->new_crtc->base != encoder->base.crtc) { | | 8197 | if (&encoder->new_crtc->base != encoder->base.crtc) { |
8194 | DRM_DEBUG_KMS("crtc changed, full mode switch\n"); | | 8198 | DRM_DEBUG_KMS("crtc changed, full mode switch\n"); |
8195 | config->mode_changed = true; | | 8199 | config->mode_changed = true; |
8196 | } | | 8200 | } |
8197 | } | | 8201 | } |
8198 | /* Now we've also updated encoder->new_crtc for all encoders. */ | | 8202 | /* Now we've also updated encoder->new_crtc for all encoders. */ |
8199 | | | 8203 | |
8200 | return 0; | | 8204 | return 0; |
8201 | } | | 8205 | } |
8202 | | | 8206 | |
8203 | static int intel_crtc_set_config(struct drm_mode_set *set) | | 8207 | static int intel_crtc_set_config(struct drm_mode_set *set) |
8204 | { | | 8208 | { |
8205 | struct drm_device *dev; | | 8209 | struct drm_device *dev; |
8206 | struct drm_mode_set save_set; | | 8210 | struct drm_mode_set save_set; |
8207 | struct intel_set_config *config; | | 8211 | struct intel_set_config *config; |
8208 | int ret; | | 8212 | int ret; |
8209 | | | 8213 | |
8210 | BUG_ON(!set); | | 8214 | BUG_ON(!set); |
8211 | BUG_ON(!set->crtc); | | 8215 | BUG_ON(!set->crtc); |
8212 | BUG_ON(!set->crtc->helper_private); | | 8216 | BUG_ON(!set->crtc->helper_private); |
8213 | | | 8217 | |
8214 | if (!set->mode) | | 8218 | if (!set->mode) |
8215 | set->fb = NULL; | | 8219 | set->fb = NULL; |
8216 | | | 8220 | |
8217 | /* The fb helper likes to play gross jokes with ->mode_set_config. | | 8221 | /* The fb helper likes to play gross jokes with ->mode_set_config. |
8218 | * Unfortunately the crtc helper doesn't do much at all for this case, | | 8222 | * Unfortunately the crtc helper doesn't do much at all for this case, |
8219 | * so we have to cope with this madness until the fb helper is fixed up. */ | | 8223 | * so we have to cope with this madness until the fb helper is fixed up. */ |
8220 | if (set->fb && set->num_connectors == 0) | | 8224 | if (set->fb && set->num_connectors == 0) |
8221 | return 0; | | 8225 | return 0; |
8222 | | | 8226 | |
8223 | if (set->fb) { | | 8227 | if (set->fb) { |
8224 | DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", | | 8228 | DRM_DEBUG_KMS("[CRTC:%d] [FB:%d] #connectors=%d (x y) (%i %i)\n", |
8225 | set->crtc->base.id, set->fb->base.id, | | 8229 | set->crtc->base.id, set->fb->base.id, |
8226 | (int)set->num_connectors, set->x, set->y); | | 8230 | (int)set->num_connectors, set->x, set->y); |
8227 | } else { | | 8231 | } else { |
8228 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); | | 8232 | DRM_DEBUG_KMS("[CRTC:%d] [NOFB]\n", set->crtc->base.id); |
8229 | } | | 8233 | } |
8230 | | | 8234 | |
8231 | dev = set->crtc->dev; | | 8235 | dev = set->crtc->dev; |
8232 | | | 8236 | |
8233 | ret = -ENOMEM; | | 8237 | ret = -ENOMEM; |
8234 | config = kzalloc(sizeof(*config), GFP_KERNEL); | | 8238 | config = kzalloc(sizeof(*config), GFP_KERNEL); |
8235 | if (!config) | | 8239 | if (!config) |
8236 | goto out_config; | | 8240 | goto out_config; |
8237 | | | 8241 | |
8238 | ret = intel_set_config_save_state(dev, config); | | 8242 | ret = intel_set_config_save_state(dev, config); |
8239 | if (ret) | | 8243 | if (ret) |
8240 | goto out_config; | | 8244 | goto out_config; |
8241 | | | 8245 | |
8242 | save_set.crtc = set->crtc; | | 8246 | save_set.crtc = set->crtc; |
8243 | save_set.mode = &set->crtc->mode; | | 8247 | save_set.mode = &set->crtc->mode; |
8244 | save_set.x = set->crtc->x; | | 8248 | save_set.x = set->crtc->x; |
8245 | save_set.y = set->crtc->y; | | 8249 | save_set.y = set->crtc->y; |
8246 | save_set.fb = set->crtc->fb; | | 8250 | save_set.fb = set->crtc->fb; |
8247 | | | 8251 | |
8248 | /* Compute whether we need a full modeset, only an fb base update or no | | 8252 | /* Compute whether we need a full modeset, only an fb base update or no |
8249 | * change at all. In the future we might also check whether only the | | 8253 | * change at all. In the future we might also check whether only the |
8250 | * mode changed, e.g. for LVDS where we only change the panel fitter in | | 8254 | * mode changed, e.g. for LVDS where we only change the panel fitter in |
8251 | * such cases. */ | | 8255 | * such cases. */ |
8252 | intel_set_config_compute_mode_changes(set, config); | | 8256 | intel_set_config_compute_mode_changes(set, config); |
8253 | | | 8257 | |
8254 | ret = intel_modeset_stage_output_state(dev, set, config); | | 8258 | ret = intel_modeset_stage_output_state(dev, set, config); |
8255 | if (ret) | | 8259 | if (ret) |
8256 | goto fail; | | 8260 | goto fail; |
8257 | | | 8261 | |
8258 | if (config->mode_changed) { | | 8262 | if (config->mode_changed) { |
8259 | if (set->mode) { | | 8263 | if (set->mode) { |
8260 | DRM_DEBUG_KMS("attempting to set mode from" | | 8264 | DRM_DEBUG_KMS("attempting to set mode from" |
8261 | " userspace\n"); | | 8265 | " userspace\n"); |
8262 | drm_mode_debug_printmodeline(set->mode); | | 8266 | drm_mode_debug_printmodeline(set->mode); |
8263 | } | | 8267 | } |
8264 | | | 8268 | |
8265 | if (!intel_set_mode(set->crtc, set->mode, | | 8269 | if (!intel_set_mode(set->crtc, set->mode, |
8266 | set->x, set->y, set->fb)) { | | 8270 | set->x, set->y, set->fb)) { |
8267 | DRM_ERROR("failed to set mode on [CRTC:%d]\n", | | 8271 | DRM_ERROR("failed to set mode on [CRTC:%d]\n", |
8268 | set->crtc->base.id); | | 8272 | set->crtc->base.id); |
8269 | ret = -EINVAL; | | 8273 | ret = -EINVAL; |
8270 | goto fail; | | 8274 | goto fail; |
8271 | } | | 8275 | } |
8272 | } else if (config->fb_changed) { | | 8276 | } else if (config->fb_changed) { |
8273 | ret = intel_pipe_set_base(set->crtc, | | 8277 | ret = intel_pipe_set_base(set->crtc, |
8274 | set->x, set->y, set->fb); | | 8278 | set->x, set->y, set->fb); |
8275 | } | | 8279 | } |
8276 | | | 8280 | |
8277 | intel_set_config_free(config); | | 8281 | intel_set_config_free(config); |
8278 | | | 8282 | |
8279 | return 0; | | 8283 | return 0; |
8280 | | | 8284 | |
8281 | fail: | | 8285 | fail: |
8282 | intel_set_config_restore_state(dev, config); | | 8286 | intel_set_config_restore_state(dev, config); |
8283 | | | 8287 | |
8284 | /* Try to restore the config */ | | 8288 | /* Try to restore the config */ |
8285 | if (config->mode_changed && | | 8289 | if (config->mode_changed && |
8286 | !intel_set_mode(save_set.crtc, save_set.mode, | | 8290 | !intel_set_mode(save_set.crtc, save_set.mode, |
8287 | save_set.x, save_set.y, save_set.fb)) | | 8291 | save_set.x, save_set.y, save_set.fb)) |
8288 | DRM_ERROR("failed to restore config after modeset failure\n"); | | 8292 | DRM_ERROR("failed to restore config after modeset failure\n"); |
8289 | | | 8293 | |
8290 | out_config: | | 8294 | out_config: |
8291 | intel_set_config_free(config); | | 8295 | intel_set_config_free(config); |
8292 | return ret; | | 8296 | return ret; |
8293 | } | | 8297 | } |
8294 | | | 8298 | |
8295 | static const struct drm_crtc_funcs intel_crtc_funcs = { | | 8299 | static const struct drm_crtc_funcs intel_crtc_funcs = { |
8296 | .cursor_set = intel_crtc_cursor_set, | | 8300 | .cursor_set = intel_crtc_cursor_set, |
8297 | .cursor_move = intel_crtc_cursor_move, | | 8301 | .cursor_move = intel_crtc_cursor_move, |
8298 | .gamma_set = intel_crtc_gamma_set, | | 8302 | .gamma_set = intel_crtc_gamma_set, |
8299 | .set_config = intel_crtc_set_config, | | 8303 | .set_config = intel_crtc_set_config, |
8300 | .destroy = intel_crtc_destroy, | | 8304 | .destroy = intel_crtc_destroy, |
8301 | .page_flip = intel_crtc_page_flip, | | 8305 | .page_flip = intel_crtc_page_flip, |
8302 | }; | | 8306 | }; |
8303 | | | 8307 | |
8304 | static void intel_cpu_pll_init(struct drm_device *dev) | | 8308 | static void intel_cpu_pll_init(struct drm_device *dev) |
8305 | { | | 8309 | { |
8306 | if (IS_HASWELL(dev)) | | 8310 | if (IS_HASWELL(dev)) |
8307 | intel_ddi_pll_init(dev); | | 8311 | intel_ddi_pll_init(dev); |
8308 | } | | 8312 | } |
8309 | | | 8313 | |
8310 | static void intel_pch_pll_init(struct drm_device *dev) | | 8314 | static void intel_pch_pll_init(struct drm_device *dev) |
8311 | { | | 8315 | { |
8312 | drm_i915_private_t *dev_priv = dev->dev_private; | | 8316 | drm_i915_private_t *dev_priv = dev->dev_private; |
8313 | int i; | | 8317 | int i; |
8314 | | | 8318 | |
8315 | if (dev_priv->num_pch_pll == 0) { | | 8319 | if (dev_priv->num_pch_pll == 0) { |
8316 | DRM_DEBUG_KMS("No PCH PLLs on this hardware, skipping initialisation\n"); | | 8320 | DRM_DEBUG_KMS("No PCH PLLs on this hardware, skipping initialisation\n"); |
8317 | return; | | 8321 | return; |
8318 | } | | 8322 | } |
8319 | | | 8323 | |
8320 | for (i = 0; i < dev_priv->num_pch_pll; i++) { | | 8324 | for (i = 0; i < dev_priv->num_pch_pll; i++) { |
8321 | dev_priv->pch_plls[i].pll_reg = _PCH_DPLL(i); | | 8325 | dev_priv->pch_plls[i].pll_reg = _PCH_DPLL(i); |
8322 | dev_priv->pch_plls[i].fp0_reg = _PCH_FP0(i); | | 8326 | dev_priv->pch_plls[i].fp0_reg = _PCH_FP0(i); |
8323 | dev_priv->pch_plls[i].fp1_reg = _PCH_FP1(i); | | 8327 | dev_priv->pch_plls[i].fp1_reg = _PCH_FP1(i); |
8324 | } | | 8328 | } |
8325 | } | | 8329 | } |
8326 | | | 8330 | |
8327 | static void intel_crtc_init(struct drm_device *dev, int pipe) | | 8331 | static void intel_crtc_init(struct drm_device *dev, int pipe) |
8328 | { | | 8332 | { |
8329 | drm_i915_private_t *dev_priv = dev->dev_private; | | 8333 | drm_i915_private_t *dev_priv = dev->dev_private; |
8330 | struct intel_crtc *intel_crtc; | | 8334 | struct intel_crtc *intel_crtc; |
8331 | int i; | | 8335 | int i; |
8332 | | | 8336 | |
8333 | intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); | | 8337 | intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); |
8334 | if (intel_crtc == NULL) | | 8338 | if (intel_crtc == NULL) |
8335 | return; | | 8339 | return; |
8336 | | | 8340 | |
8337 | drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); | | 8341 | drm_crtc_init(dev, &intel_crtc->base, &intel_crtc_funcs); |
8338 | | | 8342 | |
8339 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); | | 8343 | drm_mode_crtc_set_gamma_size(&intel_crtc->base, 256); |
8340 | for (i = 0; i < 256; i++) { | | 8344 | for (i = 0; i < 256; i++) { |
8341 | intel_crtc->lut_r[i] = i; | | 8345 | intel_crtc->lut_r[i] = i; |
8342 | intel_crtc->lut_g[i] = i; | | 8346 | intel_crtc->lut_g[i] = i; |
8343 | intel_crtc->lut_b[i] = i; | | 8347 | intel_crtc->lut_b[i] = i; |
8344 | } | | 8348 | } |
8345 | | | 8349 | |
8346 | /* Swap pipes & planes for FBC on pre-965 */ | | 8350 | /* Swap pipes & planes for FBC on pre-965 */ |
8347 | intel_crtc->pipe = pipe; | | 8351 | intel_crtc->pipe = pipe; |
8348 | intel_crtc->plane = pipe; | | 8352 | intel_crtc->plane = pipe; |
8349 | intel_crtc->cpu_transcoder = pipe; | | 8353 | intel_crtc->cpu_transcoder = pipe; |
8350 | if (IS_MOBILE(dev) && IS_GEN3(dev)) { | | 8354 | if (IS_MOBILE(dev) && IS_GEN3(dev)) { |
8351 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); | | 8355 | DRM_DEBUG_KMS("swapping pipes & planes for FBC\n"); |
8352 | intel_crtc->plane = !pipe; | | 8356 | intel_crtc->plane = !pipe; |
8353 | } | | 8357 | } |
8354 | | | 8358 | |
8355 | BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || | | 8359 | BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) || |
8356 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); | | 8360 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] != NULL); |
8357 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; | | 8361 | dev_priv->plane_to_crtc_mapping[intel_crtc->plane] = &intel_crtc->base; |
8358 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; | | 8362 | dev_priv->pipe_to_crtc_mapping[intel_crtc->pipe] = &intel_crtc->base; |
8359 | | | 8363 | |
8360 | intel_crtc->bpp = 24; /* default for pre-Ironlake */ | | 8364 | intel_crtc->bpp = 24; /* default for pre-Ironlake */ |
8361 | | | 8365 | |
8362 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); | | 8366 | drm_crtc_helper_add(&intel_crtc->base, &intel_helper_funcs); |
8363 | } | | 8367 | } |
8364 | | | 8368 | |
8365 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, | | 8369 | int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data, |
8366 | struct drm_file *file) | | 8370 | struct drm_file *file) |
8367 | { | | 8371 | { |
8368 | struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; | | 8372 | struct drm_i915_get_pipe_from_crtc_id *pipe_from_crtc_id = data; |
8369 | struct drm_mode_object *drmmode_obj; | | 8373 | struct drm_mode_object *drmmode_obj; |
8370 | struct intel_crtc *crtc; | | 8374 | struct intel_crtc *crtc; |
8371 | | | 8375 | |
8372 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) | | 8376 | if (!drm_core_check_feature(dev, DRIVER_MODESET)) |
8373 | return -ENODEV; | | 8377 | return -ENODEV; |
8374 | | | 8378 | |
8375 | drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, | | 8379 | drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id, |
8376 | DRM_MODE_OBJECT_CRTC); | | 8380 | DRM_MODE_OBJECT_CRTC); |
8377 | | | 8381 | |
8378 | if (!drmmode_obj) { | | 8382 | if (!drmmode_obj) { |
8379 | DRM_ERROR("no such CRTC id\n"); | | 8383 | DRM_ERROR("no such CRTC id\n"); |
8380 | return -EINVAL; | | 8384 | return -EINVAL; |
8381 | } | | 8385 | } |
8382 | | | 8386 | |
8383 | crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); | | 8387 | crtc = to_intel_crtc(obj_to_crtc(drmmode_obj)); |
8384 | pipe_from_crtc_id->pipe = crtc->pipe; | | 8388 | pipe_from_crtc_id->pipe = crtc->pipe; |
8385 | | | 8389 | |
8386 | return 0; | | 8390 | return 0; |
8387 | } | | 8391 | } |
8388 | | | 8392 | |
8389 | static int intel_encoder_clones(struct intel_encoder *encoder) | | 8393 | static int intel_encoder_clones(struct intel_encoder *encoder) |
8390 | { | | 8394 | { |
8391 | struct drm_device *dev = encoder->base.dev; | | 8395 | struct drm_device *dev = encoder->base.dev; |
8392 | struct intel_encoder *source_encoder; | | 8396 | struct intel_encoder *source_encoder; |
8393 | int index_mask = 0; | | 8397 | int index_mask = 0; |
8394 | int entry = 0; | | 8398 | int entry = 0; |
8395 | | | 8399 | |
8396 | list_for_each_entry(source_encoder, | | 8400 | list_for_each_entry(source_encoder, |
8397 | &dev->mode_config.encoder_list, base.head) { | | 8401 | &dev->mode_config.encoder_list, base.head) { |
8398 | | | 8402 | |
8399 | if (encoder == source_encoder) | | 8403 | if (encoder == source_encoder) |
8400 | index_mask |= (1 << entry); | | 8404 | index_mask |= (1 << entry); |
8401 | | | 8405 | |
8402 | /* Intel hw has only one MUX where enocoders could be cloned. */ | | 8406 | /* Intel hw has only one MUX where enocoders could be cloned. */ |
8403 | if (encoder->cloneable && source_encoder->cloneable) | | 8407 | if (encoder->cloneable && source_encoder->cloneable) |
8404 | index_mask |= (1 << entry); | | 8408 | index_mask |= (1 << entry); |
8405 | | | 8409 | |
8406 | entry++; | | 8410 | entry++; |
8407 | } | | 8411 | } |
8408 | | | 8412 | |
8409 | return index_mask; | | 8413 | return index_mask; |
8410 | } | | 8414 | } |
8411 | | | 8415 | |
8412 | static bool has_edp_a(struct drm_device *dev) | | 8416 | static bool has_edp_a(struct drm_device *dev) |
8413 | { | | 8417 | { |
8414 | struct drm_i915_private *dev_priv = dev->dev_private; | | 8418 | struct drm_i915_private *dev_priv = dev->dev_private; |
8415 | | | 8419 | |
8416 | if (!IS_MOBILE(dev)) | | 8420 | if (!IS_MOBILE(dev)) |
8417 | return false; | | 8421 | return false; |
8418 | | | 8422 | |
8419 | if ((I915_READ(DP_A) & DP_DETECTED) == 0) | | 8423 | if ((I915_READ(DP_A) & DP_DETECTED) == 0) |
8420 | return false; | | 8424 | return false; |
8421 | | | 8425 | |
8422 | if (IS_GEN5(dev) && | | 8426 | if (IS_GEN5(dev) && |
8423 | (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE)) | | 8427 | (I915_READ(ILK_DISPLAY_CHICKEN_FUSES) & ILK_eDP_A_DISABLE)) |
8424 | return false; | | 8428 | return false; |
8425 | | | 8429 | |
8426 | return true; | | 8430 | return true; |
8427 | } | | 8431 | } |
8428 | | | 8432 | |
8429 | static void intel_setup_outputs(struct drm_device *dev) | | 8433 | static void intel_setup_outputs(struct drm_device *dev) |
8430 | { | | 8434 | { |
8431 | struct drm_i915_private *dev_priv = dev->dev_private; | | 8435 | struct drm_i915_private *dev_priv = dev->dev_private; |
8432 | struct intel_encoder *encoder; | | 8436 | struct intel_encoder *encoder; |
8433 | bool dpd_is_edp = false; | | 8437 | bool dpd_is_edp = false; |
8434 | bool has_lvds; | | 8438 | bool has_lvds; |
8435 | | | 8439 | |
8436 | has_lvds = intel_lvds_init(dev); | | 8440 | has_lvds = intel_lvds_init(dev); |
8437 | if (!has_lvds && !HAS_PCH_SPLIT(dev)) { | | 8441 | if (!has_lvds && !HAS_PCH_SPLIT(dev)) { |
8438 | /* disable the panel fitter on everything but LVDS */ | | 8442 | /* disable the panel fitter on everything but LVDS */ |
8439 | I915_WRITE(PFIT_CONTROL, 0); | | 8443 | I915_WRITE(PFIT_CONTROL, 0); |
8440 | } | | 8444 | } |
8441 | | | 8445 | |
8442 | if (!(IS_HASWELL(dev) && | | 8446 | if (!(IS_HASWELL(dev) && |
8443 | (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES))) | | 8447 | (I915_READ(DDI_BUF_CTL(PORT_A)) & DDI_A_4_LANES))) |
8444 | intel_crt_init(dev); | | 8448 | intel_crt_init(dev); |
8445 | | | 8449 | |
8446 | if (IS_HASWELL(dev)) { | | 8450 | if (IS_HASWELL(dev)) { |
8447 | int found; | | 8451 | int found; |
8448 | | | 8452 | |
8449 | /* Haswell uses DDI functions to detect digital outputs */ | | 8453 | /* Haswell uses DDI functions to detect digital outputs */ |
8450 | found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED; | | 8454 | found = I915_READ(DDI_BUF_CTL_A) & DDI_INIT_DISPLAY_DETECTED; |
8451 | /* DDI A only supports eDP */ | | 8455 | /* DDI A only supports eDP */ |
8452 | if (found) | | 8456 | if (found) |
8453 | intel_ddi_init(dev, PORT_A); | | 8457 | intel_ddi_init(dev, PORT_A); |
8454 | | | 8458 | |
8455 | /* DDI B, C and D detection is indicated by the SFUSE_STRAP | | 8459 | /* DDI B, C and D detection is indicated by the SFUSE_STRAP |
8456 | * register */ | | 8460 | * register */ |
8457 | found = I915_READ(SFUSE_STRAP); | | 8461 | found = I915_READ(SFUSE_STRAP); |
8458 | | | 8462 | |
8459 | if (found & SFUSE_STRAP_DDIB_DETECTED) | | 8463 | if (found & SFUSE_STRAP_DDIB_DETECTED) |
8460 | intel_ddi_init(dev, PORT_B); | | 8464 | intel_ddi_init(dev, PORT_B); |
8461 | if (found & SFUSE_STRAP_DDIC_DETECTED) | | 8465 | if (found & SFUSE_STRAP_DDIC_DETECTED) |
8462 | intel_ddi_init(dev, PORT_C); | | 8466 | intel_ddi_init(dev, PORT_C); |
8463 | if (found & SFUSE_STRAP_DDID_DETECTED) | | 8467 | if (found & SFUSE_STRAP_DDID_DETECTED) |
8464 | intel_ddi_init(dev, PORT_D); | | 8468 | intel_ddi_init(dev, PORT_D); |
8465 | } else if (HAS_PCH_SPLIT(dev)) { | | 8469 | } else if (HAS_PCH_SPLIT(dev)) { |
8466 | int found; | | 8470 | int found; |
8467 | dpd_is_edp = intel_dpd_is_edp(dev); | | 8471 | dpd_is_edp = intel_dpd_is_edp(dev); |
8468 | | | 8472 | |
8469 | if (has_edp_a(dev)) | | 8473 | if (has_edp_a(dev)) |
8470 | intel_dp_init(dev, DP_A, PORT_A); | | 8474 | intel_dp_init(dev, DP_A, PORT_A); |
8471 | | | 8475 | |
8472 | if (I915_READ(HDMIB) & PORT_DETECTED) { | | 8476 | if (I915_READ(HDMIB) & PORT_DETECTED) { |
8473 | /* PCH SDVOB multiplex with HDMIB */ | | 8477 | /* PCH SDVOB multiplex with HDMIB */ |
8474 | found = intel_sdvo_init(dev, PCH_SDVOB, true); | | 8478 | found = intel_sdvo_init(dev, PCH_SDVOB, true); |
8475 | if (!found) | | 8479 | if (!found) |
8476 | intel_hdmi_init(dev, HDMIB, PORT_B); | | 8480 | intel_hdmi_init(dev, HDMIB, PORT_B); |
8477 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) | | 8481 | if (!found && (I915_READ(PCH_DP_B) & DP_DETECTED)) |
8478 | intel_dp_init(dev, PCH_DP_B, PORT_B); | | 8482 | intel_dp_init(dev, PCH_DP_B, PORT_B); |
8479 | } | | 8483 | } |
8480 | | | 8484 | |
8481 | if (I915_READ(HDMIC) & PORT_DETECTED) | | 8485 | if (I915_READ(HDMIC) & PORT_DETECTED) |
8482 | intel_hdmi_init(dev, HDMIC, PORT_C); | | 8486 | intel_hdmi_init(dev, HDMIC, PORT_C); |
8483 | | | 8487 | |
8484 | if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED) | | 8488 | if (!dpd_is_edp && I915_READ(HDMID) & PORT_DETECTED) |
8485 | intel_hdmi_init(dev, HDMID, PORT_D); | | 8489 | intel_hdmi_init(dev, HDMID, PORT_D); |
8486 | | | 8490 | |
8487 | if (I915_READ(PCH_DP_C) & DP_DETECTED) | | 8491 | if (I915_READ(PCH_DP_C) & DP_DETECTED) |
8488 | intel_dp_init(dev, PCH_DP_C, PORT_C); | | 8492 | intel_dp_init(dev, PCH_DP_C, PORT_C); |
8489 | | | 8493 | |
8490 | if (I915_READ(PCH_DP_D) & DP_DETECTED) | | 8494 | if (I915_READ(PCH_DP_D) & DP_DETECTED) |
8491 | intel_dp_init(dev, PCH_DP_D, PORT_D); | | 8495 | intel_dp_init(dev, PCH_DP_D, PORT_D); |
8492 | } else if (IS_VALLEYVIEW(dev)) { | | 8496 | } else if (IS_VALLEYVIEW(dev)) { |
8493 | int found; | | 8497 | int found; |
8494 | | | 8498 | |
8495 | /* Check for built-in panel first. Shares lanes with HDMI on SDVOC */ | | 8499 | /* Check for built-in panel first. Shares lanes with HDMI on SDVOC */ |
8496 | if (I915_READ(DP_C) & DP_DETECTED) | | 8500 | if (I915_READ(DP_C) & DP_DETECTED) |
8497 | intel_dp_init(dev, DP_C, PORT_C); | | 8501 | intel_dp_init(dev, DP_C, PORT_C); |
8498 | | | 8502 | |
8499 | if (I915_READ(SDVOB) & PORT_DETECTED) { | | 8503 | if (I915_READ(SDVOB) & PORT_DETECTED) { |
8500 | /* SDVOB multiplex with HDMIB */ | | 8504 | /* SDVOB multiplex with HDMIB */ |
8501 | found = intel_sdvo_init(dev, SDVOB, true); | | 8505 | found = intel_sdvo_init(dev, SDVOB, true); |
8502 | if (!found) | | 8506 | if (!found) |
8503 | intel_hdmi_init(dev, SDVOB, PORT_B); | | 8507 | intel_hdmi_init(dev, SDVOB, PORT_B); |
8504 | if (!found && (I915_READ(DP_B) & DP_DETECTED)) | | 8508 | if (!found && (I915_READ(DP_B) & DP_DETECTED)) |
8505 | intel_dp_init(dev, DP_B, PORT_B); | | 8509 | intel_dp_init(dev, DP_B, PORT_B); |
8506 | } | | 8510 | } |
8507 | | | 8511 | |
8508 | if (I915_READ(SDVOC) & PORT_DETECTED) | | 8512 | if (I915_READ(SDVOC) & PORT_DETECTED) |
8509 | intel_hdmi_init(dev, SDVOC, PORT_C); | | 8513 | intel_hdmi_init(dev, SDVOC, PORT_C); |
8510 | | | 8514 | |
8511 | } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { | | 8515 | } else if (SUPPORTS_DIGITAL_OUTPUTS(dev)) { |
8512 | bool found = false; | | 8516 | bool found = false; |
8513 | | | 8517 | |
8514 | if (I915_READ(SDVOB) & SDVO_DETECTED) { | | 8518 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
8515 | DRM_DEBUG_KMS("probing SDVOB\n"); | | 8519 | DRM_DEBUG_KMS("probing SDVOB\n"); |
8516 | found = intel_sdvo_init(dev, SDVOB, true); | | 8520 | found = intel_sdvo_init(dev, SDVOB, true); |
8517 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) { | | 8521 | if (!found && SUPPORTS_INTEGRATED_HDMI(dev)) { |
8518 | DRM_DEBUG_KMS("probing HDMI on SDVOB\n"); | | 8522 | DRM_DEBUG_KMS("probing HDMI on SDVOB\n"); |
8519 | intel_hdmi_init(dev, SDVOB, PORT_B); | | 8523 | intel_hdmi_init(dev, SDVOB, PORT_B); |
8520 | } | | 8524 | } |
8521 | | | 8525 | |
8522 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) { | | 8526 | if (!found && SUPPORTS_INTEGRATED_DP(dev)) { |
8523 | DRM_DEBUG_KMS("probing DP_B\n"); | | 8527 | DRM_DEBUG_KMS("probing DP_B\n"); |
8524 | intel_dp_init(dev, DP_B, PORT_B); | | 8528 | intel_dp_init(dev, DP_B, PORT_B); |
8525 | } | | 8529 | } |
8526 | } | | 8530 | } |
8527 | | | 8531 | |
8528 | /* Before G4X SDVOC doesn't have its own detect register */ | | 8532 | /* Before G4X SDVOC doesn't have its own detect register */ |
8529 | | | 8533 | |
8530 | if (I915_READ(SDVOB) & SDVO_DETECTED) { | | 8534 | if (I915_READ(SDVOB) & SDVO_DETECTED) { |
8531 | DRM_DEBUG_KMS("probing SDVOC\n"); | | 8535 | DRM_DEBUG_KMS("probing SDVOC\n"); |
8532 | found = intel_sdvo_init(dev, SDVOC, false); | | 8536 | found = intel_sdvo_init(dev, SDVOC, false); |
8533 | } | | 8537 | } |
8534 | | | 8538 | |
8535 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { | | 8539 | if (!found && (I915_READ(SDVOC) & SDVO_DETECTED)) { |
8536 | | | 8540 | |
8537 | if (SUPPORTS_INTEGRATED_HDMI(dev)) { | | 8541 | if (SUPPORTS_INTEGRATED_HDMI(dev)) { |
8538 | DRM_DEBUG_KMS("probing HDMI on SDVOC\n"); | | 8542 | DRM_DEBUG_KMS("probing HDMI on SDVOC\n"); |
8539 | intel_hdmi_init(dev, SDVOC, PORT_C); | | 8543 | intel_hdmi_init(dev, SDVOC, PORT_C); |
8540 | } | | 8544 | } |
8541 | if (SUPPORTS_INTEGRATED_DP(dev)) { | | 8545 | if (SUPPORTS_INTEGRATED_DP(dev)) { |
8542 | DRM_DEBUG_KMS("probing DP_C\n"); | | 8546 | DRM_DEBUG_KMS("probing DP_C\n"); |
8543 | intel_dp_init(dev, DP_C, PORT_C); | | 8547 | intel_dp_init(dev, DP_C, PORT_C); |
8544 | } | | 8548 | } |
8545 | } | | 8549 | } |
8546 | | | 8550 | |
8547 | if (SUPPORTS_INTEGRATED_DP(dev) && | | 8551 | if (SUPPORTS_INTEGRATED_DP(dev) && |
8548 | (I915_READ(DP_D) & DP_DETECTED)) { | | 8552 | (I915_READ(DP_D) & DP_DETECTED)) { |
8549 | DRM_DEBUG_KMS("probing DP_D\n"); | | 8553 | DRM_DEBUG_KMS("probing DP_D\n"); |
8550 | intel_dp_init(dev, DP_D, PORT_D); | | 8554 | intel_dp_init(dev, DP_D, PORT_D); |
8551 | } | | 8555 | } |
8552 | } else if (IS_GEN2(dev)) | | 8556 | } else if (IS_GEN2(dev)) |
8553 | intel_dvo_init(dev); | | 8557 | intel_dvo_init(dev); |
8554 | | | 8558 | |
8555 | if (SUPPORTS_TV(dev)) | | 8559 | if (SUPPORTS_TV(dev)) |
8556 | intel_tv_init(dev); | | 8560 | intel_tv_init(dev); |
8557 | | | 8561 | |
8558 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { | | 8562 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.head) { |
8559 | encoder->base.possible_crtcs = encoder->crtc_mask; | | 8563 | encoder->base.possible_crtcs = encoder->crtc_mask; |
8560 | encoder->base.possible_clones = | | 8564 | encoder->base.possible_clones = |
8561 | intel_encoder_clones(encoder); | | 8565 | intel_encoder_clones(encoder); |
8562 | } | | 8566 | } |
8563 | | | 8567 | |
8564 | intel_init_pch_refclk(dev); | | 8568 | intel_init_pch_refclk(dev); |
8565 | | | 8569 | |
8566 | drm_helper_move_panel_connectors_to_head(dev); | | 8570 | drm_helper_move_panel_connectors_to_head(dev); |
8567 | } | | 8571 | } |
8568 | | | 8572 | |
8569 | static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) | | 8573 | static void intel_user_framebuffer_destroy(struct drm_framebuffer *fb) |
8570 | { | | 8574 | { |
8571 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | | 8575 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
8572 | | | 8576 | |
8573 | drm_framebuffer_cleanup(fb); | | 8577 | drm_framebuffer_cleanup(fb); |
8574 | drm_gem_object_unreference_unlocked(&intel_fb->obj->base); | | 8578 | drm_gem_object_unreference_unlocked(&intel_fb->obj->base); |
8575 | | | 8579 | |
8576 | kfree(intel_fb); | | 8580 | kfree(intel_fb); |
8577 | } | | 8581 | } |
8578 | | | 8582 | |
8579 | static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, | | 8583 | static int intel_user_framebuffer_create_handle(struct drm_framebuffer *fb, |
8580 | struct drm_file *file, | | 8584 | struct drm_file *file, |
8581 | unsigned int *handle) | | 8585 | unsigned int *handle) |
8582 | { | | 8586 | { |
8583 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); | | 8587 | struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb); |
8584 | struct drm_i915_gem_object *obj = intel_fb->obj; | | 8588 | struct drm_i915_gem_object *obj = intel_fb->obj; |
8585 | | | 8589 | |
8586 | return drm_gem_handle_create(file, &obj->base, handle); | | 8590 | return drm_gem_handle_create(file, &obj->base, handle); |
8587 | } | | 8591 | } |
8588 | | | 8592 | |
8589 | static const struct drm_framebuffer_funcs intel_fb_funcs = { | | 8593 | static const struct drm_framebuffer_funcs intel_fb_funcs = { |
8590 | .destroy = intel_user_framebuffer_destroy, | | 8594 | .destroy = intel_user_framebuffer_destroy, |
8591 | .create_handle = intel_user_framebuffer_create_handle, | | 8595 | .create_handle = intel_user_framebuffer_create_handle, |
8592 | }; | | 8596 | }; |
8593 | | | 8597 | |
8594 | int intel_framebuffer_init(struct drm_device *dev, | | 8598 | int intel_framebuffer_init(struct drm_device *dev, |
8595 | struct intel_framebuffer *intel_fb, | | 8599 | struct intel_framebuffer *intel_fb, |
8596 | struct drm_mode_fb_cmd2 *mode_cmd, | | 8600 | struct drm_mode_fb_cmd2 *mode_cmd, |
8597 | struct drm_i915_gem_object *obj) | | 8601 | struct drm_i915_gem_object *obj) |
8598 | { | | 8602 | { |
8599 | int ret; | | 8603 | int ret; |
8600 | | | 8604 | |
8601 | if (obj->tiling_mode == I915_TILING_Y) { | | 8605 | if (obj->tiling_mode == I915_TILING_Y) { |
8602 | DRM_DEBUG("hardware does not support tiling Y\n"); | | 8606 | DRM_DEBUG("hardware does not support tiling Y\n"); |
8603 | return -EINVAL; | | 8607 | return -EINVAL; |
8604 | } | | 8608 | } |
8605 | | | 8609 | |
8606 | if (mode_cmd->pitches[0] & 63) { | | 8610 | if (mode_cmd->pitches[0] & 63) { |
8607 | DRM_DEBUG("pitch (%d) must be at least 64 byte aligned\n", | | 8611 | DRM_DEBUG("pitch (%d) must be at least 64 byte aligned\n", |
8608 | mode_cmd->pitches[0]); | | 8612 | mode_cmd->pitches[0]); |
8609 | return -EINVAL; | | 8613 | return -EINVAL; |
8610 | } | | 8614 | } |
8611 | | | 8615 | |
8612 | /* FIXME <= Gen4 stride limits are bit unclear */ | | 8616 | /* FIXME <= Gen4 stride limits are bit unclear */ |
8613 | if (mode_cmd->pitches[0] > 32768) { | | 8617 | if (mode_cmd->pitches[0] > 32768) { |
8614 | DRM_DEBUG("pitch (%d) must be at less than 32768\n", | | 8618 | DRM_DEBUG("pitch (%d) must be at less than 32768\n", |
8615 | mode_cmd->pitches[0]); | | 8619 | mode_cmd->pitches[0]); |
8616 | return -EINVAL; | | 8620 | return -EINVAL; |
8617 | } | | 8621 | } |
8618 | | | 8622 | |
8619 | if (obj->tiling_mode != I915_TILING_NONE && | | 8623 | if (obj->tiling_mode != I915_TILING_NONE && |
8620 | mode_cmd->pitches[0] != obj->stride) { | | 8624 | mode_cmd->pitches[0] != obj->stride) { |
8621 | DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n", | | 8625 | DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n", |
8622 | mode_cmd->pitches[0], obj->stride); | | 8626 | mode_cmd->pitches[0], obj->stride); |
8623 | return -EINVAL; | | 8627 | return -EINVAL; |
8624 | } | | 8628 | } |
8625 | | | 8629 | |
8626 | /* Reject formats not supported by any plane early. */ | | 8630 | /* Reject formats not supported by any plane early. */ |
8627 | switch (mode_cmd->pixel_format) { | | 8631 | switch (mode_cmd->pixel_format) { |
8628 | case DRM_FORMAT_C8: | | 8632 | case DRM_FORMAT_C8: |
8629 | case DRM_FORMAT_RGB565: | | 8633 | case DRM_FORMAT_RGB565: |
8630 | case DRM_FORMAT_XRGB8888: | | 8634 | case DRM_FORMAT_XRGB8888: |
8631 | case DRM_FORMAT_ARGB8888: | | 8635 | case DRM_FORMAT_ARGB8888: |
8632 | break; | | 8636 | break; |
8633 | case DRM_FORMAT_XRGB1555: | | 8637 | case DRM_FORMAT_XRGB1555: |
8634 | case DRM_FORMAT_ARGB1555: | | 8638 | case DRM_FORMAT_ARGB1555: |
8635 | if (INTEL_INFO(dev)->gen > 3) { | | 8639 | if (INTEL_INFO(dev)->gen > 3) { |
8636 | DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); | | 8640 | DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); |
8637 | return -EINVAL; | | 8641 | return -EINVAL; |
8638 | } | | 8642 | } |
8639 | break; | | 8643 | break; |
8640 | case DRM_FORMAT_XBGR8888: | | 8644 | case DRM_FORMAT_XBGR8888: |
8641 | case DRM_FORMAT_ABGR8888: | | 8645 | case DRM_FORMAT_ABGR8888: |
8642 | case DRM_FORMAT_XRGB2101010: | | 8646 | case DRM_FORMAT_XRGB2101010: |
8643 | case DRM_FORMAT_ARGB2101010: | | 8647 | case DRM_FORMAT_ARGB2101010: |
8644 | case DRM_FORMAT_XBGR2101010: | | 8648 | case DRM_FORMAT_XBGR2101010: |
8645 | case DRM_FORMAT_ABGR2101010: | | 8649 | case DRM_FORMAT_ABGR2101010: |
8646 | if (INTEL_INFO(dev)->gen < 4) { | | 8650 | if (INTEL_INFO(dev)->gen < 4) { |
8647 | DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); | | 8651 | DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); |
8648 | return -EINVAL; | | 8652 | return -EINVAL; |
8649 | } | | 8653 | } |
8650 | break; | | 8654 | break; |
8651 | case DRM_FORMAT_YUYV: | | 8655 | case DRM_FORMAT_YUYV: |
8652 | case DRM_FORMAT_UYVY: | | 8656 | case DRM_FORMAT_UYVY: |
8653 | case DRM_FORMAT_YVYU: | | 8657 | case DRM_FORMAT_YVYU: |
8654 | case DRM_FORMAT_VYUY: | | 8658 | case DRM_FORMAT_VYUY: |
8655 | if (INTEL_INFO(dev)->gen < 5) { | | 8659 | if (INTEL_INFO(dev)->gen < 5) { |
8656 | DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); | | 8660 | DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format); |
8657 | return -EINVAL; | | 8661 | return -EINVAL; |
8658 | } | | 8662 | } |
8659 | break; | | 8663 | break; |
8660 | default: | | 8664 | default: |
8661 | DRM_DEBUG("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format); | | 8665 | DRM_DEBUG("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format); |
8662 | return -EINVAL; | | 8666 | return -EINVAL; |
8663 | } | | 8667 | } |
8664 | | | 8668 | |
8665 | /* FIXME need to adjust LINOFF/TILEOFF accordingly. */ | | 8669 | /* FIXME need to adjust LINOFF/TILEOFF accordingly. */ |
8666 | if (mode_cmd->offsets[0] != 0) | | 8670 | if (mode_cmd->offsets[0] != 0) |
8667 | return -EINVAL; | | 8671 | return -EINVAL; |
8668 | | | 8672 | |
8669 | ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); | | 8673 | ret = drm_framebuffer_init(dev, &intel_fb->base, &intel_fb_funcs); |
8670 | if (ret) { | | 8674 | if (ret) { |
8671 | DRM_ERROR("framebuffer init failed %d\n", ret); | | 8675 | DRM_ERROR("framebuffer init failed %d\n", ret); |
8672 | return ret; | | 8676 | return ret; |
8673 | } | | 8677 | } |
8674 | | | 8678 | |
8675 | drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd); | | 8679 | drm_helper_mode_fill_fb_struct(&intel_fb->base, mode_cmd); |
8676 | intel_fb->obj = obj; | | 8680 | intel_fb->obj = obj; |
8677 | return 0; | | 8681 | return 0; |
8678 | } | | 8682 | } |
8679 | | | 8683 | |
8680 | static struct drm_framebuffer * | | 8684 | static struct drm_framebuffer * |
8681 | intel_user_framebuffer_create(struct drm_device *dev, | | 8685 | intel_user_framebuffer_create(struct drm_device *dev, |
8682 | struct drm_file *filp, | | 8686 | struct drm_file *filp, |
8683 | struct drm_mode_fb_cmd2 *mode_cmd) | | 8687 | struct drm_mode_fb_cmd2 *mode_cmd) |
8684 | { | | 8688 | { |
8685 | struct drm_i915_gem_object *obj; | | 8689 | struct drm_i915_gem_object *obj; |
8686 | | | 8690 | |
8687 | obj = to_intel_bo(drm_gem_object_lookup(dev, filp, | | 8691 | obj = to_intel_bo(drm_gem_object_lookup(dev, filp, |
8688 | mode_cmd->handles[0])); | | 8692 | mode_cmd->handles[0])); |
8689 | if (&obj->base == NULL) | | 8693 | if (&obj->base == NULL) |
8690 | return ERR_PTR(-ENOENT); | | 8694 | return ERR_PTR(-ENOENT); |
8691 | | | 8695 | |
8692 | return intel_framebuffer_create(dev, mode_cmd, obj); | | 8696 | return intel_framebuffer_create(dev, mode_cmd, obj); |
8693 | } | | 8697 | } |
8694 | | | 8698 | |
8695 | static const struct drm_mode_config_funcs intel_mode_funcs = { | | 8699 | static const struct drm_mode_config_funcs intel_mode_funcs = { |
8696 | .fb_create = intel_user_framebuffer_create, | | 8700 | .fb_create = intel_user_framebuffer_create, |
8697 | .output_poll_changed = intel_fb_output_poll_changed, | | 8701 | .output_poll_changed = intel_fb_output_poll_changed, |
8698 | }; | | 8702 | }; |
8699 | | | 8703 | |
8700 | /* Set up chip specific display functions */ | | 8704 | /* Set up chip specific display functions */ |
8701 | static void intel_init_display(struct drm_device *dev) | | 8705 | static void intel_init_display(struct drm_device *dev) |
8702 | { | | 8706 | { |
8703 | struct drm_i915_private *dev_priv = dev->dev_private; | | 8707 | struct drm_i915_private *dev_priv = dev->dev_private; |
8704 | | | 8708 | |
8705 | /* We always want a DPMS function */ | | 8709 | /* We always want a DPMS function */ |
8706 | if (IS_HASWELL(dev)) { | | 8710 | if (IS_HASWELL(dev)) { |
8707 | dev_priv->display.crtc_mode_set = haswell_crtc_mode_set; | | 8711 | dev_priv->display.crtc_mode_set = haswell_crtc_mode_set; |
8708 | dev_priv->display.crtc_enable = haswell_crtc_enable; | | 8712 | dev_priv->display.crtc_enable = haswell_crtc_enable; |
8709 | dev_priv->display.crtc_disable = haswell_crtc_disable; | | 8713 | dev_priv->display.crtc_disable = haswell_crtc_disable; |
8710 | dev_priv->display.off = haswell_crtc_off; | | 8714 | dev_priv->display.off = haswell_crtc_off; |
8711 | dev_priv->display.update_plane = ironlake_update_plane; | | 8715 | dev_priv->display.update_plane = ironlake_update_plane; |
8712 | } else if (HAS_PCH_SPLIT(dev)) { | | 8716 | } else if (HAS_PCH_SPLIT(dev)) { |
8713 | dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; | | 8717 | dev_priv->display.crtc_mode_set = ironlake_crtc_mode_set; |
8714 | dev_priv->display.crtc_enable = ironlake_crtc_enable; | | 8718 | dev_priv->display.crtc_enable = ironlake_crtc_enable; |
8715 | dev_priv->display.crtc_disable = ironlake_crtc_disable; | | 8719 | dev_priv->display.crtc_disable = ironlake_crtc_disable; |
8716 | dev_priv->display.off = ironlake_crtc_off; | | 8720 | dev_priv->display.off = ironlake_crtc_off; |
8717 | dev_priv->display.update_plane = ironlake_update_plane; | | 8721 | dev_priv->display.update_plane = ironlake_update_plane; |
8718 | } else { | | 8722 | } else { |
8719 | dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; | | 8723 | dev_priv->display.crtc_mode_set = i9xx_crtc_mode_set; |
8720 | dev_priv->display.crtc_enable = i9xx_crtc_enable; | | 8724 | dev_priv->display.crtc_enable = i9xx_crtc_enable; |
8721 | dev_priv->display.crtc_disable = i9xx_crtc_disable; | | 8725 | dev_priv->display.crtc_disable = i9xx_crtc_disable; |
8722 | dev_priv->display.off = i9xx_crtc_off; | | 8726 | dev_priv->display.off = i9xx_crtc_off; |
8723 | dev_priv->display.update_plane = i9xx_update_plane; | | 8727 | dev_priv->display.update_plane = i9xx_update_plane; |
8724 | } | | 8728 | } |
8725 | | | 8729 | |
8726 | /* Returns the core display clock speed */ | | 8730 | /* Returns the core display clock speed */ |
8727 | if (IS_VALLEYVIEW(dev)) | | 8731 | if (IS_VALLEYVIEW(dev)) |
8728 | dev_priv->display.get_display_clock_speed = | | 8732 | dev_priv->display.get_display_clock_speed = |
8729 | valleyview_get_display_clock_speed; | | 8733 | valleyview_get_display_clock_speed; |
8730 | else if (IS_I945G(dev) || (IS_G33(dev) && !IS_PINEVIEW_M(dev))) | | 8734 | else if (IS_I945G(dev) || (IS_G33(dev) && !IS_PINEVIEW_M(dev))) |
8731 | dev_priv->display.get_display_clock_speed = | | 8735 | dev_priv->display.get_display_clock_speed = |
8732 | i945_get_display_clock_speed; | | 8736 | i945_get_display_clock_speed; |
8733 | else if (IS_I915G(dev)) | | 8737 | else if (IS_I915G(dev)) |
8734 | dev_priv->display.get_display_clock_speed = | | 8738 | dev_priv->display.get_display_clock_speed = |
8735 | i915_get_display_clock_speed; | | 8739 | i915_get_display_clock_speed; |
8736 | else if (IS_I945GM(dev) || IS_845G(dev) || IS_PINEVIEW_M(dev)) | | 8740 | else if (IS_I945GM(dev) || IS_845G(dev) || IS_PINEVIEW_M(dev)) |
8737 | dev_priv->display.get_display_clock_speed = | | 8741 | dev_priv->display.get_display_clock_speed = |
8738 | i9xx_misc_get_display_clock_speed; | | 8742 | i9xx_misc_get_display_clock_speed; |
8739 | else if (IS_I915GM(dev)) | | 8743 | else if (IS_I915GM(dev)) |
8740 | dev_priv->display.get_display_clock_speed = | | 8744 | dev_priv->display.get_display_clock_speed = |
8741 | i915gm_get_display_clock_speed; | | 8745 | i915gm_get_display_clock_speed; |
8742 | else if (IS_I865G(dev)) | | 8746 | else if (IS_I865G(dev)) |
8743 | dev_priv->display.get_display_clock_speed = | | 8747 | dev_priv->display.get_display_clock_speed = |
8744 | i865_get_display_clock_speed; | | 8748 | i865_get_display_clock_speed; |
8745 | else if (IS_I85X(dev)) | | 8749 | else if (IS_I85X(dev)) |
8746 | dev_priv->display.get_display_clock_speed = | | 8750 | dev_priv->display.get_display_clock_speed = |
8747 | i855_get_display_clock_speed; | | 8751 | i855_get_display_clock_speed; |
8748 | else /* 852, 830 */ | | 8752 | else /* 852, 830 */ |
8749 | dev_priv->display.get_display_clock_speed = | | 8753 | dev_priv->display.get_display_clock_speed = |
8750 | i830_get_display_clock_speed; | | 8754 | i830_get_display_clock_speed; |
8751 | | | 8755 | |
8752 | if (HAS_PCH_SPLIT(dev)) { | | 8756 | if (HAS_PCH_SPLIT(dev)) { |
8753 | if (IS_GEN5(dev)) { | | 8757 | if (IS_GEN5(dev)) { |
8754 | dev_priv->display.fdi_link_train = ironlake_fdi_link_train; | | 8758 | dev_priv->display.fdi_link_train = ironlake_fdi_link_train; |
8755 | dev_priv->display.write_eld = ironlake_write_eld; | | 8759 | dev_priv->display.write_eld = ironlake_write_eld; |
8756 | } else if (IS_GEN6(dev)) { | | 8760 | } else if (IS_GEN6(dev)) { |
8757 | dev_priv->display.fdi_link_train = gen6_fdi_link_train; | | 8761 | dev_priv->display.fdi_link_train = gen6_fdi_link_train; |
8758 | dev_priv->display.write_eld = ironlake_write_eld; | | 8762 | dev_priv->display.write_eld = ironlake_write_eld; |
8759 | } else if (IS_IVYBRIDGE(dev)) { | | 8763 | } else if (IS_IVYBRIDGE(dev)) { |
8760 | /* FIXME: detect B0+ stepping and use auto training */ | | 8764 | /* FIXME: detect B0+ stepping and use auto training */ |
8761 | dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; | | 8765 | dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train; |
8762 | dev_priv->display.write_eld = ironlake_write_eld; | | 8766 | dev_priv->display.write_eld = ironlake_write_eld; |
8763 | dev_priv->display.modeset_global_resources = | | 8767 | dev_priv->display.modeset_global_resources = |
8764 | ivb_modeset_global_resources; | | 8768 | ivb_modeset_global_resources; |
8765 | } else if (IS_HASWELL(dev)) { | | 8769 | } else if (IS_HASWELL(dev)) { |
8766 | dev_priv->display.fdi_link_train = hsw_fdi_link_train; | | 8770 | dev_priv->display.fdi_link_train = hsw_fdi_link_train; |
8767 | dev_priv->display.write_eld = haswell_write_eld; | | 8771 | dev_priv->display.write_eld = haswell_write_eld; |
8768 | } else | | 8772 | } else |
8769 | dev_priv->display.update_wm = NULL; | | 8773 | dev_priv->display.update_wm = NULL; |
8770 | } else if (IS_G4X(dev)) { | | 8774 | } else if (IS_G4X(dev)) { |
8771 | dev_priv->display.write_eld = g4x_write_eld; | | 8775 | dev_priv->display.write_eld = g4x_write_eld; |
8772 | } | | 8776 | } |
8773 | | | 8777 | |
8774 | /* Default just returns -ENODEV to indicate unsupported */ | | 8778 | /* Default just returns -ENODEV to indicate unsupported */ |
8775 | dev_priv->display.queue_flip = intel_default_queue_flip; | | 8779 | dev_priv->display.queue_flip = intel_default_queue_flip; |
8776 | | | 8780 | |
8777 | switch (INTEL_INFO(dev)->gen) { | | 8781 | switch (INTEL_INFO(dev)->gen) { |
8778 | case 2: | | 8782 | case 2: |
8779 | dev_priv->display.queue_flip = intel_gen2_queue_flip; | | 8783 | dev_priv->display.queue_flip = intel_gen2_queue_flip; |
8780 | break; | | 8784 | break; |
8781 | | | 8785 | |
8782 | case 3: | | 8786 | case 3: |
8783 | dev_priv->display.queue_flip = intel_gen3_queue_flip; | | 8787 | dev_priv->display.queue_flip = intel_gen3_queue_flip; |
8784 | break; | | 8788 | break; |
8785 | | | 8789 | |
8786 | case 4: | | 8790 | case 4: |
8787 | case 5: | | 8791 | case 5: |
8788 | dev_priv->display.queue_flip = intel_gen4_queue_flip; | | 8792 | dev_priv->display.queue_flip = intel_gen4_queue_flip; |
8789 | break; | | 8793 | break; |
8790 | | | 8794 | |
8791 | case 6: | | 8795 | case 6: |
8792 | dev_priv->display.queue_flip = intel_gen6_queue_flip; | | 8796 | dev_priv->display.queue_flip = intel_gen6_queue_flip; |
8793 | break; | | 8797 | break; |
8794 | case 7: | | 8798 | case 7: |
8795 | dev_priv->display.queue_flip = intel_gen7_queue_flip; | | 8799 | dev_priv->display.queue_flip = intel_gen7_queue_flip; |
8796 | break; | | 8800 | break; |
8797 | } | | 8801 | } |
8798 | } | | 8802 | } |
8799 | | | 8803 | |
| | | 8804 | #ifndef __NetBSD__ /* XXX dmi hack */ |
8800 | /* | | 8805 | /* |
8801 | * Some BIOSes insist on assuming the GPU's pipe A is enabled at suspend, | | 8806 | * Some BIOSes insist on assuming the GPU's pipe A is enabled at suspend, |
8802 | * resume, or other times. This quirk makes sure that's the case for | | 8807 | * resume, or other times. This quirk makes sure that's the case for |
8803 | * affected systems. | | 8808 | * affected systems. |
8804 | */ | | 8809 | */ |
8805 | static void quirk_pipea_force(struct drm_device *dev) | | 8810 | static void quirk_pipea_force(struct drm_device *dev) |
8806 | { | | 8811 | { |
8807 | struct drm_i915_private *dev_priv = dev->dev_private; | | 8812 | struct drm_i915_private *dev_priv = dev->dev_private; |
8808 | | | 8813 | |
8809 | dev_priv->quirks |= QUIRK_PIPEA_FORCE; | | 8814 | dev_priv->quirks |= QUIRK_PIPEA_FORCE; |
8810 | DRM_INFO("applying pipe a force quirk\n"); | | 8815 | DRM_INFO("applying pipe a force quirk\n"); |
8811 | } | | 8816 | } |
8812 | | | 8817 | |
8813 | /* | | 8818 | /* |
8814 | * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason | | 8819 | * Some machines (Lenovo U160) do not work with SSC on LVDS for some reason |
8815 | */ | | 8820 | */ |
8816 | static void quirk_ssc_force_disable(struct drm_device *dev) | | 8821 | static void quirk_ssc_force_disable(struct drm_device *dev) |
8817 | { | | 8822 | { |
8818 | struct drm_i915_private *dev_priv = dev->dev_private; | | 8823 | struct drm_i915_private *dev_priv = dev->dev_private; |
8819 | dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE; | | 8824 | dev_priv->quirks |= QUIRK_LVDS_SSC_DISABLE; |
8820 | DRM_INFO("applying lvds SSC disable quirk\n"); | | 8825 | DRM_INFO("applying lvds SSC disable quirk\n"); |
8821 | } | | 8826 | } |
8822 | | | 8827 | |
8823 | /* | | 8828 | /* |
8824 | * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight | | 8829 | * A machine (e.g. Acer Aspire 5734Z) may need to invert the panel backlight |
8825 | * brightness value | | 8830 | * brightness value |
8826 | */ | | 8831 | */ |
8827 | static void quirk_invert_brightness(struct drm_device *dev) | | 8832 | static void quirk_invert_brightness(struct drm_device *dev) |
8828 | { | | 8833 | { |
8829 | struct drm_i915_private *dev_priv = dev->dev_private; | | 8834 | struct drm_i915_private *dev_priv = dev->dev_private; |
8830 | dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS; | | 8835 | dev_priv->quirks |= QUIRK_INVERT_BRIGHTNESS; |
8831 | DRM_INFO("applying inverted panel brightness quirk\n"); | | 8836 | DRM_INFO("applying inverted panel brightness quirk\n"); |
8832 | } | | 8837 | } |
8833 | | | 8838 | |
8834 | struct intel_quirk { | | 8839 | struct intel_quirk { |
8835 | int device; | | 8840 | int device; |
8836 | int subsystem_vendor; | | 8841 | int subsystem_vendor; |
8837 | int subsystem_device; | | 8842 | int subsystem_device; |
8838 | void (*hook)(struct drm_device *dev); | | 8843 | void (*hook)(struct drm_device *dev); |
8839 | }; | | 8844 | }; |
8840 | | | 8845 | |
8841 | /* For systems that don't have a meaningful PCI subdevice/subvendor ID */ | | 8846 | /* For systems that don't have a meaningful PCI subdevice/subvendor ID */ |
8842 | struct intel_dmi_quirk { | | 8847 | struct intel_dmi_quirk { |
8843 | void (*hook)(struct drm_device *dev); | | 8848 | void (*hook)(struct drm_device *dev); |
8844 | const struct dmi_system_id (*dmi_id_list)[]; | | 8849 | const struct dmi_system_id (*dmi_id_list)[]; |
8845 | }; | | 8850 | }; |
8846 | | | 8851 | |
8847 | static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) | | 8852 | static int intel_dmi_reverse_brightness(const struct dmi_system_id *id) |
8848 | { | | 8853 | { |
8849 | DRM_INFO("Backlight polarity reversed on %s\n", id->ident); | | 8854 | DRM_INFO("Backlight polarity reversed on %s\n", id->ident); |
8850 | return 1; | | 8855 | return 1; |
8851 | } | | 8856 | } |
8852 | | | 8857 | |
8853 | static const struct intel_dmi_quirk intel_dmi_quirks[] = { | | 8858 | static const struct intel_dmi_quirk intel_dmi_quirks[] = { |
8854 | { | | 8859 | { |
8855 | .dmi_id_list = &(const struct dmi_system_id[]) { | | 8860 | .dmi_id_list = &(const struct dmi_system_id[]) { |
8856 | { | | 8861 | { |
8857 | .callback = intel_dmi_reverse_brightness, | | 8862 | .callback = intel_dmi_reverse_brightness, |
8858 | .ident = "NCR Corporation", | | 8863 | .ident = "NCR Corporation", |
8859 | .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), | | 8864 | .matches = {DMI_MATCH(DMI_SYS_VENDOR, "NCR Corporation"), |
8860 | DMI_MATCH(DMI_PRODUCT_NAME, ""), | | 8865 | DMI_MATCH(DMI_PRODUCT_NAME, ""), |
8861 | }, | | 8866 | }, |
8862 | }, | | 8867 | }, |
8863 | { } /* terminating entry */ | | 8868 | { } /* terminating entry */ |
8864 | }, | | 8869 | }, |
8865 | .hook = quirk_invert_brightness, | | 8870 | .hook = quirk_invert_brightness, |
8866 | }, | | 8871 | }, |
8867 | }; | | 8872 | }; |
8868 | | | 8873 | |
8869 | static struct intel_quirk intel_quirks[] = { | | 8874 | static struct intel_quirk intel_quirks[] = { |
8870 | /* HP Mini needs pipe A force quirk (LP: #322104) */ | | 8875 | /* HP Mini needs pipe A force quirk (LP: #322104) */ |
8871 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, | | 8876 | { 0x27ae, 0x103c, 0x361a, quirk_pipea_force }, |
8872 | | | 8877 | |
8873 | /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ | | 8878 | /* Toshiba Protege R-205, S-209 needs pipe A force quirk */ |
8874 | { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, | | 8879 | { 0x2592, 0x1179, 0x0001, quirk_pipea_force }, |
8875 | | | 8880 | |
8876 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ | | 8881 | /* ThinkPad T60 needs pipe A force quirk (bug #16494) */ |
8877 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, | | 8882 | { 0x2782, 0x17aa, 0x201a, quirk_pipea_force }, |
8878 | | | 8883 | |
8879 | /* 830/845 need to leave pipe A & dpll A up */ | | 8884 | /* 830/845 need to leave pipe A & dpll A up */ |
8880 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | | 8885 | { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
8881 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, | | 8886 | { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force }, |
8882 | | | 8887 | |
8883 | /* Lenovo U160 cannot use SSC on LVDS */ | | 8888 | /* Lenovo U160 cannot use SSC on LVDS */ |
8884 | { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, | | 8889 | { 0x0046, 0x17aa, 0x3920, quirk_ssc_force_disable }, |
8885 | | | 8890 | |
8886 | /* Sony Vaio Y cannot use SSC on LVDS */ | | 8891 | /* Sony Vaio Y cannot use SSC on LVDS */ |
8887 | { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, | | 8892 | { 0x0046, 0x104d, 0x9076, quirk_ssc_force_disable }, |
8888 | | | 8893 | |
8889 | /* Acer Aspire 5734Z must invert backlight brightness */ | | 8894 | /* Acer Aspire 5734Z must invert backlight brightness */ |
8890 | { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness }, | | 8895 | { 0x2a42, 0x1025, 0x0459, quirk_invert_brightness }, |
8891 | }; | | 8896 | }; |
8892 | | | 8897 | |
8893 | static void intel_init_quirks(struct drm_device *dev) | | 8898 | static void intel_init_quirks(struct drm_device *dev) |
8894 | { | | 8899 | { |
8895 | struct pci_dev *d = dev->pdev; | | 8900 | struct pci_dev *d = dev->pdev; |
8896 | int i; | | 8901 | int i; |
8897 | | | 8902 | |
8898 | for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) { | | 8903 | for (i = 0; i < ARRAY_SIZE(intel_quirks); i++) { |
8899 | struct intel_quirk *q = &intel_quirks[i]; | | 8904 | struct intel_quirk *q = &intel_quirks[i]; |
8900 | | | 8905 | |
8901 | if (d->device == q->device && | | 8906 | if (d->device == q->device && |
8902 | (d->subsystem_vendor == q->subsystem_vendor || | | 8907 | (d->subsystem_vendor == q->subsystem_vendor || |
8903 | q->subsystem_vendor == PCI_ANY_ID) && | | 8908 | q->subsystem_vendor == PCI_ANY_ID) && |
8904 | (d->subsystem_device == q->subsystem_device || | | 8909 | (d->subsystem_device == q->subsystem_device || |
8905 | q->subsystem_device == PCI_ANY_ID)) | | 8910 | q->subsystem_device == PCI_ANY_ID)) |
8906 | q->hook(dev); | | 8911 | q->hook(dev); |
8907 | } | | 8912 | } |
8908 | for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { | | 8913 | for (i = 0; i < ARRAY_SIZE(intel_dmi_quirks); i++) { |
8909 | if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) | | 8914 | if (dmi_check_system(*intel_dmi_quirks[i].dmi_id_list) != 0) |
8910 | intel_dmi_quirks[i].hook(dev); | | 8915 | intel_dmi_quirks[i].hook(dev); |
8911 | } | | 8916 | } |
8912 | } | | 8917 | } |
| | | 8918 | #endif |
8913 | | | 8919 | |
8914 | /* Disable the VGA plane that we never use */ | | 8920 | /* Disable the VGA plane that we never use */ |
8915 | static void i915_disable_vga(struct drm_device *dev) | | 8921 | static void i915_disable_vga(struct drm_device *dev) |
8916 | { | | 8922 | { |
8917 | struct drm_i915_private *dev_priv = dev->dev_private; | | 8923 | struct drm_i915_private *dev_priv = dev->dev_private; |
8918 | u8 sr1; | | 8924 | u8 sr1; |
8919 | u32 vga_reg; | | 8925 | u32 vga_reg; |
8920 | | | 8926 | |
8921 | if (HAS_PCH_SPLIT(dev)) | | 8927 | if (HAS_PCH_SPLIT(dev)) |
8922 | vga_reg = CPU_VGACNTRL; | | 8928 | vga_reg = CPU_VGACNTRL; |
8923 | else | | 8929 | else |
8924 | vga_reg = VGACNTRL; | | 8930 | vga_reg = VGACNTRL; |
8925 | | | 8931 | |
8926 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); | | 8932 | vga_get_uninterruptible(dev->pdev, VGA_RSRC_LEGACY_IO); |
8927 | outb(SR01, VGA_SR_INDEX); | | 8933 | outb(SR01, VGA_SR_INDEX); |
8928 | sr1 = inb(VGA_SR_DATA); | | 8934 | sr1 = inb(VGA_SR_DATA); |
8929 | outb(sr1 | 1<<5, VGA_SR_DATA); | | 8935 | outb(sr1 | 1<<5, VGA_SR_DATA); |
8930 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | | 8936 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); |
8931 | udelay(300); | | 8937 | udelay(300); |
8932 | | | 8938 | |
8933 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | | 8939 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); |
8934 | POSTING_READ(vga_reg); | | 8940 | POSTING_READ(vga_reg); |
8935 | } | | 8941 | } |
8936 | | | 8942 | |
8937 | void intel_modeset_init_hw(struct drm_device *dev) | | 8943 | void intel_modeset_init_hw(struct drm_device *dev) |
8938 | { | | 8944 | { |
8939 | /* We attempt to init the necessary power wells early in the initialization | | 8945 | /* We attempt to init the necessary power wells early in the initialization |
8940 | * time, so the subsystems that expect power to be enabled can work. | | 8946 | * time, so the subsystems that expect power to be enabled can work. |
8941 | */ | | 8947 | */ |
8942 | intel_init_power_wells(dev); | | 8948 | intel_init_power_wells(dev); |
8943 | | | 8949 | |
8944 | intel_prepare_ddi(dev); | | 8950 | intel_prepare_ddi(dev); |
8945 | | | 8951 | |
8946 | intel_init_clock_gating(dev); | | 8952 | intel_init_clock_gating(dev); |
8947 | | | 8953 | |
8948 | mutex_lock(&dev->struct_mutex); | | 8954 | mutex_lock(&dev->struct_mutex); |
8949 | intel_enable_gt_powersave(dev); | | 8955 | intel_enable_gt_powersave(dev); |
8950 | mutex_unlock(&dev->struct_mutex); | | 8956 | mutex_unlock(&dev->struct_mutex); |
8951 | } | | 8957 | } |
8952 | | | 8958 | |
8953 | void intel_modeset_init(struct drm_device *dev) | | 8959 | void intel_modeset_init(struct drm_device *dev) |
8954 | { | | 8960 | { |
8955 | struct drm_i915_private *dev_priv = dev->dev_private; | | 8961 | struct drm_i915_private *dev_priv = dev->dev_private; |
8956 | int i, ret; | | 8962 | int i, ret; |
8957 | | | 8963 | |
8958 | drm_mode_config_init(dev); | | 8964 | drm_mode_config_init(dev); |
8959 | | | 8965 | |
8960 | dev->mode_config.min_width = 0; | | 8966 | dev->mode_config.min_width = 0; |
8961 | dev->mode_config.min_height = 0; | | 8967 | dev->mode_config.min_height = 0; |
8962 | | | 8968 | |
8963 | dev->mode_config.preferred_depth = 24; | | 8969 | dev->mode_config.preferred_depth = 24; |
8964 | dev->mode_config.prefer_shadow = 1; | | 8970 | dev->mode_config.prefer_shadow = 1; |
8965 | | | 8971 | |
8966 | dev->mode_config.funcs = &intel_mode_funcs; | | 8972 | dev->mode_config.funcs = &intel_mode_funcs; |
8967 | | | 8973 | |
| | | 8974 | #ifndef __NetBSD__ /* XXX dmi hack */ |
8968 | intel_init_quirks(dev); | | 8975 | intel_init_quirks(dev); |
| | | 8976 | #endif |
8969 | | | 8977 | |
8970 | intel_init_pm(dev); | | 8978 | intel_init_pm(dev); |
8971 | | | 8979 | |
8972 | intel_init_display(dev); | | 8980 | intel_init_display(dev); |
8973 | | | 8981 | |
8974 | if (IS_GEN2(dev)) { | | 8982 | if (IS_GEN2(dev)) { |
8975 | dev->mode_config.max_width = 2048; | | 8983 | dev->mode_config.max_width = 2048; |
8976 | dev->mode_config.max_height = 2048; | | 8984 | dev->mode_config.max_height = 2048; |
8977 | } else if (IS_GEN3(dev)) { | | 8985 | } else if (IS_GEN3(dev)) { |
8978 | dev->mode_config.max_width = 4096; | | 8986 | dev->mode_config.max_width = 4096; |
8979 | dev->mode_config.max_height = 4096; | | 8987 | dev->mode_config.max_height = 4096; |
8980 | } else { | | 8988 | } else { |
8981 | dev->mode_config.max_width = 8192; | | 8989 | dev->mode_config.max_width = 8192; |
8982 | dev->mode_config.max_height = 8192; | | 8990 | dev->mode_config.max_height = 8192; |
8983 | } | | 8991 | } |
8984 | dev->mode_config.fb_base = dev_priv->mm.gtt_base_addr; | | 8992 | dev->mode_config.fb_base = dev_priv->mm.gtt_base_addr; |
8985 | | | 8993 | |
8986 | DRM_DEBUG_KMS("%d display pipe%s available.\n", | | 8994 | DRM_DEBUG_KMS("%d display pipe%s available.\n", |
8987 | dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); | | 8995 | dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : ""); |
8988 | | | 8996 | |
8989 | for (i = 0; i < dev_priv->num_pipe; i++) { | | 8997 | for (i = 0; i < dev_priv->num_pipe; i++) { |
8990 | intel_crtc_init(dev, i); | | 8998 | intel_crtc_init(dev, i); |
8991 | ret = intel_plane_init(dev, i); | | 8999 | ret = intel_plane_init(dev, i); |
8992 | if (ret) | | 9000 | if (ret) |
8993 | DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); | | 9001 | DRM_DEBUG_KMS("plane %d init failed: %d\n", i, ret); |
8994 | } | | 9002 | } |
8995 | | | 9003 | |
8996 | intel_cpu_pll_init(dev); | | 9004 | intel_cpu_pll_init(dev); |
8997 | intel_pch_pll_init(dev); | | 9005 | intel_pch_pll_init(dev); |
8998 | | | 9006 | |
8999 | /* Just disable it once at startup */ | | 9007 | /* Just disable it once at startup */ |
9000 | i915_disable_vga(dev); | | 9008 | i915_disable_vga(dev); |
9001 | intel_setup_outputs(dev); | | 9009 | intel_setup_outputs(dev); |
9002 | } | | 9010 | } |
9003 | | | 9011 | |
9004 | static void | | 9012 | static void |
9005 | intel_connector_break_all_links(struct intel_connector *connector) | | 9013 | intel_connector_break_all_links(struct intel_connector *connector) |
9006 | { | | 9014 | { |
9007 | connector->base.dpms = DRM_MODE_DPMS_OFF; | | 9015 | connector->base.dpms = DRM_MODE_DPMS_OFF; |
9008 | connector->base.encoder = NULL; | | 9016 | connector->base.encoder = NULL; |
9009 | connector->encoder->connectors_active = false; | | 9017 | connector->encoder->connectors_active = false; |
9010 | connector->encoder->base.crtc = NULL; | | 9018 | connector->encoder->base.crtc = NULL; |
9011 | } | | 9019 | } |
9012 | | | 9020 | |
9013 | static void intel_enable_pipe_a(struct drm_device *dev) | | 9021 | static void intel_enable_pipe_a(struct drm_device *dev) |
9014 | { | | 9022 | { |
9015 | struct intel_connector *connector; | | 9023 | struct intel_connector *connector; |
9016 | struct drm_connector *crt = NULL; | | 9024 | struct drm_connector *crt = NULL; |
9017 | struct intel_load_detect_pipe load_detect_temp; | | 9025 | struct intel_load_detect_pipe load_detect_temp; |
9018 | | | 9026 | |
9019 | /* We can't just switch on the pipe A, we need to set things up with a | | 9027 | /* We can't just switch on the pipe A, we need to set things up with a |
9020 | * proper mode and output configuration. As a gross hack, enable pipe A | | 9028 | * proper mode and output configuration. As a gross hack, enable pipe A |
9021 | * by enabling the load detect pipe once. */ | | 9029 | * by enabling the load detect pipe once. */ |
9022 | list_for_each_entry(connector, | | 9030 | list_for_each_entry(connector, |
9023 | &dev->mode_config.connector_list, | | 9031 | &dev->mode_config.connector_list, |
9024 | base.head) { | | 9032 | base.head) { |
9025 | if (connector->encoder->type == INTEL_OUTPUT_ANALOG) { | | 9033 | if (connector->encoder->type == INTEL_OUTPUT_ANALOG) { |
9026 | crt = &connector->base; | | 9034 | crt = &connector->base; |
9027 | break; | | 9035 | break; |
9028 | } | | 9036 | } |
9029 | } | | 9037 | } |
9030 | | | 9038 | |
9031 | if (!crt) | | 9039 | if (!crt) |
9032 | return; | | 9040 | return; |
9033 | | | 9041 | |
9034 | if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp)) | | 9042 | if (intel_get_load_detect_pipe(crt, NULL, &load_detect_temp)) |
9035 | intel_release_load_detect_pipe(crt, &load_detect_temp); | | 9043 | intel_release_load_detect_pipe(crt, &load_detect_temp); |
9036 | | | 9044 | |
9037 | | | 9045 | |
9038 | } | | 9046 | } |
9039 | | | 9047 | |
9040 | static bool | | 9048 | static bool |
9041 | intel_check_plane_mapping(struct intel_crtc *crtc) | | 9049 | intel_check_plane_mapping(struct intel_crtc *crtc) |
9042 | { | | 9050 | { |
9043 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; | | 9051 | struct drm_i915_private *dev_priv = crtc->base.dev->dev_private; |
9044 | u32 reg, val; | | 9052 | u32 reg, val; |
9045 | | | 9053 | |
9046 | if (dev_priv->num_pipe == 1) | | 9054 | if (dev_priv->num_pipe == 1) |
9047 | return true; | | 9055 | return true; |
9048 | | | 9056 | |
9049 | reg = DSPCNTR(!crtc->plane); | | 9057 | reg = DSPCNTR(!crtc->plane); |
9050 | val = I915_READ(reg); | | 9058 | val = I915_READ(reg); |
9051 | | | 9059 | |
9052 | if ((val & DISPLAY_PLANE_ENABLE) && | | 9060 | if ((val & DISPLAY_PLANE_ENABLE) && |
9053 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) | | 9061 | (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe)) |
9054 | return false; | | 9062 | return false; |
9055 | | | 9063 | |
9056 | return true; | | 9064 | return true; |
9057 | } | | 9065 | } |
9058 | | | 9066 | |
9059 | static void intel_sanitize_crtc(struct intel_crtc *crtc) | | 9067 | static void intel_sanitize_crtc(struct intel_crtc *crtc) |
9060 | { | | 9068 | { |
9061 | struct drm_device *dev = crtc->base.dev; | | 9069 | struct drm_device *dev = crtc->base.dev; |
9062 | struct drm_i915_private *dev_priv = dev->dev_private; | | 9070 | struct drm_i915_private *dev_priv = dev->dev_private; |
9063 | u32 reg; | | 9071 | u32 reg; |
9064 | | | 9072 | |
9065 | /* Clear any frame start delays used for debugging left by the BIOS */ | | 9073 | /* Clear any frame start delays used for debugging left by the BIOS */ |
9066 | reg = PIPECONF(crtc->cpu_transcoder); | | 9074 | reg = PIPECONF(crtc->cpu_transcoder); |
9067 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); | | 9075 | I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK); |
9068 | | | 9076 | |
9069 | /* We need to sanitize the plane -> pipe mapping first because this will | | 9077 | /* We need to sanitize the plane -> pipe mapping first because this will |
9070 | * disable the crtc (and hence change the state) if it is wrong. Note | | 9078 | * disable the crtc (and hence change the state) if it is wrong. Note |
9071 | * that gen4+ has a fixed plane -> pipe mapping. */ | | 9079 | * that gen4+ has a fixed plane -> pipe mapping. */ |
9072 | if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) { | | 9080 | if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) { |
9073 | struct intel_connector *connector; | | 9081 | struct intel_connector *connector; |
9074 | bool plane; | | 9082 | bool plane; |
9075 | | | 9083 | |
9076 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", | | 9084 | DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n", |
9077 | crtc->base.base.id); | | 9085 | crtc->base.base.id); |
9078 | | | 9086 | |
9079 | /* Pipe has the wrong plane attached and the plane is active. | | 9087 | /* Pipe has the wrong plane attached and the plane is active. |
9080 | * Temporarily change the plane mapping and disable everything | | 9088 | * Temporarily change the plane mapping and disable everything |
9081 | * ... */ | | 9089 | * ... */ |
9082 | plane = crtc->plane; | | 9090 | plane = crtc->plane; |
9083 | crtc->plane = !plane; | | 9091 | crtc->plane = !plane; |
9084 | dev_priv->display.crtc_disable(&crtc->base); | | 9092 | dev_priv->display.crtc_disable(&crtc->base); |
9085 | crtc->plane = plane; | | 9093 | crtc->plane = plane; |
9086 | | | 9094 | |
9087 | /* ... and break all links. */ | | 9095 | /* ... and break all links. */ |
9088 | list_for_each_entry(connector, &dev->mode_config.connector_list, | | 9096 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
9089 | base.head) { | | 9097 | base.head) { |
9090 | if (connector->encoder->base.crtc != &crtc->base) | | 9098 | if (connector->encoder->base.crtc != &crtc->base) |
9091 | continue; | | 9099 | continue; |
9092 | | | 9100 | |
9093 | intel_connector_break_all_links(connector); | | 9101 | intel_connector_break_all_links(connector); |
9094 | } | | 9102 | } |
9095 | | | 9103 | |
9096 | WARN_ON(crtc->active); | | 9104 | WARN_ON(crtc->active); |
9097 | crtc->base.enabled = false; | | 9105 | crtc->base.enabled = false; |
9098 | } | | 9106 | } |
9099 | | | 9107 | |
9100 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && | | 9108 | if (dev_priv->quirks & QUIRK_PIPEA_FORCE && |
9101 | crtc->pipe == PIPE_A && !crtc->active) { | | 9109 | crtc->pipe == PIPE_A && !crtc->active) { |
9102 | /* BIOS forgot to enable pipe A, this mostly happens after | | 9110 | /* BIOS forgot to enable pipe A, this mostly happens after |
9103 | * resume. Force-enable the pipe to fix this, the update_dpms | | 9111 | * resume. Force-enable the pipe to fix this, the update_dpms |
9104 | * call below we restore the pipe to the right state, but leave | | 9112 | * call below we restore the pipe to the right state, but leave |
9105 | * the required bits on. */ | | 9113 | * the required bits on. */ |
9106 | intel_enable_pipe_a(dev); | | 9114 | intel_enable_pipe_a(dev); |
9107 | } | | 9115 | } |
9108 | | | 9116 | |
9109 | /* Adjust the state of the output pipe according to whether we | | 9117 | /* Adjust the state of the output pipe according to whether we |
9110 | * have active connectors/encoders. */ | | 9118 | * have active connectors/encoders. */ |
9111 | intel_crtc_update_dpms(&crtc->base); | | 9119 | intel_crtc_update_dpms(&crtc->base); |
9112 | | | 9120 | |
9113 | if (crtc->active != crtc->base.enabled) { | | 9121 | if (crtc->active != crtc->base.enabled) { |
9114 | struct intel_encoder *encoder; | | 9122 | struct intel_encoder *encoder; |
9115 | | | 9123 | |
9116 | /* This can happen either due to bugs in the get_hw_state | | 9124 | /* This can happen either due to bugs in the get_hw_state |
9117 | * functions or because the pipe is force-enabled due to the | | 9125 | * functions or because the pipe is force-enabled due to the |
9118 | * pipe A quirk. */ | | 9126 | * pipe A quirk. */ |
9119 | DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n", | | 9127 | DRM_DEBUG_KMS("[CRTC:%d] hw state adjusted, was %s, now %s\n", |
9120 | crtc->base.base.id, | | 9128 | crtc->base.base.id, |
9121 | crtc->base.enabled ? "enabled" : "disabled", | | 9129 | crtc->base.enabled ? "enabled" : "disabled", |
9122 | crtc->active ? "enabled" : "disabled"); | | 9130 | crtc->active ? "enabled" : "disabled"); |
9123 | | | 9131 | |
9124 | crtc->base.enabled = crtc->active; | | 9132 | crtc->base.enabled = crtc->active; |
9125 | | | 9133 | |
9126 | /* Because we only establish the connector -> encoder -> | | 9134 | /* Because we only establish the connector -> encoder -> |
9127 | * crtc links if something is active, this means the | | 9135 | * crtc links if something is active, this means the |
9128 | * crtc is now deactivated. Break the links. connector | | 9136 | * crtc is now deactivated. Break the links. connector |
9129 | * -> encoder links are only establish when things are | | 9137 | * -> encoder links are only establish when things are |
9130 | * actually up, hence no need to break them. */ | | 9138 | * actually up, hence no need to break them. */ |
9131 | WARN_ON(crtc->active); | | 9139 | WARN_ON(crtc->active); |
9132 | | | 9140 | |
9133 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { | | 9141 | for_each_encoder_on_crtc(dev, &crtc->base, encoder) { |
9134 | WARN_ON(encoder->connectors_active); | | 9142 | WARN_ON(encoder->connectors_active); |
9135 | encoder->base.crtc = NULL; | | 9143 | encoder->base.crtc = NULL; |
9136 | } | | 9144 | } |
9137 | } | | 9145 | } |
9138 | } | | 9146 | } |
9139 | | | 9147 | |
9140 | static void intel_sanitize_encoder(struct intel_encoder *encoder) | | 9148 | static void intel_sanitize_encoder(struct intel_encoder *encoder) |
9141 | { | | 9149 | { |
9142 | struct intel_connector *connector; | | 9150 | struct intel_connector *connector; |
9143 | struct drm_device *dev = encoder->base.dev; | | 9151 | struct drm_device *dev = encoder->base.dev; |
9144 | | | 9152 | |
9145 | /* We need to check both for a crtc link (meaning that the | | 9153 | /* We need to check both for a crtc link (meaning that the |
9146 | * encoder is active and trying to read from a pipe) and the | | 9154 | * encoder is active and trying to read from a pipe) and the |
9147 | * pipe itself being active. */ | | 9155 | * pipe itself being active. */ |
9148 | bool has_active_crtc = encoder->base.crtc && | | 9156 | bool has_active_crtc = encoder->base.crtc && |
9149 | to_intel_crtc(encoder->base.crtc)->active; | | 9157 | to_intel_crtc(encoder->base.crtc)->active; |
9150 | | | 9158 | |
9151 | if (encoder->connectors_active && !has_active_crtc) { | | 9159 | if (encoder->connectors_active && !has_active_crtc) { |
9152 | DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n", | | 9160 | DRM_DEBUG_KMS("[ENCODER:%d:%s] has active connectors but no active pipe!\n", |
9153 | encoder->base.base.id, | | 9161 | encoder->base.base.id, |
9154 | drm_get_encoder_name(&encoder->base)); | | 9162 | drm_get_encoder_name(&encoder->base)); |
9155 | | | 9163 | |
9156 | /* Connector is active, but has no active pipe. This is | | 9164 | /* Connector is active, but has no active pipe. This is |
9157 | * fallout from our resume register restoring. Disable | | 9165 | * fallout from our resume register restoring. Disable |
9158 | * the encoder manually again. */ | | 9166 | * the encoder manually again. */ |
9159 | if (encoder->base.crtc) { | | 9167 | if (encoder->base.crtc) { |
9160 | DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n", | | 9168 | DRM_DEBUG_KMS("[ENCODER:%d:%s] manually disabled\n", |
9161 | encoder->base.base.id, | | 9169 | encoder->base.base.id, |
9162 | drm_get_encoder_name(&encoder->base)); | | 9170 | drm_get_encoder_name(&encoder->base)); |
9163 | encoder->disable(encoder); | | 9171 | encoder->disable(encoder); |
9164 | } | | 9172 | } |
9165 | | | 9173 | |
9166 | /* Inconsistent output/port/pipe state happens presumably due to | | 9174 | /* Inconsistent output/port/pipe state happens presumably due to |
9167 | * a bug in one of the get_hw_state functions. Or someplace else | | 9175 | * a bug in one of the get_hw_state functions. Or someplace else |
9168 | * in our code, like the register restore mess on resume. Clamp | | 9176 | * in our code, like the register restore mess on resume. Clamp |
9169 | * things to off as a safer default. */ | | 9177 | * things to off as a safer default. */ |
9170 | list_for_each_entry(connector, | | 9178 | list_for_each_entry(connector, |
9171 | &dev->mode_config.connector_list, | | 9179 | &dev->mode_config.connector_list, |
9172 | base.head) { | | 9180 | base.head) { |
9173 | if (connector->encoder != encoder) | | 9181 | if (connector->encoder != encoder) |
9174 | continue; | | 9182 | continue; |
9175 | | | 9183 | |
9176 | intel_connector_break_all_links(connector); | | 9184 | intel_connector_break_all_links(connector); |
9177 | } | | 9185 | } |
9178 | } | | 9186 | } |
9179 | /* Enabled encoders without active connectors will be fixed in | | 9187 | /* Enabled encoders without active connectors will be fixed in |
9180 | * the crtc fixup. */ | | 9188 | * the crtc fixup. */ |
9181 | } | | 9189 | } |
9182 | | | 9190 | |
9183 | static void i915_redisable_vga(struct drm_device *dev) | | 9191 | static void i915_redisable_vga(struct drm_device *dev) |
9184 | { | | 9192 | { |
9185 | struct drm_i915_private *dev_priv = dev->dev_private; | | 9193 | struct drm_i915_private *dev_priv = dev->dev_private; |
9186 | u32 vga_reg; | | 9194 | u32 vga_reg; |
9187 | | | 9195 | |
9188 | if (HAS_PCH_SPLIT(dev)) | | 9196 | if (HAS_PCH_SPLIT(dev)) |
9189 | vga_reg = CPU_VGACNTRL; | | 9197 | vga_reg = CPU_VGACNTRL; |
9190 | else | | 9198 | else |
9191 | vga_reg = VGACNTRL; | | 9199 | vga_reg = VGACNTRL; |
9192 | | | 9200 | |
9193 | if (I915_READ(vga_reg) != VGA_DISP_DISABLE) { | | 9201 | if (I915_READ(vga_reg) != VGA_DISP_DISABLE) { |
9194 | DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); | | 9202 | DRM_DEBUG_KMS("Something enabled VGA plane, disabling it\n"); |
9195 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); | | 9203 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); |
9196 | POSTING_READ(vga_reg); | | 9204 | POSTING_READ(vga_reg); |
9197 | } | | 9205 | } |
9198 | } | | 9206 | } |
9199 | | | 9207 | |
9200 | /* Scan out the current hw modeset state, sanitizes it and maps it into the drm | | 9208 | /* Scan out the current hw modeset state, sanitizes it and maps it into the drm |
9201 | * and i915 state tracking structures. */ | | 9209 | * and i915 state tracking structures. */ |
9202 | void intel_modeset_setup_hw_state(struct drm_device *dev, | | 9210 | void intel_modeset_setup_hw_state(struct drm_device *dev, |
9203 | bool force_restore) | | 9211 | bool force_restore) |
9204 | { | | 9212 | { |
9205 | struct drm_i915_private *dev_priv = dev->dev_private; | | 9213 | struct drm_i915_private *dev_priv = dev->dev_private; |
9206 | enum pipe pipe; | | 9214 | enum pipe pipe; |
9207 | u32 tmp; | | 9215 | u32 tmp; |
9208 | struct intel_crtc *crtc; | | 9216 | struct intel_crtc *crtc; |
9209 | struct intel_encoder *encoder; | | 9217 | struct intel_encoder *encoder; |
9210 | struct intel_connector *connector; | | 9218 | struct intel_connector *connector; |
9211 | | | 9219 | |
9212 | if (IS_HASWELL(dev)) { | | 9220 | if (IS_HASWELL(dev)) { |
9213 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); | | 9221 | tmp = I915_READ(TRANS_DDI_FUNC_CTL(TRANSCODER_EDP)); |
9214 | | | 9222 | |
9215 | if (tmp & TRANS_DDI_FUNC_ENABLE) { | | 9223 | if (tmp & TRANS_DDI_FUNC_ENABLE) { |
9216 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { | | 9224 | switch (tmp & TRANS_DDI_EDP_INPUT_MASK) { |
9217 | case TRANS_DDI_EDP_INPUT_A_ON: | | 9225 | case TRANS_DDI_EDP_INPUT_A_ON: |
9218 | case TRANS_DDI_EDP_INPUT_A_ONOFF: | | 9226 | case TRANS_DDI_EDP_INPUT_A_ONOFF: |
9219 | pipe = PIPE_A; | | 9227 | pipe = PIPE_A; |
9220 | break; | | 9228 | break; |
9221 | case TRANS_DDI_EDP_INPUT_B_ONOFF: | | 9229 | case TRANS_DDI_EDP_INPUT_B_ONOFF: |
9222 | pipe = PIPE_B; | | 9230 | pipe = PIPE_B; |
9223 | break; | | 9231 | break; |
9224 | case TRANS_DDI_EDP_INPUT_C_ONOFF: | | 9232 | case TRANS_DDI_EDP_INPUT_C_ONOFF: |
9225 | pipe = PIPE_C; | | 9233 | pipe = PIPE_C; |
9226 | break; | | 9234 | break; |
9227 | } | | 9235 | } |
9228 | | | 9236 | |
9229 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | | 9237 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
9230 | crtc->cpu_transcoder = TRANSCODER_EDP; | | 9238 | crtc->cpu_transcoder = TRANSCODER_EDP; |
9231 | | | 9239 | |
9232 | DRM_DEBUG_KMS("Pipe %c using transcoder EDP\n", | | 9240 | DRM_DEBUG_KMS("Pipe %c using transcoder EDP\n", |
9233 | pipe_name(pipe)); | | 9241 | pipe_name(pipe)); |
9234 | } | | 9242 | } |
9235 | } | | 9243 | } |
9236 | | | 9244 | |
9237 | for_each_pipe(pipe) { | | 9245 | for_each_pipe(pipe) { |
9238 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | | 9246 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
9239 | | | 9247 | |
9240 | tmp = I915_READ(PIPECONF(crtc->cpu_transcoder)); | | 9248 | tmp = I915_READ(PIPECONF(crtc->cpu_transcoder)); |
9241 | if (tmp & PIPECONF_ENABLE) | | 9249 | if (tmp & PIPECONF_ENABLE) |
9242 | crtc->active = true; | | 9250 | crtc->active = true; |
9243 | else | | 9251 | else |
9244 | crtc->active = false; | | 9252 | crtc->active = false; |
9245 | | | 9253 | |
9246 | crtc->base.enabled = crtc->active; | | 9254 | crtc->base.enabled = crtc->active; |
9247 | | | 9255 | |
9248 | DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n", | | 9256 | DRM_DEBUG_KMS("[CRTC:%d] hw state readout: %s\n", |
9249 | crtc->base.base.id, | | 9257 | crtc->base.base.id, |
9250 | crtc->active ? "enabled" : "disabled"); | | 9258 | crtc->active ? "enabled" : "disabled"); |
9251 | } | | 9259 | } |
9252 | | | 9260 | |
9253 | if (IS_HASWELL(dev)) | | 9261 | if (IS_HASWELL(dev)) |
9254 | intel_ddi_setup_hw_pll_state(dev); | | 9262 | intel_ddi_setup_hw_pll_state(dev); |
9255 | | | 9263 | |
9256 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | | 9264 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
9257 | base.head) { | | 9265 | base.head) { |
9258 | pipe = 0; | | 9266 | pipe = 0; |
9259 | | | 9267 | |
9260 | if (encoder->get_hw_state(encoder, &pipe)) { | | 9268 | if (encoder->get_hw_state(encoder, &pipe)) { |
9261 | encoder->base.crtc = | | 9269 | encoder->base.crtc = |
9262 | dev_priv->pipe_to_crtc_mapping[pipe]; | | 9270 | dev_priv->pipe_to_crtc_mapping[pipe]; |
9263 | } else { | | 9271 | } else { |
9264 | encoder->base.crtc = NULL; | | 9272 | encoder->base.crtc = NULL; |
9265 | } | | 9273 | } |
9266 | | | 9274 | |
9267 | encoder->connectors_active = false; | | 9275 | encoder->connectors_active = false; |
9268 | DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe=%i\n", | | 9276 | DRM_DEBUG_KMS("[ENCODER:%d:%s] hw state readout: %s, pipe=%i\n", |
9269 | encoder->base.base.id, | | 9277 | encoder->base.base.id, |
9270 | drm_get_encoder_name(&encoder->base), | | 9278 | drm_get_encoder_name(&encoder->base), |
9271 | encoder->base.crtc ? "enabled" : "disabled", | | 9279 | encoder->base.crtc ? "enabled" : "disabled", |
9272 | pipe); | | 9280 | pipe); |
9273 | } | | 9281 | } |
9274 | | | 9282 | |
9275 | list_for_each_entry(connector, &dev->mode_config.connector_list, | | 9283 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
9276 | base.head) { | | 9284 | base.head) { |
9277 | if (connector->get_hw_state(connector)) { | | 9285 | if (connector->get_hw_state(connector)) { |
9278 | connector->base.dpms = DRM_MODE_DPMS_ON; | | 9286 | connector->base.dpms = DRM_MODE_DPMS_ON; |
9279 | connector->encoder->connectors_active = true; | | 9287 | connector->encoder->connectors_active = true; |
9280 | connector->base.encoder = &connector->encoder->base; | | 9288 | connector->base.encoder = &connector->encoder->base; |
9281 | } else { | | 9289 | } else { |
9282 | connector->base.dpms = DRM_MODE_DPMS_OFF; | | 9290 | connector->base.dpms = DRM_MODE_DPMS_OFF; |
9283 | connector->base.encoder = NULL; | | 9291 | connector->base.encoder = NULL; |
9284 | } | | 9292 | } |
9285 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hw state readout: %s\n", | | 9293 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] hw state readout: %s\n", |
9286 | connector->base.base.id, | | 9294 | connector->base.base.id, |
9287 | drm_get_connector_name(&connector->base), | | 9295 | drm_get_connector_name(&connector->base), |
9288 | connector->base.encoder ? "enabled" : "disabled"); | | 9296 | connector->base.encoder ? "enabled" : "disabled"); |
9289 | } | | 9297 | } |
9290 | | | 9298 | |
9291 | /* HW state is read out, now we need to sanitize this mess. */ | | 9299 | /* HW state is read out, now we need to sanitize this mess. */ |
9292 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, | | 9300 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, |
9293 | base.head) { | | 9301 | base.head) { |
9294 | intel_sanitize_encoder(encoder); | | 9302 | intel_sanitize_encoder(encoder); |
9295 | } | | 9303 | } |
9296 | | | 9304 | |
9297 | for_each_pipe(pipe) { | | 9305 | for_each_pipe(pipe) { |
9298 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | | 9306 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
9299 | intel_sanitize_crtc(crtc); | | 9307 | intel_sanitize_crtc(crtc); |
9300 | } | | 9308 | } |
9301 | | | 9309 | |
9302 | if (force_restore) { | | 9310 | if (force_restore) { |
9303 | for_each_pipe(pipe) { | | 9311 | for_each_pipe(pipe) { |
9304 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); | | 9312 | crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]); |
9305 | intel_set_mode(&crtc->base, &crtc->base.mode, | | 9313 | intel_set_mode(&crtc->base, &crtc->base.mode, |
9306 | crtc->base.x, crtc->base.y, crtc->base.fb); | | 9314 | crtc->base.x, crtc->base.y, crtc->base.fb); |
9307 | } | | 9315 | } |
9308 | | | 9316 | |
9309 | i915_redisable_vga(dev); | | 9317 | i915_redisable_vga(dev); |
9310 | } else { | | 9318 | } else { |
9311 | intel_modeset_update_staged_output_state(dev); | | 9319 | intel_modeset_update_staged_output_state(dev); |
9312 | } | | 9320 | } |
9313 | | | 9321 | |
9314 | intel_modeset_check_state(dev); | | 9322 | intel_modeset_check_state(dev); |
9315 | | | 9323 | |
9316 | drm_mode_config_reset(dev); | | 9324 | drm_mode_config_reset(dev); |
9317 | } | | 9325 | } |
9318 | | | 9326 | |
9319 | void intel_modeset_gem_init(struct drm_device *dev) | | 9327 | void intel_modeset_gem_init(struct drm_device *dev) |
9320 | { | | 9328 | { |
9321 | intel_modeset_init_hw(dev); | | 9329 | intel_modeset_init_hw(dev); |
9322 | | | 9330 | |
9323 | intel_setup_overlay(dev); | | 9331 | intel_setup_overlay(dev); |
9324 | | | 9332 | |
9325 | intel_modeset_setup_hw_state(dev, false); | | 9333 | intel_modeset_setup_hw_state(dev, false); |
9326 | } | | 9334 | } |
9327 | | | 9335 | |
9328 | void intel_modeset_cleanup(struct drm_device *dev) | | 9336 | void intel_modeset_cleanup(struct drm_device *dev) |
9329 | { | | 9337 | { |
9330 | struct drm_i915_private *dev_priv = dev->dev_private; | | 9338 | struct drm_i915_private *dev_priv = dev->dev_private; |
9331 | struct drm_crtc *crtc; | | 9339 | struct drm_crtc *crtc; |
9332 | struct intel_crtc *intel_crtc; | | 9340 | struct intel_crtc *intel_crtc; |
9333 | | | 9341 | |
9334 | drm_kms_helper_poll_fini(dev); | | 9342 | drm_kms_helper_poll_fini(dev); |
9335 | mutex_lock(&dev->struct_mutex); | | 9343 | mutex_lock(&dev->struct_mutex); |
9336 | | | 9344 | |
9337 | intel_unregister_dsm_handler(); | | 9345 | intel_unregister_dsm_handler(); |
9338 | | | 9346 | |
9339 | | | 9347 | |
9340 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | | 9348 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
9341 | /* Skip inactive CRTCs */ | | 9349 | /* Skip inactive CRTCs */ |
9342 | if (!crtc->fb) | | 9350 | if (!crtc->fb) |
9343 | continue; | | 9351 | continue; |
9344 | | | 9352 | |
9345 | intel_crtc = to_intel_crtc(crtc); | | 9353 | intel_crtc = to_intel_crtc(crtc); |
9346 | intel_increase_pllclock(crtc); | | 9354 | intel_increase_pllclock(crtc); |
9347 | } | | 9355 | } |
9348 | | | 9356 | |
9349 | intel_disable_fbc(dev); | | 9357 | intel_disable_fbc(dev); |
9350 | | | 9358 | |
9351 | intel_disable_gt_powersave(dev); | | 9359 | intel_disable_gt_powersave(dev); |
9352 | | | 9360 | |
9353 | ironlake_teardown_rc6(dev); | | 9361 | ironlake_teardown_rc6(dev); |
9354 | | | 9362 | |
9355 | if (IS_VALLEYVIEW(dev)) | | 9363 | if (IS_VALLEYVIEW(dev)) |
9356 | vlv_init_dpio(dev); | | 9364 | vlv_init_dpio(dev); |
9357 | | | 9365 | |
9358 | mutex_unlock(&dev->struct_mutex); | | 9366 | mutex_unlock(&dev->struct_mutex); |
9359 | | | 9367 | |
9360 | /* Disable the irq before mode object teardown, for the irq might | | 9368 | /* Disable the irq before mode object teardown, for the irq might |
9361 | * enqueue unpin/hotplug work. */ | | 9369 | * enqueue unpin/hotplug work. */ |
9362 | drm_irq_uninstall(dev); | | 9370 | drm_irq_uninstall(dev); |
9363 | cancel_work_sync(&dev_priv->hotplug_work); | | 9371 | cancel_work_sync(&dev_priv->hotplug_work); |
9364 | cancel_work_sync(&dev_priv->rps.work); | | 9372 | cancel_work_sync(&dev_priv->rps.work); |
9365 | | | 9373 | |
9366 | /* flush any delayed tasks or pending work */ | | 9374 | /* flush any delayed tasks or pending work */ |
9367 | flush_scheduled_work(); | | 9375 | flush_scheduled_work(); |
9368 | | | 9376 | |
9369 | drm_mode_config_cleanup(dev); | | 9377 | drm_mode_config_cleanup(dev); |
9370 | } | | 9378 | } |
9371 | | | 9379 | |
9372 | /* | | 9380 | /* |
9373 | * Return which encoder is currently attached for connector. | | 9381 | * Return which encoder is currently attached for connector. |
9374 | */ | | 9382 | */ |
9375 | struct drm_encoder *intel_best_encoder(struct drm_connector *connector) | | 9383 | struct drm_encoder *intel_best_encoder(struct drm_connector *connector) |
9376 | { | | 9384 | { |
9377 | return &intel_attached_encoder(connector)->base; | | 9385 | return &intel_attached_encoder(connector)->base; |
9378 | } | | 9386 | } |
9379 | | | 9387 | |
9380 | void intel_connector_attach_encoder(struct intel_connector *connector, | | 9388 | void intel_connector_attach_encoder(struct intel_connector *connector, |
9381 | struct intel_encoder *encoder) | | 9389 | struct intel_encoder *encoder) |
9382 | { | | 9390 | { |
9383 | connector->encoder = encoder; | | 9391 | connector->encoder = encoder; |
9384 | drm_mode_connector_attach_encoder(&connector->base, | | 9392 | drm_mode_connector_attach_encoder(&connector->base, |
9385 | &encoder->base); | | 9393 | &encoder->base); |
9386 | } | | 9394 | } |
9387 | | | 9395 | |
9388 | /* | | 9396 | /* |
9389 | * set vga decode state - true == enable VGA decode | | 9397 | * set vga decode state - true == enable VGA decode |
9390 | */ | | 9398 | */ |
9391 | int intel_modeset_vga_set_state(struct drm_device *dev, bool state) | | 9399 | int intel_modeset_vga_set_state(struct drm_device *dev, bool state) |
9392 | { | | 9400 | { |
9393 | struct drm_i915_private *dev_priv = dev->dev_private; | | 9401 | struct drm_i915_private *dev_priv = dev->dev_private; |
9394 | u16 gmch_ctrl; | | 9402 | u16 gmch_ctrl; |
9395 | | | 9403 | |
9396 | pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl); | | 9404 | pci_read_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, &gmch_ctrl); |
9397 | if (state) | | 9405 | if (state) |
9398 | gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; | | 9406 | gmch_ctrl &= ~INTEL_GMCH_VGA_DISABLE; |
9399 | else | | 9407 | else |
9400 | gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; | | 9408 | gmch_ctrl |= INTEL_GMCH_VGA_DISABLE; |
9401 | pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); | | 9409 | pci_write_config_word(dev_priv->bridge_dev, INTEL_GMCH_CTRL, gmch_ctrl); |
9402 | return 0; | | 9410 | return 0; |
9403 | } | | 9411 | } |
9404 | | | 9412 | |
9405 | #ifdef CONFIG_DEBUG_FS | | 9413 | #ifdef CONFIG_DEBUG_FS |
9406 | #include <linux/seq_file.h> | | 9414 | #include <linux/seq_file.h> |
9407 | | | 9415 | |
9408 | struct intel_display_error_state { | | 9416 | struct intel_display_error_state { |
9409 | struct intel_cursor_error_state { | | 9417 | struct intel_cursor_error_state { |
9410 | u32 control; | | 9418 | u32 control; |
9411 | u32 position; | | 9419 | u32 position; |
9412 | u32 base; | | 9420 | u32 base; |
9413 | u32 size; | | 9421 | u32 size; |
9414 | } cursor[I915_MAX_PIPES]; | | 9422 | } cursor[I915_MAX_PIPES]; |
9415 | | | 9423 | |
9416 | struct intel_pipe_error_state { | | 9424 | struct intel_pipe_error_state { |
9417 | u32 conf; | | 9425 | u32 conf; |
9418 | u32 source; | | 9426 | u32 source; |
9419 | | | 9427 | |
9420 | u32 htotal; | | 9428 | u32 htotal; |
9421 | u32 hblank; | | 9429 | u32 hblank; |
9422 | u32 hsync; | | 9430 | u32 hsync; |
9423 | u32 vtotal; | | 9431 | u32 vtotal; |
9424 | u32 vblank; | | 9432 | u32 vblank; |
9425 | u32 vsync; | | 9433 | u32 vsync; |
9426 | } pipe[I915_MAX_PIPES]; | | 9434 | } pipe[I915_MAX_PIPES]; |
9427 | | | 9435 | |
9428 | struct intel_plane_error_state { | | 9436 | struct intel_plane_error_state { |
9429 | u32 control; | | 9437 | u32 control; |
9430 | u32 stride; | | 9438 | u32 stride; |
9431 | u32 size; | | 9439 | u32 size; |
9432 | u32 pos; | | 9440 | u32 pos; |
9433 | u32 addr; | | 9441 | u32 addr; |
9434 | u32 surface; | | 9442 | u32 surface; |
9435 | u32 tile_offset; | | 9443 | u32 tile_offset; |
9436 | } plane[I915_MAX_PIPES]; | | 9444 | } plane[I915_MAX_PIPES]; |
9437 | }; | | 9445 | }; |
9438 | | | 9446 | |
9439 | struct intel_display_error_state * | | 9447 | struct intel_display_error_state * |
9440 | intel_display_capture_error_state(struct drm_device *dev) | | 9448 | intel_display_capture_error_state(struct drm_device *dev) |
9441 | { | | 9449 | { |
9442 | drm_i915_private_t *dev_priv = dev->dev_private; | | 9450 | drm_i915_private_t *dev_priv = dev->dev_private; |
9443 | struct intel_display_error_state *error; | | 9451 | struct intel_display_error_state *error; |
9444 | enum transcoder cpu_transcoder; | | 9452 | enum transcoder cpu_transcoder; |
9445 | int i; | | 9453 | int i; |
9446 | | | 9454 | |
9447 | error = kmalloc(sizeof(*error), GFP_ATOMIC); | | 9455 | error = kmalloc(sizeof(*error), GFP_ATOMIC); |
9448 | if (error == NULL) | | 9456 | if (error == NULL) |
9449 | return NULL; | | 9457 | return NULL; |
9450 | | | 9458 | |
9451 | for_each_pipe(i) { | | 9459 | for_each_pipe(i) { |
9452 | cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i); | | 9460 | cpu_transcoder = intel_pipe_to_cpu_transcoder(dev_priv, i); |
9453 | | | 9461 | |
9454 | error->cursor[i].control = I915_READ(CURCNTR(i)); | | 9462 | error->cursor[i].control = I915_READ(CURCNTR(i)); |
9455 | error->cursor[i].position = I915_READ(CURPOS(i)); | | 9463 | error->cursor[i].position = I915_READ(CURPOS(i)); |
9456 | error->cursor[i].base = I915_READ(CURBASE(i)); | | 9464 | error->cursor[i].base = I915_READ(CURBASE(i)); |
9457 | | | 9465 | |
9458 | error->plane[i].control = I915_READ(DSPCNTR(i)); | | 9466 | error->plane[i].control = I915_READ(DSPCNTR(i)); |
9459 | error->plane[i].stride = I915_READ(DSPSTRIDE(i)); | | 9467 | error->plane[i].stride = I915_READ(DSPSTRIDE(i)); |
9460 | error->plane[i].size = I915_READ(DSPSIZE(i)); | | 9468 | error->plane[i].size = I915_READ(DSPSIZE(i)); |
9461 | error->plane[i].pos = I915_READ(DSPPOS(i)); | | 9469 | error->plane[i].pos = I915_READ(DSPPOS(i)); |
9462 | error->plane[i].addr = I915_READ(DSPADDR(i)); | | 9470 | error->plane[i].addr = I915_READ(DSPADDR(i)); |
9463 | if (INTEL_INFO(dev)->gen >= 4) { | | 9471 | if (INTEL_INFO(dev)->gen >= 4) { |
9464 | error->plane[i].surface = I915_READ(DSPSURF(i)); | | 9472 | error->plane[i].surface = I915_READ(DSPSURF(i)); |
9465 | error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); | | 9473 | error->plane[i].tile_offset = I915_READ(DSPTILEOFF(i)); |
9466 | } | | 9474 | } |
9467 | | | 9475 | |
9468 | error->pipe[i].conf = I915_READ(PIPECONF(cpu_transcoder)); | | 9476 | error->pipe[i].conf = I915_READ(PIPECONF(cpu_transcoder)); |
9469 | error->pipe[i].source = I915_READ(PIPESRC(i)); | | 9477 | error->pipe[i].source = I915_READ(PIPESRC(i)); |
9470 | error->pipe[i].htotal = I915_READ(HTOTAL(cpu_transcoder)); | | 9478 | error->pipe[i].htotal = I915_READ(HTOTAL(cpu_transcoder)); |
9471 | error->pipe[i].hblank = I915_READ(HBLANK(cpu_transcoder)); | | 9479 | error->pipe[i].hblank = I915_READ(HBLANK(cpu_transcoder)); |
9472 | error->pipe[i].hsync = I915_READ(HSYNC(cpu_transcoder)); | | 9480 | error->pipe[i].hsync = I915_READ(HSYNC(cpu_transcoder)); |
9473 | error->pipe[i].vtotal = I915_READ(VTOTAL(cpu_transcoder)); | | 9481 | error->pipe[i].vtotal = I915_READ(VTOTAL(cpu_transcoder)); |
9474 | error->pipe[i].vblank = I915_READ(VBLANK(cpu_transcoder)); | | 9482 | error->pipe[i].vblank = I915_READ(VBLANK(cpu_transcoder)); |
9475 | error->pipe[i].vsync = I915_READ(VSYNC(cpu_transcoder)); | | 9483 | error->pipe[i].vsync = I915_READ(VSYNC(cpu_transcoder)); |
9476 | } | | 9484 | } |
9477 | | | 9485 | |
9478 | return error; | | 9486 | return error; |
9479 | } | | 9487 | } |
9480 | | | 9488 | |
9481 | void | | 9489 | void |
9482 | intel_display_print_error_state(struct seq_file *m, | | 9490 | intel_display_print_error_state(struct seq_file *m, |
9483 | struct drm_device *dev, | | 9491 | struct drm_device *dev, |
9484 | struct intel_display_error_state *error) | | 9492 | struct intel_display_error_state *error) |
9485 | { | | 9493 | { |
9486 | drm_i915_private_t *dev_priv = dev->dev_private; | | 9494 | drm_i915_private_t *dev_priv = dev->dev_private; |
9487 | int i; | | 9495 | int i; |
9488 | | | 9496 | |
9489 | seq_printf(m, "Num Pipes: %d\n", dev_priv->num_pipe); | | 9497 | seq_printf(m, "Num Pipes: %d\n", dev_priv->num_pipe); |
9490 | for_each_pipe(i) { | | 9498 | for_each_pipe(i) { |
9491 | seq_printf(m, "Pipe [%d]:\n", i); | | 9499 | seq_printf(m, "Pipe [%d]:\n", i); |
9492 | seq_printf(m, " CONF: %08x\n", error->pipe[i].conf); | | 9500 | seq_printf(m, " CONF: %08x\n", error->pipe[i].conf); |
9493 | seq_printf(m, " SRC: %08x\n", error->pipe[i].source); | | 9501 | seq_printf(m, " SRC: %08x\n", error->pipe[i].source); |
9494 | seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); | | 9502 | seq_printf(m, " HTOTAL: %08x\n", error->pipe[i].htotal); |
9495 | seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); | | 9503 | seq_printf(m, " HBLANK: %08x\n", error->pipe[i].hblank); |
9496 | seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); | | 9504 | seq_printf(m, " HSYNC: %08x\n", error->pipe[i].hsync); |
9497 | seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); | | 9505 | seq_printf(m, " VTOTAL: %08x\n", error->pipe[i].vtotal); |
9498 | seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); | | 9506 | seq_printf(m, " VBLANK: %08x\n", error->pipe[i].vblank); |
9499 | seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); | | 9507 | seq_printf(m, " VSYNC: %08x\n", error->pipe[i].vsync); |
9500 | | | 9508 | |
9501 | seq_printf(m, "Plane [%d]:\n", i); | | 9509 | seq_printf(m, "Plane [%d]:\n", i); |
9502 | seq_printf(m, " CNTR: %08x\n", error->plane[i].control); | | 9510 | seq_printf(m, " CNTR: %08x\n", error->plane[i].control); |
9503 | seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride); | | 9511 | seq_printf(m, " STRIDE: %08x\n", error->plane[i].stride); |
9504 | seq_printf(m, " SIZE: %08x\n", error->plane[i].size); | | 9512 | seq_printf(m, " SIZE: %08x\n", error->plane[i].size); |
9505 | seq_printf(m, " POS: %08x\n", error->plane[i].pos); | | 9513 | seq_printf(m, " POS: %08x\n", error->plane[i].pos); |
9506 | seq_printf(m, " ADDR: %08x\n", error->plane[i].addr); | | 9514 | seq_printf(m, " ADDR: %08x\n", error->plane[i].addr); |
9507 | if (INTEL_INFO(dev)->gen >= 4) { | | 9515 | if (INTEL_INFO(dev)->gen >= 4) { |
9508 | seq_printf(m, " SURF: %08x\n", error->plane[i].surface); | | 9516 | seq_printf(m, " SURF: %08x\n", error->plane[i].surface); |
9509 | seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset); | | 9517 | seq_printf(m, " TILEOFF: %08x\n", error->plane[i].tile_offset); |
9510 | } | | 9518 | } |
9511 | | | 9519 | |
9512 | seq_printf(m, "Cursor [%d]:\n", i); | | 9520 | seq_printf(m, "Cursor [%d]:\n", i); |
9513 | seq_printf(m, " CNTR: %08x\n", error->cursor[i].control); | | 9521 | seq_printf(m, " CNTR: %08x\n", error->cursor[i].control); |
9514 | seq_printf(m, " POS: %08x\n", error->cursor[i].position); | | 9522 | seq_printf(m, " POS: %08x\n", error->cursor[i].position); |
9515 | seq_printf(m, " BASE: %08x\n", error->cursor[i].base); | | 9523 | seq_printf(m, " BASE: %08x\n", error->cursor[i].base); |
9516 | } | | 9524 | } |
9517 | } | | 9525 | } |
9518 | #endif | | 9526 | #endif |