File: | dev/pci/drm/radeon/radeon_dp_mst.c |
Warning: | line 45, column 10 The result of the left shift is undefined because the right operand is negative |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | // SPDX-License-Identifier: MIT | |||
2 | ||||
3 | #include <drm/drm_debugfs.h> | |||
4 | #include <drm/drm_dp_mst_helper.h> | |||
5 | #include <drm/drm_fb_helper.h> | |||
6 | #include <drm/drm_file.h> | |||
7 | #include <drm/drm_probe_helper.h> | |||
8 | ||||
9 | #include "atom.h" | |||
10 | #include "ni_reg.h" | |||
11 | #include "radeon.h" | |||
12 | ||||
13 | static struct radeon_encoder *radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector); | |||
14 | ||||
15 | static int radeon_atom_set_enc_offset(int id) | |||
16 | { | |||
17 | static const int offsets[] = { EVERGREEN_CRTC0_REGISTER_OFFSET(0x6df0 - 0x6df0), | |||
18 | EVERGREEN_CRTC1_REGISTER_OFFSET(0x79f0 - 0x6df0), | |||
19 | EVERGREEN_CRTC2_REGISTER_OFFSET(0x105f0 - 0x6df0), | |||
20 | EVERGREEN_CRTC3_REGISTER_OFFSET(0x111f0 - 0x6df0), | |||
21 | EVERGREEN_CRTC4_REGISTER_OFFSET(0x11df0 - 0x6df0), | |||
22 | EVERGREEN_CRTC5_REGISTER_OFFSET(0x129f0 - 0x6df0), | |||
23 | 0x13830 - 0x7030 }; | |||
24 | ||||
25 | return offsets[id]; | |||
26 | } | |||
27 | ||||
28 | static int radeon_dp_mst_set_be_cntl(struct radeon_encoder *primary, | |||
29 | struct radeon_encoder_mst *mst_enc, | |||
30 | enum radeon_hpd_id hpd, bool_Bool enable) | |||
31 | { | |||
32 | struct drm_device *dev = primary->base.dev; | |||
33 | struct radeon_device *rdev = dev->dev_private; | |||
34 | uint32_t reg; | |||
35 | int retries = 0; | |||
36 | uint32_t temp; | |||
37 | ||||
38 | reg = RREG32(NI_DIG_BE_CNTL + primary->offset)r100_mm_rreg(rdev, (0x7140 + primary->offset), 0); | |||
39 | ||||
40 | /* set MST mode */ | |||
41 | reg &= ~NI_DIG_FE_DIG_MODE(7)(((7) & 0x7) << 16); | |||
42 | reg |= NI_DIG_FE_DIG_MODE(NI_DIG_MODE_DP_MST)(((5) & 0x7) << 16); | |||
43 | ||||
44 | if (enable
| |||
45 | reg |= NI_DIG_FE_SOURCE_SELECT(1 << mst_enc->fe)(((1 << mst_enc->fe) & 0x7f) << 8); | |||
| ||||
46 | else | |||
47 | reg &= ~NI_DIG_FE_SOURCE_SELECT(1 << mst_enc->fe)(((1 << mst_enc->fe) & 0x7f) << 8); | |||
48 | ||||
49 | reg |= NI_DIG_HPD_SELECT(hpd)(((hpd) & 0x7) << 28); | |||
50 | DRM_DEBUG_KMS("writing 0x%08x 0x%08x\n", NI_DIG_BE_CNTL + primary->offset, reg)__drm_dbg(DRM_UT_KMS, "writing 0x%08x 0x%08x\n", 0x7140 + primary ->offset, reg); | |||
51 | WREG32(NI_DIG_BE_CNTL + primary->offset, reg)r100_mm_wreg(rdev, (0x7140 + primary->offset), (reg), 0); | |||
52 | ||||
53 | if (enable) { | |||
54 | uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe); | |||
55 | ||||
56 | do { | |||
57 | temp = RREG32(NI_DIG_FE_CNTL + offset)r100_mm_rreg(rdev, (0x7000 + offset), 0); | |||
58 | } while ((temp & NI_DIG_SYMCLK_FE_ON(0x1 << 24)) && retries++ < 10000); | |||
59 | if (retries == 10000) | |||
60 | DRM_ERROR("timed out waiting for FE %d %d\n", primary->offset, mst_enc->fe)__drm_err("timed out waiting for FE %d %d\n", primary->offset , mst_enc->fe); | |||
61 | } | |||
62 | return 0; | |||
63 | } | |||
64 | ||||
65 | static int radeon_dp_mst_set_stream_attrib(struct radeon_encoder *primary, | |||
66 | int stream_number, | |||
67 | int fe, | |||
68 | int slots) | |||
69 | { | |||
70 | struct drm_device *dev = primary->base.dev; | |||
71 | struct radeon_device *rdev = dev->dev_private; | |||
72 | u32 temp, val; | |||
73 | int retries = 0; | |||
74 | int satreg, satidx; | |||
75 | ||||
76 | satreg = stream_number >> 1; | |||
77 | satidx = stream_number & 1; | |||
78 | ||||
79 | temp = RREG32(NI_DP_MSE_SAT0 + satreg + primary->offset)r100_mm_rreg(rdev, (0x7390 + satreg + primary->offset), 0); | |||
80 | ||||
81 | val = NI_DP_MSE_SAT_SLOT_COUNT0(slots)(((slots) & 0x3f) << 8) | NI_DP_MSE_SAT_SRC0(fe)(((fe) & 0x7) << 0); | |||
82 | ||||
83 | val <<= (16 * satidx); | |||
84 | ||||
85 | temp &= ~(0xffff << (16 * satidx)); | |||
86 | ||||
87 | temp |= val; | |||
88 | ||||
89 | DRM_DEBUG_KMS("writing 0x%08x 0x%08x\n", NI_DP_MSE_SAT0 + satreg + primary->offset, temp)__drm_dbg(DRM_UT_KMS, "writing 0x%08x 0x%08x\n", 0x7390 + satreg + primary->offset, temp); | |||
90 | WREG32(NI_DP_MSE_SAT0 + satreg + primary->offset, temp)r100_mm_wreg(rdev, (0x7390 + satreg + primary->offset), (temp ), 0); | |||
91 | ||||
92 | WREG32(NI_DP_MSE_SAT_UPDATE + primary->offset, 1)r100_mm_wreg(rdev, (0x739c + primary->offset), (1), 0); | |||
93 | ||||
94 | do { | |||
95 | unsigned value1, value2; | |||
96 | udelay(10); | |||
97 | temp = RREG32(NI_DP_MSE_SAT_UPDATE + primary->offset)r100_mm_rreg(rdev, (0x739c + primary->offset), 0); | |||
98 | ||||
99 | value1 = temp & NI_DP_MSE_SAT_UPDATE_MASK0x3; | |||
100 | value2 = temp & NI_DP_MSE_16_MTP_KEEPOUT0x100; | |||
101 | ||||
102 | if (!value1 && !value2) | |||
103 | break; | |||
104 | } while (retries++ < 50); | |||
105 | ||||
106 | if (retries == 10000) | |||
107 | DRM_ERROR("timed out waitin for SAT update %d\n", primary->offset)__drm_err("timed out waitin for SAT update %d\n", primary-> offset); | |||
108 | ||||
109 | /* MTP 16 ? */ | |||
110 | return 0; | |||
111 | } | |||
112 | ||||
113 | static int radeon_dp_mst_update_stream_attribs(struct radeon_connector *mst_conn, | |||
114 | struct radeon_encoder *primary) | |||
115 | { | |||
116 | struct drm_device *dev = mst_conn->base.dev; | |||
117 | struct stream_attribs new_attribs[6]; | |||
118 | int i; | |||
119 | int idx = 0; | |||
120 | struct radeon_connector *radeon_connector; | |||
121 | struct drm_connector *connector; | |||
122 | ||||
123 | memset(new_attribs, 0, sizeof(new_attribs))__builtin_memset((new_attribs), (0), (sizeof(new_attribs))); | |||
124 | list_for_each_entry(connector, &dev->mode_config.connector_list, head)for (connector = ({ const __typeof( ((__typeof(*connector) *) 0)->head ) *__mptr = ((&dev->mode_config.connector_list )->next); (__typeof(*connector) *)( (char *)__mptr - __builtin_offsetof (__typeof(*connector), head) );}); &connector->head != (&dev->mode_config.connector_list); connector = ({ const __typeof( ((__typeof(*connector) *)0)->head ) *__mptr = ( connector->head.next); (__typeof(*connector) *)( (char *)__mptr - __builtin_offsetof(__typeof(*connector), head) );})) { | |||
125 | struct radeon_encoder *subenc; | |||
126 | struct radeon_encoder_mst *mst_enc; | |||
127 | ||||
128 | radeon_connector = to_radeon_connector(connector)({ const __typeof( ((struct radeon_connector *)0)->base ) * __mptr = (connector); (struct radeon_connector *)( (char *)__mptr - __builtin_offsetof(struct radeon_connector, base) );}); | |||
129 | if (!radeon_connector->is_mst_connector) | |||
130 | continue; | |||
131 | ||||
132 | if (radeon_connector->mst_port != mst_conn) | |||
133 | continue; | |||
134 | ||||
135 | subenc = radeon_connector->mst_encoder; | |||
136 | mst_enc = subenc->enc_priv; | |||
137 | ||||
138 | if (!mst_enc->enc_active) | |||
139 | continue; | |||
140 | ||||
141 | new_attribs[idx].fe = mst_enc->fe; | |||
142 | new_attribs[idx].slots = drm_dp_mst_get_vcpi_slots(&mst_conn->mst_mgr, mst_enc->port); | |||
143 | idx++; | |||
144 | } | |||
145 | ||||
146 | for (i = 0; i < idx; i++) { | |||
147 | if (new_attribs[i].fe != mst_conn->cur_stream_attribs[i].fe || | |||
148 | new_attribs[i].slots != mst_conn->cur_stream_attribs[i].slots) { | |||
149 | radeon_dp_mst_set_stream_attrib(primary, i, new_attribs[i].fe, new_attribs[i].slots); | |||
150 | mst_conn->cur_stream_attribs[i].fe = new_attribs[i].fe; | |||
151 | mst_conn->cur_stream_attribs[i].slots = new_attribs[i].slots; | |||
152 | } | |||
153 | } | |||
154 | ||||
155 | for (i = idx; i < mst_conn->enabled_attribs; i++) { | |||
156 | radeon_dp_mst_set_stream_attrib(primary, i, 0, 0); | |||
157 | mst_conn->cur_stream_attribs[i].fe = 0; | |||
158 | mst_conn->cur_stream_attribs[i].slots = 0; | |||
159 | } | |||
160 | mst_conn->enabled_attribs = idx; | |||
161 | return 0; | |||
162 | } | |||
163 | ||||
164 | static int radeon_dp_mst_set_vcp_size(struct radeon_encoder *mst, s64 avg_time_slots_per_mtp) | |||
165 | { | |||
166 | struct drm_device *dev = mst->base.dev; | |||
167 | struct radeon_device *rdev = dev->dev_private; | |||
168 | struct radeon_encoder_mst *mst_enc = mst->enc_priv; | |||
169 | uint32_t val, temp; | |||
170 | uint32_t offset = radeon_atom_set_enc_offset(mst_enc->fe); | |||
171 | int retries = 0; | |||
172 | uint32_t x = drm_fixp2int(avg_time_slots_per_mtp); | |||
173 | uint32_t y = drm_fixp2int_ceil((avg_time_slots_per_mtp - x) << 26); | |||
174 | ||||
175 | val = NI_DP_MSE_RATE_X(x)(((x) & 0x3f) << 26) | NI_DP_MSE_RATE_Y(y)(((y) & 0x3ffffff) << 0); | |||
176 | ||||
177 | WREG32(NI_DP_MSE_RATE_CNTL + offset, val)r100_mm_wreg(rdev, (0x7384 + offset), (val), 0); | |||
178 | ||||
179 | do { | |||
180 | temp = RREG32(NI_DP_MSE_RATE_UPDATE + offset)r100_mm_rreg(rdev, (0x738c + offset), 0); | |||
181 | udelay(10); | |||
182 | } while ((temp & 0x1) && (retries++ < 10000)); | |||
183 | ||||
184 | if (retries >= 10000) | |||
185 | DRM_ERROR("timed out wait for rate cntl %d\n", mst_enc->fe)__drm_err("timed out wait for rate cntl %d\n", mst_enc->fe ); | |||
186 | return 0; | |||
187 | } | |||
188 | ||||
189 | static int radeon_dp_mst_get_ddc_modes(struct drm_connector *connector) | |||
190 | { | |||
191 | struct radeon_connector *radeon_connector = to_radeon_connector(connector)({ const __typeof( ((struct radeon_connector *)0)->base ) * __mptr = (connector); (struct radeon_connector *)( (char *)__mptr - __builtin_offsetof(struct radeon_connector, base) );}); | |||
192 | struct radeon_connector *master = radeon_connector->mst_port; | |||
193 | struct edid *edid; | |||
194 | int ret = 0; | |||
195 | ||||
196 | edid = drm_dp_mst_get_edid(connector, &master->mst_mgr, radeon_connector->port); | |||
197 | radeon_connector->edid = edid; | |||
198 | DRM_DEBUG_KMS("edid retrieved %p\n", edid)__drm_dbg(DRM_UT_KMS, "edid retrieved %p\n", edid); | |||
199 | if (radeon_connector->edid) { | |||
200 | drm_connector_update_edid_property(&radeon_connector->base, radeon_connector->edid); | |||
201 | ret = drm_add_edid_modes(&radeon_connector->base, radeon_connector->edid); | |||
202 | return ret; | |||
203 | } | |||
204 | drm_connector_update_edid_property(&radeon_connector->base, NULL((void *)0)); | |||
205 | ||||
206 | return ret; | |||
207 | } | |||
208 | ||||
209 | static int radeon_dp_mst_get_modes(struct drm_connector *connector) | |||
210 | { | |||
211 | return radeon_dp_mst_get_ddc_modes(connector); | |||
212 | } | |||
213 | ||||
214 | static enum drm_mode_status | |||
215 | radeon_dp_mst_mode_valid(struct drm_connector *connector, | |||
216 | struct drm_display_mode *mode) | |||
217 | { | |||
218 | /* TODO - validate mode against available PBN for link */ | |||
219 | if (mode->clock < 10000) | |||
220 | return MODE_CLOCK_LOW; | |||
221 | ||||
222 | if (mode->flags & DRM_MODE_FLAG_DBLCLK(1<<12)) | |||
223 | return MODE_H_ILLEGAL; | |||
224 | ||||
225 | return MODE_OK; | |||
226 | } | |||
227 | ||||
228 | static struct | |||
229 | drm_encoder *radeon_mst_best_encoder(struct drm_connector *connector) | |||
230 | { | |||
231 | struct radeon_connector *radeon_connector = to_radeon_connector(connector)({ const __typeof( ((struct radeon_connector *)0)->base ) * __mptr = (connector); (struct radeon_connector *)( (char *)__mptr - __builtin_offsetof(struct radeon_connector, base) );}); | |||
232 | ||||
233 | return &radeon_connector->mst_encoder->base; | |||
234 | } | |||
235 | ||||
236 | static int | |||
237 | radeon_dp_mst_detect(struct drm_connector *connector, | |||
238 | struct drm_modeset_acquire_ctx *ctx, | |||
239 | bool_Bool force) | |||
240 | { | |||
241 | struct radeon_connector *radeon_connector = | |||
242 | to_radeon_connector(connector)({ const __typeof( ((struct radeon_connector *)0)->base ) * __mptr = (connector); (struct radeon_connector *)( (char *)__mptr - __builtin_offsetof(struct radeon_connector, base) );}); | |||
243 | struct radeon_connector *master = radeon_connector->mst_port; | |||
244 | ||||
245 | if (drm_connector_is_unregistered(connector)) | |||
246 | return connector_status_disconnected; | |||
247 | ||||
248 | return drm_dp_mst_detect_port(connector, ctx, &master->mst_mgr, | |||
249 | radeon_connector->port); | |||
250 | } | |||
251 | ||||
252 | static const struct drm_connector_helper_funcs radeon_dp_mst_connector_helper_funcs = { | |||
253 | .get_modes = radeon_dp_mst_get_modes, | |||
254 | .mode_valid = radeon_dp_mst_mode_valid, | |||
255 | .best_encoder = radeon_mst_best_encoder, | |||
256 | .detect_ctx = radeon_dp_mst_detect, | |||
257 | }; | |||
258 | ||||
259 | static void | |||
260 | radeon_dp_mst_connector_destroy(struct drm_connector *connector) | |||
261 | { | |||
262 | struct radeon_connector *radeon_connector = to_radeon_connector(connector)({ const __typeof( ((struct radeon_connector *)0)->base ) * __mptr = (connector); (struct radeon_connector *)( (char *)__mptr - __builtin_offsetof(struct radeon_connector, base) );}); | |||
263 | struct radeon_encoder *radeon_encoder = radeon_connector->mst_encoder; | |||
264 | ||||
265 | drm_encoder_cleanup(&radeon_encoder->base); | |||
266 | kfree(radeon_encoder); | |||
267 | drm_connector_cleanup(connector); | |||
268 | kfree(radeon_connector); | |||
269 | } | |||
270 | ||||
271 | static const struct drm_connector_funcs radeon_dp_mst_connector_funcs = { | |||
272 | .dpms = drm_helper_connector_dpms, | |||
273 | .fill_modes = drm_helper_probe_single_connector_modes, | |||
274 | .destroy = radeon_dp_mst_connector_destroy, | |||
275 | }; | |||
276 | ||||
277 | static struct drm_connector *radeon_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, | |||
278 | struct drm_dp_mst_port *port, | |||
279 | const char *pathprop) | |||
280 | { | |||
281 | struct radeon_connector *master = container_of(mgr, struct radeon_connector, mst_mgr)({ const __typeof( ((struct radeon_connector *)0)->mst_mgr ) *__mptr = (mgr); (struct radeon_connector *)( (char *)__mptr - __builtin_offsetof(struct radeon_connector, mst_mgr) );}); | |||
282 | struct drm_device *dev = master->base.dev; | |||
283 | struct radeon_connector *radeon_connector; | |||
284 | struct drm_connector *connector; | |||
285 | ||||
286 | radeon_connector = kzalloc(sizeof(*radeon_connector), GFP_KERNEL(0x0001 | 0x0004)); | |||
287 | if (!radeon_connector) | |||
288 | return NULL((void *)0); | |||
289 | ||||
290 | radeon_connector->is_mst_connector = true1; | |||
291 | connector = &radeon_connector->base; | |||
292 | radeon_connector->port = port; | |||
293 | radeon_connector->mst_port = master; | |||
294 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
295 | ||||
296 | drm_connector_init(dev, connector, &radeon_dp_mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort10); | |||
297 | drm_connector_helper_add(connector, &radeon_dp_mst_connector_helper_funcs); | |||
298 | radeon_connector->mst_encoder = radeon_dp_create_fake_mst_encoder(master); | |||
299 | ||||
300 | drm_object_attach_property(&connector->base, dev->mode_config.path_property, 0); | |||
301 | drm_object_attach_property(&connector->base, dev->mode_config.tile_property, 0); | |||
302 | drm_connector_set_path_property(connector, pathprop); | |||
303 | ||||
304 | return connector; | |||
305 | } | |||
306 | ||||
307 | static const struct drm_dp_mst_topology_cbs mst_cbs = { | |||
308 | .add_connector = radeon_dp_add_mst_connector, | |||
309 | }; | |||
310 | ||||
311 | static struct | |||
312 | radeon_connector *radeon_mst_find_connector(struct drm_encoder *encoder) | |||
313 | { | |||
314 | struct drm_device *dev = encoder->dev; | |||
315 | struct drm_connector *connector; | |||
316 | ||||
317 | list_for_each_entry(connector, &dev->mode_config.connector_list, head)for (connector = ({ const __typeof( ((__typeof(*connector) *) 0)->head ) *__mptr = ((&dev->mode_config.connector_list )->next); (__typeof(*connector) *)( (char *)__mptr - __builtin_offsetof (__typeof(*connector), head) );}); &connector->head != (&dev->mode_config.connector_list); connector = ({ const __typeof( ((__typeof(*connector) *)0)->head ) *__mptr = ( connector->head.next); (__typeof(*connector) *)( (char *)__mptr - __builtin_offsetof(__typeof(*connector), head) );})) { | |||
318 | struct radeon_connector *radeon_connector = to_radeon_connector(connector)({ const __typeof( ((struct radeon_connector *)0)->base ) * __mptr = (connector); (struct radeon_connector *)( (char *)__mptr - __builtin_offsetof(struct radeon_connector, base) );}); | |||
319 | if (!connector->encoder) | |||
320 | continue; | |||
321 | if (!radeon_connector->is_mst_connector) | |||
322 | continue; | |||
323 | ||||
324 | DRM_DEBUG_KMS("checking %p vs %p\n", connector->encoder, encoder)__drm_dbg(DRM_UT_KMS, "checking %p vs %p\n", connector->encoder , encoder); | |||
325 | if (connector->encoder == encoder) | |||
326 | return radeon_connector; | |||
327 | } | |||
328 | return NULL((void *)0); | |||
329 | } | |||
330 | ||||
331 | void radeon_dp_mst_prepare_pll(struct drm_crtc *crtc, struct drm_display_mode *mode) | |||
332 | { | |||
333 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc)({ const __typeof( ((struct radeon_crtc *)0)->base ) *__mptr = (crtc); (struct radeon_crtc *)( (char *)__mptr - __builtin_offsetof (struct radeon_crtc, base) );}); | |||
334 | struct drm_device *dev = crtc->dev; | |||
335 | struct radeon_device *rdev = dev->dev_private; | |||
336 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(radeon_crtc->encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (radeon_crtc->encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof(struct radeon_encoder, base) ) ;}); | |||
337 | struct radeon_encoder_mst *mst_enc = radeon_encoder->enc_priv; | |||
338 | struct radeon_connector *radeon_connector = radeon_mst_find_connector(&radeon_encoder->base); | |||
339 | int dp_clock; | |||
340 | struct radeon_connector_atom_dig *dig_connector = mst_enc->connector->con_priv; | |||
341 | ||||
342 | if (radeon_connector) { | |||
343 | radeon_connector->pixelclock_for_modeset = mode->clock; | |||
344 | if (radeon_connector->base.display_info.bpc) | |||
345 | radeon_crtc->bpc = radeon_connector->base.display_info.bpc; | |||
346 | else | |||
347 | radeon_crtc->bpc = 8; | |||
348 | } | |||
349 | ||||
350 | DRM_DEBUG_KMS("dp_clock %p %d\n", dig_connector, dig_connector->dp_clock)__drm_dbg(DRM_UT_KMS, "dp_clock %p %d\n", dig_connector, dig_connector ->dp_clock); | |||
351 | dp_clock = dig_connector->dp_clock; | |||
352 | radeon_crtc->ss_enabled = | |||
353 | radeon_atombios_get_asic_ss_info(rdev, &radeon_crtc->ss, | |||
354 | ASIC_INTERNAL_SS_ON_DP7, | |||
355 | dp_clock); | |||
356 | } | |||
357 | ||||
358 | static void | |||
359 | radeon_mst_encoder_dpms(struct drm_encoder *encoder, int mode) | |||
360 | { | |||
361 | struct drm_device *dev = encoder->dev; | |||
362 | struct radeon_device *rdev = dev->dev_private; | |||
363 | struct radeon_encoder *radeon_encoder, *primary; | |||
364 | struct radeon_encoder_mst *mst_enc; | |||
365 | struct radeon_encoder_atom_dig *dig_enc; | |||
366 | struct radeon_connector *radeon_connector; | |||
367 | struct drm_crtc *crtc; | |||
368 | struct radeon_crtc *radeon_crtc; | |||
369 | int ret, slots; | |||
370 | s64 fixed_pbn, fixed_pbn_per_slot, avg_time_slots_per_mtp; | |||
371 | if (!ASIC_IS_DCE5(rdev)((rdev->family >= CHIP_BARTS))) { | |||
372 | DRM_ERROR("got mst dpms on non-DCE5\n")__drm_err("got mst dpms on non-DCE5\n"); | |||
373 | return; | |||
374 | } | |||
375 | ||||
376 | radeon_connector = radeon_mst_find_connector(encoder); | |||
377 | if (!radeon_connector
| |||
378 | return; | |||
379 | ||||
380 | radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
381 | ||||
382 | mst_enc = radeon_encoder->enc_priv; | |||
383 | ||||
384 | primary = mst_enc->primary; | |||
385 | ||||
386 | dig_enc = primary->enc_priv; | |||
387 | ||||
388 | crtc = encoder->crtc; | |||
389 | DRM_DEBUG_KMS("got connector %d\n", dig_enc->active_mst_links)__drm_dbg(DRM_UT_KMS, "got connector %d\n", dig_enc->active_mst_links ); | |||
390 | ||||
391 | switch (mode) { | |||
392 | case DRM_MODE_DPMS_ON0: | |||
393 | dig_enc->active_mst_links++; | |||
394 | ||||
395 | radeon_crtc = to_radeon_crtc(crtc)({ const __typeof( ((struct radeon_crtc *)0)->base ) *__mptr = (crtc); (struct radeon_crtc *)( (char *)__mptr - __builtin_offsetof (struct radeon_crtc, base) );}); | |||
396 | ||||
397 | if (dig_enc->active_mst_links == 1) { | |||
398 | mst_enc->fe = dig_enc->dig_encoder; | |||
399 | mst_enc->fe_from_be = true1; | |||
400 | atombios_set_mst_encoder_crtc_source(encoder, mst_enc->fe); | |||
401 | ||||
402 | atombios_dig_encoder_setup(&primary->base, ATOM_ENCODER_CMD_SETUP0x0f, 0); | |||
403 | atombios_dig_transmitter_setup2(&primary->base, ATOM_TRANSMITTER_ACTION_ENABLE1, | |||
404 | 0, 0, dig_enc->dig_encoder); | |||
405 | ||||
406 | if (radeon_dp_needs_link_train(mst_enc->connector) || | |||
407 | dig_enc->active_mst_links == 1) { | |||
408 | radeon_dp_link_train(&primary->base, &mst_enc->connector->base); | |||
409 | } | |||
410 | ||||
411 | } else { | |||
412 | mst_enc->fe = radeon_atom_pick_dig_encoder(encoder, radeon_crtc->crtc_id); | |||
413 | if (mst_enc->fe == -1) | |||
414 | DRM_ERROR("failed to get frontend for dig encoder\n")__drm_err("failed to get frontend for dig encoder\n"); | |||
415 | mst_enc->fe_from_be = false0; | |||
416 | atombios_set_mst_encoder_crtc_source(encoder, mst_enc->fe); | |||
417 | } | |||
418 | ||||
419 | DRM_DEBUG_KMS("dig encoder is %d %d %d\n", dig_enc->dig_encoder,__drm_dbg(DRM_UT_KMS, "dig encoder is %d %d %d\n", dig_enc-> dig_encoder, dig_enc->linkb, radeon_crtc->crtc_id) | |||
420 | dig_enc->linkb, radeon_crtc->crtc_id)__drm_dbg(DRM_UT_KMS, "dig encoder is %d %d %d\n", dig_enc-> dig_encoder, dig_enc->linkb, radeon_crtc->crtc_id); | |||
421 | ||||
422 | slots = drm_dp_find_vcpi_slots(&radeon_connector->mst_port->mst_mgr, | |||
423 | mst_enc->pbn); | |||
424 | ret = drm_dp_mst_allocate_vcpi(&radeon_connector->mst_port->mst_mgr, | |||
425 | radeon_connector->port, | |||
426 | mst_enc->pbn, slots); | |||
427 | ret = drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr); | |||
428 | ||||
429 | radeon_dp_mst_set_be_cntl(primary, mst_enc, | |||
430 | radeon_connector->mst_port->hpd.hpd, true1); | |||
431 | ||||
432 | mst_enc->enc_active = true1; | |||
433 | radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary); | |||
434 | ||||
435 | fixed_pbn = drm_int2fixp(mst_enc->pbn); | |||
436 | fixed_pbn_per_slot = drm_int2fixp(radeon_connector->mst_port->mst_mgr.pbn_div); | |||
437 | avg_time_slots_per_mtp = drm_fixp_div(fixed_pbn, fixed_pbn_per_slot); | |||
438 | radeon_dp_mst_set_vcp_size(radeon_encoder, avg_time_slots_per_mtp); | |||
439 | ||||
440 | atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_ON0x0d, 0, | |||
441 | mst_enc->fe); | |||
442 | ret = drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr); | |||
443 | ||||
444 | ret = drm_dp_update_payload_part2(&radeon_connector->mst_port->mst_mgr); | |||
445 | ||||
446 | break; | |||
447 | case DRM_MODE_DPMS_STANDBY1: | |||
448 | case DRM_MODE_DPMS_SUSPEND2: | |||
449 | case DRM_MODE_DPMS_OFF3: | |||
450 | DRM_ERROR("DPMS OFF %d\n", dig_enc->active_mst_links)__drm_err("DPMS OFF %d\n", dig_enc->active_mst_links); | |||
451 | ||||
452 | if (!mst_enc->enc_active) | |||
453 | return; | |||
454 | ||||
455 | drm_dp_mst_reset_vcpi_slots(&radeon_connector->mst_port->mst_mgr, mst_enc->port); | |||
456 | ret = drm_dp_update_payload_part1(&radeon_connector->mst_port->mst_mgr); | |||
457 | ||||
458 | drm_dp_check_act_status(&radeon_connector->mst_port->mst_mgr); | |||
459 | /* and this can also fail */ | |||
460 | drm_dp_update_payload_part2(&radeon_connector->mst_port->mst_mgr); | |||
461 | ||||
462 | drm_dp_mst_deallocate_vcpi(&radeon_connector->mst_port->mst_mgr, mst_enc->port); | |||
463 | ||||
464 | mst_enc->enc_active = false0; | |||
465 | radeon_dp_mst_update_stream_attribs(radeon_connector->mst_port, primary); | |||
466 | ||||
467 | radeon_dp_mst_set_be_cntl(primary, mst_enc, | |||
468 | radeon_connector->mst_port->hpd.hpd, false0); | |||
469 | atombios_dig_encoder_setup2(&primary->base, ATOM_ENCODER_CMD_DP_VIDEO_OFF0x0c, 0, | |||
470 | mst_enc->fe); | |||
471 | ||||
472 | if (!mst_enc->fe_from_be) | |||
473 | radeon_atom_release_dig_encoder(rdev, mst_enc->fe); | |||
474 | ||||
475 | mst_enc->fe_from_be = false0; | |||
476 | dig_enc->active_mst_links--; | |||
477 | if (dig_enc->active_mst_links == 0) { | |||
478 | /* drop link */ | |||
479 | } | |||
480 | ||||
481 | break; | |||
482 | } | |||
483 | ||||
484 | } | |||
485 | ||||
486 | static bool_Bool radeon_mst_mode_fixup(struct drm_encoder *encoder, | |||
487 | const struct drm_display_mode *mode, | |||
488 | struct drm_display_mode *adjusted_mode) | |||
489 | { | |||
490 | struct radeon_encoder_mst *mst_enc; | |||
491 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
492 | struct radeon_connector_atom_dig *dig_connector; | |||
493 | int bpp = 24; | |||
494 | ||||
495 | mst_enc = radeon_encoder->enc_priv; | |||
496 | ||||
497 | mst_enc->pbn = drm_dp_calc_pbn_mode(adjusted_mode->clock, bpp, false0); | |||
498 | ||||
499 | mst_enc->primary->active_device = mst_enc->primary->devices & mst_enc->connector->devices; | |||
500 | DRM_DEBUG_KMS("setting active device to %08x from %08x %08x for encoder %d\n",__drm_dbg(DRM_UT_KMS, "setting active device to %08x from %08x %08x for encoder %d\n" , mst_enc->primary->active_device, mst_enc->primary-> devices, mst_enc->connector->devices, mst_enc->primary ->base.encoder_type) | |||
501 | mst_enc->primary->active_device, mst_enc->primary->devices,__drm_dbg(DRM_UT_KMS, "setting active device to %08x from %08x %08x for encoder %d\n" , mst_enc->primary->active_device, mst_enc->primary-> devices, mst_enc->connector->devices, mst_enc->primary ->base.encoder_type) | |||
502 | mst_enc->connector->devices, mst_enc->primary->base.encoder_type)__drm_dbg(DRM_UT_KMS, "setting active device to %08x from %08x %08x for encoder %d\n" , mst_enc->primary->active_device, mst_enc->primary-> devices, mst_enc->connector->devices, mst_enc->primary ->base.encoder_type); | |||
503 | ||||
504 | ||||
505 | drm_mode_set_crtcinfo(adjusted_mode, 0); | |||
506 | dig_connector = mst_enc->connector->con_priv; | |||
507 | dig_connector->dp_lane_count = drm_dp_max_lane_count(dig_connector->dpcd); | |||
508 | dig_connector->dp_clock = drm_dp_max_link_rate(dig_connector->dpcd); | |||
509 | DRM_DEBUG_KMS("dig clock %p %d %d\n", dig_connector,__drm_dbg(DRM_UT_KMS, "dig clock %p %d %d\n", dig_connector, dig_connector ->dp_lane_count, dig_connector->dp_clock) | |||
510 | dig_connector->dp_lane_count, dig_connector->dp_clock)__drm_dbg(DRM_UT_KMS, "dig clock %p %d %d\n", dig_connector, dig_connector ->dp_lane_count, dig_connector->dp_clock); | |||
511 | return true1; | |||
512 | } | |||
513 | ||||
514 | static void radeon_mst_encoder_prepare(struct drm_encoder *encoder) | |||
515 | { | |||
516 | struct radeon_connector *radeon_connector; | |||
517 | struct radeon_encoder *radeon_encoder, *primary; | |||
518 | struct radeon_encoder_mst *mst_enc; | |||
519 | struct radeon_encoder_atom_dig *dig_enc; | |||
520 | ||||
521 | radeon_connector = radeon_mst_find_connector(encoder); | |||
522 | if (!radeon_connector) { | |||
523 | DRM_DEBUG_KMS("failed to find connector %p\n", encoder)__drm_dbg(DRM_UT_KMS, "failed to find connector %p\n", encoder ); | |||
524 | return; | |||
525 | } | |||
526 | radeon_encoder = to_radeon_encoder(encoder)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (encoder); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
527 | ||||
528 | radeon_mst_encoder_dpms(encoder, DRM_MODE_DPMS_OFF3); | |||
529 | ||||
530 | mst_enc = radeon_encoder->enc_priv; | |||
531 | ||||
532 | primary = mst_enc->primary; | |||
533 | ||||
534 | dig_enc = primary->enc_priv; | |||
535 | ||||
536 | mst_enc->port = radeon_connector->port; | |||
537 | ||||
538 | if (dig_enc->dig_encoder == -1) { | |||
539 | dig_enc->dig_encoder = radeon_atom_pick_dig_encoder(&primary->base, -1); | |||
540 | primary->offset = radeon_atom_set_enc_offset(dig_enc->dig_encoder); | |||
541 | atombios_set_mst_encoder_crtc_source(encoder, dig_enc->dig_encoder); | |||
542 | ||||
543 | ||||
544 | } | |||
545 | DRM_DEBUG_KMS("%d %d\n", dig_enc->dig_encoder, primary->offset)__drm_dbg(DRM_UT_KMS, "%d %d\n", dig_enc->dig_encoder, primary ->offset); | |||
546 | } | |||
547 | ||||
548 | static void | |||
549 | radeon_mst_encoder_mode_set(struct drm_encoder *encoder, | |||
550 | struct drm_display_mode *mode, | |||
551 | struct drm_display_mode *adjusted_mode) | |||
552 | { | |||
553 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
554 | } | |||
555 | ||||
556 | static void radeon_mst_encoder_commit(struct drm_encoder *encoder) | |||
557 | { | |||
558 | radeon_mst_encoder_dpms(encoder, DRM_MODE_DPMS_ON0); | |||
| ||||
559 | DRM_DEBUG_KMS("\n")__drm_dbg(DRM_UT_KMS, "\n"); | |||
560 | } | |||
561 | ||||
562 | static const struct drm_encoder_helper_funcs radeon_mst_helper_funcs = { | |||
563 | .dpms = radeon_mst_encoder_dpms, | |||
564 | .mode_fixup = radeon_mst_mode_fixup, | |||
565 | .prepare = radeon_mst_encoder_prepare, | |||
566 | .mode_set = radeon_mst_encoder_mode_set, | |||
567 | .commit = radeon_mst_encoder_commit, | |||
568 | }; | |||
569 | ||||
570 | static void radeon_dp_mst_encoder_destroy(struct drm_encoder *encoder) | |||
571 | { | |||
572 | drm_encoder_cleanup(encoder); | |||
573 | kfree(encoder); | |||
574 | } | |||
575 | ||||
576 | static const struct drm_encoder_funcs radeon_dp_mst_enc_funcs = { | |||
577 | .destroy = radeon_dp_mst_encoder_destroy, | |||
578 | }; | |||
579 | ||||
580 | static struct radeon_encoder * | |||
581 | radeon_dp_create_fake_mst_encoder(struct radeon_connector *connector) | |||
582 | { | |||
583 | struct drm_device *dev = connector->base.dev; | |||
584 | struct radeon_device *rdev = dev->dev_private; | |||
585 | struct radeon_encoder *radeon_encoder; | |||
586 | struct radeon_encoder_mst *mst_enc; | |||
587 | struct drm_encoder *encoder; | |||
588 | const struct drm_connector_helper_funcs *connector_funcs = connector->base.helper_private; | |||
589 | struct drm_encoder *enc_master = connector_funcs->best_encoder(&connector->base); | |||
590 | ||||
591 | DRM_DEBUG_KMS("enc master is %p\n", enc_master)__drm_dbg(DRM_UT_KMS, "enc master is %p\n", enc_master); | |||
592 | radeon_encoder = kzalloc(sizeof(*radeon_encoder), GFP_KERNEL(0x0001 | 0x0004)); | |||
593 | if (!radeon_encoder) | |||
594 | return NULL((void *)0); | |||
595 | ||||
596 | radeon_encoder->enc_priv = kzalloc(sizeof(*mst_enc), GFP_KERNEL(0x0001 | 0x0004)); | |||
597 | if (!radeon_encoder->enc_priv) { | |||
598 | kfree(radeon_encoder); | |||
599 | return NULL((void *)0); | |||
600 | } | |||
601 | encoder = &radeon_encoder->base; | |||
602 | switch (rdev->num_crtc) { | |||
603 | case 1: | |||
604 | encoder->possible_crtcs = 0x1; | |||
605 | break; | |||
606 | case 2: | |||
607 | default: | |||
608 | encoder->possible_crtcs = 0x3; | |||
609 | break; | |||
610 | case 4: | |||
611 | encoder->possible_crtcs = 0xf; | |||
612 | break; | |||
613 | case 6: | |||
614 | encoder->possible_crtcs = 0x3f; | |||
615 | break; | |||
616 | } | |||
617 | ||||
618 | drm_encoder_init(dev, &radeon_encoder->base, &radeon_dp_mst_enc_funcs, | |||
619 | DRM_MODE_ENCODER_DPMST7, NULL((void *)0)); | |||
620 | drm_encoder_helper_add(encoder, &radeon_mst_helper_funcs); | |||
621 | ||||
622 | mst_enc = radeon_encoder->enc_priv; | |||
623 | mst_enc->connector = connector; | |||
624 | mst_enc->primary = to_radeon_encoder(enc_master)({ const __typeof( ((struct radeon_encoder *)0)->base ) *__mptr = (enc_master); (struct radeon_encoder *)( (char *)__mptr - __builtin_offsetof (struct radeon_encoder, base) );}); | |||
625 | radeon_encoder->is_mst_encoder = true1; | |||
626 | return radeon_encoder; | |||
627 | } | |||
628 | ||||
629 | int | |||
630 | radeon_dp_mst_init(struct radeon_connector *radeon_connector) | |||
631 | { | |||
632 | struct drm_device *dev = radeon_connector->base.dev; | |||
633 | ||||
634 | if (!radeon_connector->ddc_bus->has_aux) | |||
635 | return 0; | |||
636 | ||||
637 | radeon_connector->mst_mgr.cbs = &mst_cbs; | |||
638 | return drm_dp_mst_topology_mgr_init(&radeon_connector->mst_mgr, dev, | |||
639 | &radeon_connector->ddc_bus->aux, 16, 6, | |||
640 | radeon_connector->base.base.id); | |||
641 | } | |||
642 | ||||
643 | int | |||
644 | radeon_dp_mst_probe(struct radeon_connector *radeon_connector) | |||
645 | { | |||
646 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | |||
647 | struct drm_device *dev = radeon_connector->base.dev; | |||
648 | struct radeon_device *rdev = dev->dev_private; | |||
649 | int ret; | |||
650 | u8 msg[1]; | |||
651 | ||||
652 | if (!radeon_mst) | |||
653 | return 0; | |||
654 | ||||
655 | if (!ASIC_IS_DCE5(rdev)((rdev->family >= CHIP_BARTS))) | |||
656 | return 0; | |||
657 | ||||
658 | if (dig_connector->dpcd[DP_DPCD_REV0x000] < 0x12) | |||
659 | return 0; | |||
660 | ||||
661 | ret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_MSTM_CAP0x021, msg, | |||
662 | 1); | |||
663 | if (ret) { | |||
664 | if (msg[0] & DP_MST_CAP(1 << 0)) { | |||
665 | DRM_DEBUG_KMS("Sink is MST capable\n")__drm_dbg(DRM_UT_KMS, "Sink is MST capable\n"); | |||
666 | dig_connector->is_mst = true1; | |||
667 | } else { | |||
668 | DRM_DEBUG_KMS("Sink is not MST capable\n")__drm_dbg(DRM_UT_KMS, "Sink is not MST capable\n"); | |||
669 | dig_connector->is_mst = false0; | |||
670 | } | |||
671 | ||||
672 | } | |||
673 | drm_dp_mst_topology_mgr_set_mst(&radeon_connector->mst_mgr, | |||
674 | dig_connector->is_mst); | |||
675 | return dig_connector->is_mst; | |||
676 | } | |||
677 | ||||
678 | int | |||
679 | radeon_dp_mst_check_status(struct radeon_connector *radeon_connector) | |||
680 | { | |||
681 | struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv; | |||
682 | int retry; | |||
683 | ||||
684 | if (dig_connector->is_mst) { | |||
685 | u8 esi[16] = { 0 }; | |||
686 | int dret; | |||
687 | int ret = 0; | |||
688 | bool_Bool handled; | |||
689 | ||||
690 | dret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, | |||
691 | DP_SINK_COUNT_ESI0x2002, esi, 8); | |||
692 | go_again: | |||
693 | if (dret == 8) { | |||
694 | DRM_DEBUG_KMS("got esi %3ph\n", esi)__drm_dbg(DRM_UT_KMS, "got esi %3ph\n", esi); | |||
695 | ret = drm_dp_mst_hpd_irq(&radeon_connector->mst_mgr, esi, &handled); | |||
696 | ||||
697 | if (handled) { | |||
698 | for (retry = 0; retry < 3; retry++) { | |||
699 | int wret; | |||
700 | wret = drm_dp_dpcd_write(&radeon_connector->ddc_bus->aux, | |||
701 | DP_SINK_COUNT_ESI0x2002 + 1, &esi[1], 3); | |||
702 | if (wret == 3) | |||
703 | break; | |||
704 | } | |||
705 | ||||
706 | dret = drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, | |||
707 | DP_SINK_COUNT_ESI0x2002, esi, 8); | |||
708 | if (dret == 8) { | |||
709 | DRM_DEBUG_KMS("got esi2 %3ph\n", esi)__drm_dbg(DRM_UT_KMS, "got esi2 %3ph\n", esi); | |||
710 | goto go_again; | |||
711 | } | |||
712 | } else | |||
713 | ret = 0; | |||
714 | ||||
715 | return ret; | |||
716 | } else { | |||
717 | DRM_DEBUG_KMS("failed to get ESI - device may have failed %d\n", ret)__drm_dbg(DRM_UT_KMS, "failed to get ESI - device may have failed %d\n" , ret); | |||
718 | dig_connector->is_mst = false0; | |||
719 | drm_dp_mst_topology_mgr_set_mst(&radeon_connector->mst_mgr, | |||
720 | dig_connector->is_mst); | |||
721 | /* send a hotplug event */ | |||
722 | } | |||
723 | } | |||
724 | return -EINVAL22; | |||
725 | } | |||
726 | ||||
727 | #if defined(CONFIG_DEBUG_FS) | |||
728 | ||||
729 | static int radeon_debugfs_mst_info(struct seq_file *m, void *data) | |||
730 | { | |||
731 | struct drm_info_node *node = (struct drm_info_node *)m->private; | |||
732 | struct drm_device *dev = node->minor->dev; | |||
733 | struct drm_connector *connector; | |||
734 | struct radeon_connector *radeon_connector; | |||
735 | struct radeon_connector_atom_dig *dig_connector; | |||
736 | int i; | |||
737 | ||||
738 | drm_modeset_lock_all(dev); | |||
739 | list_for_each_entry(connector, &dev->mode_config.connector_list, head)for (connector = ({ const __typeof( ((__typeof(*connector) *) 0)->head ) *__mptr = ((&dev->mode_config.connector_list )->next); (__typeof(*connector) *)( (char *)__mptr - __builtin_offsetof (__typeof(*connector), head) );}); &connector->head != (&dev->mode_config.connector_list); connector = ({ const __typeof( ((__typeof(*connector) *)0)->head ) *__mptr = ( connector->head.next); (__typeof(*connector) *)( (char *)__mptr - __builtin_offsetof(__typeof(*connector), head) );})) { | |||
740 | if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort10) | |||
741 | continue; | |||
742 | ||||
743 | radeon_connector = to_radeon_connector(connector)({ const __typeof( ((struct radeon_connector *)0)->base ) * __mptr = (connector); (struct radeon_connector *)( (char *)__mptr - __builtin_offsetof(struct radeon_connector, base) );}); | |||
744 | dig_connector = radeon_connector->con_priv; | |||
745 | if (radeon_connector->is_mst_connector) | |||
746 | continue; | |||
747 | if (!dig_connector->is_mst) | |||
748 | continue; | |||
749 | drm_dp_mst_dump_topology(m, &radeon_connector->mst_mgr); | |||
750 | ||||
751 | for (i = 0; i < radeon_connector->enabled_attribs; i++) | |||
752 | seq_printf(m, "attrib %d: %d %d\n", i, | |||
753 | radeon_connector->cur_stream_attribs[i].fe, | |||
754 | radeon_connector->cur_stream_attribs[i].slots); | |||
755 | } | |||
756 | drm_modeset_unlock_all(dev); | |||
757 | return 0; | |||
758 | } | |||
759 | ||||
760 | static struct drm_info_list radeon_debugfs_mst_list[] = { | |||
761 | {"radeon_mst_info", &radeon_debugfs_mst_info, 0, NULL((void *)0)}, | |||
762 | }; | |||
763 | #endif | |||
764 | ||||
765 | int radeon_mst_debugfs_init(struct radeon_device *rdev) | |||
766 | { | |||
767 | #if defined(CONFIG_DEBUG_FS) | |||
768 | return radeon_debugfs_add_files(rdev, radeon_debugfs_mst_list, 1); | |||
769 | #endif | |||
770 | return 0; | |||
771 | } |