Blame view

drivers/gpu/drm/radeon/r600.c 132 KB
771fe6b91   Jerome Glisse   drm/radeon: intro...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
  /*
   * Copyright 2008 Advanced Micro Devices, Inc.
   * Copyright 2008 Red Hat Inc.
   * Copyright 2009 Jerome Glisse.
   *
   * Permission is hereby granted, free of charge, to any person obtaining a
   * copy of this software and associated documentation files (the "Software"),
   * to deal in the Software without restriction, including without limitation
   * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   * and/or sell copies of the Software, and to permit persons to whom the
   * Software is furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
   * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   * OTHER DEALINGS IN THE SOFTWARE.
   *
   * Authors: Dave Airlie
   *          Alex Deucher
   *          Jerome Glisse
   */
5a0e3ad6a   Tejun Heo   include cleanup: ...
28
  #include <linux/slab.h>
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
29
30
  #include <linux/seq_file.h>
  #include <linux/firmware.h>
e0cd36081   Paul Gortmaker   gpu: add module.h...
31
  #include <linux/module.h>
760285e7e   David Howells   UAPI: (Scripted) ...
32
33
  #include <drm/drmP.h>
  #include <drm/radeon_drm.h>
771fe6b91   Jerome Glisse   drm/radeon: intro...
34
  #include "radeon.h"
e6990375e   Daniel Vetter   drm/radeon: inclu...
35
  #include "radeon_asic.h"
bfc1f97d8   Slava Grigorev   radeon/audio: con...
36
  #include "radeon_audio.h"
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
37
  #include "radeon_mode.h"
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
38
  #include "r600d.h"
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
39
  #include "atom.h"
d39c3b895   Jerome Glisse   drm/radeon/kms: C...
40
  #include "avivod.h"
138e4e16f   Alex Deucher   drm/radeon/kms: m...
41
  #include "radeon_ucode.h"
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
  
  /* Firmware Names */
  MODULE_FIRMWARE("radeon/R600_pfp.bin");
  MODULE_FIRMWARE("radeon/R600_me.bin");
  MODULE_FIRMWARE("radeon/RV610_pfp.bin");
  MODULE_FIRMWARE("radeon/RV610_me.bin");
  MODULE_FIRMWARE("radeon/RV630_pfp.bin");
  MODULE_FIRMWARE("radeon/RV630_me.bin");
  MODULE_FIRMWARE("radeon/RV620_pfp.bin");
  MODULE_FIRMWARE("radeon/RV620_me.bin");
  MODULE_FIRMWARE("radeon/RV635_pfp.bin");
  MODULE_FIRMWARE("radeon/RV635_me.bin");
  MODULE_FIRMWARE("radeon/RV670_pfp.bin");
  MODULE_FIRMWARE("radeon/RV670_me.bin");
  MODULE_FIRMWARE("radeon/RS780_pfp.bin");
  MODULE_FIRMWARE("radeon/RS780_me.bin");
  MODULE_FIRMWARE("radeon/RV770_pfp.bin");
  MODULE_FIRMWARE("radeon/RV770_me.bin");
66229b200   Alex Deucher   drm/radeon/kms: a...
60
  MODULE_FIRMWARE("radeon/RV770_smc.bin");
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
61
62
  MODULE_FIRMWARE("radeon/RV730_pfp.bin");
  MODULE_FIRMWARE("radeon/RV730_me.bin");
66229b200   Alex Deucher   drm/radeon/kms: a...
63
64
  MODULE_FIRMWARE("radeon/RV730_smc.bin");
  MODULE_FIRMWARE("radeon/RV740_smc.bin");
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
65
66
  MODULE_FIRMWARE("radeon/RV710_pfp.bin");
  MODULE_FIRMWARE("radeon/RV710_me.bin");
66229b200   Alex Deucher   drm/radeon/kms: a...
67
  MODULE_FIRMWARE("radeon/RV710_smc.bin");
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
68
69
  MODULE_FIRMWARE("radeon/R600_rlc.bin");
  MODULE_FIRMWARE("radeon/R700_rlc.bin");
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
70
71
  MODULE_FIRMWARE("radeon/CEDAR_pfp.bin");
  MODULE_FIRMWARE("radeon/CEDAR_me.bin");
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
72
  MODULE_FIRMWARE("radeon/CEDAR_rlc.bin");
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
73
  MODULE_FIRMWARE("radeon/CEDAR_smc.bin");
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
74
75
  MODULE_FIRMWARE("radeon/REDWOOD_pfp.bin");
  MODULE_FIRMWARE("radeon/REDWOOD_me.bin");
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
76
  MODULE_FIRMWARE("radeon/REDWOOD_rlc.bin");
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
77
  MODULE_FIRMWARE("radeon/REDWOOD_smc.bin");
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
78
79
  MODULE_FIRMWARE("radeon/JUNIPER_pfp.bin");
  MODULE_FIRMWARE("radeon/JUNIPER_me.bin");
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
80
  MODULE_FIRMWARE("radeon/JUNIPER_rlc.bin");
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
81
  MODULE_FIRMWARE("radeon/JUNIPER_smc.bin");
a7433742d   Dave Airlie   drm/radeon: fix c...
82
  MODULE_FIRMWARE("radeon/CYPRESS_pfp.bin");
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
83
  MODULE_FIRMWARE("radeon/CYPRESS_me.bin");
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
84
  MODULE_FIRMWARE("radeon/CYPRESS_rlc.bin");
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
85
  MODULE_FIRMWARE("radeon/CYPRESS_smc.bin");
439bd6cde   Alex Deucher   drm/radeon/kms: a...
86
87
88
  MODULE_FIRMWARE("radeon/PALM_pfp.bin");
  MODULE_FIRMWARE("radeon/PALM_me.bin");
  MODULE_FIRMWARE("radeon/SUMO_rlc.bin");
d5c5a72f2   Alex Deucher   drm/radeon/kms: a...
89
90
91
92
  MODULE_FIRMWARE("radeon/SUMO_pfp.bin");
  MODULE_FIRMWARE("radeon/SUMO_me.bin");
  MODULE_FIRMWARE("radeon/SUMO2_pfp.bin");
  MODULE_FIRMWARE("radeon/SUMO2_me.bin");
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
93

f13f7731a   Alex Deucher   drm/radeon: use s...
94
95
96
97
98
  static const u32 crtc_offsets[2] =
  {
  	0,
  	AVIVO_D2CRTC_H_TOTAL - AVIVO_D1CRTC_H_TOTAL
  };
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
99
  int r600_debugfs_mc_info_init(struct radeon_device *rdev);
771fe6b91   Jerome Glisse   drm/radeon: intro...
100

1a029b768   Jerome Glisse   drm/radeon/kms: F...
101
  /* r600,rv610,rv630,rv620,rv635,rv670 */
771fe6b91   Jerome Glisse   drm/radeon: intro...
102
  int r600_mc_wait_for_idle(struct radeon_device *rdev);
1109ca09b   Lauri Kasanen   drm/radeon: Mark ...
103
  static void r600_gpu_init(struct radeon_device *rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
104
  void r600_fini(struct radeon_device *rdev);
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
105
  void r600_irq_disable(struct radeon_device *rdev);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
106
  static void r600_pcie_gen2_enable(struct radeon_device *rdev);
2948f5e6c   Alex Deucher   drm/radeon: prope...
107
  extern int evergreen_rlc_resume(struct radeon_device *rdev);
de9ae7447   Alex Deucher   drm/radeon: imple...
108
  extern void rv770_set_clk_bypass_mode(struct radeon_device *rdev);
771fe6b91   Jerome Glisse   drm/radeon: intro...
109

454d2e2a3   Alex Deucher   drm/radeon: add a...
110
111
112
113
114
115
116
117
118
119
120
121
  /**
   * r600_get_xclk - get the xclk
   *
   * @rdev: radeon_device pointer
   *
   * Returns the reference clock used by the gfx engine
   * (r6xx, IGPs, APUs).
   */
  u32 r600_get_xclk(struct radeon_device *rdev)
  {
  	return rdev->clock.spll.reference_freq;
  }
1b9ba70a4   Alex Deucher   drm/radeon/r6xx: ...
122
123
  int r600_set_uvd_clocks(struct radeon_device *rdev, u32 vclk, u32 dclk)
  {
4a956a70a   Alex Deucher   drm/radeon: add s...
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
  	unsigned fb_div = 0, ref_div, vclk_div = 0, dclk_div = 0;
  	int r;
  
  	/* bypass vclk and dclk with bclk */
  	WREG32_P(CG_UPLL_FUNC_CNTL_2,
  		 VCLK_SRC_SEL(1) | DCLK_SRC_SEL(1),
  		 ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
  
  	/* assert BYPASS_EN, deassert UPLL_RESET, UPLL_SLEEP and UPLL_CTLREQ */
  	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_BYPASS_EN_MASK, ~(
  		 UPLL_RESET_MASK | UPLL_SLEEP_MASK | UPLL_CTLREQ_MASK));
  
  	if (rdev->family >= CHIP_RS780)
  		WREG32_P(GFX_MACRO_BYPASS_CNTL, UPLL_BYPASS_CNTL,
  			 ~UPLL_BYPASS_CNTL);
  
  	if (!vclk || !dclk) {
  		/* keep the Bypass mode, put PLL to sleep */
  		WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_SLEEP_MASK, ~UPLL_SLEEP_MASK);
  		return 0;
  	}
  
  	if (rdev->clock.spll.reference_freq == 10000)
  		ref_div = 34;
  	else
  		ref_div = 4;
  
  	r = radeon_uvd_calc_upll_dividers(rdev, vclk, dclk, 50000, 160000,
  					  ref_div + 1, 0xFFF, 2, 30, ~0,
  					  &fb_div, &vclk_div, &dclk_div);
  	if (r)
  		return r;
  
  	if (rdev->family >= CHIP_RV670 && rdev->family < CHIP_RS780)
  		fb_div >>= 1;
  	else
  		fb_div |= 1;
  
  	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
          if (r)
                  return r;
  
  	/* assert PLL_RESET */
  	WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_RESET_MASK, ~UPLL_RESET_MASK);
  
  	/* For RS780 we have to choose ref clk */
  	if (rdev->family >= CHIP_RS780)
  		WREG32_P(CG_UPLL_FUNC_CNTL, UPLL_REFCLK_SRC_SEL_MASK,
  			 ~UPLL_REFCLK_SRC_SEL_MASK);
  
  	/* set the required fb, ref and post divder values */
  	WREG32_P(CG_UPLL_FUNC_CNTL,
  		 UPLL_FB_DIV(fb_div) |
  		 UPLL_REF_DIV(ref_div),
  		 ~(UPLL_FB_DIV_MASK | UPLL_REF_DIV_MASK));
  	WREG32_P(CG_UPLL_FUNC_CNTL_2,
  		 UPLL_SW_HILEN(vclk_div >> 1) |
  		 UPLL_SW_LOLEN((vclk_div >> 1) + (vclk_div & 1)) |
  		 UPLL_SW_HILEN2(dclk_div >> 1) |
  		 UPLL_SW_LOLEN2((dclk_div >> 1) + (dclk_div & 1)) |
  		 UPLL_DIVEN_MASK | UPLL_DIVEN2_MASK,
  		 ~UPLL_SW_MASK);
  
  	/* give the PLL some time to settle */
  	mdelay(15);
  
  	/* deassert PLL_RESET */
  	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_RESET_MASK);
  
  	mdelay(15);
  
  	/* deassert BYPASS EN */
  	WREG32_P(CG_UPLL_FUNC_CNTL, 0, ~UPLL_BYPASS_EN_MASK);
  
  	if (rdev->family >= CHIP_RS780)
  		WREG32_P(GFX_MACRO_BYPASS_CNTL, 0, ~UPLL_BYPASS_CNTL);
  
  	r = radeon_uvd_send_upll_ctlreq(rdev, CG_UPLL_FUNC_CNTL);
  	if (r)
  		return r;
  
  	/* switch VCLK and DCLK selection */
  	WREG32_P(CG_UPLL_FUNC_CNTL_2,
  		 VCLK_SRC_SEL(2) | DCLK_SRC_SEL(2),
  		 ~(VCLK_SRC_SEL_MASK | DCLK_SRC_SEL_MASK));
  
  	mdelay(100);
1b9ba70a4   Alex Deucher   drm/radeon/r6xx: ...
211
212
  	return 0;
  }
134b480f4   Alex Deucher   drm/radeon: Add s...
213
214
215
216
217
218
219
220
221
  void dce3_program_fmt(struct drm_encoder *encoder)
  {
  	struct drm_device *dev = encoder->dev;
  	struct radeon_device *rdev = dev->dev_private;
  	struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
  	struct radeon_crtc *radeon_crtc = to_radeon_crtc(encoder->crtc);
  	struct drm_connector *connector = radeon_get_connector_for_encoder(encoder);
  	int bpc = 0;
  	u32 tmp = 0;
6214bb748   Alex Deucher   drm/radeon: add a...
222
  	enum radeon_connector_dither dither = RADEON_FMT_DITHER_DISABLE;
134b480f4   Alex Deucher   drm/radeon: Add s...
223

6214bb748   Alex Deucher   drm/radeon: add a...
224
225
  	if (connector) {
  		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
134b480f4   Alex Deucher   drm/radeon: Add s...
226
  		bpc = radeon_get_monitor_bpc(connector);
6214bb748   Alex Deucher   drm/radeon: add a...
227
228
  		dither = radeon_connector->dither;
  	}
134b480f4   Alex Deucher   drm/radeon: Add s...
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
  
  	/* LVDS FMT is set up by atom */
  	if (radeon_encoder->devices & ATOM_DEVICE_LCD_SUPPORT)
  		return;
  
  	/* not needed for analog */
  	if ((radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC1) ||
  	    (radeon_encoder->encoder_id == ENCODER_OBJECT_ID_INTERNAL_KLDSCP_DAC2))
  		return;
  
  	if (bpc == 0)
  		return;
  
  	switch (bpc) {
  	case 6:
6214bb748   Alex Deucher   drm/radeon: add a...
244
  		if (dither == RADEON_FMT_DITHER_ENABLE)
134b480f4   Alex Deucher   drm/radeon: Add s...
245
246
247
248
249
250
  			/* XXX sort out optimal dither settings */
  			tmp |= FMT_SPATIAL_DITHER_EN;
  		else
  			tmp |= FMT_TRUNCATE_EN;
  		break;
  	case 8:
6214bb748   Alex Deucher   drm/radeon: add a...
251
  		if (dither == RADEON_FMT_DITHER_ENABLE)
134b480f4   Alex Deucher   drm/radeon: Add s...
252
253
254
255
256
257
258
259
260
261
262
263
264
  			/* XXX sort out optimal dither settings */
  			tmp |= (FMT_SPATIAL_DITHER_EN | FMT_SPATIAL_DITHER_DEPTH);
  		else
  			tmp |= (FMT_TRUNCATE_EN | FMT_TRUNCATE_DEPTH);
  		break;
  	case 10:
  	default:
  		/* not needed */
  		break;
  	}
  
  	WREG32(FMT_BIT_DEPTH_CONTROL + radeon_crtc->crtc_offset, tmp);
  }
21a8122ad   Alex Deucher   drm/radeon/kms: a...
265
  /* get temperature in millidegrees */
20d391d72   Alex Deucher   drm/radeon/kms: r...
266
  int rv6xx_get_temp(struct radeon_device *rdev)
21a8122ad   Alex Deucher   drm/radeon/kms: a...
267
268
269
  {
  	u32 temp = (RREG32(CG_THERMAL_STATUS) & ASIC_T_MASK) >>
  		ASIC_T_SHIFT;
20d391d72   Alex Deucher   drm/radeon/kms: r...
270
  	int actual_temp = temp & 0xff;
21a8122ad   Alex Deucher   drm/radeon/kms: a...
271

20d391d72   Alex Deucher   drm/radeon/kms: r...
272
273
274
275
  	if (temp & 0x100)
  		actual_temp -= 256;
  
  	return actual_temp * 1000;
21a8122ad   Alex Deucher   drm/radeon/kms: a...
276
  }
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
277
  void r600_pm_get_dynpm_state(struct radeon_device *rdev)
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
278
279
  {
  	int i;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
280
281
  	rdev->pm.dynpm_can_upclock = true;
  	rdev->pm.dynpm_can_downclock = true;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
282
283
284
285
286
287
288
  
  	/* power state array is low to high, default is first */
  	if ((rdev->flags & RADEON_IS_IGP) || (rdev->family == CHIP_R600)) {
  		int min_power_state_index = 0;
  
  		if (rdev->pm.num_power_states > 2)
  			min_power_state_index = 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
289
290
  		switch (rdev->pm.dynpm_planned_action) {
  		case DYNPM_ACTION_MINIMUM:
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
291
292
  			rdev->pm.requested_power_state_index = min_power_state_index;
  			rdev->pm.requested_clock_mode_index = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
293
  			rdev->pm.dynpm_can_downclock = false;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
294
  			break;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
295
  		case DYNPM_ACTION_DOWNCLOCK:
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
296
297
  			if (rdev->pm.current_power_state_index == min_power_state_index) {
  				rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
298
  				rdev->pm.dynpm_can_downclock = false;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
299
300
301
  			} else {
  				if (rdev->pm.active_crtc_count > 1) {
  					for (i = 0; i < rdev->pm.num_power_states; i++) {
d7311171c   Alex Deucher   drm/radeon/kms/pm...
302
  						if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
303
304
305
306
307
308
309
310
311
312
  							continue;
  						else if (i >= rdev->pm.current_power_state_index) {
  							rdev->pm.requested_power_state_index =
  								rdev->pm.current_power_state_index;
  							break;
  						} else {
  							rdev->pm.requested_power_state_index = i;
  							break;
  						}
  					}
773c3fa3a   Alex Deucher   drm/radeon/kms/pm...
313
314
315
316
317
318
319
320
  				} else {
  					if (rdev->pm.current_power_state_index == 0)
  						rdev->pm.requested_power_state_index =
  							rdev->pm.num_power_states - 1;
  					else
  						rdev->pm.requested_power_state_index =
  							rdev->pm.current_power_state_index - 1;
  				}
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
321
322
  			}
  			rdev->pm.requested_clock_mode_index = 0;
d7311171c   Alex Deucher   drm/radeon/kms/pm...
323
324
325
326
327
328
329
  			/* don't use the power state if crtcs are active and no display flag is set */
  			if ((rdev->pm.active_crtc_count > 0) &&
  			    (rdev->pm.power_state[rdev->pm.requested_power_state_index].
  			     clock_info[rdev->pm.requested_clock_mode_index].flags &
  			     RADEON_PM_MODE_NO_DISPLAY)) {
  				rdev->pm.requested_power_state_index++;
  			}
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
330
  			break;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
331
  		case DYNPM_ACTION_UPCLOCK:
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
332
333
  			if (rdev->pm.current_power_state_index == (rdev->pm.num_power_states - 1)) {
  				rdev->pm.requested_power_state_index = rdev->pm.current_power_state_index;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
334
  				rdev->pm.dynpm_can_upclock = false;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
335
336
337
  			} else {
  				if (rdev->pm.active_crtc_count > 1) {
  					for (i = (rdev->pm.num_power_states - 1); i >= 0; i--) {
d7311171c   Alex Deucher   drm/radeon/kms/pm...
338
  						if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
  							continue;
  						else if (i <= rdev->pm.current_power_state_index) {
  							rdev->pm.requested_power_state_index =
  								rdev->pm.current_power_state_index;
  							break;
  						} else {
  							rdev->pm.requested_power_state_index = i;
  							break;
  						}
  					}
  				} else
  					rdev->pm.requested_power_state_index =
  						rdev->pm.current_power_state_index + 1;
  			}
  			rdev->pm.requested_clock_mode_index = 0;
  			break;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
355
  		case DYNPM_ACTION_DEFAULT:
58e21dff5   Alex Deucher   drm/radeon/kms/pm...
356
357
  			rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index;
  			rdev->pm.requested_clock_mode_index = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
358
  			rdev->pm.dynpm_can_upclock = false;
58e21dff5   Alex Deucher   drm/radeon/kms/pm...
359
  			break;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
360
  		case DYNPM_ACTION_NONE:
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
361
362
363
364
365
366
367
368
369
370
371
372
373
  		default:
  			DRM_ERROR("Requested mode for not defined action
  ");
  			return;
  		}
  	} else {
  		/* XXX select a power state based on AC/DC, single/dualhead, etc. */
  		/* for now just select the first power state and switch between clock modes */
  		/* power state array is low to high, default is first (0) */
  		if (rdev->pm.active_crtc_count > 1) {
  			rdev->pm.requested_power_state_index = -1;
  			/* start at 1 as we don't want the default mode */
  			for (i = 1; i < rdev->pm.num_power_states; i++) {
d7311171c   Alex Deucher   drm/radeon/kms/pm...
374
  				if (rdev->pm.power_state[i].flags & RADEON_PM_STATE_SINGLE_DISPLAY_ONLY)
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
375
376
377
378
379
380
381
382
383
384
385
386
  					continue;
  				else if ((rdev->pm.power_state[i].type == POWER_STATE_TYPE_PERFORMANCE) ||
  					 (rdev->pm.power_state[i].type == POWER_STATE_TYPE_BATTERY)) {
  					rdev->pm.requested_power_state_index = i;
  					break;
  				}
  			}
  			/* if nothing selected, grab the default state. */
  			if (rdev->pm.requested_power_state_index == -1)
  				rdev->pm.requested_power_state_index = 0;
  		} else
  			rdev->pm.requested_power_state_index = 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
387
388
  		switch (rdev->pm.dynpm_planned_action) {
  		case DYNPM_ACTION_MINIMUM:
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
389
  			rdev->pm.requested_clock_mode_index = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
390
  			rdev->pm.dynpm_can_downclock = false;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
391
  			break;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
392
  		case DYNPM_ACTION_DOWNCLOCK:
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
393
394
395
  			if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) {
  				if (rdev->pm.current_clock_mode_index == 0) {
  					rdev->pm.requested_clock_mode_index = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
396
  					rdev->pm.dynpm_can_downclock = false;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
397
398
399
400
401
  				} else
  					rdev->pm.requested_clock_mode_index =
  						rdev->pm.current_clock_mode_index - 1;
  			} else {
  				rdev->pm.requested_clock_mode_index = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
402
  				rdev->pm.dynpm_can_downclock = false;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
403
  			}
d7311171c   Alex Deucher   drm/radeon/kms/pm...
404
405
406
407
408
409
410
  			/* don't use the power state if crtcs are active and no display flag is set */
  			if ((rdev->pm.active_crtc_count > 0) &&
  			    (rdev->pm.power_state[rdev->pm.requested_power_state_index].
  			     clock_info[rdev->pm.requested_clock_mode_index].flags &
  			     RADEON_PM_MODE_NO_DISPLAY)) {
  				rdev->pm.requested_clock_mode_index++;
  			}
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
411
  			break;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
412
  		case DYNPM_ACTION_UPCLOCK:
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
413
414
415
416
  			if (rdev->pm.requested_power_state_index == rdev->pm.current_power_state_index) {
  				if (rdev->pm.current_clock_mode_index ==
  				    (rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1)) {
  					rdev->pm.requested_clock_mode_index = rdev->pm.current_clock_mode_index;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
417
  					rdev->pm.dynpm_can_upclock = false;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
418
419
420
421
422
423
  				} else
  					rdev->pm.requested_clock_mode_index =
  						rdev->pm.current_clock_mode_index + 1;
  			} else {
  				rdev->pm.requested_clock_mode_index =
  					rdev->pm.power_state[rdev->pm.requested_power_state_index].num_clock_modes - 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
424
  				rdev->pm.dynpm_can_upclock = false;
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
425
426
  			}
  			break;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
427
  		case DYNPM_ACTION_DEFAULT:
58e21dff5   Alex Deucher   drm/radeon/kms/pm...
428
429
  			rdev->pm.requested_power_state_index = rdev->pm.default_power_state_index;
  			rdev->pm.requested_clock_mode_index = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
430
  			rdev->pm.dynpm_can_upclock = false;
58e21dff5   Alex Deucher   drm/radeon/kms/pm...
431
  			break;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
432
  		case DYNPM_ACTION_NONE:
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
433
434
435
436
437
438
  		default:
  			DRM_ERROR("Requested mode for not defined action
  ");
  			return;
  		}
  	}
d9fdaafbe   Dave Airlie   drm/radeon/kms: m...
439
440
  	DRM_DEBUG_DRIVER("Requested: e: %d m: %d p: %d
  ",
ce8a3eb20   Alex Deucher   drm/radeon/kms/pm...
441
442
443
444
445
446
  		  rdev->pm.power_state[rdev->pm.requested_power_state_index].
  		  clock_info[rdev->pm.requested_clock_mode_index].sclk,
  		  rdev->pm.power_state[rdev->pm.requested_power_state_index].
  		  clock_info[rdev->pm.requested_clock_mode_index].mclk,
  		  rdev->pm.power_state[rdev->pm.requested_power_state_index].
  		  pcie_lanes);
a48b9b4ed   Alex Deucher   drm/radeon/kms/pm...
447
  }
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
448
449
450
451
452
453
454
455
456
457
458
459
460
  void rs780_pm_init_profile(struct radeon_device *rdev)
  {
  	if (rdev->pm.num_power_states == 2) {
  		/* default */
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
  		/* low sh */
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
461
462
463
464
465
  		/* mid sh */
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
466
467
468
469
470
471
472
473
474
475
  		/* high sh */
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
  		/* low mh */
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
476
477
478
479
480
  		/* mid mh */
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
  		/* high mh */
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
  	} else if (rdev->pm.num_power_states == 3) {
  		/* default */
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
  		/* low sh */
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
497
498
499
500
501
  		/* mid sh */
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
502
503
504
505
506
507
508
509
510
511
  		/* high sh */
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
  		/* low mh */
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
512
513
514
515
516
  		/* mid mh */
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
  		/* high mh */
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 1;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
  	} else {
  		/* default */
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
  		/* low sh */
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
533
534
535
536
537
  		/* mid sh */
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
538
539
540
541
542
543
544
545
546
547
  		/* high sh */
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 3;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
  		/* low mh */
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
548
549
550
551
552
  		/* mid mh */
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
553
554
555
556
557
558
559
  		/* high mh */
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 3;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
  	}
  }
bae6b5627   Alex Deucher   drm/radeon/kms/pm...
560

ce8f53709   Alex Deucher   drm/radeon/kms/pm...
561
562
  void r600_pm_init_profile(struct radeon_device *rdev)
  {
bbe26ffe9   Alex Deucher   drm/radeon/kms: o...
563
  	int idx;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
564
565
566
567
568
569
  	if (rdev->family == CHIP_R600) {
  		/* XXX */
  		/* default */
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
4bff51711   Alex Deucher   drm/radeon/kms/pm...
570
  		rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
571
572
573
574
  		/* low sh */
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
4bff51711   Alex Deucher   drm/radeon/kms/pm...
575
  		rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
576
577
578
579
580
  		/* mid sh */
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
581
582
583
584
  		/* high sh */
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
4bff51711   Alex Deucher   drm/radeon/kms/pm...
585
  		rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
586
587
588
589
  		/* low mh */
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
4bff51711   Alex Deucher   drm/radeon/kms/pm...
590
  		rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
591
592
593
594
595
  		/* mid mh */
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
  		rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
596
597
598
599
  		/* high mh */
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
4bff51711   Alex Deucher   drm/radeon/kms/pm...
600
  		rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 0;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
601
602
603
604
605
606
607
608
  	} else {
  		if (rdev->pm.num_power_states < 4) {
  			/* default */
  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
  			/* low sh */
4bff51711   Alex Deucher   drm/radeon/kms/pm...
609
610
  			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = 1;
  			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
611
  			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
612
613
614
615
616
617
  			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
  			/* mid sh */
  			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = 1;
  			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = 1;
  			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
618
  			/* high sh */
4bff51711   Alex Deucher   drm/radeon/kms/pm...
619
620
  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = 1;
  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
621
622
623
  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
  			/* low mh */
4bff51711   Alex Deucher   drm/radeon/kms/pm...
624
625
  			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = 2;
  			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = 2;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
626
  			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
627
628
629
630
631
632
  			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
  			/* low mh */
  			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = 2;
  			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = 2;
  			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
633
  			/* high mh */
4bff51711   Alex Deucher   drm/radeon/kms/pm...
634
635
  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = 2;
  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = 2;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
636
637
638
639
640
641
642
643
644
  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
  		} else {
  			/* default */
  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_ps_idx = rdev->pm.default_power_state_index;
  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_ps_idx = rdev->pm.default_power_state_index;
  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_DEFAULT_IDX].dpms_on_cm_idx = 2;
  			/* low sh */
bbe26ffe9   Alex Deucher   drm/radeon/kms: o...
645
646
647
648
649
650
651
652
  			if (rdev->flags & RADEON_IS_MOBILITY)
  				idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 0);
  			else
  				idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
  			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_LOW_SH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
653
  			/* mid sh */
bbe26ffe9   Alex Deucher   drm/radeon/kms: o...
654
655
656
657
  			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_MID_SH_IDX].dpms_on_cm_idx = 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
658
  			/* high sh */
bbe26ffe9   Alex Deucher   drm/radeon/kms: o...
659
660
661
  			idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 0);
  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_ps_idx = idx;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
662
663
664
  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_HIGH_SH_IDX].dpms_on_cm_idx = 2;
  			/* low mh */
bbe26ffe9   Alex Deucher   drm/radeon/kms: o...
665
666
667
668
669
670
671
672
  			if (rdev->flags & RADEON_IS_MOBILITY)
  				idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_BATTERY, 1);
  			else
  				idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
  			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_LOW_MH_IDX].dpms_on_cm_idx = 0;
c9e75b212   Alex Deucher   drm/radeon/kms/pm...
673
  			/* mid mh */
bbe26ffe9   Alex Deucher   drm/radeon/kms: o...
674
675
676
677
  			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_MID_MH_IDX].dpms_on_cm_idx = 1;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
678
  			/* high mh */
bbe26ffe9   Alex Deucher   drm/radeon/kms: o...
679
680
681
  			idx = radeon_pm_get_type_index(rdev, POWER_STATE_TYPE_PERFORMANCE, 1);
  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_ps_idx = idx;
  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_ps_idx = idx;
ce8f53709   Alex Deucher   drm/radeon/kms/pm...
682
683
684
685
  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_off_cm_idx = 0;
  			rdev->pm.profiles[PM_PROFILE_HIGH_MH_IDX].dpms_on_cm_idx = 2;
  		}
  	}
bae6b5627   Alex Deucher   drm/radeon/kms/pm...
686
  }
49e02b730   Alex Deucher   drm/radeon/kms/pm...
687
688
  void r600_pm_misc(struct radeon_device *rdev)
  {
a081a9d6f   Rafał Miłecki   drm/radeon/kms/r6...
689
690
691
692
  	int req_ps_idx = rdev->pm.requested_power_state_index;
  	int req_cm_idx = rdev->pm.requested_clock_mode_index;
  	struct radeon_power_state *ps = &rdev->pm.power_state[req_ps_idx];
  	struct radeon_voltage *voltage = &ps->clock_info[req_cm_idx].voltage;
7ac9aa5a1   Alex Deucher   drm/radeon/kms/pm...
693

4d60173fc   Alex Deucher   drm/radeon/kms/pm...
694
  	if ((voltage->type == VOLTAGE_SW) && voltage->voltage) {
a377e187d   Alex Deucher   drm/radeon/kms/r6...
695
696
697
  		/* 0xff01 is a flag rather then an actual voltage */
  		if (voltage->voltage == 0xff01)
  			return;
4d60173fc   Alex Deucher   drm/radeon/kms/pm...
698
  		if (voltage->voltage != rdev->pm.current_vddc) {
8a83ec5ee   Alex Deucher   drm/radeon/kms: a...
699
  			radeon_atom_set_voltage(rdev, voltage->voltage, SET_VOLTAGE_TYPE_ASIC_VDDC);
4d60173fc   Alex Deucher   drm/radeon/kms/pm...
700
  			rdev->pm.current_vddc = voltage->voltage;
d9fdaafbe   Dave Airlie   drm/radeon/kms: m...
701
702
  			DRM_DEBUG_DRIVER("Setting: v: %d
  ", voltage->voltage);
4d60173fc   Alex Deucher   drm/radeon/kms/pm...
703
704
  		}
  	}
49e02b730   Alex Deucher   drm/radeon/kms/pm...
705
  }
def9ba9cf   Alex Deucher   drm/radeon/kms: a...
706
707
708
709
710
711
712
  bool r600_gui_idle(struct radeon_device *rdev)
  {
  	if (RREG32(GRBM_STATUS) & GUI_ACTIVE)
  		return false;
  	else
  		return true;
  }
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
  /* hpd for digital panel detect/disconnect */
  bool r600_hpd_sense(struct radeon_device *rdev, enum radeon_hpd_id hpd)
  {
  	bool connected = false;
  
  	if (ASIC_IS_DCE3(rdev)) {
  		switch (hpd) {
  		case RADEON_HPD_1:
  			if (RREG32(DC_HPD1_INT_STATUS) & DC_HPDx_SENSE)
  				connected = true;
  			break;
  		case RADEON_HPD_2:
  			if (RREG32(DC_HPD2_INT_STATUS) & DC_HPDx_SENSE)
  				connected = true;
  			break;
  		case RADEON_HPD_3:
  			if (RREG32(DC_HPD3_INT_STATUS) & DC_HPDx_SENSE)
  				connected = true;
  			break;
  		case RADEON_HPD_4:
  			if (RREG32(DC_HPD4_INT_STATUS) & DC_HPDx_SENSE)
  				connected = true;
  			break;
  			/* DCE 3.2 */
  		case RADEON_HPD_5:
  			if (RREG32(DC_HPD5_INT_STATUS) & DC_HPDx_SENSE)
  				connected = true;
  			break;
  		case RADEON_HPD_6:
  			if (RREG32(DC_HPD6_INT_STATUS) & DC_HPDx_SENSE)
  				connected = true;
  			break;
  		default:
  			break;
  		}
  	} else {
  		switch (hpd) {
  		case RADEON_HPD_1:
  			if (RREG32(DC_HOT_PLUG_DETECT1_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
  				connected = true;
  			break;
  		case RADEON_HPD_2:
  			if (RREG32(DC_HOT_PLUG_DETECT2_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
  				connected = true;
  			break;
  		case RADEON_HPD_3:
  			if (RREG32(DC_HOT_PLUG_DETECT3_INT_STATUS) & DC_HOT_PLUG_DETECTx_SENSE)
  				connected = true;
  			break;
  		default:
  			break;
  		}
  	}
  	return connected;
  }
  
  void r600_hpd_set_polarity(struct radeon_device *rdev,
429770b3e   Alex Deucher   drm/radeon/kms: a...
770
  			   enum radeon_hpd_id hpd)
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
  {
  	u32 tmp;
  	bool connected = r600_hpd_sense(rdev, hpd);
  
  	if (ASIC_IS_DCE3(rdev)) {
  		switch (hpd) {
  		case RADEON_HPD_1:
  			tmp = RREG32(DC_HPD1_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HPDx_INT_POLARITY;
  			else
  				tmp |= DC_HPDx_INT_POLARITY;
  			WREG32(DC_HPD1_INT_CONTROL, tmp);
  			break;
  		case RADEON_HPD_2:
  			tmp = RREG32(DC_HPD2_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HPDx_INT_POLARITY;
  			else
  				tmp |= DC_HPDx_INT_POLARITY;
  			WREG32(DC_HPD2_INT_CONTROL, tmp);
  			break;
  		case RADEON_HPD_3:
  			tmp = RREG32(DC_HPD3_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HPDx_INT_POLARITY;
  			else
  				tmp |= DC_HPDx_INT_POLARITY;
  			WREG32(DC_HPD3_INT_CONTROL, tmp);
  			break;
  		case RADEON_HPD_4:
  			tmp = RREG32(DC_HPD4_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HPDx_INT_POLARITY;
  			else
  				tmp |= DC_HPDx_INT_POLARITY;
  			WREG32(DC_HPD4_INT_CONTROL, tmp);
  			break;
  		case RADEON_HPD_5:
  			tmp = RREG32(DC_HPD5_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HPDx_INT_POLARITY;
  			else
  				tmp |= DC_HPDx_INT_POLARITY;
  			WREG32(DC_HPD5_INT_CONTROL, tmp);
  			break;
  			/* DCE 3.2 */
  		case RADEON_HPD_6:
  			tmp = RREG32(DC_HPD6_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HPDx_INT_POLARITY;
  			else
  				tmp |= DC_HPDx_INT_POLARITY;
  			WREG32(DC_HPD6_INT_CONTROL, tmp);
  			break;
  		default:
  			break;
  		}
  	} else {
  		switch (hpd) {
  		case RADEON_HPD_1:
  			tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
  			else
  				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
  			WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
  			break;
  		case RADEON_HPD_2:
  			tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
  			else
  				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
  			WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
  			break;
  		case RADEON_HPD_3:
  			tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
  			if (connected)
  				tmp &= ~DC_HOT_PLUG_DETECTx_INT_POLARITY;
  			else
  				tmp |= DC_HOT_PLUG_DETECTx_INT_POLARITY;
  			WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
  			break;
  		default:
  			break;
  		}
  	}
  }
  
  void r600_hpd_init(struct radeon_device *rdev)
  {
  	struct drm_device *dev = rdev->ddev;
  	struct drm_connector *connector;
fb98257a9   Christian Koenig   drm/radeon: apply...
865
  	unsigned enable = 0;
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
866

64912e997   Alex Deucher   drm/radeon/kms: s...
867
868
  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
455c89b95   Jerome Glisse   drm/radeon: don't...
869
870
871
872
873
874
875
876
  		if (connector->connector_type == DRM_MODE_CONNECTOR_eDP ||
  		    connector->connector_type == DRM_MODE_CONNECTOR_LVDS) {
  			/* don't try to enable hpd on eDP or LVDS avoid breaking the
  			 * aux dp channel on imac and help (but not completely fix)
  			 * https://bugzilla.redhat.com/show_bug.cgi?id=726143
  			 */
  			continue;
  		}
64912e997   Alex Deucher   drm/radeon/kms: s...
877
878
879
880
  		if (ASIC_IS_DCE3(rdev)) {
  			u32 tmp = DC_HPDx_CONNECTION_TIMER(0x9c4) | DC_HPDx_RX_INT_TIMER(0xfa);
  			if (ASIC_IS_DCE32(rdev))
  				tmp |= DC_HPDx_EN;
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
881

e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
882
883
884
  			switch (radeon_connector->hpd.hpd) {
  			case RADEON_HPD_1:
  				WREG32(DC_HPD1_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
885
886
887
  				break;
  			case RADEON_HPD_2:
  				WREG32(DC_HPD2_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
888
889
890
  				break;
  			case RADEON_HPD_3:
  				WREG32(DC_HPD3_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
891
892
893
  				break;
  			case RADEON_HPD_4:
  				WREG32(DC_HPD4_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
894
895
896
897
  				break;
  				/* DCE 3.2 */
  			case RADEON_HPD_5:
  				WREG32(DC_HPD5_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
898
899
900
  				break;
  			case RADEON_HPD_6:
  				WREG32(DC_HPD6_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
901
902
903
904
  				break;
  			default:
  				break;
  			}
64912e997   Alex Deucher   drm/radeon/kms: s...
905
  		} else {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
906
907
908
  			switch (radeon_connector->hpd.hpd) {
  			case RADEON_HPD_1:
  				WREG32(DC_HOT_PLUG_DETECT1_CONTROL, DC_HOT_PLUG_DETECTx_EN);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
909
910
911
  				break;
  			case RADEON_HPD_2:
  				WREG32(DC_HOT_PLUG_DETECT2_CONTROL, DC_HOT_PLUG_DETECTx_EN);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
912
913
914
  				break;
  			case RADEON_HPD_3:
  				WREG32(DC_HOT_PLUG_DETECT3_CONTROL, DC_HOT_PLUG_DETECTx_EN);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
915
916
917
918
919
  				break;
  			default:
  				break;
  			}
  		}
fb98257a9   Christian Koenig   drm/radeon: apply...
920
  		enable |= 1 << radeon_connector->hpd.hpd;
64912e997   Alex Deucher   drm/radeon/kms: s...
921
  		radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
922
  	}
fb98257a9   Christian Koenig   drm/radeon: apply...
923
  	radeon_irq_kms_enable_hpd(rdev, enable);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
924
925
926
927
928
929
  }
  
  void r600_hpd_fini(struct radeon_device *rdev)
  {
  	struct drm_device *dev = rdev->ddev;
  	struct drm_connector *connector;
fb98257a9   Christian Koenig   drm/radeon: apply...
930
  	unsigned disable = 0;
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
931

fb98257a9   Christian Koenig   drm/radeon: apply...
932
933
934
  	list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  		struct radeon_connector *radeon_connector = to_radeon_connector(connector);
  		if (ASIC_IS_DCE3(rdev)) {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
935
936
937
  			switch (radeon_connector->hpd.hpd) {
  			case RADEON_HPD_1:
  				WREG32(DC_HPD1_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
938
939
940
  				break;
  			case RADEON_HPD_2:
  				WREG32(DC_HPD2_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
941
942
943
  				break;
  			case RADEON_HPD_3:
  				WREG32(DC_HPD3_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
944
945
946
  				break;
  			case RADEON_HPD_4:
  				WREG32(DC_HPD4_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
947
948
949
950
  				break;
  				/* DCE 3.2 */
  			case RADEON_HPD_5:
  				WREG32(DC_HPD5_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
951
952
953
  				break;
  			case RADEON_HPD_6:
  				WREG32(DC_HPD6_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
954
955
956
957
  				break;
  			default:
  				break;
  			}
fb98257a9   Christian Koenig   drm/radeon: apply...
958
  		} else {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
959
960
961
  			switch (radeon_connector->hpd.hpd) {
  			case RADEON_HPD_1:
  				WREG32(DC_HOT_PLUG_DETECT1_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
962
963
964
  				break;
  			case RADEON_HPD_2:
  				WREG32(DC_HOT_PLUG_DETECT2_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
965
966
967
  				break;
  			case RADEON_HPD_3:
  				WREG32(DC_HOT_PLUG_DETECT3_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
968
969
970
971
972
  				break;
  			default:
  				break;
  			}
  		}
fb98257a9   Christian Koenig   drm/radeon: apply...
973
  		disable |= 1 << radeon_connector->hpd.hpd;
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
974
  	}
fb98257a9   Christian Koenig   drm/radeon: apply...
975
  	radeon_irq_kms_disable_hpd(rdev, disable);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
976
  }
771fe6b91   Jerome Glisse   drm/radeon: intro...
977
  /*
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
978
   * R600 PCIE GART
771fe6b91   Jerome Glisse   drm/radeon: intro...
979
   */
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
980
981
982
983
  void r600_pcie_gart_tlb_flush(struct radeon_device *rdev)
  {
  	unsigned i;
  	u32 tmp;
2e98f10a7   Dave Airlie   drm/radeon/kms: f...
984
  	/* flush hdp cache so updates hit vram */
f3886f85c   Alex Deucher   drm/radeon/kms: d...
985
986
  	if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
  	    !(rdev->flags & RADEON_IS_AGP)) {
c9a1be962   Jerome Glisse   drm/radeon/kms: c...
987
  		void __iomem *ptr = (void *)rdev->gart.ptr;
812d04691   Alex Deucher   drm/radeon/kms/r7...
988
989
990
991
  		u32 tmp;
  
  		/* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
  		 * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL
f3886f85c   Alex Deucher   drm/radeon/kms: d...
992
993
  		 * This seems to cause problems on some AGP cards. Just use the old
  		 * method for them.
812d04691   Alex Deucher   drm/radeon/kms/r7...
994
995
996
997
998
  		 */
  		WREG32(HDP_DEBUG1, 0);
  		tmp = readl((void __iomem *)ptr);
  	} else
  		WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
2e98f10a7   Dave Airlie   drm/radeon/kms: f...
999

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
  	WREG32(VM_CONTEXT0_INVALIDATION_LOW_ADDR, rdev->mc.gtt_start >> 12);
  	WREG32(VM_CONTEXT0_INVALIDATION_HIGH_ADDR, (rdev->mc.gtt_end - 1) >> 12);
  	WREG32(VM_CONTEXT0_REQUEST_RESPONSE, REQUEST_TYPE(1));
  	for (i = 0; i < rdev->usec_timeout; i++) {
  		/* read MC_STATUS */
  		tmp = RREG32(VM_CONTEXT0_REQUEST_RESPONSE);
  		tmp = (tmp & RESPONSE_TYPE_MASK) >> RESPONSE_TYPE_SHIFT;
  		if (tmp == 2) {
  			printk(KERN_WARNING "[drm] r600 flush TLB failed
  ");
  			return;
  		}
  		if (tmp) {
  			return;
  		}
  		udelay(1);
  	}
  }
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1018
  int r600_pcie_gart_init(struct radeon_device *rdev)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1019
  {
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1020
  	int r;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1021

c9a1be962   Jerome Glisse   drm/radeon/kms: c...
1022
  	if (rdev->gart.robj) {
fce7d61be   Joe Perches   drivers/gpu/drm: ...
1023
1024
  		WARN(1, "R600 PCIE GART already initialized
  ");
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1025
1026
  		return 0;
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1027
1028
  	/* Initialize common gart structure */
  	r = radeon_gart_init(rdev);
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1029
  	if (r)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1030
  		return r;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1031
  	rdev->gart.table_size = rdev->gart.num_gpu_pages * 8;
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1032
1033
  	return radeon_gart_table_vram_alloc(rdev);
  }
1109ca09b   Lauri Kasanen   drm/radeon: Mark ...
1034
  static int r600_pcie_gart_enable(struct radeon_device *rdev)
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1035
1036
1037
  {
  	u32 tmp;
  	int r, i;
c9a1be962   Jerome Glisse   drm/radeon/kms: c...
1038
  	if (rdev->gart.robj == NULL) {
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1039
1040
1041
  		dev_err(rdev->dev, "No VRAM object for PCIE GART.
  ");
  		return -EINVAL;
771fe6b91   Jerome Glisse   drm/radeon: intro...
1042
  	}
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1043
1044
1045
  	r = radeon_gart_table_vram_pin(rdev);
  	if (r)
  		return r;
bc1a631e5   Dave Airlie   drm/radeon/r600: ...
1046

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
  	/* Setup L2 cache */
  	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
  				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
  				EFFECTIVE_L2_QUEUE_SIZE(7));
  	WREG32(VM_L2_CNTL2, 0);
  	WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
  	/* Setup TLB control */
  	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
  		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
  		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
  		ENABLE_WAIT_L2_QUERY;
  	WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
  	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
a8fba64ab   Christian König   drm/radeon: prope...
1070
1071
  	WREG32(MC_VM_L1_TLB_MCB_RD_UVD_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_UVD_CNTL, tmp);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1072
1073
1074
  	WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
  	WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
  	WREG32(VM_CONTEXT0_PAGE_TABLE_START_ADDR, rdev->mc.gtt_start >> 12);
1a029b768   Jerome Glisse   drm/radeon/kms: F...
1075
  	WREG32(VM_CONTEXT0_PAGE_TABLE_END_ADDR, rdev->mc.gtt_end >> 12);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1076
1077
1078
1079
1080
1081
1082
  	WREG32(VM_CONTEXT0_PAGE_TABLE_BASE_ADDR, rdev->gart.table_addr >> 12);
  	WREG32(VM_CONTEXT0_CNTL, ENABLE_CONTEXT | PAGE_TABLE_DEPTH(0) |
  				RANGE_PROTECTION_FAULT_ENABLE_DEFAULT);
  	WREG32(VM_CONTEXT0_PROTECTION_FAULT_DEFAULT_ADDR,
  			(u32)(rdev->dummy_page.addr >> 12));
  	for (i = 1; i < 7; i++)
  		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
771fe6b91   Jerome Glisse   drm/radeon: intro...
1083

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1084
  	r600_pcie_gart_tlb_flush(rdev);
fcf4de5ac   Tormod Volden   drm/radeon: Print...
1085
1086
1087
1088
  	DRM_INFO("PCIE GART of %uM enabled (table at 0x%016llX).
  ",
  		 (unsigned)(rdev->mc.gtt_size >> 20),
  		 (unsigned long long)rdev->gart.table_addr);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1089
  	rdev->gart.ready = true;
771fe6b91   Jerome Glisse   drm/radeon: intro...
1090
1091
  	return 0;
  }
1109ca09b   Lauri Kasanen   drm/radeon: Mark ...
1092
  static void r600_pcie_gart_disable(struct radeon_device *rdev)
771fe6b91   Jerome Glisse   drm/radeon: intro...
1093
  {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1094
  	u32 tmp;
c9a1be962   Jerome Glisse   drm/radeon/kms: c...
1095
  	int i;
771fe6b91   Jerome Glisse   drm/radeon: intro...
1096

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1097
1098
1099
  	/* Disable all tables */
  	for (i = 0; i < 7; i++)
  		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
771fe6b91   Jerome Glisse   drm/radeon: intro...
1100

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
  	/* Disable L2 cache */
  	WREG32(VM_L2_CNTL, ENABLE_L2_FRAGMENT_PROCESSING |
  				EFFECTIVE_L2_QUEUE_SIZE(7));
  	WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
  	/* Setup L1 TLB control */
  	tmp = EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
  		ENABLE_WAIT_L2_QUERY;
  	WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
a8fba64ab   Christian König   drm/radeon: prope...
1122
1123
  	WREG32(MC_VM_L1_TLB_MCB_RD_UVD_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_UVD_CNTL, tmp);
c9a1be962   Jerome Glisse   drm/radeon/kms: c...
1124
  	radeon_gart_table_vram_unpin(rdev);
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1125
  }
1109ca09b   Lauri Kasanen   drm/radeon: Mark ...
1126
  static void r600_pcie_gart_fini(struct radeon_device *rdev)
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1127
  {
f92745620   Jerome Glisse   drm/radeon/kms: a...
1128
  	radeon_gart_fini(rdev);
4aac04732   Jerome Glisse   drm/radeon/kms: c...
1129
1130
  	r600_pcie_gart_disable(rdev);
  	radeon_gart_table_vram_free(rdev);
771fe6b91   Jerome Glisse   drm/radeon: intro...
1131
  }
1109ca09b   Lauri Kasanen   drm/radeon: Mark ...
1132
  static void r600_agp_enable(struct radeon_device *rdev)
1a029b768   Jerome Glisse   drm/radeon/kms: F...
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
  {
  	u32 tmp;
  	int i;
  
  	/* Setup L2 cache */
  	WREG32(VM_L2_CNTL, ENABLE_L2_CACHE | ENABLE_L2_FRAGMENT_PROCESSING |
  				ENABLE_L2_PTE_CACHE_LRU_UPDATE_BY_WRITE |
  				EFFECTIVE_L2_QUEUE_SIZE(7));
  	WREG32(VM_L2_CNTL2, 0);
  	WREG32(VM_L2_CNTL3, BANK_SELECT_0(0) | BANK_SELECT_1(1));
  	/* Setup TLB control */
  	tmp = ENABLE_L1_TLB | ENABLE_L1_FRAGMENT_PROCESSING |
  		SYSTEM_ACCESS_MODE_NOT_IN_SYS |
  		EFFECTIVE_L1_TLB_SIZE(5) | EFFECTIVE_L1_QUEUE_SIZE(5) |
  		ENABLE_WAIT_L2_QUERY;
  	WREG32(MC_VM_L1_TLB_MCB_RD_SYS_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_SYS_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_HDP_CNTL, tmp | ENABLE_L1_STRICT_ORDERING);
  	WREG32(MC_VM_L1_TLB_MCB_WR_HDP_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_RD_A_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_WR_A_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_RD_B_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCD_WR_B_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_GFX_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_GFX_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_PDMA_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_WR_PDMA_CNTL, tmp);
  	WREG32(MC_VM_L1_TLB_MCB_RD_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
  	WREG32(MC_VM_L1_TLB_MCB_WR_SEM_CNTL, tmp | ENABLE_SEMAPHORE_MODE);
  	for (i = 0; i < 7; i++)
  		WREG32(VM_CONTEXT0_CNTL + (i * 4), 0);
  }
771fe6b91   Jerome Glisse   drm/radeon: intro...
1165
1166
  int r600_mc_wait_for_idle(struct radeon_device *rdev)
  {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
  	unsigned i;
  	u32 tmp;
  
  	for (i = 0; i < rdev->usec_timeout; i++) {
  		/* read MC_STATUS */
  		tmp = RREG32(R_000E50_SRBM_STATUS) & 0x3F00;
  		if (!tmp)
  			return 0;
  		udelay(1);
  	}
  	return -1;
771fe6b91   Jerome Glisse   drm/radeon: intro...
1178
  }
65337e60a   Samuel Li   drm/radeon: Use d...
1179
1180
  uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg)
  {
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
1181
  	unsigned long flags;
65337e60a   Samuel Li   drm/radeon: Use d...
1182
  	uint32_t r;
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
1183
  	spin_lock_irqsave(&rdev->mc_idx_lock, flags);
65337e60a   Samuel Li   drm/radeon: Use d...
1184
1185
1186
  	WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg));
  	r = RREG32(R_0028FC_MC_DATA);
  	WREG32(R_0028F8_MC_INDEX, ~C_0028F8_MC_IND_ADDR);
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
1187
  	spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);
65337e60a   Samuel Li   drm/radeon: Use d...
1188
1189
1190
1191
1192
  	return r;
  }
  
  void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
  {
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
1193
1194
1195
  	unsigned long flags;
  
  	spin_lock_irqsave(&rdev->mc_idx_lock, flags);
65337e60a   Samuel Li   drm/radeon: Use d...
1196
1197
1198
1199
  	WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg) |
  		S_0028F8_MC_IND_WR_EN(1));
  	WREG32(R_0028FC_MC_DATA, v);
  	WREG32(R_0028F8_MC_INDEX, 0x7F);
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
1200
  	spin_unlock_irqrestore(&rdev->mc_idx_lock, flags);
65337e60a   Samuel Li   drm/radeon: Use d...
1201
  }
a3c1945aa   Jerome Glisse   drm/radeon/kms: F...
1202
  static void r600_mc_program(struct radeon_device *rdev)
771fe6b91   Jerome Glisse   drm/radeon: intro...
1203
  {
a3c1945aa   Jerome Glisse   drm/radeon/kms: F...
1204
  	struct rv515_mc_save save;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1205
1206
  	u32 tmp;
  	int i, j;
771fe6b91   Jerome Glisse   drm/radeon: intro...
1207

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1208
1209
1210
1211
1212
1213
1214
1215
1216
  	/* Initialize HDP */
  	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
  		WREG32((0x2c14 + j), 0x00000000);
  		WREG32((0x2c18 + j), 0x00000000);
  		WREG32((0x2c1c + j), 0x00000000);
  		WREG32((0x2c20 + j), 0x00000000);
  		WREG32((0x2c24 + j), 0x00000000);
  	}
  	WREG32(HDP_REG_COHERENCY_FLUSH_CNTL, 0);
771fe6b91   Jerome Glisse   drm/radeon: intro...
1217

a3c1945aa   Jerome Glisse   drm/radeon/kms: F...
1218
  	rv515_mc_stop(rdev, &save);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1219
  	if (r600_mc_wait_for_idle(rdev)) {
a3c1945aa   Jerome Glisse   drm/radeon/kms: F...
1220
1221
  		dev_warn(rdev->dev, "Wait for MC idle timedout !
  ");
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1222
  	}
a3c1945aa   Jerome Glisse   drm/radeon/kms: F...
1223
  	/* Lockout access through VGA aperture (doesn't exist before R600) */
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1224
  	WREG32(VGA_HDP_CONTROL, VGA_MEMORY_DISABLE);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1225
  	/* Update configuration */
1a029b768   Jerome Glisse   drm/radeon/kms: F...
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
  	if (rdev->flags & RADEON_IS_AGP) {
  		if (rdev->mc.vram_start < rdev->mc.gtt_start) {
  			/* VRAM before AGP */
  			WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
  				rdev->mc.vram_start >> 12);
  			WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
  				rdev->mc.gtt_end >> 12);
  		} else {
  			/* VRAM after AGP */
  			WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR,
  				rdev->mc.gtt_start >> 12);
  			WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR,
  				rdev->mc.vram_end >> 12);
  		}
  	} else {
  		WREG32(MC_VM_SYSTEM_APERTURE_LOW_ADDR, rdev->mc.vram_start >> 12);
  		WREG32(MC_VM_SYSTEM_APERTURE_HIGH_ADDR, rdev->mc.vram_end >> 12);
  	}
16cdf04d3   Alex Deucher   drm/radeon/kms: a...
1244
  	WREG32(MC_VM_SYSTEM_APERTURE_DEFAULT_ADDR, rdev->vram_scratch.gpu_addr >> 12);
1a029b768   Jerome Glisse   drm/radeon/kms: F...
1245
  	tmp = ((rdev->mc.vram_end >> 24) & 0xFFFF) << 16;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1246
1247
1248
1249
  	tmp |= ((rdev->mc.vram_start >> 24) & 0xFFFF);
  	WREG32(MC_VM_FB_LOCATION, tmp);
  	WREG32(HDP_NONSURFACE_BASE, (rdev->mc.vram_start >> 8));
  	WREG32(HDP_NONSURFACE_INFO, (2 << 7));
46fcd2b3d   Jerome Glisse   drm/radeon/kms: F...
1250
  	WREG32(HDP_NONSURFACE_SIZE, 0x3FFFFFFF);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1251
  	if (rdev->flags & RADEON_IS_AGP) {
1a029b768   Jerome Glisse   drm/radeon/kms: F...
1252
1253
  		WREG32(MC_VM_AGP_TOP, rdev->mc.gtt_end >> 22);
  		WREG32(MC_VM_AGP_BOT, rdev->mc.gtt_start >> 22);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1254
1255
1256
1257
1258
1259
  		WREG32(MC_VM_AGP_BASE, rdev->mc.agp_base >> 22);
  	} else {
  		WREG32(MC_VM_AGP_BASE, 0);
  		WREG32(MC_VM_AGP_TOP, 0x0FFFFFFF);
  		WREG32(MC_VM_AGP_BOT, 0x0FFFFFFF);
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1260
  	if (r600_mc_wait_for_idle(rdev)) {
a3c1945aa   Jerome Glisse   drm/radeon/kms: F...
1261
1262
  		dev_warn(rdev->dev, "Wait for MC idle timedout !
  ");
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1263
  	}
a3c1945aa   Jerome Glisse   drm/radeon/kms: F...
1264
  	rv515_mc_resume(rdev, &save);
698443d9e   Dave Airlie   drm/radeon/kms: d...
1265
1266
  	/* we need to own VRAM, so turn off the VGA renderer here
  	 * to stop it overwriting our objects */
d39c3b895   Jerome Glisse   drm/radeon/kms: C...
1267
  	rv515_vga_render_disable(rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1268
  }
d594e46ac   Jerome Glisse   drm/radeon/kms: s...
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
  /**
   * r600_vram_gtt_location - try to find VRAM & GTT location
   * @rdev: radeon device structure holding all necessary informations
   * @mc: memory controller structure holding memory informations
   *
   * Function will place try to place VRAM at same place as in CPU (PCI)
   * address space as some GPU seems to have issue when we reprogram at
   * different address space.
   *
   * If there is not enough space to fit the unvisible VRAM after the
   * aperture then we limit the VRAM size to the aperture.
   *
   * If we are using AGP then place VRAM adjacent to AGP aperture are we need
   * them to be in one from GPU point of view so that we can program GPU to
   * catch access outside them (weird GPU policy see ??).
   *
   * This function will never fails, worst case are limiting VRAM or GTT.
   *
   * Note: GTT start, end, size should be initialized before calling this
   * function on AGP platform.
   */
0ef0c1f73   Alex Deucher   drm/radeon/kms: m...
1290
  static void r600_vram_gtt_location(struct radeon_device *rdev, struct radeon_mc *mc)
d594e46ac   Jerome Glisse   drm/radeon/kms: s...
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
  {
  	u64 size_bf, size_af;
  
  	if (mc->mc_vram_size > 0xE0000000) {
  		/* leave room for at least 512M GTT */
  		dev_warn(rdev->dev, "limiting VRAM
  ");
  		mc->real_vram_size = 0xE0000000;
  		mc->mc_vram_size = 0xE0000000;
  	}
  	if (rdev->flags & RADEON_IS_AGP) {
  		size_bf = mc->gtt_start;
9ed8b1f93   Alex Deucher   drm/radeon: clean...
1303
  		size_af = mc->mc_mask - mc->gtt_end;
d594e46ac   Jerome Glisse   drm/radeon/kms: s...
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
  		if (size_bf > size_af) {
  			if (mc->mc_vram_size > size_bf) {
  				dev_warn(rdev->dev, "limiting VRAM
  ");
  				mc->real_vram_size = size_bf;
  				mc->mc_vram_size = size_bf;
  			}
  			mc->vram_start = mc->gtt_start - mc->mc_vram_size;
  		} else {
  			if (mc->mc_vram_size > size_af) {
  				dev_warn(rdev->dev, "limiting VRAM
  ");
  				mc->real_vram_size = size_af;
  				mc->mc_vram_size = size_af;
  			}
dfc6ae5bd   Jerome Glisse   radeon: fix r600/...
1319
  			mc->vram_start = mc->gtt_end + 1;
d594e46ac   Jerome Glisse   drm/radeon/kms: s...
1320
1321
1322
1323
1324
1325
1326
1327
  		}
  		mc->vram_end = mc->vram_start + mc->mc_vram_size - 1;
  		dev_info(rdev->dev, "VRAM: %lluM 0x%08llX - 0x%08llX (%lluM used)
  ",
  				mc->mc_vram_size >> 20, mc->vram_start,
  				mc->vram_end, mc->real_vram_size >> 20);
  	} else {
  		u64 base = 0;
8961d52d4   Alex Deucher   drm/radeon/kms: f...
1328
1329
1330
1331
  		if (rdev->flags & RADEON_IS_IGP) {
  			base = RREG32(MC_VM_FB_LOCATION) & 0xFFFF;
  			base <<= 24;
  		}
d594e46ac   Jerome Glisse   drm/radeon/kms: s...
1332
  		radeon_vram_location(rdev, &rdev->mc, base);
8d369bb19   Alex Deucher   drm/radeon/kms: f...
1333
  		rdev->mc.gtt_base_align = 0;
d594e46ac   Jerome Glisse   drm/radeon/kms: s...
1334
1335
1336
  		radeon_gtt_location(rdev, mc);
  	}
  }
1109ca09b   Lauri Kasanen   drm/radeon: Mark ...
1337
  static int r600_mc_init(struct radeon_device *rdev)
771fe6b91   Jerome Glisse   drm/radeon: intro...
1338
  {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1339
  	u32 tmp;
5885b7a9f   Alex Deucher   drm/radeon/kms: f...
1340
  	int chansize, numchan;
65337e60a   Samuel Li   drm/radeon: Use d...
1341
1342
  	uint32_t h_addr, l_addr;
  	unsigned long long k8_addr;
771fe6b91   Jerome Glisse   drm/radeon: intro...
1343

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1344
  	/* Get VRAM informations */
771fe6b91   Jerome Glisse   drm/radeon: intro...
1345
  	rdev->mc.vram_is_ddr = true;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1346
1347
  	tmp = RREG32(RAMCFG);
  	if (tmp & CHANSIZE_OVERRIDE) {
771fe6b91   Jerome Glisse   drm/radeon: intro...
1348
  		chansize = 16;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1349
  	} else if (tmp & CHANSIZE_MASK) {
771fe6b91   Jerome Glisse   drm/radeon: intro...
1350
1351
1352
1353
  		chansize = 64;
  	} else {
  		chansize = 32;
  	}
5885b7a9f   Alex Deucher   drm/radeon/kms: f...
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
  	tmp = RREG32(CHMAP);
  	switch ((tmp & NOOFCHAN_MASK) >> NOOFCHAN_SHIFT) {
  	case 0:
  	default:
  		numchan = 1;
  		break;
  	case 1:
  		numchan = 2;
  		break;
  	case 2:
  		numchan = 4;
  		break;
  	case 3:
  		numchan = 8;
  		break;
771fe6b91   Jerome Glisse   drm/radeon: intro...
1369
  	}
5885b7a9f   Alex Deucher   drm/radeon/kms: f...
1370
  	rdev->mc.vram_width = numchan * chansize;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1371
  	/* Could aper size report 0 ? */
01d73a696   Jordan Crouse   drm: Remove drm_r...
1372
1373
  	rdev->mc.aper_base = pci_resource_start(rdev->pdev, 0);
  	rdev->mc.aper_size = pci_resource_len(rdev->pdev, 0);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1374
1375
1376
  	/* Setup GPU memory space */
  	rdev->mc.mc_vram_size = RREG32(CONFIG_MEMSIZE);
  	rdev->mc.real_vram_size = RREG32(CONFIG_MEMSIZE);
51e5fcd35   Jerome Glisse   drm/radeon/kms: f...
1377
  	rdev->mc.visible_vram_size = rdev->mc.aper_size;
d594e46ac   Jerome Glisse   drm/radeon/kms: s...
1378
  	r600_vram_gtt_location(rdev, &rdev->mc);
f47299c55   Alex Deucher   drm/radeon/kms: d...
1379

f892034a8   Alex Deucher   drm/radeon/kms/ig...
1380
1381
  	if (rdev->flags & RADEON_IS_IGP) {
  		rs690_pm_info(rdev);
06b6476d6   Alex Deucher   drm/radeon/kms: d...
1382
  		rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev);
65337e60a   Samuel Li   drm/radeon: Use d...
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
  
  		if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) {
  			/* Use K8 direct mapping for fast fb access. */
  			rdev->fastfb_working = false;
  			h_addr = G_000012_K8_ADDR_EXT(RREG32_MC(R_000012_MC_MISC_UMA_CNTL));
  			l_addr = RREG32_MC(R_000011_K8_FB_LOCATION);
  			k8_addr = ((unsigned long long)h_addr) << 32 | l_addr;
  #if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE)
  			if (k8_addr + rdev->mc.visible_vram_size < 0x100000000ULL)
  #endif
  			{
  				/* FastFB shall be used with UMA memory. Here it is simply disabled when sideport
  		 		* memory is present.
  		 		*/
  				if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) {
  					DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.
  ",
  						(unsigned long long)rdev->mc.aper_base, k8_addr);
  					rdev->mc.aper_base = (resource_size_t)k8_addr;
  					rdev->fastfb_working = true;
  				}
  			}
    		}
f892034a8   Alex Deucher   drm/radeon/kms/ig...
1406
  	}
65337e60a   Samuel Li   drm/radeon: Use d...
1407

f47299c55   Alex Deucher   drm/radeon/kms: d...
1408
  	radeon_update_bandwidth_info(rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1409
  	return 0;
771fe6b91   Jerome Glisse   drm/radeon: intro...
1410
  }
16cdf04d3   Alex Deucher   drm/radeon/kms: a...
1411
1412
1413
1414
1415
1416
1417
  int r600_vram_scratch_init(struct radeon_device *rdev)
  {
  	int r;
  
  	if (rdev->vram_scratch.robj == NULL) {
  		r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE,
  				     PAGE_SIZE, true, RADEON_GEM_DOMAIN_VRAM,
831b6966a   Maarten Lankhorst   drm/radeon: expor...
1418
  				     0, NULL, NULL, &rdev->vram_scratch.robj);
16cdf04d3   Alex Deucher   drm/radeon/kms: a...
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
  		if (r) {
  			return r;
  		}
  	}
  
  	r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
  	if (unlikely(r != 0))
  		return r;
  	r = radeon_bo_pin(rdev->vram_scratch.robj,
  			  RADEON_GEM_DOMAIN_VRAM, &rdev->vram_scratch.gpu_addr);
  	if (r) {
  		radeon_bo_unreserve(rdev->vram_scratch.robj);
  		return r;
  	}
  	r = radeon_bo_kmap(rdev->vram_scratch.robj,
  				(void **)&rdev->vram_scratch.ptr);
  	if (r)
  		radeon_bo_unpin(rdev->vram_scratch.robj);
  	radeon_bo_unreserve(rdev->vram_scratch.robj);
  
  	return r;
  }
  
  void r600_vram_scratch_fini(struct radeon_device *rdev)
  {
  	int r;
  
  	if (rdev->vram_scratch.robj == NULL) {
  		return;
  	}
  	r = radeon_bo_reserve(rdev->vram_scratch.robj, false);
  	if (likely(r == 0)) {
  		radeon_bo_kunmap(rdev->vram_scratch.robj);
  		radeon_bo_unpin(rdev->vram_scratch.robj);
  		radeon_bo_unreserve(rdev->vram_scratch.robj);
  	}
  	radeon_bo_unref(&rdev->vram_scratch.robj);
  }
410a3418a   Alex Deucher   drm/radeon: add a...
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
  void r600_set_bios_scratch_engine_hung(struct radeon_device *rdev, bool hung)
  {
  	u32 tmp = RREG32(R600_BIOS_3_SCRATCH);
  
  	if (hung)
  		tmp |= ATOM_S3_ASIC_GUI_ENGINE_HUNG;
  	else
  		tmp &= ~ATOM_S3_ASIC_GUI_ENGINE_HUNG;
  
  	WREG32(R600_BIOS_3_SCRATCH, tmp);
  }
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1468
  static void r600_print_gpu_status_regs(struct radeon_device *rdev)
771fe6b91   Jerome Glisse   drm/radeon: intro...
1469
  {
64c56e8ce   Jerome Glisse   drm/radeon: reset...
1470
1471
  	dev_info(rdev->dev, "  R_008010_GRBM_STATUS      = 0x%08X
  ",
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1472
  		 RREG32(R_008010_GRBM_STATUS));
64c56e8ce   Jerome Glisse   drm/radeon: reset...
1473
1474
  	dev_info(rdev->dev, "  R_008014_GRBM_STATUS2     = 0x%08X
  ",
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1475
  		 RREG32(R_008014_GRBM_STATUS2));
64c56e8ce   Jerome Glisse   drm/radeon: reset...
1476
1477
  	dev_info(rdev->dev, "  R_000E50_SRBM_STATUS      = 0x%08X
  ",
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1478
  		 RREG32(R_000E50_SRBM_STATUS));
440a7cd87   Jerome Glisse   drm/radeon: impro...
1479
1480
  	dev_info(rdev->dev, "  R_008674_CP_STALLED_STAT1 = 0x%08X
  ",
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1481
  		 RREG32(CP_STALLED_STAT1));
440a7cd87   Jerome Glisse   drm/radeon: impro...
1482
1483
  	dev_info(rdev->dev, "  R_008678_CP_STALLED_STAT2 = 0x%08X
  ",
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1484
  		 RREG32(CP_STALLED_STAT2));
440a7cd87   Jerome Glisse   drm/radeon: impro...
1485
1486
  	dev_info(rdev->dev, "  R_00867C_CP_BUSY_STAT     = 0x%08X
  ",
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1487
  		 RREG32(CP_BUSY_STAT));
440a7cd87   Jerome Glisse   drm/radeon: impro...
1488
1489
  	dev_info(rdev->dev, "  R_008680_CP_STAT          = 0x%08X
  ",
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1490
  		 RREG32(CP_STAT));
71e3d1578   Alex Deucher   drm/radeon: switc...
1491
1492
1493
1494
  	dev_info(rdev->dev, "  R_00D034_DMA_STATUS_REG   = 0x%08X
  ",
  		RREG32(DMA_STATUS_REG));
  }
f13f7731a   Alex Deucher   drm/radeon: use s...
1495
  static bool r600_is_display_hung(struct radeon_device *rdev)
71e3d1578   Alex Deucher   drm/radeon: switc...
1496
  {
f13f7731a   Alex Deucher   drm/radeon: use s...
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
  	u32 crtc_hung = 0;
  	u32 crtc_status[2];
  	u32 i, j, tmp;
  
  	for (i = 0; i < rdev->num_crtc; i++) {
  		if (RREG32(AVIVO_D1CRTC_CONTROL + crtc_offsets[i]) & AVIVO_CRTC_EN) {
  			crtc_status[i] = RREG32(AVIVO_D1CRTC_STATUS_HV_COUNT + crtc_offsets[i]);
  			crtc_hung |= (1 << i);
  		}
  	}
  
  	for (j = 0; j < 10; j++) {
  		for (i = 0; i < rdev->num_crtc; i++) {
  			if (crtc_hung & (1 << i)) {
  				tmp = RREG32(AVIVO_D1CRTC_STATUS_HV_COUNT + crtc_offsets[i]);
  				if (tmp != crtc_status[i])
  					crtc_hung &= ~(1 << i);
  			}
  		}
  		if (crtc_hung == 0)
  			return false;
  		udelay(100);
  	}
  
  	return true;
  }
2483b4ea9   Christian König   drm/radeon: separ...
1523
  u32 r600_gpu_check_soft_reset(struct radeon_device *rdev)
f13f7731a   Alex Deucher   drm/radeon: use s...
1524
1525
  {
  	u32 reset_mask = 0;
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1526
  	u32 tmp;
71e3d1578   Alex Deucher   drm/radeon: switc...
1527

f13f7731a   Alex Deucher   drm/radeon: use s...
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
  	/* GRBM_STATUS */
  	tmp = RREG32(R_008010_GRBM_STATUS);
  	if (rdev->family >= CHIP_RV770) {
  		if (G_008010_PA_BUSY(tmp) | G_008010_SC_BUSY(tmp) |
  		    G_008010_SH_BUSY(tmp) | G_008010_SX_BUSY(tmp) |
  		    G_008010_TA_BUSY(tmp) | G_008010_VGT_BUSY(tmp) |
  		    G_008010_DB03_BUSY(tmp) | G_008010_CB03_BUSY(tmp) |
  		    G_008010_SPI03_BUSY(tmp) | G_008010_VGT_BUSY_NO_DMA(tmp))
  			reset_mask |= RADEON_RESET_GFX;
  	} else {
  		if (G_008010_PA_BUSY(tmp) | G_008010_SC_BUSY(tmp) |
  		    G_008010_SH_BUSY(tmp) | G_008010_SX_BUSY(tmp) |
  		    G_008010_TA03_BUSY(tmp) | G_008010_VGT_BUSY(tmp) |
  		    G_008010_DB03_BUSY(tmp) | G_008010_CB03_BUSY(tmp) |
  		    G_008010_SPI03_BUSY(tmp) | G_008010_VGT_BUSY_NO_DMA(tmp))
  			reset_mask |= RADEON_RESET_GFX;
  	}
  
  	if (G_008010_CF_RQ_PENDING(tmp) | G_008010_PF_RQ_PENDING(tmp) |
  	    G_008010_CP_BUSY(tmp) | G_008010_CP_COHERENCY_BUSY(tmp))
  		reset_mask |= RADEON_RESET_CP;
  
  	if (G_008010_GRBM_EE_BUSY(tmp))
  		reset_mask |= RADEON_RESET_GRBM | RADEON_RESET_GFX | RADEON_RESET_CP;
  
  	/* DMA_STATUS_REG */
  	tmp = RREG32(DMA_STATUS_REG);
  	if (!(tmp & DMA_IDLE))
  		reset_mask |= RADEON_RESET_DMA;
  
  	/* SRBM_STATUS */
  	tmp = RREG32(R_000E50_SRBM_STATUS);
  	if (G_000E50_RLC_RQ_PENDING(tmp) | G_000E50_RLC_BUSY(tmp))
  		reset_mask |= RADEON_RESET_RLC;
  
  	if (G_000E50_IH_BUSY(tmp))
  		reset_mask |= RADEON_RESET_IH;
  
  	if (G_000E50_SEM_BUSY(tmp))
  		reset_mask |= RADEON_RESET_SEM;
19fc42ed9   Alex Deucher   drm/radeon: clear...
1568

f13f7731a   Alex Deucher   drm/radeon: use s...
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
  	if (G_000E50_GRBM_RQ_PENDING(tmp))
  		reset_mask |= RADEON_RESET_GRBM;
  
  	if (G_000E50_VMC_BUSY(tmp))
  		reset_mask |= RADEON_RESET_VMC;
  
  	if (G_000E50_MCB_BUSY(tmp) | G_000E50_MCDZ_BUSY(tmp) |
  	    G_000E50_MCDY_BUSY(tmp) | G_000E50_MCDX_BUSY(tmp) |
  	    G_000E50_MCDW_BUSY(tmp))
  		reset_mask |= RADEON_RESET_MC;
  
  	if (r600_is_display_hung(rdev))
  		reset_mask |= RADEON_RESET_DISPLAY;
d808fc882   Alex Deucher   drm/radeon: skip ...
1582
1583
1584
1585
1586
1587
  	/* Skip MC reset as it's mostly likely not hung, just busy */
  	if (reset_mask & RADEON_RESET_MC) {
  		DRM_DEBUG("MC busy: 0x%08X, clearing.
  ", reset_mask);
  		reset_mask &= ~RADEON_RESET_MC;
  	}
f13f7731a   Alex Deucher   drm/radeon: use s...
1588
1589
1590
1591
1592
1593
1594
1595
  	return reset_mask;
  }
  
  static void r600_gpu_soft_reset(struct radeon_device *rdev, u32 reset_mask)
  {
  	struct rv515_mc_save save;
  	u32 grbm_soft_reset = 0, srbm_soft_reset = 0;
  	u32 tmp;
19fc42ed9   Alex Deucher   drm/radeon: clear...
1596

71e3d1578   Alex Deucher   drm/radeon: switc...
1597
  	if (reset_mask == 0)
f13f7731a   Alex Deucher   drm/radeon: use s...
1598
  		return;
71e3d1578   Alex Deucher   drm/radeon: switc...
1599
1600
1601
  
  	dev_info(rdev->dev, "GPU softreset: 0x%08X
  ", reset_mask);
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1602
  	r600_print_gpu_status_regs(rdev);
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
  	/* Disable CP parsing/prefetching */
  	if (rdev->family >= CHIP_RV770)
  		WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1) | S_0086D8_CP_PFP_HALT(1));
  	else
  		WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
  
  	/* disable the RLC */
  	WREG32(RLC_CNTL, 0);
  
  	if (reset_mask & RADEON_RESET_DMA) {
  		/* Disable DMA */
  		tmp = RREG32(DMA_RB_CNTL);
  		tmp &= ~DMA_RB_ENABLE;
  		WREG32(DMA_RB_CNTL, tmp);
  	}
  
  	mdelay(50);
ca57802e5   Alex Deucher   drm/radeon: halt ...
1620
1621
1622
1623
1624
  	rv515_mc_stop(rdev, &save);
  	if (r600_mc_wait_for_idle(rdev)) {
  		dev_warn(rdev->dev, "Wait for MC idle timedout !
  ");
  	}
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
  	if (reset_mask & (RADEON_RESET_GFX | RADEON_RESET_COMPUTE)) {
  		if (rdev->family >= CHIP_RV770)
  			grbm_soft_reset |= S_008020_SOFT_RESET_DB(1) |
  				S_008020_SOFT_RESET_CB(1) |
  				S_008020_SOFT_RESET_PA(1) |
  				S_008020_SOFT_RESET_SC(1) |
  				S_008020_SOFT_RESET_SPI(1) |
  				S_008020_SOFT_RESET_SX(1) |
  				S_008020_SOFT_RESET_SH(1) |
  				S_008020_SOFT_RESET_TC(1) |
  				S_008020_SOFT_RESET_TA(1) |
  				S_008020_SOFT_RESET_VC(1) |
  				S_008020_SOFT_RESET_VGT(1);
  		else
  			grbm_soft_reset |= S_008020_SOFT_RESET_CR(1) |
  				S_008020_SOFT_RESET_DB(1) |
  				S_008020_SOFT_RESET_CB(1) |
  				S_008020_SOFT_RESET_PA(1) |
  				S_008020_SOFT_RESET_SC(1) |
  				S_008020_SOFT_RESET_SMX(1) |
  				S_008020_SOFT_RESET_SPI(1) |
  				S_008020_SOFT_RESET_SX(1) |
  				S_008020_SOFT_RESET_SH(1) |
  				S_008020_SOFT_RESET_TC(1) |
  				S_008020_SOFT_RESET_TA(1) |
  				S_008020_SOFT_RESET_VC(1) |
  				S_008020_SOFT_RESET_VGT(1);
  	}
  
  	if (reset_mask & RADEON_RESET_CP) {
  		grbm_soft_reset |= S_008020_SOFT_RESET_CP(1) |
  			S_008020_SOFT_RESET_VGT(1);
  
  		srbm_soft_reset |= S_000E60_SOFT_RESET_GRBM(1);
  	}
  
  	if (reset_mask & RADEON_RESET_DMA) {
  		if (rdev->family >= CHIP_RV770)
  			srbm_soft_reset |= RV770_SOFT_RESET_DMA;
  		else
  			srbm_soft_reset |= SOFT_RESET_DMA;
  	}
f13f7731a   Alex Deucher   drm/radeon: use s...
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
  	if (reset_mask & RADEON_RESET_RLC)
  		srbm_soft_reset |= S_000E60_SOFT_RESET_RLC(1);
  
  	if (reset_mask & RADEON_RESET_SEM)
  		srbm_soft_reset |= S_000E60_SOFT_RESET_SEM(1);
  
  	if (reset_mask & RADEON_RESET_IH)
  		srbm_soft_reset |= S_000E60_SOFT_RESET_IH(1);
  
  	if (reset_mask & RADEON_RESET_GRBM)
  		srbm_soft_reset |= S_000E60_SOFT_RESET_GRBM(1);
24178ec42   Alex Deucher   drm/radeon: don't...
1678
1679
1680
1681
  	if (!(rdev->flags & RADEON_IS_IGP)) {
  		if (reset_mask & RADEON_RESET_MC)
  			srbm_soft_reset |= S_000E60_SOFT_RESET_MC(1);
  	}
f13f7731a   Alex Deucher   drm/radeon: use s...
1682
1683
1684
  
  	if (reset_mask & RADEON_RESET_VMC)
  		srbm_soft_reset |= S_000E60_SOFT_RESET_VMC(1);
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
  	if (grbm_soft_reset) {
  		tmp = RREG32(R_008020_GRBM_SOFT_RESET);
  		tmp |= grbm_soft_reset;
  		dev_info(rdev->dev, "R_008020_GRBM_SOFT_RESET=0x%08X
  ", tmp);
  		WREG32(R_008020_GRBM_SOFT_RESET, tmp);
  		tmp = RREG32(R_008020_GRBM_SOFT_RESET);
  
  		udelay(50);
  
  		tmp &= ~grbm_soft_reset;
  		WREG32(R_008020_GRBM_SOFT_RESET, tmp);
  		tmp = RREG32(R_008020_GRBM_SOFT_RESET);
  	}
  
  	if (srbm_soft_reset) {
  		tmp = RREG32(SRBM_SOFT_RESET);
  		tmp |= srbm_soft_reset;
  		dev_info(rdev->dev, "SRBM_SOFT_RESET=0x%08X
  ", tmp);
  		WREG32(SRBM_SOFT_RESET, tmp);
  		tmp = RREG32(SRBM_SOFT_RESET);
  
  		udelay(50);
71e3d1578   Alex Deucher   drm/radeon: switc...
1709

d3cb781e8   Alex Deucher   drm/radeon: rewor...
1710
1711
1712
1713
  		tmp &= ~srbm_soft_reset;
  		WREG32(SRBM_SOFT_RESET, tmp);
  		tmp = RREG32(SRBM_SOFT_RESET);
  	}
71e3d1578   Alex Deucher   drm/radeon: switc...
1714
1715
1716
  
  	/* Wait a little for things to settle down */
  	mdelay(1);
a3c1945aa   Jerome Glisse   drm/radeon/kms: F...
1717
  	rv515_mc_resume(rdev, &save);
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1718
  	udelay(50);
410a3418a   Alex Deucher   drm/radeon: add a...
1719

d3cb781e8   Alex Deucher   drm/radeon: rewor...
1720
  	r600_print_gpu_status_regs(rdev);
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1721
  }
de9ae7447   Alex Deucher   drm/radeon: imple...
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
  static void r600_gpu_pci_config_reset(struct radeon_device *rdev)
  {
  	struct rv515_mc_save save;
  	u32 tmp, i;
  
  	dev_info(rdev->dev, "GPU pci config reset
  ");
  
  	/* disable dpm? */
  
  	/* Disable CP parsing/prefetching */
  	if (rdev->family >= CHIP_RV770)
  		WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1) | S_0086D8_CP_PFP_HALT(1));
  	else
  		WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
  
  	/* disable the RLC */
  	WREG32(RLC_CNTL, 0);
  
  	/* Disable DMA */
  	tmp = RREG32(DMA_RB_CNTL);
  	tmp &= ~DMA_RB_ENABLE;
  	WREG32(DMA_RB_CNTL, tmp);
  
  	mdelay(50);
  
  	/* set mclk/sclk to bypass */
  	if (rdev->family >= CHIP_RV770)
  		rv770_set_clk_bypass_mode(rdev);
  	/* disable BM */
  	pci_clear_master(rdev->pdev);
  	/* disable mem access */
  	rv515_mc_stop(rdev, &save);
  	if (r600_mc_wait_for_idle(rdev)) {
  		dev_warn(rdev->dev, "Wait for MC idle timedout !
  ");
  	}
  
  	/* BIF reset workaround.  Not sure if this is needed on 6xx */
  	tmp = RREG32(BUS_CNTL);
  	tmp |= VGA_COHE_SPEC_TIMER_DIS;
  	WREG32(BUS_CNTL, tmp);
  
  	tmp = RREG32(BIF_SCRATCH0);
  
  	/* reset */
  	radeon_pci_config_reset(rdev);
  	mdelay(1);
  
  	/* BIF reset workaround.  Not sure if this is needed on 6xx */
  	tmp = SOFT_RESET_BIF;
  	WREG32(SRBM_SOFT_RESET, tmp);
  	mdelay(1);
  	WREG32(SRBM_SOFT_RESET, 0);
  
  	/* wait for asic to come out of reset */
  	for (i = 0; i < rdev->usec_timeout; i++) {
  		if (RREG32(CONFIG_MEMSIZE) != 0xffffffff)
  			break;
  		udelay(1);
  	}
  }
d3cb781e8   Alex Deucher   drm/radeon: rewor...
1784
1785
  int r600_asic_reset(struct radeon_device *rdev)
  {
f13f7731a   Alex Deucher   drm/radeon: use s...
1786
1787
1788
1789
1790
1791
  	u32 reset_mask;
  
  	reset_mask = r600_gpu_check_soft_reset(rdev);
  
  	if (reset_mask)
  		r600_set_bios_scratch_engine_hung(rdev, true);
de9ae7447   Alex Deucher   drm/radeon: imple...
1792
  	/* try soft reset */
f13f7731a   Alex Deucher   drm/radeon: use s...
1793
1794
1795
  	r600_gpu_soft_reset(rdev, reset_mask);
  
  	reset_mask = r600_gpu_check_soft_reset(rdev);
de9ae7447   Alex Deucher   drm/radeon: imple...
1796
1797
1798
1799
1800
  	/* try pci config reset */
  	if (reset_mask && radeon_hard_reset)
  		r600_gpu_pci_config_reset(rdev);
  
  	reset_mask = r600_gpu_check_soft_reset(rdev);
f13f7731a   Alex Deucher   drm/radeon: use s...
1801
1802
1803
1804
  	if (!reset_mask)
  		r600_set_bios_scratch_engine_hung(rdev, false);
  
  	return 0;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1805
  }
123bc1832   Alex Deucher   drm/radeon: use t...
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
  /**
   * r600_gfx_is_lockup - Check if the GFX engine is locked up
   *
   * @rdev: radeon_device pointer
   * @ring: radeon_ring structure holding ring information
   *
   * Check if the GFX engine is locked up.
   * Returns true if the engine appears to be locked up, false if not.
   */
  bool r600_gfx_is_lockup(struct radeon_device *rdev, struct radeon_ring *ring)
225758d8b   Jerome Glisse   drm/radeon/kms: f...
1816
  {
123bc1832   Alex Deucher   drm/radeon: use t...
1817
1818
1819
1820
1821
  	u32 reset_mask = r600_gpu_check_soft_reset(rdev);
  
  	if (!(reset_mask & (RADEON_RESET_GFX |
  			    RADEON_RESET_COMPUTE |
  			    RADEON_RESET_CP))) {
ff212f25f   Christian König   drm/radeon: drop ...
1822
  		radeon_ring_lockup_update(rdev, ring);
225758d8b   Jerome Glisse   drm/radeon/kms: f...
1823
1824
  		return false;
  	}
069211e55   Christian König   drm/radeon: move ...
1825
  	return radeon_ring_test_lockup(rdev, ring);
225758d8b   Jerome Glisse   drm/radeon/kms: f...
1826
  }
416a2bd27   Alex Deucher   drm/radeon: fixup...
1827
1828
1829
1830
1831
  u32 r6xx_remap_render_backend(struct radeon_device *rdev,
  			      u32 tiling_pipe_num,
  			      u32 max_rb_num,
  			      u32 total_max_rb_num,
  			      u32 disabled_rb_mask)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1832
  {
416a2bd27   Alex Deucher   drm/radeon: fixup...
1833
  	u32 rendering_pipe_num, rb_num_width, req_rb_num;
f689e3acb   Mikko Tiihonen   drm/radeon: prote...
1834
  	u32 pipe_rb_ratio, pipe_rb_remain, tmp;
416a2bd27   Alex Deucher   drm/radeon: fixup...
1835
1836
  	u32 data = 0, mask = 1 << (max_rb_num - 1);
  	unsigned i, j;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1837

416a2bd27   Alex Deucher   drm/radeon: fixup...
1838
  	/* mask out the RBs that don't exist on that asic */
f689e3acb   Mikko Tiihonen   drm/radeon: prote...
1839
1840
1841
1842
  	tmp = disabled_rb_mask | ((0xff << max_rb_num) & 0xff);
  	/* make sure at least one RB is available */
  	if ((tmp & 0xff) != 0xff)
  		disabled_rb_mask = tmp;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1843

416a2bd27   Alex Deucher   drm/radeon: fixup...
1844
1845
1846
  	rendering_pipe_num = 1 << tiling_pipe_num;
  	req_rb_num = total_max_rb_num - r600_count_pipe_bits(disabled_rb_mask);
  	BUG_ON(rendering_pipe_num < req_rb_num);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1847

416a2bd27   Alex Deucher   drm/radeon: fixup...
1848
1849
  	pipe_rb_ratio = rendering_pipe_num / req_rb_num;
  	pipe_rb_remain = rendering_pipe_num - pipe_rb_ratio * req_rb_num;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1850

416a2bd27   Alex Deucher   drm/radeon: fixup...
1851
1852
1853
1854
1855
1856
1857
  	if (rdev->family <= CHIP_RV740) {
  		/* r6xx/r7xx */
  		rb_num_width = 2;
  	} else {
  		/* eg+ */
  		rb_num_width = 4;
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1858

416a2bd27   Alex Deucher   drm/radeon: fixup...
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
  	for (i = 0; i < max_rb_num; i++) {
  		if (!(mask & disabled_rb_mask)) {
  			for (j = 0; j < pipe_rb_ratio; j++) {
  				data <<= rb_num_width;
  				data |= max_rb_num - i - 1;
  			}
  			if (pipe_rb_remain) {
  				data <<= rb_num_width;
  				data |= max_rb_num - i - 1;
  				pipe_rb_remain--;
  			}
  		}
  		mask >>= 1;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1872
  	}
416a2bd27   Alex Deucher   drm/radeon: fixup...
1873
  	return data;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1874
1875
1876
1877
  }
  
  int r600_count_pipe_bits(uint32_t val)
  {
ef8cf3a1c   Akinobu Mita   drm/radeon: Use h...
1878
  	return hweight32(val);
771fe6b91   Jerome Glisse   drm/radeon: intro...
1879
  }
1109ca09b   Lauri Kasanen   drm/radeon: Mark ...
1880
  static void r600_gpu_init(struct radeon_device *rdev)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1881
1882
1883
  {
  	u32 tiling_config;
  	u32 ramcfg;
d03f5d597   Alex Deucher   drm/radeon: fixes...
1884
  	u32 cc_gc_shader_pipe_config;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1885
1886
1887
1888
1889
1890
1891
1892
  	u32 tmp;
  	int i, j;
  	u32 sq_config;
  	u32 sq_gpr_resource_mgmt_1 = 0;
  	u32 sq_gpr_resource_mgmt_2 = 0;
  	u32 sq_thread_resource_mgmt = 0;
  	u32 sq_stack_resource_mgmt_1 = 0;
  	u32 sq_stack_resource_mgmt_2 = 0;
416a2bd27   Alex Deucher   drm/radeon: fixup...
1893
  	u32 disabled_rb_mask;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1894

416a2bd27   Alex Deucher   drm/radeon: fixup...
1895
  	rdev->config.r600.tiling_group_size = 256;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
  	switch (rdev->family) {
  	case CHIP_R600:
  		rdev->config.r600.max_pipes = 4;
  		rdev->config.r600.max_tile_pipes = 8;
  		rdev->config.r600.max_simds = 4;
  		rdev->config.r600.max_backends = 4;
  		rdev->config.r600.max_gprs = 256;
  		rdev->config.r600.max_threads = 192;
  		rdev->config.r600.max_stack_entries = 256;
  		rdev->config.r600.max_hw_contexts = 8;
  		rdev->config.r600.max_gs_threads = 16;
  		rdev->config.r600.sx_max_export_size = 128;
  		rdev->config.r600.sx_max_export_pos_size = 16;
  		rdev->config.r600.sx_max_export_smx_size = 128;
  		rdev->config.r600.sq_num_cf_insts = 2;
  		break;
  	case CHIP_RV630:
  	case CHIP_RV635:
  		rdev->config.r600.max_pipes = 2;
  		rdev->config.r600.max_tile_pipes = 2;
  		rdev->config.r600.max_simds = 3;
  		rdev->config.r600.max_backends = 1;
  		rdev->config.r600.max_gprs = 128;
  		rdev->config.r600.max_threads = 192;
  		rdev->config.r600.max_stack_entries = 128;
  		rdev->config.r600.max_hw_contexts = 8;
  		rdev->config.r600.max_gs_threads = 4;
  		rdev->config.r600.sx_max_export_size = 128;
  		rdev->config.r600.sx_max_export_pos_size = 16;
  		rdev->config.r600.sx_max_export_smx_size = 128;
  		rdev->config.r600.sq_num_cf_insts = 2;
  		break;
  	case CHIP_RV610:
  	case CHIP_RV620:
  	case CHIP_RS780:
  	case CHIP_RS880:
  		rdev->config.r600.max_pipes = 1;
  		rdev->config.r600.max_tile_pipes = 1;
  		rdev->config.r600.max_simds = 2;
  		rdev->config.r600.max_backends = 1;
  		rdev->config.r600.max_gprs = 128;
  		rdev->config.r600.max_threads = 192;
  		rdev->config.r600.max_stack_entries = 128;
  		rdev->config.r600.max_hw_contexts = 4;
  		rdev->config.r600.max_gs_threads = 4;
  		rdev->config.r600.sx_max_export_size = 128;
  		rdev->config.r600.sx_max_export_pos_size = 16;
  		rdev->config.r600.sx_max_export_smx_size = 128;
  		rdev->config.r600.sq_num_cf_insts = 1;
  		break;
  	case CHIP_RV670:
  		rdev->config.r600.max_pipes = 4;
  		rdev->config.r600.max_tile_pipes = 4;
  		rdev->config.r600.max_simds = 4;
  		rdev->config.r600.max_backends = 4;
  		rdev->config.r600.max_gprs = 192;
  		rdev->config.r600.max_threads = 192;
  		rdev->config.r600.max_stack_entries = 256;
  		rdev->config.r600.max_hw_contexts = 8;
  		rdev->config.r600.max_gs_threads = 16;
  		rdev->config.r600.sx_max_export_size = 128;
  		rdev->config.r600.sx_max_export_pos_size = 16;
  		rdev->config.r600.sx_max_export_smx_size = 128;
  		rdev->config.r600.sq_num_cf_insts = 2;
  		break;
  	default:
  		break;
  	}
  
  	/* Initialize HDP */
  	for (i = 0, j = 0; i < 32; i++, j += 0x18) {
  		WREG32((0x2c14 + j), 0x00000000);
  		WREG32((0x2c18 + j), 0x00000000);
  		WREG32((0x2c1c + j), 0x00000000);
  		WREG32((0x2c20 + j), 0x00000000);
  		WREG32((0x2c24 + j), 0x00000000);
  	}
  
  	WREG32(GRBM_CNTL, GRBM_READ_TIMEOUT(0xff));
  
  	/* Setup tiling */
  	tiling_config = 0;
  	ramcfg = RREG32(RAMCFG);
  	switch (rdev->config.r600.max_tile_pipes) {
  	case 1:
  		tiling_config |= PIPE_TILING(0);
  		break;
  	case 2:
  		tiling_config |= PIPE_TILING(1);
  		break;
  	case 4:
  		tiling_config |= PIPE_TILING(2);
  		break;
  	case 8:
  		tiling_config |= PIPE_TILING(3);
  		break;
  	default:
  		break;
  	}
d03f5d597   Alex Deucher   drm/radeon: fixes...
1995
  	rdev->config.r600.tiling_npipes = rdev->config.r600.max_tile_pipes;
961fb597c   Jerome Glisse   drm/radeon/kms: r...
1996
  	rdev->config.r600.tiling_nbanks = 4 << ((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
1997
  	tiling_config |= BANK_TILING((ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT);
881fe6c1d   Alex Deucher   drm/radeon/kms: p...
1998
  	tiling_config |= GROUP_SIZE((ramcfg & BURSTLENGTH_MASK) >> BURSTLENGTH_SHIFT);
416a2bd27   Alex Deucher   drm/radeon: fixup...
1999

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2000
2001
2002
2003
2004
2005
2006
2007
2008
  	tmp = (ramcfg & NOOFROWS_MASK) >> NOOFROWS_SHIFT;
  	if (tmp > 3) {
  		tiling_config |= ROW_TILING(3);
  		tiling_config |= SAMPLE_SPLIT(3);
  	} else {
  		tiling_config |= ROW_TILING(tmp);
  		tiling_config |= SAMPLE_SPLIT(tmp);
  	}
  	tiling_config |= BANK_SWAPS(1);
d03f5d597   Alex Deucher   drm/radeon: fixes...
2009

416a2bd27   Alex Deucher   drm/radeon: fixup...
2010
  	cc_gc_shader_pipe_config = RREG32(CC_GC_SHADER_PIPE_CONFIG) & 0x00ffff00;
65fcf668e   Alex Deucher   drm/radeon: add q...
2011
2012
2013
  	tmp = rdev->config.r600.max_simds -
  		r600_count_pipe_bits((cc_gc_shader_pipe_config >> 16) & R6XX_MAX_SIMDS_MASK);
  	rdev->config.r600.active_simds = tmp;
416a2bd27   Alex Deucher   drm/radeon: fixup...
2014
2015
  
  	disabled_rb_mask = (RREG32(CC_RB_BACKEND_DISABLE) >> 16) & R6XX_MAX_BACKENDS_MASK;
0a5f6e9d6   Alex Deucher   drm/radeon: handl...
2016
2017
2018
2019
2020
2021
2022
2023
  	tmp = 0;
  	for (i = 0; i < rdev->config.r600.max_backends; i++)
  		tmp |= (1 << i);
  	/* if all the backends are disabled, fix it up here */
  	if ((disabled_rb_mask & tmp) == tmp) {
  		for (i = 0; i < rdev->config.r600.max_backends; i++)
  			disabled_rb_mask &= ~(1 << i);
  	}
416a2bd27   Alex Deucher   drm/radeon: fixup...
2024
2025
2026
2027
2028
  	tmp = (tiling_config & PIPE_TILING__MASK) >> PIPE_TILING__SHIFT;
  	tmp = r6xx_remap_render_backend(rdev, tmp, rdev->config.r600.max_backends,
  					R6XX_MAX_BACKENDS, disabled_rb_mask);
  	tiling_config |= tmp << 16;
  	rdev->config.r600.backend_map = tmp;
e7aeeba6a   Alex Deucher   drm/radeon/kms/r6...
2029
  	rdev->config.r600.tile_config = tiling_config;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2030
2031
2032
  	WREG32(GB_TILING_CONFIG, tiling_config);
  	WREG32(DCP_TILING_CONFIG, tiling_config & 0xffff);
  	WREG32(HDP_TILING_CONFIG, tiling_config & 0xffff);
4d75658bf   Alex Deucher   drm/radeon/kms: A...
2033
  	WREG32(DMA_TILING_CONFIG, tiling_config & 0xffff);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2034

d03f5d597   Alex Deucher   drm/radeon: fixes...
2035
  	tmp = R6XX_MAX_PIPES - r600_count_pipe_bits((cc_gc_shader_pipe_config & INACTIVE_QD_PIPES_MASK) >> 8);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
  	WREG32(VGT_OUT_DEALLOC_CNTL, (tmp * 4) & DEALLOC_DIST_MASK);
  	WREG32(VGT_VERTEX_REUSE_BLOCK_CNTL, ((tmp * 4) - 2) & VTX_REUSE_DEPTH_MASK);
  
  	/* Setup some CP states */
  	WREG32(CP_QUEUE_THRESHOLDS, (ROQ_IB1_START(0x16) | ROQ_IB2_START(0x2b)));
  	WREG32(CP_MEQ_THRESHOLDS, (MEQ_END(0x40) | ROQ_END(0x40)));
  
  	WREG32(TA_CNTL_AUX, (DISABLE_CUBE_ANISO | SYNC_GRADIENT |
  			     SYNC_WALKER | SYNC_ALIGNER));
  	/* Setup various GPU states */
  	if (rdev->family == CHIP_RV670)
  		WREG32(ARB_GDEC_RD_CNTL, 0x00000021);
  
  	tmp = RREG32(SX_DEBUG_1);
  	tmp |= SMX_EVENT_RELEASE;
  	if ((rdev->family > CHIP_R600))
  		tmp |= ENABLE_NEW_SMX_ADDRESS;
  	WREG32(SX_DEBUG_1, tmp);
  
  	if (((rdev->family) == CHIP_R600) ||
  	    ((rdev->family) == CHIP_RV630) ||
  	    ((rdev->family) == CHIP_RV610) ||
  	    ((rdev->family) == CHIP_RV620) ||
ee59f2b46   Alex Deucher   drm/radeon/kms/r6...
2059
2060
  	    ((rdev->family) == CHIP_RS780) ||
  	    ((rdev->family) == CHIP_RS880)) {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
  		WREG32(DB_DEBUG, PREZ_MUST_WAIT_FOR_POSTZ_DONE);
  	} else {
  		WREG32(DB_DEBUG, 0);
  	}
  	WREG32(DB_WATERMARKS, (DEPTH_FREE(4) | DEPTH_CACHELINE_FREE(16) |
  			       DEPTH_FLUSH(16) | DEPTH_PENDING_FREE(4)));
  
  	WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
  	WREG32(VGT_NUM_INSTANCES, 0);
  
  	WREG32(SPI_CONFIG_CNTL, GPR_WRITE_PRIORITY(0));
  	WREG32(SPI_CONFIG_CNTL_1, VTX_DONE_DELAY(0));
  
  	tmp = RREG32(SQ_MS_FIFO_SIZES);
  	if (((rdev->family) == CHIP_RV610) ||
  	    ((rdev->family) == CHIP_RV620) ||
ee59f2b46   Alex Deucher   drm/radeon/kms/r6...
2077
2078
  	    ((rdev->family) == CHIP_RS780) ||
  	    ((rdev->family) == CHIP_RS880)) {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
  		tmp = (CACHE_FIFO_SIZE(0xa) |
  		       FETCH_FIFO_HIWATER(0xa) |
  		       DONE_FIFO_HIWATER(0xe0) |
  		       ALU_UPDATE_FIFO_HIWATER(0x8));
  	} else if (((rdev->family) == CHIP_R600) ||
  		   ((rdev->family) == CHIP_RV630)) {
  		tmp &= ~DONE_FIFO_HIWATER(0xff);
  		tmp |= DONE_FIFO_HIWATER(0x4);
  	}
  	WREG32(SQ_MS_FIFO_SIZES, tmp);
  
  	/* SQ_CONFIG, SQ_GPR_RESOURCE_MGMT, SQ_THREAD_RESOURCE_MGMT, SQ_STACK_RESOURCE_MGMT
  	 * should be adjusted as needed by the 2D/3D drivers.  This just sets default values
  	 */
  	sq_config = RREG32(SQ_CONFIG);
  	sq_config &= ~(PS_PRIO(3) |
  		       VS_PRIO(3) |
  		       GS_PRIO(3) |
  		       ES_PRIO(3));
  	sq_config |= (DX9_CONSTS |
  		      VC_ENABLE |
  		      PS_PRIO(0) |
  		      VS_PRIO(1) |
  		      GS_PRIO(2) |
  		      ES_PRIO(3));
  
  	if ((rdev->family) == CHIP_R600) {
  		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(124) |
  					  NUM_VS_GPRS(124) |
  					  NUM_CLAUSE_TEMP_GPRS(4));
  		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(0) |
  					  NUM_ES_GPRS(0));
  		sq_thread_resource_mgmt = (NUM_PS_THREADS(136) |
  					   NUM_VS_THREADS(48) |
  					   NUM_GS_THREADS(4) |
  					   NUM_ES_THREADS(4));
  		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(128) |
  					    NUM_VS_STACK_ENTRIES(128));
  		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(0) |
  					    NUM_ES_STACK_ENTRIES(0));
  	} else if (((rdev->family) == CHIP_RV610) ||
  		   ((rdev->family) == CHIP_RV620) ||
ee59f2b46   Alex Deucher   drm/radeon/kms/r6...
2121
2122
  		   ((rdev->family) == CHIP_RS780) ||
  		   ((rdev->family) == CHIP_RS880)) {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
  		/* no vertex cache */
  		sq_config &= ~VC_ENABLE;
  
  		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
  					  NUM_VS_GPRS(44) |
  					  NUM_CLAUSE_TEMP_GPRS(2));
  		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) |
  					  NUM_ES_GPRS(17));
  		sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
  					   NUM_VS_THREADS(78) |
  					   NUM_GS_THREADS(4) |
  					   NUM_ES_THREADS(31));
  		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) |
  					    NUM_VS_STACK_ENTRIES(40));
  		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) |
  					    NUM_ES_STACK_ENTRIES(16));
  	} else if (((rdev->family) == CHIP_RV630) ||
  		   ((rdev->family) == CHIP_RV635)) {
  		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
  					  NUM_VS_GPRS(44) |
  					  NUM_CLAUSE_TEMP_GPRS(2));
  		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(18) |
  					  NUM_ES_GPRS(18));
  		sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
  					   NUM_VS_THREADS(78) |
  					   NUM_GS_THREADS(4) |
  					   NUM_ES_THREADS(31));
  		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(40) |
  					    NUM_VS_STACK_ENTRIES(40));
  		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(32) |
  					    NUM_ES_STACK_ENTRIES(16));
  	} else if ((rdev->family) == CHIP_RV670) {
  		sq_gpr_resource_mgmt_1 = (NUM_PS_GPRS(44) |
  					  NUM_VS_GPRS(44) |
  					  NUM_CLAUSE_TEMP_GPRS(2));
  		sq_gpr_resource_mgmt_2 = (NUM_GS_GPRS(17) |
  					  NUM_ES_GPRS(17));
  		sq_thread_resource_mgmt = (NUM_PS_THREADS(79) |
  					   NUM_VS_THREADS(78) |
  					   NUM_GS_THREADS(4) |
  					   NUM_ES_THREADS(31));
  		sq_stack_resource_mgmt_1 = (NUM_PS_STACK_ENTRIES(64) |
  					    NUM_VS_STACK_ENTRIES(64));
  		sq_stack_resource_mgmt_2 = (NUM_GS_STACK_ENTRIES(64) |
  					    NUM_ES_STACK_ENTRIES(64));
  	}
  
  	WREG32(SQ_CONFIG, sq_config);
  	WREG32(SQ_GPR_RESOURCE_MGMT_1,  sq_gpr_resource_mgmt_1);
  	WREG32(SQ_GPR_RESOURCE_MGMT_2,  sq_gpr_resource_mgmt_2);
  	WREG32(SQ_THREAD_RESOURCE_MGMT, sq_thread_resource_mgmt);
  	WREG32(SQ_STACK_RESOURCE_MGMT_1, sq_stack_resource_mgmt_1);
  	WREG32(SQ_STACK_RESOURCE_MGMT_2, sq_stack_resource_mgmt_2);
  
  	if (((rdev->family) == CHIP_RV610) ||
  	    ((rdev->family) == CHIP_RV620) ||
ee59f2b46   Alex Deucher   drm/radeon/kms/r6...
2179
2180
  	    ((rdev->family) == CHIP_RS780) ||
  	    ((rdev->family) == CHIP_RS880)) {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
  		WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(TC_ONLY));
  	} else {
  		WREG32(VGT_CACHE_INVALIDATION, CACHE_INVALIDATION(VC_AND_TC));
  	}
  
  	/* More default values. 2D/3D driver should adjust as needed */
  	WREG32(PA_SC_AA_SAMPLE_LOCS_2S, (S0_X(0xc) | S0_Y(0x4) |
  					 S1_X(0x4) | S1_Y(0xc)));
  	WREG32(PA_SC_AA_SAMPLE_LOCS_4S, (S0_X(0xe) | S0_Y(0xe) |
  					 S1_X(0x2) | S1_Y(0x2) |
  					 S2_X(0xa) | S2_Y(0x6) |
  					 S3_X(0x6) | S3_Y(0xa)));
  	WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD0, (S0_X(0xe) | S0_Y(0xb) |
  					     S1_X(0x4) | S1_Y(0xc) |
  					     S2_X(0x1) | S2_Y(0x6) |
  					     S3_X(0xa) | S3_Y(0xe)));
  	WREG32(PA_SC_AA_SAMPLE_LOCS_8S_WD1, (S4_X(0x6) | S4_Y(0x1) |
  					     S5_X(0x0) | S5_Y(0x0) |
  					     S6_X(0xb) | S6_Y(0x4) |
  					     S7_X(0x7) | S7_Y(0x8)));
  
  	WREG32(VGT_STRMOUT_EN, 0);
  	tmp = rdev->config.r600.max_pipes * 16;
  	switch (rdev->family) {
  	case CHIP_RV610:
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2206
  	case CHIP_RV620:
ee59f2b46   Alex Deucher   drm/radeon/kms/r6...
2207
2208
  	case CHIP_RS780:
  	case CHIP_RS880:
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
  		tmp += 32;
  		break;
  	case CHIP_RV670:
  		tmp += 128;
  		break;
  	default:
  		break;
  	}
  	if (tmp > 256) {
  		tmp = 256;
  	}
  	WREG32(VGT_ES_PER_GS, 128);
  	WREG32(VGT_GS_PER_ES, tmp);
  	WREG32(VGT_GS_PER_VS, 2);
  	WREG32(VGT_GS_VERTEX_REUSE, 16);
  
  	/* more default values. 2D/3D driver should adjust as needed */
  	WREG32(PA_SC_LINE_STIPPLE_STATE, 0);
  	WREG32(VGT_STRMOUT_EN, 0);
  	WREG32(SX_MISC, 0);
  	WREG32(PA_SC_MODE_CNTL, 0);
  	WREG32(PA_SC_AA_CONFIG, 0);
  	WREG32(PA_SC_LINE_STIPPLE, 0);
  	WREG32(SPI_INPUT_Z, 0);
  	WREG32(SPI_PS_IN_CONTROL_0, NUM_INTERP(2));
  	WREG32(CB_COLOR7_FRAG, 0);
  
  	/* Clear render buffer base addresses */
  	WREG32(CB_COLOR0_BASE, 0);
  	WREG32(CB_COLOR1_BASE, 0);
  	WREG32(CB_COLOR2_BASE, 0);
  	WREG32(CB_COLOR3_BASE, 0);
  	WREG32(CB_COLOR4_BASE, 0);
  	WREG32(CB_COLOR5_BASE, 0);
  	WREG32(CB_COLOR6_BASE, 0);
  	WREG32(CB_COLOR7_BASE, 0);
  	WREG32(CB_COLOR7_FRAG, 0);
  
  	switch (rdev->family) {
  	case CHIP_RV610:
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2249
  	case CHIP_RV620:
ee59f2b46   Alex Deucher   drm/radeon/kms/r6...
2250
2251
  	case CHIP_RS780:
  	case CHIP_RS880:
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
  		tmp = TC_L2_SIZE(8);
  		break;
  	case CHIP_RV630:
  	case CHIP_RV635:
  		tmp = TC_L2_SIZE(4);
  		break;
  	case CHIP_R600:
  		tmp = TC_L2_SIZE(0) | L2_DISABLE_LATE_HIT;
  		break;
  	default:
  		tmp = TC_L2_SIZE(0);
  		break;
  	}
  	WREG32(TC_CNTL, tmp);
  
  	tmp = RREG32(HDP_HOST_PATH_CNTL);
  	WREG32(HDP_HOST_PATH_CNTL, tmp);
  
  	tmp = RREG32(ARB_POP);
  	tmp |= ENABLE_TC128;
  	WREG32(ARB_POP, tmp);
  
  	WREG32(PA_SC_MULTI_CHIP_CNTL, 0);
  	WREG32(PA_CL_ENHANCE, (CLIP_VTX_REORDER_ENA |
  			       NUM_CLIP_SEQ(3)));
  	WREG32(PA_SC_ENHANCE, FORCE_EOV_MAX_CLK_CNT(4095));
b866d1334   Alex Deucher   drm/radeon: add s...
2278
  	WREG32(VC_ENHANCE, 0);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2279
  }
771fe6b91   Jerome Glisse   drm/radeon: intro...
2280
2281
2282
  /*
   * Indirect registers accessor
   */
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2283
2284
  u32 r600_pciep_rreg(struct radeon_device *rdev, u32 reg)
  {
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
2285
  	unsigned long flags;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2286
  	u32 r;
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
2287
  	spin_lock_irqsave(&rdev->pciep_idx_lock, flags);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2288
2289
2290
  	WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
  	(void)RREG32(PCIE_PORT_INDEX);
  	r = RREG32(PCIE_PORT_DATA);
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
2291
  	spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2292
2293
2294
2295
2296
  	return r;
  }
  
  void r600_pciep_wreg(struct radeon_device *rdev, u32 reg, u32 v)
  {
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
2297
2298
2299
  	unsigned long flags;
  
  	spin_lock_irqsave(&rdev->pciep_idx_lock, flags);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2300
2301
2302
2303
  	WREG32(PCIE_PORT_INDEX, ((reg) & 0xff));
  	(void)RREG32(PCIE_PORT_INDEX);
  	WREG32(PCIE_PORT_DATA, (v));
  	(void)RREG32(PCIE_PORT_DATA);
0a5b7b0bd   Alex Deucher   drm/radeon: add s...
2304
  	spin_unlock_irqrestore(&rdev->pciep_idx_lock, flags);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2305
  }
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2306
2307
2308
2309
2310
  /*
   * CP & Ring
   */
  void r600_cp_stop(struct radeon_device *rdev)
  {
50efa51af   Alex Deucher   drm/radeon: clean...
2311
2312
  	if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
  		radeon_ttm_set_active_vram_size(rdev, rdev->mc.visible_vram_size);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2313
  	WREG32(R_0086D8_CP_ME_CNTL, S_0086D8_CP_ME_HALT(1));
724c80e1d   Alex Deucher   drm/radeon/kms: e...
2314
  	WREG32(SCRATCH_UMSK, 0);
4d75658bf   Alex Deucher   drm/radeon/kms: A...
2315
  	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ready = false;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2316
  }
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2317
  int r600_init_microcode(struct radeon_device *rdev)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2318
  {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2319
  	const char *chip_name;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2320
  	const char *rlc_chip_name;
66229b200   Alex Deucher   drm/radeon/kms: a...
2321
2322
  	const char *smc_chip_name = "RV770";
  	size_t pfp_req_size, me_req_size, rlc_req_size, smc_req_size = 0;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2323
2324
2325
2326
2327
  	char fw_name[30];
  	int err;
  
  	DRM_DEBUG("
  ");
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2328
  	switch (rdev->family) {
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
  	case CHIP_R600:
  		chip_name = "R600";
  		rlc_chip_name = "R600";
  		break;
  	case CHIP_RV610:
  		chip_name = "RV610";
  		rlc_chip_name = "R600";
  		break;
  	case CHIP_RV630:
  		chip_name = "RV630";
  		rlc_chip_name = "R600";
  		break;
  	case CHIP_RV620:
  		chip_name = "RV620";
  		rlc_chip_name = "R600";
  		break;
  	case CHIP_RV635:
  		chip_name = "RV635";
  		rlc_chip_name = "R600";
  		break;
  	case CHIP_RV670:
  		chip_name = "RV670";
  		rlc_chip_name = "R600";
  		break;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2353
  	case CHIP_RS780:
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2354
2355
2356
2357
2358
2359
2360
  	case CHIP_RS880:
  		chip_name = "RS780";
  		rlc_chip_name = "R600";
  		break;
  	case CHIP_RV770:
  		chip_name = "RV770";
  		rlc_chip_name = "R700";
66229b200   Alex Deucher   drm/radeon/kms: a...
2361
2362
  		smc_chip_name = "RV770";
  		smc_req_size = ALIGN(RV770_SMC_UCODE_SIZE, 4);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2363
  		break;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2364
  	case CHIP_RV730:
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2365
2366
  		chip_name = "RV730";
  		rlc_chip_name = "R700";
66229b200   Alex Deucher   drm/radeon/kms: a...
2367
2368
  		smc_chip_name = "RV730";
  		smc_req_size = ALIGN(RV730_SMC_UCODE_SIZE, 4);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2369
2370
2371
2372
  		break;
  	case CHIP_RV710:
  		chip_name = "RV710";
  		rlc_chip_name = "R700";
66229b200   Alex Deucher   drm/radeon/kms: a...
2373
2374
2375
2376
2377
2378
2379
2380
  		smc_chip_name = "RV710";
  		smc_req_size = ALIGN(RV710_SMC_UCODE_SIZE, 4);
  		break;
  	case CHIP_RV740:
  		chip_name = "RV730";
  		rlc_chip_name = "R700";
  		smc_chip_name = "RV740";
  		smc_req_size = ALIGN(RV740_SMC_UCODE_SIZE, 4);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2381
  		break;
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
2382
2383
  	case CHIP_CEDAR:
  		chip_name = "CEDAR";
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
2384
  		rlc_chip_name = "CEDAR";
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
2385
2386
  		smc_chip_name = "CEDAR";
  		smc_req_size = ALIGN(CEDAR_SMC_UCODE_SIZE, 4);
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
2387
2388
2389
  		break;
  	case CHIP_REDWOOD:
  		chip_name = "REDWOOD";
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
2390
  		rlc_chip_name = "REDWOOD";
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
2391
2392
  		smc_chip_name = "REDWOOD";
  		smc_req_size = ALIGN(REDWOOD_SMC_UCODE_SIZE, 4);
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
2393
2394
2395
  		break;
  	case CHIP_JUNIPER:
  		chip_name = "JUNIPER";
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
2396
  		rlc_chip_name = "JUNIPER";
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
2397
2398
  		smc_chip_name = "JUNIPER";
  		smc_req_size = ALIGN(JUNIPER_SMC_UCODE_SIZE, 4);
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
2399
2400
2401
2402
  		break;
  	case CHIP_CYPRESS:
  	case CHIP_HEMLOCK:
  		chip_name = "CYPRESS";
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
2403
  		rlc_chip_name = "CYPRESS";
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
2404
2405
  		smc_chip_name = "CYPRESS";
  		smc_req_size = ALIGN(CYPRESS_SMC_UCODE_SIZE, 4);
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
2406
  		break;
439bd6cde   Alex Deucher   drm/radeon/kms: a...
2407
2408
2409
2410
  	case CHIP_PALM:
  		chip_name = "PALM";
  		rlc_chip_name = "SUMO";
  		break;
d5c5a72f2   Alex Deucher   drm/radeon/kms: a...
2411
2412
2413
2414
2415
2416
2417
2418
  	case CHIP_SUMO:
  		chip_name = "SUMO";
  		rlc_chip_name = "SUMO";
  		break;
  	case CHIP_SUMO2:
  		chip_name = "SUMO2";
  		rlc_chip_name = "SUMO";
  		break;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2419
2420
  	default: BUG();
  	}
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
2421
2422
2423
  	if (rdev->family >= CHIP_CEDAR) {
  		pfp_req_size = EVERGREEN_PFP_UCODE_SIZE * 4;
  		me_req_size = EVERGREEN_PM4_UCODE_SIZE * 4;
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
2424
  		rlc_req_size = EVERGREEN_RLC_UCODE_SIZE * 4;
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
2425
  	} else if (rdev->family >= CHIP_RV770) {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2426
2427
  		pfp_req_size = R700_PFP_UCODE_SIZE * 4;
  		me_req_size = R700_PM4_UCODE_SIZE * 4;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2428
  		rlc_req_size = R700_RLC_UCODE_SIZE * 4;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2429
  	} else {
138e4e16f   Alex Deucher   drm/radeon/kms: m...
2430
2431
2432
  		pfp_req_size = R600_PFP_UCODE_SIZE * 4;
  		me_req_size = R600_PM4_UCODE_SIZE * 12;
  		rlc_req_size = R600_RLC_UCODE_SIZE * 4;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2433
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2434
2435
  	DRM_INFO("Loading %s Microcode
  ", chip_name);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2436
2437
  
  	snprintf(fw_name, sizeof(fw_name), "radeon/%s_pfp.bin", chip_name);
0a1689339   Jerome Glisse   drm/radeon: use r...
2438
  	err = request_firmware(&rdev->pfp_fw, fw_name, rdev->dev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
  	if (err)
  		goto out;
  	if (rdev->pfp_fw->size != pfp_req_size) {
  		printk(KERN_ERR
  		       "r600_cp: Bogus length %zu in firmware \"%s\"
  ",
  		       rdev->pfp_fw->size, fw_name);
  		err = -EINVAL;
  		goto out;
  	}
  
  	snprintf(fw_name, sizeof(fw_name), "radeon/%s_me.bin", chip_name);
0a1689339   Jerome Glisse   drm/radeon: use r...
2451
  	err = request_firmware(&rdev->me_fw, fw_name, rdev->dev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2452
2453
2454
2455
2456
2457
2458
2459
2460
  	if (err)
  		goto out;
  	if (rdev->me_fw->size != me_req_size) {
  		printk(KERN_ERR
  		       "r600_cp: Bogus length %zu in firmware \"%s\"
  ",
  		       rdev->me_fw->size, fw_name);
  		err = -EINVAL;
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2461
2462
  
  	snprintf(fw_name, sizeof(fw_name), "radeon/%s_rlc.bin", rlc_chip_name);
0a1689339   Jerome Glisse   drm/radeon: use r...
2463
  	err = request_firmware(&rdev->rlc_fw, fw_name, rdev->dev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2464
2465
2466
2467
2468
2469
2470
2471
2472
  	if (err)
  		goto out;
  	if (rdev->rlc_fw->size != rlc_req_size) {
  		printk(KERN_ERR
  		       "r600_rlc: Bogus length %zu in firmware \"%s\"
  ",
  		       rdev->rlc_fw->size, fw_name);
  		err = -EINVAL;
  	}
dc50ba7f9   Alex Deucher   drm/radeon/kms: a...
2473
  	if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_HEMLOCK)) {
66229b200   Alex Deucher   drm/radeon/kms: a...
2474
  		snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", smc_chip_name);
0a1689339   Jerome Glisse   drm/radeon: use r...
2475
  		err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
8a53fa23f   Alex Deucher   drm/radeon: make ...
2476
2477
2478
2479
2480
2481
2482
  		if (err) {
  			printk(KERN_ERR
  			       "smc: error loading firmware \"%s\"
  ",
  			       fw_name);
  			release_firmware(rdev->smc_fw);
  			rdev->smc_fw = NULL;
d83671126   Alex Deucher   drm/radeon: make ...
2483
  			err = 0;
8a53fa23f   Alex Deucher   drm/radeon: make ...
2484
  		} else if (rdev->smc_fw->size != smc_req_size) {
66229b200   Alex Deucher   drm/radeon/kms: a...
2485
2486
2487
2488
2489
2490
2491
  			printk(KERN_ERR
  			       "smc: Bogus length %zu in firmware \"%s\"
  ",
  			       rdev->smc_fw->size, fw_name);
  			err = -EINVAL;
  		}
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2492
  out:
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
  	if (err) {
  		if (err != -EINVAL)
  			printk(KERN_ERR
  			       "r600_cp: Failed to load firmware \"%s\"
  ",
  			       fw_name);
  		release_firmware(rdev->pfp_fw);
  		rdev->pfp_fw = NULL;
  		release_firmware(rdev->me_fw);
  		rdev->me_fw = NULL;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2503
2504
  		release_firmware(rdev->rlc_fw);
  		rdev->rlc_fw = NULL;
66229b200   Alex Deucher   drm/radeon/kms: a...
2505
2506
  		release_firmware(rdev->smc_fw);
  		rdev->smc_fw = NULL;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2507
2508
2509
  	}
  	return err;
  }
ea31bf697   Alex Deucher   drm/radeon: remov...
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
  u32 r600_gfx_get_rptr(struct radeon_device *rdev,
  		      struct radeon_ring *ring)
  {
  	u32 rptr;
  
  	if (rdev->wb.enabled)
  		rptr = rdev->wb.wb[ring->rptr_offs/4];
  	else
  		rptr = RREG32(R600_CP_RB_RPTR);
  
  	return rptr;
  }
  
  u32 r600_gfx_get_wptr(struct radeon_device *rdev,
  		      struct radeon_ring *ring)
  {
  	u32 wptr;
  
  	wptr = RREG32(R600_CP_RB_WPTR);
  
  	return wptr;
  }
  
  void r600_gfx_set_wptr(struct radeon_device *rdev,
  		       struct radeon_ring *ring)
  {
  	WREG32(R600_CP_RB_WPTR, ring->wptr);
  	(void)RREG32(R600_CP_RB_WPTR);
  }
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2539
2540
2541
2542
2543
2544
2545
2546
2547
  static int r600_cp_load_microcode(struct radeon_device *rdev)
  {
  	const __be32 *fw_data;
  	int i;
  
  	if (!rdev->me_fw || !rdev->pfp_fw)
  		return -EINVAL;
  
  	r600_cp_stop(rdev);
4eace7fdf   Cédric Cano   drm/radeon/kms: 6...
2548
2549
2550
2551
2552
  	WREG32(CP_RB_CNTL,
  #ifdef __BIG_ENDIAN
  	       BUF_SWAP_32BIT |
  #endif
  	       RB_NO_UPDATE | RB_BLKSZ(15) | RB_BUFSZ(3));
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
  
  	/* Reset cp */
  	WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
  	RREG32(GRBM_SOFT_RESET);
  	mdelay(15);
  	WREG32(GRBM_SOFT_RESET, 0);
  
  	WREG32(CP_ME_RAM_WADDR, 0);
  
  	fw_data = (const __be32 *)rdev->me_fw->data;
  	WREG32(CP_ME_RAM_WADDR, 0);
138e4e16f   Alex Deucher   drm/radeon/kms: m...
2564
  	for (i = 0; i < R600_PM4_UCODE_SIZE * 3; i++)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2565
2566
2567
2568
2569
  		WREG32(CP_ME_RAM_DATA,
  		       be32_to_cpup(fw_data++));
  
  	fw_data = (const __be32 *)rdev->pfp_fw->data;
  	WREG32(CP_PFP_UCODE_ADDR, 0);
138e4e16f   Alex Deucher   drm/radeon/kms: m...
2570
  	for (i = 0; i < R600_PFP_UCODE_SIZE; i++)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
  		WREG32(CP_PFP_UCODE_DATA,
  		       be32_to_cpup(fw_data++));
  
  	WREG32(CP_PFP_UCODE_ADDR, 0);
  	WREG32(CP_ME_RAM_WADDR, 0);
  	WREG32(CP_ME_RAM_RADDR, 0);
  	return 0;
  }
  
  int r600_cp_start(struct radeon_device *rdev)
  {
e32eb50db   Christian König   drm/radeon: renam...
2582
  	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2583
2584
  	int r;
  	uint32_t cp_me;
e32eb50db   Christian König   drm/radeon: renam...
2585
  	r = radeon_ring_lock(rdev, ring, 7);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2586
2587
2588
2589
2590
  	if (r) {
  		DRM_ERROR("radeon: cp failed to lock ring (%d).
  ", r);
  		return r;
  	}
e32eb50db   Christian König   drm/radeon: renam...
2591
2592
  	radeon_ring_write(ring, PACKET3(PACKET3_ME_INITIALIZE, 5));
  	radeon_ring_write(ring, 0x1);
7e7b41d2f   Alex Deucher   drm/radeon/kms/ev...
2593
  	if (rdev->family >= CHIP_RV770) {
e32eb50db   Christian König   drm/radeon: renam...
2594
2595
  		radeon_ring_write(ring, 0x0);
  		radeon_ring_write(ring, rdev->config.rv770.max_hw_contexts - 1);
fe251e2ff   Alex Deucher   drm/radeon/kms/ev...
2596
  	} else {
e32eb50db   Christian König   drm/radeon: renam...
2597
2598
  		radeon_ring_write(ring, 0x3);
  		radeon_ring_write(ring, rdev->config.r600.max_hw_contexts - 1);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2599
  	}
e32eb50db   Christian König   drm/radeon: renam...
2600
2601
2602
  	radeon_ring_write(ring, PACKET3_ME_INITIALIZE_DEVICE_ID(1));
  	radeon_ring_write(ring, 0);
  	radeon_ring_write(ring, 0);
1538a9e0e   Michel Dänzer   drm/radeon: Only ...
2603
  	radeon_ring_unlock_commit(rdev, ring, false);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2604
2605
2606
2607
2608
2609
2610
2611
  
  	cp_me = 0xff;
  	WREG32(R_0086D8_CP_ME_CNTL, cp_me);
  	return 0;
  }
  
  int r600_cp_resume(struct radeon_device *rdev)
  {
e32eb50db   Christian König   drm/radeon: renam...
2612
  	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
  	u32 tmp;
  	u32 rb_bufsz;
  	int r;
  
  	/* Reset cp */
  	WREG32(GRBM_SOFT_RESET, SOFT_RESET_CP);
  	RREG32(GRBM_SOFT_RESET);
  	mdelay(15);
  	WREG32(GRBM_SOFT_RESET, 0);
  
  	/* Set ring buffer size */
b72a8925f   Daniel Vetter   drm/radeon: s/drm...
2624
2625
  	rb_bufsz = order_base_2(ring->ring_size / 8);
  	tmp = (order_base_2(RADEON_GPU_PAGE_SIZE/8) << 8) | rb_bufsz;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2626
  #ifdef __BIG_ENDIAN
d6f28938d   Alex Deucher   drm/radeon/kms: D...
2627
  	tmp |= BUF_SWAP_32BIT;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2628
  #endif
d6f28938d   Alex Deucher   drm/radeon/kms: D...
2629
  	WREG32(CP_RB_CNTL, tmp);
15d3332f3   Christian König   drm/radeon/kms: a...
2630
  	WREG32(CP_SEM_WAIT_TIMER, 0x0);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2631
2632
2633
2634
2635
  
  	/* Set the write pointer delay */
  	WREG32(CP_RB_WPTR_DELAY, 0);
  
  	/* Initialize the ring buffer's read and write pointers */
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2636
2637
  	WREG32(CP_RB_CNTL, tmp | RB_RPTR_WR_ENA);
  	WREG32(CP_RB_RPTR_WR, 0);
e32eb50db   Christian König   drm/radeon: renam...
2638
2639
  	ring->wptr = 0;
  	WREG32(CP_RB_WPTR, ring->wptr);
724c80e1d   Alex Deucher   drm/radeon/kms: e...
2640
2641
  
  	/* set the wb address whether it's enabled or not */
4eace7fdf   Cédric Cano   drm/radeon/kms: 6...
2642
  	WREG32(CP_RB_RPTR_ADDR,
4eace7fdf   Cédric Cano   drm/radeon/kms: 6...
2643
  	       ((rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFFFFFFFC));
724c80e1d   Alex Deucher   drm/radeon/kms: e...
2644
2645
2646
2647
2648
2649
2650
2651
2652
  	WREG32(CP_RB_RPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + RADEON_WB_CP_RPTR_OFFSET) & 0xFF);
  	WREG32(SCRATCH_ADDR, ((rdev->wb.gpu_addr + RADEON_WB_SCRATCH_OFFSET) >> 8) & 0xFFFFFFFF);
  
  	if (rdev->wb.enabled)
  		WREG32(SCRATCH_UMSK, 0xff);
  	else {
  		tmp |= RB_NO_UPDATE;
  		WREG32(SCRATCH_UMSK, 0);
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2653
2654
  	mdelay(1);
  	WREG32(CP_RB_CNTL, tmp);
e32eb50db   Christian König   drm/radeon: renam...
2655
  	WREG32(CP_RB_BASE, ring->gpu_addr >> 8);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2656
  	WREG32(CP_DEBUG, (1 << 27) | (1 << 28));
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2657
  	r600_cp_start(rdev);
e32eb50db   Christian König   drm/radeon: renam...
2658
  	ring->ready = true;
f712812e1   Alex Deucher   drm/radeon/kms: m...
2659
  	r = radeon_ring_test(rdev, RADEON_RING_TYPE_GFX_INDEX, ring);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2660
  	if (r) {
e32eb50db   Christian König   drm/radeon: renam...
2661
  		ring->ready = false;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2662
2663
  		return r;
  	}
b9ace36f1   Alex Deucher   drm/radeon: skip ...
2664

50efa51af   Alex Deucher   drm/radeon: clean...
2665
  	if (rdev->asic->copy.copy_ring_index == RADEON_RING_TYPE_GFX_INDEX)
b9ace36f1   Alex Deucher   drm/radeon: skip ...
2666
  		radeon_ttm_set_active_vram_size(rdev, rdev->mc.real_vram_size);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2667
2668
  	return 0;
  }
e32eb50db   Christian König   drm/radeon: renam...
2669
  void r600_ring_init(struct radeon_device *rdev, struct radeon_ring *ring, unsigned ring_size)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2670
2671
  {
  	u32 rb_bufsz;
45df68035   Christian König   drm/radeon: recor...
2672
  	int r;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2673
2674
  
  	/* Align ring size */
b72a8925f   Daniel Vetter   drm/radeon: s/drm...
2675
  	rb_bufsz = order_base_2(ring_size / 8);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2676
  	ring_size = (1 << (rb_bufsz + 1)) * 4;
e32eb50db   Christian König   drm/radeon: renam...
2677
2678
  	ring->ring_size = ring_size;
  	ring->align_mask = 16 - 1;
45df68035   Christian König   drm/radeon: recor...
2679

89d35807f   Alex Deucher   drm/radeon: updat...
2680
2681
2682
2683
2684
2685
2686
  	if (radeon_ring_supports_scratch_reg(rdev, ring)) {
  		r = radeon_scratch_get(rdev, &ring->rptr_save_reg);
  		if (r) {
  			DRM_ERROR("failed to get scratch reg for rptr save (%d).
  ", r);
  			ring->rptr_save_reg = 0;
  		}
45df68035   Christian König   drm/radeon: recor...
2687
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2688
  }
655efd3dc   Jerome Glisse   drm/radeon/kms: d...
2689
2690
  void r600_cp_fini(struct radeon_device *rdev)
  {
45df68035   Christian König   drm/radeon: recor...
2691
  	struct radeon_ring *ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
655efd3dc   Jerome Glisse   drm/radeon/kms: d...
2692
  	r600_cp_stop(rdev);
45df68035   Christian König   drm/radeon: recor...
2693
2694
  	radeon_ring_fini(rdev, ring);
  	radeon_scratch_free(rdev, ring->rptr_save_reg);
655efd3dc   Jerome Glisse   drm/radeon/kms: d...
2695
  }
4d75658bf   Alex Deucher   drm/radeon/kms: A...
2696
  /*
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2697
2698
2699
2700
2701
2702
2703
   * GPU scratch registers helpers function.
   */
  void r600_scratch_init(struct radeon_device *rdev)
  {
  	int i;
  
  	rdev->scratch.num_reg = 7;
724c80e1d   Alex Deucher   drm/radeon/kms: e...
2704
  	rdev->scratch.reg_base = SCRATCH_REG0;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2705
2706
  	for (i = 0; i < rdev->scratch.num_reg; i++) {
  		rdev->scratch.free[i] = true;
724c80e1d   Alex Deucher   drm/radeon/kms: e...
2707
  		rdev->scratch.reg[i] = rdev->scratch.reg_base + (i * 4);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2708
2709
  	}
  }
e32eb50db   Christian König   drm/radeon: renam...
2710
  int r600_ring_test(struct radeon_device *rdev, struct radeon_ring *ring)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2711
2712
2713
  {
  	uint32_t scratch;
  	uint32_t tmp = 0;
8b25ed348   Alex Deucher   drm/radeon: remov...
2714
  	unsigned i;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2715
2716
2717
2718
2719
2720
2721
2722
2723
  	int r;
  
  	r = radeon_scratch_get(rdev, &scratch);
  	if (r) {
  		DRM_ERROR("radeon: cp failed to get scratch reg (%d).
  ", r);
  		return r;
  	}
  	WREG32(scratch, 0xCAFEDEAD);
e32eb50db   Christian König   drm/radeon: renam...
2724
  	r = radeon_ring_lock(rdev, ring, 3);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2725
  	if (r) {
8b25ed348   Alex Deucher   drm/radeon: remov...
2726
2727
  		DRM_ERROR("radeon: cp failed to lock ring %d (%d).
  ", ring->idx, r);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2728
2729
2730
  		radeon_scratch_free(rdev, scratch);
  		return r;
  	}
e32eb50db   Christian König   drm/radeon: renam...
2731
2732
2733
  	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
  	radeon_ring_write(ring, ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
  	radeon_ring_write(ring, 0xDEADBEEF);
1538a9e0e   Michel Dänzer   drm/radeon: Only ...
2734
  	radeon_ring_unlock_commit(rdev, ring, false);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2735
2736
2737
2738
2739
2740
2741
  	for (i = 0; i < rdev->usec_timeout; i++) {
  		tmp = RREG32(scratch);
  		if (tmp == 0xDEADBEEF)
  			break;
  		DRM_UDELAY(1);
  	}
  	if (i < rdev->usec_timeout) {
8b25ed348   Alex Deucher   drm/radeon: remov...
2742
2743
  		DRM_INFO("ring test on %d succeeded in %d usecs
  ", ring->idx, i);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2744
  	} else {
bf8527995   Christian König   drm/radeon: make ...
2745
2746
  		DRM_ERROR("radeon: ring %d test failed (scratch(0x%04X)=0x%08X)
  ",
8b25ed348   Alex Deucher   drm/radeon: remov...
2747
  			  ring->idx, scratch, tmp);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2748
2749
2750
2751
2752
  		r = -EINVAL;
  	}
  	radeon_scratch_free(rdev, scratch);
  	return r;
  }
4d75658bf   Alex Deucher   drm/radeon/kms: A...
2753
2754
2755
  /*
   * CP fences/semaphores
   */
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2756
2757
2758
  void r600_fence_ring_emit(struct radeon_device *rdev,
  			  struct radeon_fence *fence)
  {
e32eb50db   Christian König   drm/radeon: renam...
2759
  	struct radeon_ring *ring = &rdev->ring[fence->ring];
d45b964a2   Alex Deucher   drm/radeon: set t...
2760
2761
2762
2763
2764
  	u32 cp_coher_cntl = PACKET3_TC_ACTION_ENA | PACKET3_VC_ACTION_ENA |
  		PACKET3_SH_ACTION_ENA;
  
  	if (rdev->family >= CHIP_RV770)
  		cp_coher_cntl |= PACKET3_FULL_CACHE_ENA;
7b1f2485d   Christian König   drm/radeon: make ...
2765

d0f8a854c   Alex Deucher   drm/radeon/kms/r6...
2766
  	if (rdev->wb.use_event) {
30eb77f4e   Jerome Glisse   drm/radeon: preco...
2767
  		u64 addr = rdev->fence_drv[fence->ring].gpu_addr;
77b1bad42   Jerome Glisse   drm/radeon: flush...
2768
  		/* flush read cache over gart */
e32eb50db   Christian König   drm/radeon: renam...
2769
  		radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
d45b964a2   Alex Deucher   drm/radeon: set t...
2770
  		radeon_ring_write(ring, cp_coher_cntl);
e32eb50db   Christian König   drm/radeon: renam...
2771
2772
2773
  		radeon_ring_write(ring, 0xFFFFFFFF);
  		radeon_ring_write(ring, 0);
  		radeon_ring_write(ring, 10); /* poll interval */
d0f8a854c   Alex Deucher   drm/radeon/kms/r6...
2774
  		/* EVENT_WRITE_EOP - flush caches, send int */
e32eb50db   Christian König   drm/radeon: renam...
2775
2776
  		radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE_EOP, 4));
  		radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT_TS) | EVENT_INDEX(5));
5e167cdbf   Christian König   drm/radeon: use l...
2777
  		radeon_ring_write(ring, lower_32_bits(addr));
e32eb50db   Christian König   drm/radeon: renam...
2778
2779
2780
  		radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | DATA_SEL(1) | INT_SEL(2));
  		radeon_ring_write(ring, fence->seq);
  		radeon_ring_write(ring, 0);
d0f8a854c   Alex Deucher   drm/radeon/kms/r6...
2781
  	} else {
77b1bad42   Jerome Glisse   drm/radeon: flush...
2782
  		/* flush read cache over gart */
e32eb50db   Christian König   drm/radeon: renam...
2783
  		radeon_ring_write(ring, PACKET3(PACKET3_SURFACE_SYNC, 3));
d45b964a2   Alex Deucher   drm/radeon: set t...
2784
  		radeon_ring_write(ring, cp_coher_cntl);
e32eb50db   Christian König   drm/radeon: renam...
2785
2786
2787
2788
2789
  		radeon_ring_write(ring, 0xFFFFFFFF);
  		radeon_ring_write(ring, 0);
  		radeon_ring_write(ring, 10); /* poll interval */
  		radeon_ring_write(ring, PACKET3(PACKET3_EVENT_WRITE, 0));
  		radeon_ring_write(ring, EVENT_TYPE(CACHE_FLUSH_AND_INV_EVENT) | EVENT_INDEX(0));
d0f8a854c   Alex Deucher   drm/radeon/kms/r6...
2790
  		/* wait for 3D idle clean */
e32eb50db   Christian König   drm/radeon: renam...
2791
2792
2793
  		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
  		radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
  		radeon_ring_write(ring, WAIT_3D_IDLE_bit | WAIT_3D_IDLECLEAN_bit);
d0f8a854c   Alex Deucher   drm/radeon/kms/r6...
2794
  		/* Emit fence sequence & fire IRQ */
e32eb50db   Christian König   drm/radeon: renam...
2795
2796
2797
  		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
  		radeon_ring_write(ring, ((rdev->fence_drv[fence->ring].scratch_reg - PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
  		radeon_ring_write(ring, fence->seq);
d0f8a854c   Alex Deucher   drm/radeon/kms/r6...
2798
  		/* CP_INTERRUPT packet 3 no longer exists, use packet 0 */
e32eb50db   Christian König   drm/radeon: renam...
2799
2800
  		radeon_ring_write(ring, PACKET0(CP_INT_STATUS, 0));
  		radeon_ring_write(ring, RB_INT_STAT);
d0f8a854c   Alex Deucher   drm/radeon/kms/r6...
2801
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2802
  }
86302eead   Christian König   drm/radeon: Sync ...
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
  /**
   * r600_semaphore_ring_emit - emit a semaphore on the CP ring
   *
   * @rdev: radeon_device pointer
   * @ring: radeon ring buffer object
   * @semaphore: radeon semaphore object
   * @emit_wait: Is this a sempahore wait?
   *
   * Emits a semaphore signal/wait packet to the CP ring and prevents the PFP
   * from running ahead of semaphore waits.
   */
1654b817d   Christian König   drm/radeon: allow...
2814
  bool r600_semaphore_ring_emit(struct radeon_device *rdev,
e32eb50db   Christian König   drm/radeon: renam...
2815
  			      struct radeon_ring *ring,
15d3332f3   Christian König   drm/radeon/kms: a...
2816
  			      struct radeon_semaphore *semaphore,
7b1f2485d   Christian König   drm/radeon: make ...
2817
  			      bool emit_wait)
15d3332f3   Christian König   drm/radeon/kms: a...
2818
2819
2820
  {
  	uint64_t addr = semaphore->gpu_addr;
  	unsigned sel = emit_wait ? PACKET3_SEM_SEL_WAIT : PACKET3_SEM_SEL_SIGNAL;
0be70439f   Christian König   drm/radeon: fix a...
2821
2822
  	if (rdev->family < CHIP_CAYMAN)
  		sel |= PACKET3_SEM_WAIT_ON_SIGNAL;
e32eb50db   Christian König   drm/radeon: renam...
2823
  	radeon_ring_write(ring, PACKET3(PACKET3_MEM_SEMAPHORE, 1));
5e167cdbf   Christian König   drm/radeon: use l...
2824
  	radeon_ring_write(ring, lower_32_bits(addr));
e32eb50db   Christian König   drm/radeon: renam...
2825
  	radeon_ring_write(ring, (upper_32_bits(addr) & 0xff) | sel);
1654b817d   Christian König   drm/radeon: allow...
2826

b6c2b4faf   Alex Deucher   drm/radeon: only ...
2827
2828
  	/* PFP_SYNC_ME packet only exists on 7xx+, only enable it on eg+ */
  	if (emit_wait && (rdev->family >= CHIP_CEDAR)) {
86302eead   Christian König   drm/radeon: Sync ...
2829
2830
2831
2832
  		/* Prevent the PFP from running ahead of the semaphore wait */
  		radeon_ring_write(ring, PACKET3(PACKET3_PFP_SYNC_ME, 0));
  		radeon_ring_write(ring, 0x0);
  	}
1654b817d   Christian König   drm/radeon: allow...
2833
  	return true;
15d3332f3   Christian König   drm/radeon/kms: a...
2834
  }
4d75658bf   Alex Deucher   drm/radeon/kms: A...
2835
  /**
072b5acc7   Alex Deucher   drm/radeon: imple...
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
   * r600_copy_cpdma - copy pages using the CP DMA engine
   *
   * @rdev: radeon_device pointer
   * @src_offset: src GPU address
   * @dst_offset: dst GPU address
   * @num_gpu_pages: number of GPU pages to xfer
   * @fence: radeon fence object
   *
   * Copy GPU paging using the CP DMA engine (r6xx+).
   * Used by the radeon ttm implementation to move pages if
   * registered as the asic copy callback.
   */
57d20a43c   Christian König   drm/radeon: add t...
2848
2849
2850
2851
  struct radeon_fence *r600_copy_cpdma(struct radeon_device *rdev,
  				     uint64_t src_offset, uint64_t dst_offset,
  				     unsigned num_gpu_pages,
  				     struct reservation_object *resv)
072b5acc7   Alex Deucher   drm/radeon: imple...
2852
  {
57d20a43c   Christian König   drm/radeon: add t...
2853
  	struct radeon_fence *fence;
975700d2c   Christian König   drm/radeon: split...
2854
  	struct radeon_sync sync;
072b5acc7   Alex Deucher   drm/radeon: imple...
2855
2856
2857
2858
2859
  	int ring_index = rdev->asic->copy.blit_ring_index;
  	struct radeon_ring *ring = &rdev->ring[ring_index];
  	u32 size_in_bytes, cur_size_in_bytes, tmp;
  	int i, num_loops;
  	int r = 0;
975700d2c   Christian König   drm/radeon: split...
2860
  	radeon_sync_create(&sync);
072b5acc7   Alex Deucher   drm/radeon: imple...
2861
2862
2863
  
  	size_in_bytes = (num_gpu_pages << RADEON_GPU_PAGE_SHIFT);
  	num_loops = DIV_ROUND_UP(size_in_bytes, 0x1fffff);
745a39a9e   Alex Deucher   drm/radeon: wait ...
2864
  	r = radeon_ring_lock(rdev, ring, num_loops * 6 + 24);
072b5acc7   Alex Deucher   drm/radeon: imple...
2865
2866
2867
  	if (r) {
  		DRM_ERROR("radeon: moving bo (%d).
  ", r);
975700d2c   Christian König   drm/radeon: split...
2868
  		radeon_sync_free(rdev, &sync, NULL);
57d20a43c   Christian König   drm/radeon: add t...
2869
  		return ERR_PTR(r);
072b5acc7   Alex Deucher   drm/radeon: imple...
2870
  	}
975700d2c   Christian König   drm/radeon: split...
2871
2872
  	radeon_sync_resv(rdev, &sync, resv, false);
  	radeon_sync_rings(rdev, &sync, ring->idx);
072b5acc7   Alex Deucher   drm/radeon: imple...
2873

745a39a9e   Alex Deucher   drm/radeon: wait ...
2874
2875
2876
  	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
  	radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
  	radeon_ring_write(ring, WAIT_3D_IDLE_bit);
072b5acc7   Alex Deucher   drm/radeon: imple...
2877
2878
2879
2880
2881
2882
2883
2884
2885
  	for (i = 0; i < num_loops; i++) {
  		cur_size_in_bytes = size_in_bytes;
  		if (cur_size_in_bytes > 0x1fffff)
  			cur_size_in_bytes = 0x1fffff;
  		size_in_bytes -= cur_size_in_bytes;
  		tmp = upper_32_bits(src_offset) & 0xff;
  		if (size_in_bytes == 0)
  			tmp |= PACKET3_CP_DMA_CP_SYNC;
  		radeon_ring_write(ring, PACKET3(PACKET3_CP_DMA, 4));
5e167cdbf   Christian König   drm/radeon: use l...
2886
  		radeon_ring_write(ring, lower_32_bits(src_offset));
072b5acc7   Alex Deucher   drm/radeon: imple...
2887
  		radeon_ring_write(ring, tmp);
5e167cdbf   Christian König   drm/radeon: use l...
2888
  		radeon_ring_write(ring, lower_32_bits(dst_offset));
072b5acc7   Alex Deucher   drm/radeon: imple...
2889
2890
2891
2892
2893
2894
2895
2896
  		radeon_ring_write(ring, upper_32_bits(dst_offset) & 0xff);
  		radeon_ring_write(ring, cur_size_in_bytes);
  		src_offset += cur_size_in_bytes;
  		dst_offset += cur_size_in_bytes;
  	}
  	radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
  	radeon_ring_write(ring, (WAIT_UNTIL - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
  	radeon_ring_write(ring, WAIT_CP_DMA_IDLE_bit);
57d20a43c   Christian König   drm/radeon: add t...
2897
  	r = radeon_fence_emit(rdev, &fence, ring->idx);
072b5acc7   Alex Deucher   drm/radeon: imple...
2898
2899
  	if (r) {
  		radeon_ring_unlock_undo(rdev, ring);
975700d2c   Christian König   drm/radeon: split...
2900
  		radeon_sync_free(rdev, &sync, NULL);
57d20a43c   Christian König   drm/radeon: add t...
2901
  		return ERR_PTR(r);
072b5acc7   Alex Deucher   drm/radeon: imple...
2902
  	}
1538a9e0e   Michel Dänzer   drm/radeon: Only ...
2903
  	radeon_ring_unlock_commit(rdev, ring, false);
975700d2c   Christian König   drm/radeon: split...
2904
  	radeon_sync_free(rdev, &sync, fence);
072b5acc7   Alex Deucher   drm/radeon: imple...
2905

57d20a43c   Christian König   drm/radeon: add t...
2906
  	return fence;
072b5acc7   Alex Deucher   drm/radeon: imple...
2907
  }
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
  int r600_set_surface_reg(struct radeon_device *rdev, int reg,
  			 uint32_t tiling_flags, uint32_t pitch,
  			 uint32_t offset, uint32_t obj_size)
  {
  	/* FIXME: implement */
  	return 0;
  }
  
  void r600_clear_surface_reg(struct radeon_device *rdev, int reg)
  {
  	/* FIXME: implement */
  }
1109ca09b   Lauri Kasanen   drm/radeon: Mark ...
2920
  static int r600_startup(struct radeon_device *rdev)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2921
  {
4d75658bf   Alex Deucher   drm/radeon/kms: A...
2922
  	struct radeon_ring *ring;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2923
  	int r;
9e46a48df   Alex Deucher   drm/radeon/kms: a...
2924
2925
  	/* enable pcie gen2 link */
  	r600_pcie_gen2_enable(rdev);
e5903d399   Alex Deucher   drm/radeon: fix i...
2926
2927
2928
2929
  	/* scratch needs to be initialized before MC */
  	r = r600_vram_scratch_init(rdev);
  	if (r)
  		return r;
6fab3febf   Alex Deucher   drm/radeon: alway...
2930
  	r600_mc_program(rdev);
1a029b768   Jerome Glisse   drm/radeon/kms: F...
2931
2932
2933
2934
2935
2936
2937
  	if (rdev->flags & RADEON_IS_AGP) {
  		r600_agp_enable(rdev);
  	} else {
  		r = r600_pcie_gart_enable(rdev);
  		if (r)
  			return r;
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2938
  	r600_gpu_init(rdev);
b70d6bb3f   Alex Deucher   drm/radeon/kms: c...
2939

724c80e1d   Alex Deucher   drm/radeon/kms: e...
2940
2941
2942
2943
  	/* allocate wb buffer */
  	r = radeon_wb_init(rdev);
  	if (r)
  		return r;
30eb77f4e   Jerome Glisse   drm/radeon: preco...
2944
2945
2946
2947
2948
2949
  	r = radeon_fence_driver_start_ring(rdev, RADEON_RING_TYPE_GFX_INDEX);
  	if (r) {
  		dev_err(rdev->dev, "failed initializing CP fences (%d).
  ", r);
  		return r;
  	}
bdc99722d   Alex Deucher   drm/radeon: 760G/...
2950
2951
2952
2953
2954
2955
2956
2957
  	if (rdev->has_uvd) {
  		r = uvd_v1_0_resume(rdev);
  		if (!r) {
  			r = radeon_fence_driver_start_ring(rdev, R600_RING_TYPE_UVD_INDEX);
  			if (r) {
  				dev_err(rdev->dev, "failed initializing UVD fences (%d).
  ", r);
  			}
856754c3a   Christian König   drm/radeon: add U...
2958
  		}
bdc99722d   Alex Deucher   drm/radeon: 760G/...
2959
2960
  		if (r)
  			rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0;
856754c3a   Christian König   drm/radeon: add U...
2961
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2962
  	/* Enable IRQ */
e49f3959a   Adis Hamzić   radeon: Fix syste...
2963
2964
2965
2966
2967
  	if (!rdev->irq.installed) {
  		r = radeon_irq_kms_init(rdev);
  		if (r)
  			return r;
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
2968
2969
2970
2971
2972
2973
2974
2975
  	r = r600_irq_init(rdev);
  	if (r) {
  		DRM_ERROR("radeon: IH init failed (%d).
  ", r);
  		radeon_irq_kms_fini(rdev);
  		return r;
  	}
  	r600_irq_set(rdev);
4d75658bf   Alex Deucher   drm/radeon/kms: A...
2976
  	ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX];
e32eb50db   Christian König   drm/radeon: renam...
2977
  	r = radeon_ring_init(rdev, ring, ring->ring_size, RADEON_WB_CP_RPTR_OFFSET,
2e1e6dad6   Christian König   drm/radeon: remov...
2978
  			     RADEON_CP_PACKET2);
4d75658bf   Alex Deucher   drm/radeon/kms: A...
2979
2980
  	if (r)
  		return r;
5596a9db1   Christian König   drm/radeon: make ...
2981

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
2982
2983
2984
2985
2986
2987
  	r = r600_cp_load_microcode(rdev);
  	if (r)
  		return r;
  	r = r600_cp_resume(rdev);
  	if (r)
  		return r;
724c80e1d   Alex Deucher   drm/radeon/kms: e...
2988

bdc99722d   Alex Deucher   drm/radeon: 760G/...
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
  	if (rdev->has_uvd) {
  		ring = &rdev->ring[R600_RING_TYPE_UVD_INDEX];
  		if (ring->ring_size) {
  			r = radeon_ring_init(rdev, ring, ring->ring_size, 0,
  					     RADEON_CP_PACKET2);
  			if (!r)
  				r = uvd_v1_0_init(rdev);
  			if (r)
  				DRM_ERROR("radeon: failed initializing UVD (%d).
  ", r);
  		}
856754c3a   Christian König   drm/radeon: add U...
3000
  	}
2898c348e   Christian König   drm/radeon: remov...
3001
3002
3003
3004
  	r = radeon_ib_pool_init(rdev);
  	if (r) {
  		dev_err(rdev->dev, "IB initialization failed (%d).
  ", r);
b15ba5120   Jerome Glisse   drm/radeon: intro...
3005
  		return r;
2898c348e   Christian König   drm/radeon: remov...
3006
  	}
b15ba5120   Jerome Glisse   drm/radeon: intro...
3007

bfc1f97d8   Slava Grigorev   radeon/audio: con...
3008
  	r = radeon_audio_init(rdev);
d4e30ef05   Alex Deucher   drm/radeon: make ...
3009
3010
3011
3012
3013
  	if (r) {
  		DRM_ERROR("radeon: audio init failed
  ");
  		return r;
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3014
3015
  	return 0;
  }
28d520433   Dave Airlie   drm/vgaarb: add V...
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
  void r600_vga_set_state(struct radeon_device *rdev, bool state)
  {
  	uint32_t temp;
  
  	temp = RREG32(CONFIG_CNTL);
  	if (state == false) {
  		temp &= ~(1<<0);
  		temp |= (1<<1);
  	} else {
  		temp &= ~(1<<1);
  	}
  	WREG32(CONFIG_CNTL, temp);
  }
fc30b8efb   Dave Airlie   drm/radeon/kms: m...
3029
3030
3031
  int r600_resume(struct radeon_device *rdev)
  {
  	int r;
1a029b768   Jerome Glisse   drm/radeon/kms: F...
3032
3033
3034
3035
  	/* Do not reset GPU before posting, on r600 hw unlike on r500 hw,
  	 * posting will perform necessary task to bring back GPU into good
  	 * shape.
  	 */
fc30b8efb   Dave Airlie   drm/radeon/kms: m...
3036
  	/* post card */
e7d40b9a0   Jerome Glisse   drm/radeon/kms: R...
3037
  	atom_asic_init(rdev->mode_info.atom_context);
fc30b8efb   Dave Airlie   drm/radeon/kms: m...
3038

bc6a62955   Alex Deucher   drm/radeon: resum...
3039
3040
  	if (rdev->pm.pm_method == PM_METHOD_DPM)
  		radeon_pm_resume(rdev);
6c7bccea3   Alex Deucher   drm/radeon/pm: mo...
3041

b15ba5120   Jerome Glisse   drm/radeon: intro...
3042
  	rdev->accel_working = true;
fc30b8efb   Dave Airlie   drm/radeon/kms: m...
3043
3044
3045
3046
  	r = r600_startup(rdev);
  	if (r) {
  		DRM_ERROR("r600 startup failed on resume
  ");
6b7746e87   Jerome Glisse   drm/radeon/kms: p...
3047
  		rdev->accel_working = false;
fc30b8efb   Dave Airlie   drm/radeon/kms: m...
3048
3049
  		return r;
  	}
fc30b8efb   Dave Airlie   drm/radeon/kms: m...
3050
3051
  	return r;
  }
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3052
3053
  int r600_suspend(struct radeon_device *rdev)
  {
6c7bccea3   Alex Deucher   drm/radeon/pm: mo...
3054
  	radeon_pm_suspend(rdev);
7991d6650   Slava Grigorev   radeon/audio: con...
3055
  	radeon_audio_fini(rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3056
  	r600_cp_stop(rdev);
bdc99722d   Alex Deucher   drm/radeon: 760G/...
3057
3058
3059
3060
  	if (rdev->has_uvd) {
  		uvd_v1_0_fini(rdev);
  		radeon_uvd_suspend(rdev);
  	}
0c45249f4   Jerome Glisse   drm/radeon/kms: r...
3061
  	r600_irq_suspend(rdev);
724c80e1d   Alex Deucher   drm/radeon/kms: e...
3062
  	radeon_wb_disable(rdev);
4aac04732   Jerome Glisse   drm/radeon/kms: c...
3063
  	r600_pcie_gart_disable(rdev);
6ddddfe73   Alex Deucher   drm/radeon/kms: m...
3064

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
  	return 0;
  }
  
  /* Plan is to move initialization in that function and use
   * helper function so that radeon_device_init pretty much
   * do nothing more than calling asic specific function. This
   * should also allow to remove a bunch of callback function
   * like vram_info.
   */
  int r600_init(struct radeon_device *rdev)
771fe6b91   Jerome Glisse   drm/radeon: intro...
3075
  {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3076
  	int r;
771fe6b91   Jerome Glisse   drm/radeon: intro...
3077

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3078
3079
3080
3081
  	if (r600_debugfs_mc_info_init(rdev)) {
  		DRM_ERROR("Failed to register debugfs file for mc !
  ");
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3082
3083
3084
3085
3086
3087
  	/* Read BIOS */
  	if (!radeon_get_bios(rdev)) {
  		if (ASIC_IS_AVIVO(rdev))
  			return -EINVAL;
  	}
  	/* Must be an ATOMBIOS */
e7d40b9a0   Jerome Glisse   drm/radeon/kms: R...
3088
3089
3090
  	if (!rdev->is_atom_bios) {
  		dev_err(rdev->dev, "Expecting atombios for R600 GPU
  ");
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3091
  		return -EINVAL;
e7d40b9a0   Jerome Glisse   drm/radeon/kms: R...
3092
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3093
3094
3095
3096
  	r = radeon_atombios_init(rdev);
  	if (r)
  		return r;
  	/* Post card if necessary */
fd909c371   Alex Deucher   drm/radeon/kms: r...
3097
  	if (!radeon_card_posted(rdev)) {
72542d770   Dave Airlie   drm/radeon/kms: i...
3098
3099
3100
3101
3102
  		if (!rdev->bios) {
  			dev_err(rdev->dev, "Card not posted and no BIOS - ignoring
  ");
  			return -EINVAL;
  		}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3103
3104
3105
3106
3107
3108
3109
3110
  		DRM_INFO("GPU not posted. posting now...
  ");
  		atom_asic_init(rdev->mode_info.atom_context);
  	}
  	/* Initialize scratch registers */
  	r600_scratch_init(rdev);
  	/* Initialize surface registers */
  	radeon_surface_init(rdev);
7433874e3   Rafał Miłecki   drm/radeon/kms: a...
3111
  	/* Initialize clocks */
5e6dde7ec   Michel Dänzer   drm/radeon/kms: M...
3112
  	radeon_get_clock_info(rdev->ddev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3113
  	/* Fence driver */
30eb77f4e   Jerome Glisse   drm/radeon: preco...
3114
  	r = radeon_fence_driver_init(rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3115
3116
  	if (r)
  		return r;
700a0cc08   Jerome Glisse   drm/radeon/kms: U...
3117
3118
3119
3120
3121
  	if (rdev->flags & RADEON_IS_AGP) {
  		r = radeon_agp_init(rdev);
  		if (r)
  			radeon_agp_disable(rdev);
  	}
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3122
  	r = r600_mc_init(rdev);
b574f251f   Jerome Glisse   drm/radeon/kms: F...
3123
  	if (r)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3124
  		return r;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3125
  	/* Memory manager */
4c7886791   Jerome Glisse   drm/radeon/kms: R...
3126
  	r = radeon_bo_init(rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3127
3128
  	if (r)
  		return r;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3129

01ac8794a   Alex Deucher   drm/radeon: re-or...
3130
3131
3132
3133
3134
3135
3136
3137
  	if (!rdev->me_fw || !rdev->pfp_fw || !rdev->rlc_fw) {
  		r = r600_init_microcode(rdev);
  		if (r) {
  			DRM_ERROR("Failed to load firmware!
  ");
  			return r;
  		}
  	}
6c7bccea3   Alex Deucher   drm/radeon/pm: mo...
3138
3139
  	/* Initialize power management */
  	radeon_pm_init(rdev);
e32eb50db   Christian König   drm/radeon: renam...
3140
3141
  	rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL;
  	r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3142

bdc99722d   Alex Deucher   drm/radeon: 760G/...
3143
3144
3145
3146
3147
3148
  	if (rdev->has_uvd) {
  		r = radeon_uvd_init(rdev);
  		if (!r) {
  			rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_obj = NULL;
  			r600_ring_init(rdev, &rdev->ring[R600_RING_TYPE_UVD_INDEX], 4096);
  		}
856754c3a   Christian König   drm/radeon: add U...
3149
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3150
3151
  	rdev->ih.ring_obj = NULL;
  	r600_ih_ring_init(rdev, 64 * 1024);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3152

4aac04732   Jerome Glisse   drm/radeon/kms: c...
3153
3154
3155
  	r = r600_pcie_gart_init(rdev);
  	if (r)
  		return r;
779720a32   Alex Deucher   drm/radeon/kms/r6...
3156
  	rdev->accel_working = true;
fc30b8efb   Dave Airlie   drm/radeon/kms: m...
3157
  	r = r600_startup(rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3158
  	if (r) {
655efd3dc   Jerome Glisse   drm/radeon/kms: d...
3159
3160
3161
  		dev_err(rdev->dev, "disabling GPU acceleration
  ");
  		r600_cp_fini(rdev);
655efd3dc   Jerome Glisse   drm/radeon/kms: d...
3162
  		r600_irq_fini(rdev);
724c80e1d   Alex Deucher   drm/radeon/kms: e...
3163
  		radeon_wb_fini(rdev);
2898c348e   Christian König   drm/radeon: remov...
3164
  		radeon_ib_pool_fini(rdev);
655efd3dc   Jerome Glisse   drm/radeon/kms: d...
3165
  		radeon_irq_kms_fini(rdev);
75c812989   Jerome Glisse   drm/radeon/kms: F...
3166
  		r600_pcie_gart_fini(rdev);
733289c26   Jerome Glisse   drm/radeon/kms: d...
3167
  		rdev->accel_working = false;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3168
  	}
dafc3bd51   Christian Koenig   drm/radeon/kms: H...
3169

3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3170
3171
3172
3173
3174
  	return 0;
  }
  
  void r600_fini(struct radeon_device *rdev)
  {
6c7bccea3   Alex Deucher   drm/radeon/pm: mo...
3175
  	radeon_pm_fini(rdev);
7991d6650   Slava Grigorev   radeon/audio: con...
3176
  	radeon_audio_fini(rdev);
655efd3dc   Jerome Glisse   drm/radeon/kms: d...
3177
  	r600_cp_fini(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3178
  	r600_irq_fini(rdev);
bdc99722d   Alex Deucher   drm/radeon: 760G/...
3179
3180
3181
3182
  	if (rdev->has_uvd) {
  		uvd_v1_0_fini(rdev);
  		radeon_uvd_fini(rdev);
  	}
724c80e1d   Alex Deucher   drm/radeon/kms: e...
3183
  	radeon_wb_fini(rdev);
2898c348e   Christian König   drm/radeon: remov...
3184
  	radeon_ib_pool_fini(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3185
  	radeon_irq_kms_fini(rdev);
4aac04732   Jerome Glisse   drm/radeon/kms: c...
3186
  	r600_pcie_gart_fini(rdev);
16cdf04d3   Alex Deucher   drm/radeon/kms: a...
3187
  	r600_vram_scratch_fini(rdev);
655efd3dc   Jerome Glisse   drm/radeon/kms: d...
3188
  	radeon_agp_fini(rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3189
3190
  	radeon_gem_fini(rdev);
  	radeon_fence_driver_fini(rdev);
4c7886791   Jerome Glisse   drm/radeon/kms: R...
3191
  	radeon_bo_fini(rdev);
e7d40b9a0   Jerome Glisse   drm/radeon/kms: R...
3192
  	radeon_atombios_fini(rdev);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3193
3194
  	kfree(rdev->bios);
  	rdev->bios = NULL;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3195
3196
3197
3198
3199
3200
3201
3202
  }
  
  
  /*
   * CS stuff
   */
  void r600_ring_ib_execute(struct radeon_device *rdev, struct radeon_ib *ib)
  {
876dc9f32   Christian König   drm/radeon: remov...
3203
  	struct radeon_ring *ring = &rdev->ring[ib->ring];
89d35807f   Alex Deucher   drm/radeon: updat...
3204
  	u32 next_rptr;
7b1f2485d   Christian König   drm/radeon: make ...
3205

45df68035   Christian König   drm/radeon: recor...
3206
  	if (ring->rptr_save_reg) {
89d35807f   Alex Deucher   drm/radeon: updat...
3207
  		next_rptr = ring->wptr + 3 + 4;
45df68035   Christian König   drm/radeon: recor...
3208
3209
3210
3211
  		radeon_ring_write(ring, PACKET3(PACKET3_SET_CONFIG_REG, 1));
  		radeon_ring_write(ring, ((ring->rptr_save_reg -
  					 PACKET3_SET_CONFIG_REG_OFFSET) >> 2));
  		radeon_ring_write(ring, next_rptr);
89d35807f   Alex Deucher   drm/radeon: updat...
3212
3213
3214
3215
3216
3217
3218
  	} else if (rdev->wb.enabled) {
  		next_rptr = ring->wptr + 5 + 4;
  		radeon_ring_write(ring, PACKET3(PACKET3_MEM_WRITE, 3));
  		radeon_ring_write(ring, ring->next_rptr_gpu_addr & 0xfffffffc);
  		radeon_ring_write(ring, (upper_32_bits(ring->next_rptr_gpu_addr) & 0xff) | (1 << 18));
  		radeon_ring_write(ring, next_rptr);
  		radeon_ring_write(ring, 0);
45df68035   Christian König   drm/radeon: recor...
3219
  	}
e32eb50db   Christian König   drm/radeon: renam...
3220
3221
  	radeon_ring_write(ring, PACKET3(PACKET3_INDIRECT_BUFFER, 2));
  	radeon_ring_write(ring,
4eace7fdf   Cédric Cano   drm/radeon/kms: 6...
3222
3223
3224
3225
  #ifdef __BIG_ENDIAN
  			  (2 << 0) |
  #endif
  			  (ib->gpu_addr & 0xFFFFFFFC));
e32eb50db   Christian König   drm/radeon: renam...
3226
3227
  	radeon_ring_write(ring, upper_32_bits(ib->gpu_addr) & 0xFF);
  	radeon_ring_write(ring, ib->length_dw);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3228
  }
f712812e1   Alex Deucher   drm/radeon/kms: m...
3229
  int r600_ib_test(struct radeon_device *rdev, struct radeon_ring *ring)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3230
  {
f2e392210   Jerome Glisse   drm/radeon: make ...
3231
  	struct radeon_ib ib;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
  	uint32_t scratch;
  	uint32_t tmp = 0;
  	unsigned i;
  	int r;
  
  	r = radeon_scratch_get(rdev, &scratch);
  	if (r) {
  		DRM_ERROR("radeon: failed to get scratch reg (%d).
  ", r);
  		return r;
  	}
  	WREG32(scratch, 0xCAFEDEAD);
4bf3dd926   Christian König   drm/radeon: clean...
3244
  	r = radeon_ib_get(rdev, ring->idx, &ib, NULL, 256);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3245
3246
3247
  	if (r) {
  		DRM_ERROR("radeon: failed to get ib (%d).
  ", r);
af026c5bd   Michel Dänzer   drm/radeon: Fix s...
3248
  		goto free_scratch;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3249
  	}
f2e392210   Jerome Glisse   drm/radeon: make ...
3250
3251
3252
3253
  	ib.ptr[0] = PACKET3(PACKET3_SET_CONFIG_REG, 1);
  	ib.ptr[1] = ((scratch - PACKET3_SET_CONFIG_REG_OFFSET) >> 2);
  	ib.ptr[2] = 0xDEADBEEF;
  	ib.length_dw = 3;
1538a9e0e   Michel Dänzer   drm/radeon: Only ...
3254
  	r = radeon_ib_schedule(rdev, &ib, NULL, false);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3255
  	if (r) {
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3256
3257
  		DRM_ERROR("radeon: failed to schedule ib (%d).
  ", r);
af026c5bd   Michel Dänzer   drm/radeon: Fix s...
3258
  		goto free_ib;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3259
  	}
f2e392210   Jerome Glisse   drm/radeon: make ...
3260
  	r = radeon_fence_wait(ib.fence, false);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3261
3262
3263
  	if (r) {
  		DRM_ERROR("radeon: fence wait failed (%d).
  ", r);
af026c5bd   Michel Dänzer   drm/radeon: Fix s...
3264
  		goto free_ib;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3265
3266
3267
3268
3269
3270
3271
3272
  	}
  	for (i = 0; i < rdev->usec_timeout; i++) {
  		tmp = RREG32(scratch);
  		if (tmp == 0xDEADBEEF)
  			break;
  		DRM_UDELAY(1);
  	}
  	if (i < rdev->usec_timeout) {
f2e392210   Jerome Glisse   drm/radeon: make ...
3273
3274
  		DRM_INFO("ib test on ring %d succeeded in %u usecs
  ", ib.fence->ring, i);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3275
  	} else {
4417d7f60   Daniel J Blueman   drm: radeon clean...
3276
3277
  		DRM_ERROR("radeon: ib test failed (scratch(0x%04X)=0x%08X)
  ",
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3278
3279
3280
  			  scratch, tmp);
  		r = -EINVAL;
  	}
af026c5bd   Michel Dänzer   drm/radeon: Fix s...
3281
  free_ib:
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3282
  	radeon_ib_free(rdev, &ib);
af026c5bd   Michel Dänzer   drm/radeon: Fix s...
3283
3284
  free_scratch:
  	radeon_scratch_free(rdev, scratch);
771fe6b91   Jerome Glisse   drm/radeon: intro...
3285
3286
  	return r;
  }
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
  /*
   * Interrupts
   *
   * Interrupts use a ring buffer on r6xx/r7xx hardware.  It works pretty
   * the same as the CP ring buffer, but in reverse.  Rather than the CPU
   * writing to the ring and the GPU consuming, the GPU writes to the ring
   * and host consumes.  As the host irq handler processes interrupts, it
   * increments the rptr.  When the rptr catches up with the wptr, all the
   * current interrupts have been processed.
   */
  
  void r600_ih_ring_init(struct radeon_device *rdev, unsigned ring_size)
  {
  	u32 rb_bufsz;
  
  	/* Align ring size */
b72a8925f   Daniel Vetter   drm/radeon: s/drm...
3303
  	rb_bufsz = order_base_2(ring_size / 4);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3304
3305
  	ring_size = (1 << rb_bufsz) * 4;
  	rdev->ih.ring_size = ring_size;
0c45249f4   Jerome Glisse   drm/radeon/kms: r...
3306
3307
  	rdev->ih.ptr_mask = rdev->ih.ring_size - 1;
  	rdev->ih.rptr = 0;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3308
  }
25a857fbe   Alex Deucher   drm/radeon/kms: a...
3309
  int r600_ih_ring_alloc(struct radeon_device *rdev)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3310
3311
  {
  	int r;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3312
3313
  	/* Allocate ring buffer */
  	if (rdev->ih.ring_obj == NULL) {
441921d53   Daniel Vetter   drm/radeon: embed...
3314
  		r = radeon_bo_create(rdev, rdev->ih.ring_size,
268b2510d   Alex Deucher   drm/radeon/kms: f...
3315
  				     PAGE_SIZE, true,
02376d828   Michel Dänzer   drm/radeon: Allow...
3316
  				     RADEON_GEM_DOMAIN_GTT, 0,
831b6966a   Maarten Lankhorst   drm/radeon: expor...
3317
  				     NULL, NULL, &rdev->ih.ring_obj);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3318
3319
3320
3321
3322
  		if (r) {
  			DRM_ERROR("radeon: failed to create ih ring buffer (%d).
  ", r);
  			return r;
  		}
4c7886791   Jerome Glisse   drm/radeon/kms: R...
3323
3324
3325
3326
3327
3328
  		r = radeon_bo_reserve(rdev->ih.ring_obj, false);
  		if (unlikely(r != 0))
  			return r;
  		r = radeon_bo_pin(rdev->ih.ring_obj,
  				  RADEON_GEM_DOMAIN_GTT,
  				  &rdev->ih.gpu_addr);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3329
  		if (r) {
4c7886791   Jerome Glisse   drm/radeon/kms: R...
3330
  			radeon_bo_unreserve(rdev->ih.ring_obj);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3331
3332
3333
3334
  			DRM_ERROR("radeon: failed to pin ih ring buffer (%d).
  ", r);
  			return r;
  		}
4c7886791   Jerome Glisse   drm/radeon/kms: R...
3335
3336
3337
  		r = radeon_bo_kmap(rdev->ih.ring_obj,
  				   (void **)&rdev->ih.ring);
  		radeon_bo_unreserve(rdev->ih.ring_obj);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3338
3339
3340
3341
3342
3343
  		if (r) {
  			DRM_ERROR("radeon: failed to map ih ring buffer (%d).
  ", r);
  			return r;
  		}
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3344
3345
  	return 0;
  }
25a857fbe   Alex Deucher   drm/radeon/kms: a...
3346
  void r600_ih_ring_fini(struct radeon_device *rdev)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3347
  {
4c7886791   Jerome Glisse   drm/radeon/kms: R...
3348
  	int r;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3349
  	if (rdev->ih.ring_obj) {
4c7886791   Jerome Glisse   drm/radeon/kms: R...
3350
3351
3352
3353
3354
3355
3356
  		r = radeon_bo_reserve(rdev->ih.ring_obj, false);
  		if (likely(r == 0)) {
  			radeon_bo_kunmap(rdev->ih.ring_obj);
  			radeon_bo_unpin(rdev->ih.ring_obj);
  			radeon_bo_unreserve(rdev->ih.ring_obj);
  		}
  		radeon_bo_unref(&rdev->ih.ring_obj);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3357
3358
3359
3360
  		rdev->ih.ring = NULL;
  		rdev->ih.ring_obj = NULL;
  	}
  }
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
3361
  void r600_rlc_stop(struct radeon_device *rdev)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3362
  {
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
3363
3364
  	if ((rdev->family >= CHIP_RV770) &&
  	    (rdev->family <= CHIP_RV740)) {
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3365
3366
3367
  		/* r7xx asics need to soft reset RLC before halting */
  		WREG32(SRBM_SOFT_RESET, SOFT_RESET_RLC);
  		RREG32(SRBM_SOFT_RESET);
4de833c33   Arnd Bergmann   drm/radeon: repla...
3368
  		mdelay(15);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
  		WREG32(SRBM_SOFT_RESET, 0);
  		RREG32(SRBM_SOFT_RESET);
  	}
  
  	WREG32(RLC_CNTL, 0);
  }
  
  static void r600_rlc_start(struct radeon_device *rdev)
  {
  	WREG32(RLC_CNTL, RLC_ENABLE);
  }
2948f5e6c   Alex Deucher   drm/radeon: prope...
3380
  static int r600_rlc_resume(struct radeon_device *rdev)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3381
3382
3383
3384
3385
3386
3387
3388
  {
  	u32 i;
  	const __be32 *fw_data;
  
  	if (!rdev->rlc_fw)
  		return -EINVAL;
  
  	r600_rlc_stop(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3389
  	WREG32(RLC_HB_CNTL, 0);
c420c7454   Alex Deucher   drm/radeon/kms: a...
3390

2948f5e6c   Alex Deucher   drm/radeon: prope...
3391
3392
3393
3394
3395
  	WREG32(RLC_HB_BASE, 0);
  	WREG32(RLC_HB_RPTR, 0);
  	WREG32(RLC_HB_WPTR, 0);
  	WREG32(RLC_HB_WPTR_LSB_ADDR, 0);
  	WREG32(RLC_HB_WPTR_MSB_ADDR, 0);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3396
3397
3398
3399
  	WREG32(RLC_MC_CNTL, 0);
  	WREG32(RLC_UCODE_CNTL, 0);
  
  	fw_data = (const __be32 *)rdev->rlc_fw->data;
2948f5e6c   Alex Deucher   drm/radeon: prope...
3400
  	if (rdev->family >= CHIP_RV770) {
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3401
3402
3403
3404
3405
  		for (i = 0; i < R700_RLC_UCODE_SIZE; i++) {
  			WREG32(RLC_UCODE_ADDR, i);
  			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
  		}
  	} else {
138e4e16f   Alex Deucher   drm/radeon/kms: m...
3406
  		for (i = 0; i < R600_RLC_UCODE_SIZE; i++) {
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
  			WREG32(RLC_UCODE_ADDR, i);
  			WREG32(RLC_UCODE_DATA, be32_to_cpup(fw_data++));
  		}
  	}
  	WREG32(RLC_UCODE_ADDR, 0);
  
  	r600_rlc_start(rdev);
  
  	return 0;
  }
  
  static void r600_enable_interrupts(struct radeon_device *rdev)
  {
  	u32 ih_cntl = RREG32(IH_CNTL);
  	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
  
  	ih_cntl |= ENABLE_INTR;
  	ih_rb_cntl |= IH_RB_ENABLE;
  	WREG32(IH_CNTL, ih_cntl);
  	WREG32(IH_RB_CNTL, ih_rb_cntl);
  	rdev->ih.enabled = true;
  }
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
3429
  void r600_disable_interrupts(struct radeon_device *rdev)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
3441
  {
  	u32 ih_rb_cntl = RREG32(IH_RB_CNTL);
  	u32 ih_cntl = RREG32(IH_CNTL);
  
  	ih_rb_cntl &= ~IH_RB_ENABLE;
  	ih_cntl &= ~ENABLE_INTR;
  	WREG32(IH_RB_CNTL, ih_rb_cntl);
  	WREG32(IH_CNTL, ih_cntl);
  	/* set rptr, wptr to 0 */
  	WREG32(IH_RB_RPTR, 0);
  	WREG32(IH_RB_WPTR, 0);
  	rdev->ih.enabled = false;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3442
3443
  	rdev->ih.rptr = 0;
  }
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3444
3445
3446
  static void r600_disable_interrupt_state(struct radeon_device *rdev)
  {
  	u32 tmp;
3555e53b5   Alex Deucher   drm/radeon/kms: l...
3447
  	WREG32(CP_INT_CNTL, CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE);
4d75658bf   Alex Deucher   drm/radeon/kms: A...
3448
3449
  	tmp = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
  	WREG32(DMA_CNTL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3450
3451
  	WREG32(GRBM_INT_CNTL, 0);
  	WREG32(DxMODE_INT_MASK, 0);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3452
3453
  	WREG32(D1GRPH_INTERRUPT_CONTROL, 0);
  	WREG32(D2GRPH_INTERRUPT_CONTROL, 0);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
  	if (ASIC_IS_DCE3(rdev)) {
  		WREG32(DCE3_DACA_AUTODETECT_INT_CONTROL, 0);
  		WREG32(DCE3_DACB_AUTODETECT_INT_CONTROL, 0);
  		tmp = RREG32(DC_HPD1_INT_CONTROL) & DC_HPDx_INT_POLARITY;
  		WREG32(DC_HPD1_INT_CONTROL, tmp);
  		tmp = RREG32(DC_HPD2_INT_CONTROL) & DC_HPDx_INT_POLARITY;
  		WREG32(DC_HPD2_INT_CONTROL, tmp);
  		tmp = RREG32(DC_HPD3_INT_CONTROL) & DC_HPDx_INT_POLARITY;
  		WREG32(DC_HPD3_INT_CONTROL, tmp);
  		tmp = RREG32(DC_HPD4_INT_CONTROL) & DC_HPDx_INT_POLARITY;
  		WREG32(DC_HPD4_INT_CONTROL, tmp);
  		if (ASIC_IS_DCE32(rdev)) {
  			tmp = RREG32(DC_HPD5_INT_CONTROL) & DC_HPDx_INT_POLARITY;
5898b1f33   Alex Deucher   drm/radeon/kms: f...
3467
  			WREG32(DC_HPD5_INT_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3468
  			tmp = RREG32(DC_HPD6_INT_CONTROL) & DC_HPDx_INT_POLARITY;
5898b1f33   Alex Deucher   drm/radeon/kms: f...
3469
  			WREG32(DC_HPD6_INT_CONTROL, tmp);
c6543a6e6   Rafał Miłecki   drm/radeon/kms/hd...
3470
3471
3472
3473
  			tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
  			WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, tmp);
  			tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
  			WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, tmp);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3474
3475
3476
3477
3478
  		} else {
  			tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
  			WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp);
  			tmp = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
  			WREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3479
3480
3481
3482
3483
  		}
  	} else {
  		WREG32(DACA_AUTODETECT_INT_CONTROL, 0);
  		WREG32(DACB_AUTODETECT_INT_CONTROL, 0);
  		tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
5898b1f33   Alex Deucher   drm/radeon/kms: f...
3484
  		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3485
  		tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
5898b1f33   Alex Deucher   drm/radeon/kms: f...
3486
  		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3487
  		tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & DC_HOT_PLUG_DETECTx_INT_POLARITY;
5898b1f33   Alex Deucher   drm/radeon/kms: f...
3488
  		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3489
3490
3491
3492
  		tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
  		WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp);
  		tmp = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
  		WREG32(HDMI1_AUDIO_PACKET_CONTROL, tmp);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3493
3494
  	}
  }
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3495
3496
3497
3498
3499
3500
3501
  int r600_irq_init(struct radeon_device *rdev)
  {
  	int ret = 0;
  	int rb_bufsz;
  	u32 interrupt_cntl, ih_cntl, ih_rb_cntl;
  
  	/* allocate ring */
0c45249f4   Jerome Glisse   drm/radeon/kms: r...
3502
  	ret = r600_ih_ring_alloc(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3503
3504
3505
3506
3507
3508
3509
  	if (ret)
  		return ret;
  
  	/* disable irqs */
  	r600_disable_interrupts(rdev);
  
  	/* init rlc */
2948f5e6c   Alex Deucher   drm/radeon: prope...
3510
3511
3512
3513
  	if (rdev->family >= CHIP_CEDAR)
  		ret = evergreen_rlc_resume(rdev);
  	else
  		ret = r600_rlc_resume(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
  	if (ret) {
  		r600_ih_ring_fini(rdev);
  		return ret;
  	}
  
  	/* setup interrupt control */
  	/* set dummy read address to ring address */
  	WREG32(INTERRUPT_CNTL2, rdev->ih.gpu_addr >> 8);
  	interrupt_cntl = RREG32(INTERRUPT_CNTL);
  	/* IH_DUMMY_RD_OVERRIDE=0 - dummy read disabled with msi, enabled without msi
  	 * IH_DUMMY_RD_OVERRIDE=1 - dummy read controlled by IH_DUMMY_RD_EN
  	 */
  	interrupt_cntl &= ~IH_DUMMY_RD_OVERRIDE;
  	/* IH_REQ_NONSNOOP_EN=1 if ring is in non-cacheable memory, e.g., vram */
  	interrupt_cntl &= ~IH_REQ_NONSNOOP_EN;
  	WREG32(INTERRUPT_CNTL, interrupt_cntl);
  
  	WREG32(IH_RB_BASE, rdev->ih.gpu_addr >> 8);
b72a8925f   Daniel Vetter   drm/radeon: s/drm...
3532
  	rb_bufsz = order_base_2(rdev->ih.ring_size / 4);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3533
3534
3535
3536
  
  	ih_rb_cntl = (IH_WPTR_OVERFLOW_ENABLE |
  		      IH_WPTR_OVERFLOW_CLEAR |
  		      (rb_bufsz << 1));
724c80e1d   Alex Deucher   drm/radeon/kms: e...
3537
3538
3539
3540
3541
3542
3543
  
  	if (rdev->wb.enabled)
  		ih_rb_cntl |= IH_WPTR_WRITEBACK_ENABLE;
  
  	/* set the writeback address whether it's enabled or not */
  	WREG32(IH_RB_WPTR_ADDR_LO, (rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFFFFFFFC);
  	WREG32(IH_RB_WPTR_ADDR_HI, upper_32_bits(rdev->wb.gpu_addr + R600_WB_IH_WPTR_OFFSET) & 0xFF);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
  
  	WREG32(IH_RB_CNTL, ih_rb_cntl);
  
  	/* set rptr, wptr to 0 */
  	WREG32(IH_RB_RPTR, 0);
  	WREG32(IH_RB_WPTR, 0);
  
  	/* Default settings for IH_CNTL (disabled at first) */
  	ih_cntl = MC_WRREQ_CREDIT(0x10) | MC_WR_CLEAN_CNT(0x10);
  	/* RPTR_REARM only works if msi's are enabled */
  	if (rdev->msi_enabled)
  		ih_cntl |= RPTR_REARM;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3556
3557
3558
  	WREG32(IH_CNTL, ih_cntl);
  
  	/* force the active interrupt state to all disabled */
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
3559
3560
3561
3562
  	if (rdev->family >= CHIP_CEDAR)
  		evergreen_disable_interrupt_state(rdev);
  	else
  		r600_disable_interrupt_state(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3563

2099810f9   Dave Airlie   drm/radeon: enabl...
3564
3565
  	/* at this point everything should be setup correctly to enable master */
  	pci_set_master(rdev->pdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3566
3567
3568
3569
3570
  	/* enable irqs */
  	r600_enable_interrupts(rdev);
  
  	return ret;
  }
0c45249f4   Jerome Glisse   drm/radeon/kms: r...
3571
  void r600_irq_suspend(struct radeon_device *rdev)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3572
  {
45f9a39be   Alex Deucher   drm/radeon/kms/ev...
3573
  	r600_irq_disable(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3574
  	r600_rlc_stop(rdev);
0c45249f4   Jerome Glisse   drm/radeon/kms: r...
3575
3576
3577
3578
3579
  }
  
  void r600_irq_fini(struct radeon_device *rdev)
  {
  	r600_irq_suspend(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3580
3581
3582
3583
3584
  	r600_ih_ring_fini(rdev);
  }
  
  int r600_irq_set(struct radeon_device *rdev)
  {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3585
3586
3587
  	u32 cp_int_cntl = CNTX_BUSY_INT_ENABLE | CNTX_EMPTY_INT_ENABLE;
  	u32 mode_int = 0;
  	u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0;
2031f77ca   Alex Deucher   drm/radeon/kms: a...
3588
  	u32 grbm_int_cntl = 0;
f122c6109   Alex Deucher   drm/radeon/kms: f...
3589
  	u32 hdmi0, hdmi1;
4d75658bf   Alex Deucher   drm/radeon/kms: A...
3590
  	u32 dma_cntl;
4a6369e99   Alex Deucher   drm/radeon/kms: a...
3591
  	u32 thermal_int = 0;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3592

003e69f98   Jerome Glisse   drm/radeon/kms: D...
3593
  	if (!rdev->irq.installed) {
fce7d61be   Joe Perches   drivers/gpu/drm: ...
3594
3595
  		WARN(1, "Can't enable IRQ/MSI because no handler is installed
  ");
003e69f98   Jerome Glisse   drm/radeon/kms: D...
3596
3597
  		return -EINVAL;
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3598
  	/* don't enable anything if the ih is disabled */
79c2bbc50   Jerome Glisse   drm/radeon/kms: r...
3599
3600
3601
3602
  	if (!rdev->ih.enabled) {
  		r600_disable_interrupts(rdev);
  		/* force the active interrupt state to all disabled */
  		r600_disable_interrupt_state(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3603
  		return 0;
79c2bbc50   Jerome Glisse   drm/radeon/kms: r...
3604
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3605

e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3606
3607
3608
3609
3610
3611
3612
3613
  	if (ASIC_IS_DCE3(rdev)) {
  		hpd1 = RREG32(DC_HPD1_INT_CONTROL) & ~DC_HPDx_INT_EN;
  		hpd2 = RREG32(DC_HPD2_INT_CONTROL) & ~DC_HPDx_INT_EN;
  		hpd3 = RREG32(DC_HPD3_INT_CONTROL) & ~DC_HPDx_INT_EN;
  		hpd4 = RREG32(DC_HPD4_INT_CONTROL) & ~DC_HPDx_INT_EN;
  		if (ASIC_IS_DCE32(rdev)) {
  			hpd5 = RREG32(DC_HPD5_INT_CONTROL) & ~DC_HPDx_INT_EN;
  			hpd6 = RREG32(DC_HPD6_INT_CONTROL) & ~DC_HPDx_INT_EN;
c6543a6e6   Rafał Miłecki   drm/radeon/kms/hd...
3614
3615
  			hdmi0 = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
  			hdmi1 = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1) & ~AFMT_AZ_FORMAT_WTRIG_MASK;
f122c6109   Alex Deucher   drm/radeon/kms: f...
3616
3617
3618
  		} else {
  			hdmi0 = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
  			hdmi1 = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3619
3620
3621
3622
3623
  		}
  	} else {
  		hpd1 = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL) & ~DC_HPDx_INT_EN;
  		hpd2 = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL) & ~DC_HPDx_INT_EN;
  		hpd3 = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL) & ~DC_HPDx_INT_EN;
f122c6109   Alex Deucher   drm/radeon/kms: f...
3624
3625
  		hdmi0 = RREG32(HDMI0_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
  		hdmi1 = RREG32(HDMI1_AUDIO_PACKET_CONTROL) & ~HDMI0_AZ_FORMAT_WTRIG_MASK;
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3626
  	}
4a6369e99   Alex Deucher   drm/radeon/kms: a...
3627

4d75658bf   Alex Deucher   drm/radeon/kms: A...
3628
  	dma_cntl = RREG32(DMA_CNTL) & ~TRAP_ENABLE;
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3629

4a6369e99   Alex Deucher   drm/radeon/kms: a...
3630
3631
3632
  	if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) {
  		thermal_int = RREG32(CG_THERMAL_INT) &
  			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
66229b200   Alex Deucher   drm/radeon/kms: a...
3633
3634
3635
3636
3637
3638
3639
3640
  	} else if (rdev->family >= CHIP_RV770) {
  		thermal_int = RREG32(RV770_CG_THERMAL_INT) &
  			~(THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW);
  	}
  	if (rdev->irq.dpm_thermal) {
  		DRM_DEBUG("dpm thermal
  ");
  		thermal_int |= THERM_INT_MASK_HIGH | THERM_INT_MASK_LOW;
4a6369e99   Alex Deucher   drm/radeon/kms: a...
3641
  	}
736fc37fd   Christian Koenig   drm/radeon: repla...
3642
  	if (atomic_read(&rdev->irq.ring_int[RADEON_RING_TYPE_GFX_INDEX])) {
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3643
3644
3645
  		DRM_DEBUG("r600_irq_set: sw int
  ");
  		cp_int_cntl |= RB_INT_ENABLE;
d0f8a854c   Alex Deucher   drm/radeon/kms/r6...
3646
  		cp_int_cntl |= TIME_STAMP_INT_ENABLE;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3647
  	}
4d75658bf   Alex Deucher   drm/radeon/kms: A...
3648
3649
3650
3651
3652
3653
  
  	if (atomic_read(&rdev->irq.ring_int[R600_RING_TYPE_DMA_INDEX])) {
  		DRM_DEBUG("r600_irq_set: sw int dma
  ");
  		dma_cntl |= TRAP_ENABLE;
  	}
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3654
  	if (rdev->irq.crtc_vblank_int[0] ||
736fc37fd   Christian Koenig   drm/radeon: repla...
3655
  	    atomic_read(&rdev->irq.pflip[0])) {
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3656
3657
3658
3659
  		DRM_DEBUG("r600_irq_set: vblank 0
  ");
  		mode_int |= D1MODE_VBLANK_INT_MASK;
  	}
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3660
  	if (rdev->irq.crtc_vblank_int[1] ||
736fc37fd   Christian Koenig   drm/radeon: repla...
3661
  	    atomic_read(&rdev->irq.pflip[1])) {
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3662
3663
3664
3665
  		DRM_DEBUG("r600_irq_set: vblank 1
  ");
  		mode_int |= D2MODE_VBLANK_INT_MASK;
  	}
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3666
3667
3668
3669
3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
  	if (rdev->irq.hpd[0]) {
  		DRM_DEBUG("r600_irq_set: hpd 1
  ");
  		hpd1 |= DC_HPDx_INT_EN;
  	}
  	if (rdev->irq.hpd[1]) {
  		DRM_DEBUG("r600_irq_set: hpd 2
  ");
  		hpd2 |= DC_HPDx_INT_EN;
  	}
  	if (rdev->irq.hpd[2]) {
  		DRM_DEBUG("r600_irq_set: hpd 3
  ");
  		hpd3 |= DC_HPDx_INT_EN;
  	}
  	if (rdev->irq.hpd[3]) {
  		DRM_DEBUG("r600_irq_set: hpd 4
  ");
  		hpd4 |= DC_HPDx_INT_EN;
  	}
  	if (rdev->irq.hpd[4]) {
  		DRM_DEBUG("r600_irq_set: hpd 5
  ");
  		hpd5 |= DC_HPDx_INT_EN;
  	}
  	if (rdev->irq.hpd[5]) {
  		DRM_DEBUG("r600_irq_set: hpd 6
  ");
  		hpd6 |= DC_HPDx_INT_EN;
  	}
f122c6109   Alex Deucher   drm/radeon/kms: f...
3696
3697
3698
3699
  	if (rdev->irq.afmt[0]) {
  		DRM_DEBUG("r600_irq_set: hdmi 0
  ");
  		hdmi0 |= HDMI0_AZ_FORMAT_WTRIG_MASK;
f2594933d   Christian Koenig   drm/radeon/kms: H...
3700
  	}
f122c6109   Alex Deucher   drm/radeon/kms: f...
3701
3702
3703
3704
  	if (rdev->irq.afmt[1]) {
  		DRM_DEBUG("r600_irq_set: hdmi 0
  ");
  		hdmi1 |= HDMI0_AZ_FORMAT_WTRIG_MASK;
f2594933d   Christian Koenig   drm/radeon/kms: H...
3705
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3706
3707
  
  	WREG32(CP_INT_CNTL, cp_int_cntl);
4d75658bf   Alex Deucher   drm/radeon/kms: A...
3708
  	WREG32(DMA_CNTL, dma_cntl);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3709
  	WREG32(DxMODE_INT_MASK, mode_int);
f5d636d2a   Christian König   drm/radeon: use p...
3710
3711
  	WREG32(D1GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
  	WREG32(D2GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK);
2031f77ca   Alex Deucher   drm/radeon/kms: a...
3712
  	WREG32(GRBM_INT_CNTL, grbm_int_cntl);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3713
3714
3715
3716
3717
3718
3719
3720
  	if (ASIC_IS_DCE3(rdev)) {
  		WREG32(DC_HPD1_INT_CONTROL, hpd1);
  		WREG32(DC_HPD2_INT_CONTROL, hpd2);
  		WREG32(DC_HPD3_INT_CONTROL, hpd3);
  		WREG32(DC_HPD4_INT_CONTROL, hpd4);
  		if (ASIC_IS_DCE32(rdev)) {
  			WREG32(DC_HPD5_INT_CONTROL, hpd5);
  			WREG32(DC_HPD6_INT_CONTROL, hpd6);
c6543a6e6   Rafał Miłecki   drm/radeon/kms/hd...
3721
3722
  			WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, hdmi0);
  			WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, hdmi1);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3723
3724
3725
  		} else {
  			WREG32(HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
  			WREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL, hdmi1);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3726
3727
3728
3729
3730
  		}
  	} else {
  		WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, hpd1);
  		WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, hpd2);
  		WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, hpd3);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3731
3732
  		WREG32(HDMI0_AUDIO_PACKET_CONTROL, hdmi0);
  		WREG32(HDMI1_AUDIO_PACKET_CONTROL, hdmi1);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3733
  	}
4a6369e99   Alex Deucher   drm/radeon/kms: a...
3734
3735
  	if ((rdev->family > CHIP_R600) && (rdev->family < CHIP_RV770)) {
  		WREG32(CG_THERMAL_INT, thermal_int);
66229b200   Alex Deucher   drm/radeon/kms: a...
3736
3737
  	} else if (rdev->family >= CHIP_RV770) {
  		WREG32(RV770_CG_THERMAL_INT, thermal_int);
4a6369e99   Alex Deucher   drm/radeon/kms: a...
3738
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3739

9d1393f23   Alex Deucher   drm/radeon: do a ...
3740
3741
  	/* posting read */
  	RREG32(R_000E50_SRBM_STATUS);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3742
3743
  	return 0;
  }
ce580fab7   Andi Kleen   drm/radeon: Move ...
3744
  static void r600_irq_ack(struct radeon_device *rdev)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3745
  {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3746
3747
3748
  	u32 tmp;
  
  	if (ASIC_IS_DCE3(rdev)) {
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3749
3750
3751
  		rdev->irq.stat_regs.r600.disp_int = RREG32(DCE3_DISP_INTERRUPT_STATUS);
  		rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE);
  		rdev->irq.stat_regs.r600.disp_int_cont2 = RREG32(DCE3_DISP_INTERRUPT_STATUS_CONTINUE2);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3752
  		if (ASIC_IS_DCE32(rdev)) {
c6543a6e6   Rafał Miłecki   drm/radeon/kms/hd...
3753
3754
  			rdev->irq.stat_regs.r600.hdmi0_status = RREG32(AFMT_STATUS + DCE3_HDMI_OFFSET0);
  			rdev->irq.stat_regs.r600.hdmi1_status = RREG32(AFMT_STATUS + DCE3_HDMI_OFFSET1);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3755
3756
3757
3758
  		} else {
  			rdev->irq.stat_regs.r600.hdmi0_status = RREG32(HDMI0_STATUS);
  			rdev->irq.stat_regs.r600.hdmi1_status = RREG32(DCE3_HDMI1_STATUS);
  		}
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3759
  	} else {
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3760
3761
3762
  		rdev->irq.stat_regs.r600.disp_int = RREG32(DISP_INTERRUPT_STATUS);
  		rdev->irq.stat_regs.r600.disp_int_cont = RREG32(DISP_INTERRUPT_STATUS_CONTINUE);
  		rdev->irq.stat_regs.r600.disp_int_cont2 = 0;
f122c6109   Alex Deucher   drm/radeon/kms: f...
3763
3764
  		rdev->irq.stat_regs.r600.hdmi0_status = RREG32(HDMI0_STATUS);
  		rdev->irq.stat_regs.r600.hdmi1_status = RREG32(HDMI1_STATUS);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3765
3766
3767
3768
3769
3770
3771
3772
3773
  	}
  	rdev->irq.stat_regs.r600.d1grph_int = RREG32(D1GRPH_INTERRUPT_STATUS);
  	rdev->irq.stat_regs.r600.d2grph_int = RREG32(D2GRPH_INTERRUPT_STATUS);
  
  	if (rdev->irq.stat_regs.r600.d1grph_int & DxGRPH_PFLIP_INT_OCCURRED)
  		WREG32(D1GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR);
  	if (rdev->irq.stat_regs.r600.d2grph_int & DxGRPH_PFLIP_INT_OCCURRED)
  		WREG32(D2GRPH_INTERRUPT_STATUS, DxGRPH_PFLIP_INT_CLEAR);
  	if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3774
  		WREG32(D1MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3775
  	if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3776
  		WREG32(D1MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3777
  	if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3778
  		WREG32(D2MODE_VBLANK_STATUS, DxMODE_VBLANK_ACK);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3779
  	if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3780
  		WREG32(D2MODE_VLINE_STATUS, DxMODE_VLINE_ACK);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3781
  	if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
  		if (ASIC_IS_DCE3(rdev)) {
  			tmp = RREG32(DC_HPD1_INT_CONTROL);
  			tmp |= DC_HPDx_INT_ACK;
  			WREG32(DC_HPD1_INT_CONTROL, tmp);
  		} else {
  			tmp = RREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL);
  			tmp |= DC_HPDx_INT_ACK;
  			WREG32(DC_HOT_PLUG_DETECT1_INT_CONTROL, tmp);
  		}
  	}
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3792
  	if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
  		if (ASIC_IS_DCE3(rdev)) {
  			tmp = RREG32(DC_HPD2_INT_CONTROL);
  			tmp |= DC_HPDx_INT_ACK;
  			WREG32(DC_HPD2_INT_CONTROL, tmp);
  		} else {
  			tmp = RREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL);
  			tmp |= DC_HPDx_INT_ACK;
  			WREG32(DC_HOT_PLUG_DETECT2_INT_CONTROL, tmp);
  		}
  	}
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3803
  	if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
  		if (ASIC_IS_DCE3(rdev)) {
  			tmp = RREG32(DC_HPD3_INT_CONTROL);
  			tmp |= DC_HPDx_INT_ACK;
  			WREG32(DC_HPD3_INT_CONTROL, tmp);
  		} else {
  			tmp = RREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL);
  			tmp |= DC_HPDx_INT_ACK;
  			WREG32(DC_HOT_PLUG_DETECT3_INT_CONTROL, tmp);
  		}
  	}
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3814
  	if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3815
3816
3817
3818
3819
  		tmp = RREG32(DC_HPD4_INT_CONTROL);
  		tmp |= DC_HPDx_INT_ACK;
  		WREG32(DC_HPD4_INT_CONTROL, tmp);
  	}
  	if (ASIC_IS_DCE32(rdev)) {
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3820
  		if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3821
3822
3823
3824
  			tmp = RREG32(DC_HPD5_INT_CONTROL);
  			tmp |= DC_HPDx_INT_ACK;
  			WREG32(DC_HPD5_INT_CONTROL, tmp);
  		}
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3825
  		if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) {
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3826
3827
3828
3829
  			tmp = RREG32(DC_HPD5_INT_CONTROL);
  			tmp |= DC_HPDx_INT_ACK;
  			WREG32(DC_HPD6_INT_CONTROL, tmp);
  		}
f122c6109   Alex Deucher   drm/radeon/kms: f...
3830
  		if (rdev->irq.stat_regs.r600.hdmi0_status & AFMT_AZ_FORMAT_WTRIG) {
c6543a6e6   Rafał Miłecki   drm/radeon/kms/hd...
3831
  			tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3832
  			tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
c6543a6e6   Rafał Miłecki   drm/radeon/kms/hd...
3833
  			WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET0, tmp);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3834
3835
  		}
  		if (rdev->irq.stat_regs.r600.hdmi1_status & AFMT_AZ_FORMAT_WTRIG) {
c6543a6e6   Rafał Miłecki   drm/radeon/kms/hd...
3836
  			tmp = RREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1);
f122c6109   Alex Deucher   drm/radeon/kms: f...
3837
  			tmp |= AFMT_AZ_FORMAT_WTRIG_ACK;
c6543a6e6   Rafał Miłecki   drm/radeon/kms/hd...
3838
  			WREG32(AFMT_AUDIO_PACKET_CONTROL + DCE3_HDMI_OFFSET1, tmp);
f2594933d   Christian Koenig   drm/radeon/kms: H...
3839
3840
  		}
  	} else {
f122c6109   Alex Deucher   drm/radeon/kms: f...
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
3853
3854
3855
  		if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) {
  			tmp = RREG32(HDMI0_AUDIO_PACKET_CONTROL);
  			tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK;
  			WREG32(HDMI0_AUDIO_PACKET_CONTROL, tmp);
  		}
  		if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) {
  			if (ASIC_IS_DCE3(rdev)) {
  				tmp = RREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL);
  				tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK;
  				WREG32(DCE3_HDMI1_AUDIO_PACKET_CONTROL, tmp);
  			} else {
  				tmp = RREG32(HDMI1_AUDIO_PACKET_CONTROL);
  				tmp |= HDMI0_AZ_FORMAT_WTRIG_ACK;
  				WREG32(HDMI1_AUDIO_PACKET_CONTROL, tmp);
  			}
f2594933d   Christian Koenig   drm/radeon/kms: H...
3856
3857
  		}
  	}
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3858
3859
3860
3861
  }
  
  void r600_irq_disable(struct radeon_device *rdev)
  {
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3862
3863
3864
  	r600_disable_interrupts(rdev);
  	/* Wait and acknowledge irq */
  	mdelay(1);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3865
  	r600_irq_ack(rdev);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
3866
  	r600_disable_interrupt_state(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3867
  }
ce580fab7   Andi Kleen   drm/radeon: Move ...
3868
  static u32 r600_get_ih_wptr(struct radeon_device *rdev)
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3869
3870
  {
  	u32 wptr, tmp;
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3871

724c80e1d   Alex Deucher   drm/radeon/kms: e...
3872
  	if (rdev->wb.enabled)
204ae24dc   Cédric Cano   drm/radeon/kms: f...
3873
  		wptr = le32_to_cpu(rdev->wb.wb[R600_WB_IH_WPTR_OFFSET/4]);
724c80e1d   Alex Deucher   drm/radeon/kms: e...
3874
3875
  	else
  		wptr = RREG32(IH_RB_WPTR);
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3876

d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3877
  	if (wptr & RB_OVERFLOW) {
11bab0ae9   Michel Dänzer   drm/radeon: Clear...
3878
  		wptr &= ~RB_OVERFLOW;
7924e5eb8   Jerome Glisse   drm/radeon/kms: r...
3879
3880
3881
3882
  		/* When a ring buffer overflow happen start parsing interrupt
  		 * from the last not overwritten vector (wptr + 16). Hopefully
  		 * this should allow us to catchup.
  		 */
6cc2fda21   Michel Dänzer   drm/radeon: Make ...
3883
3884
3885
  		dev_warn(rdev->dev, "IH ring buffer overflow (0x%08X, 0x%08X, 0x%08X)
  ",
  			 wptr, rdev->ih.rptr, (wptr + 16) & rdev->ih.ptr_mask);
7924e5eb8   Jerome Glisse   drm/radeon/kms: r...
3886
  		rdev->ih.rptr = (wptr + 16) & rdev->ih.ptr_mask;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3887
3888
3889
3890
  		tmp = RREG32(IH_RB_CNTL);
  		tmp |= IH_WPTR_OVERFLOW_CLEAR;
  		WREG32(IH_RB_CNTL, tmp);
  	}
0c45249f4   Jerome Glisse   drm/radeon/kms: r...
3891
  	return (wptr & rdev->ih.ptr_mask);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3892
  }
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
3893

d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
  /*        r600 IV Ring
   * Each IV ring entry is 128 bits:
   * [7:0]    - interrupt source id
   * [31:8]   - reserved
   * [59:32]  - interrupt source data
   * [127:60]  - reserved
   *
   * The basic interrupt vector entries
   * are decoded as follows:
   * src_id  src_data  description
   *      1         0  D1 Vblank
   *      1         1  D1 Vline
   *      5         0  D2 Vblank
   *      5         1  D2 Vline
   *     19         0  FP Hot plug detection A
   *     19         1  FP Hot plug detection B
   *     19         2  DAC A auto-detection
   *     19         3  DAC B auto-detection
f2594933d   Christian Koenig   drm/radeon/kms: H...
3912
3913
   *     21         4  HDMI block A
   *     21         5  HDMI block B
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3914
3915
3916
3917
3918
3919
3920
3921
3922
3923
3924
3925
   *    176         -  CP_INT RB
   *    177         -  CP_INT IB1
   *    178         -  CP_INT IB2
   *    181         -  EOP Interrupt
   *    233         -  GUI Idle
   *
   * Note, these are based on r600 and may need to be
   * adjusted or added to on newer asics
   */
  
  int r600_irq_process(struct radeon_device *rdev)
  {
682f1a54a   Dave Airlie   drm/radeon: avoid...
3926
3927
  	u32 wptr;
  	u32 rptr;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3928
  	u32 src_id, src_data;
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3929
  	u32 ring_index;
d4877cf22   Alex Deucher   drm/radeon/kms: e...
3930
  	bool queue_hotplug = false;
f122c6109   Alex Deucher   drm/radeon/kms: f...
3931
  	bool queue_hdmi = false;
4a6369e99   Alex Deucher   drm/radeon/kms: a...
3932
  	bool queue_thermal = false;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3933

682f1a54a   Dave Airlie   drm/radeon: avoid...
3934
  	if (!rdev->ih.enabled || rdev->shutdown)
79c2bbc50   Jerome Glisse   drm/radeon/kms: r...
3935
  		return IRQ_NONE;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3936

f6a569397   Benjamin Herrenschmidt   drm/radeon: Do an...
3937
3938
3939
  	/* No MSIs, need a dummy read to flush PCI DMAs */
  	if (!rdev->msi_enabled)
  		RREG32(IH_RB_WPTR);
682f1a54a   Dave Airlie   drm/radeon: avoid...
3940
  	wptr = r600_get_ih_wptr(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3941

c20dc3698   Christian Koenig   drm/radeon: fix &...
3942
3943
3944
  restart_ih:
  	/* is somebody else already processing irqs? */
  	if (atomic_xchg(&rdev->ih.lock, 1))
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3945
  		return IRQ_NONE;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3946

c20dc3698   Christian Koenig   drm/radeon: fix &...
3947
3948
3949
  	rptr = rdev->ih.rptr;
  	DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d
  ", rptr, wptr);
964f66452   Benjamin Herrenschmidt   drm/radeon: Add a...
3950
3951
  	/* Order reading of wptr vs. reading of IH ring data */
  	rmb();
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3952
  	/* display interrupts */
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3953
  	r600_irq_ack(rdev);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3954

d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3955
3956
3957
  	while (rptr != wptr) {
  		/* wptr/rptr are in bytes! */
  		ring_index = rptr / 4;
4eace7fdf   Cédric Cano   drm/radeon/kms: 6...
3958
3959
  		src_id = le32_to_cpu(rdev->ih.ring[ring_index]) & 0xff;
  		src_data = le32_to_cpu(rdev->ih.ring[ring_index + 1]) & 0xfffffff;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3960
3961
3962
3963
3964
  
  		switch (src_id) {
  		case 1: /* D1 vblank/vline */
  			switch (src_data) {
  			case 0: /* D1 vblank */
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3965
  				if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VBLANK_INTERRUPT) {
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3966
3967
3968
3969
3970
  					if (rdev->irq.crtc_vblank_int[0]) {
  						drm_handle_vblank(rdev->ddev, 0);
  						rdev->pm.vblank_sync = true;
  						wake_up(&rdev->irq.vblank_queue);
  					}
736fc37fd   Christian Koenig   drm/radeon: repla...
3971
  					if (atomic_read(&rdev->irq.pflip[0]))
1a0e79184   Christian König   drm/radeon: separ...
3972
  						radeon_crtc_handle_vblank(rdev, 0);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3973
  					rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VBLANK_INTERRUPT;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3974
3975
3976
3977
3978
  					DRM_DEBUG("IH: D1 vblank
  ");
  				}
  				break;
  			case 1: /* D1 vline */
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3979
3980
  				if (rdev->irq.stat_regs.r600.disp_int & LB_D1_VLINE_INTERRUPT) {
  					rdev->irq.stat_regs.r600.disp_int &= ~LB_D1_VLINE_INTERRUPT;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3981
3982
3983
3984
3985
  					DRM_DEBUG("IH: D1 vline
  ");
  				}
  				break;
  			default:
b042589ca   Alex Deucher   drm/radeon/kms/r6...
3986
3987
  				DRM_DEBUG("Unhandled interrupt: %d %d
  ", src_id, src_data);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
3988
3989
3990
3991
3992
3993
  				break;
  			}
  			break;
  		case 5: /* D2 vblank/vline */
  			switch (src_data) {
  			case 0: /* D2 vblank */
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3994
  				if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VBLANK_INTERRUPT) {
6f34be50b   Alex Deucher   drm/radeon/kms: a...
3995
3996
3997
3998
3999
  					if (rdev->irq.crtc_vblank_int[1]) {
  						drm_handle_vblank(rdev->ddev, 1);
  						rdev->pm.vblank_sync = true;
  						wake_up(&rdev->irq.vblank_queue);
  					}
736fc37fd   Christian Koenig   drm/radeon: repla...
4000
  					if (atomic_read(&rdev->irq.pflip[1]))
1a0e79184   Christian König   drm/radeon: separ...
4001
  						radeon_crtc_handle_vblank(rdev, 1);
6f34be50b   Alex Deucher   drm/radeon/kms: a...
4002
  					rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VBLANK_INTERRUPT;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4003
4004
4005
4006
4007
  					DRM_DEBUG("IH: D2 vblank
  ");
  				}
  				break;
  			case 1: /* D1 vline */
6f34be50b   Alex Deucher   drm/radeon/kms: a...
4008
4009
  				if (rdev->irq.stat_regs.r600.disp_int & LB_D2_VLINE_INTERRUPT) {
  					rdev->irq.stat_regs.r600.disp_int &= ~LB_D2_VLINE_INTERRUPT;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4010
4011
4012
4013
4014
  					DRM_DEBUG("IH: D2 vline
  ");
  				}
  				break;
  			default:
b042589ca   Alex Deucher   drm/radeon/kms/r6...
4015
4016
  				DRM_DEBUG("Unhandled interrupt: %d %d
  ", src_id, src_data);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4017
4018
4019
  				break;
  			}
  			break;
f5d636d2a   Christian König   drm/radeon: use p...
4020
4021
4022
  		case 9: /* D1 pflip */
  			DRM_DEBUG("IH: D1 flip
  ");
39dc5454e   Mario Kleiner   drm/radeon: Use p...
4023
4024
  			if (radeon_use_pflipirq > 0)
  				radeon_crtc_handle_flip(rdev, 0);
f5d636d2a   Christian König   drm/radeon: use p...
4025
4026
4027
4028
  			break;
  		case 11: /* D2 pflip */
  			DRM_DEBUG("IH: D2 flip
  ");
39dc5454e   Mario Kleiner   drm/radeon: Use p...
4029
4030
  			if (radeon_use_pflipirq > 0)
  				radeon_crtc_handle_flip(rdev, 1);
f5d636d2a   Christian König   drm/radeon: use p...
4031
  			break;
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
4032
4033
4034
  		case 19: /* HPD/DAC hotplug */
  			switch (src_data) {
  			case 0:
6f34be50b   Alex Deucher   drm/radeon/kms: a...
4035
4036
  				if (rdev->irq.stat_regs.r600.disp_int & DC_HPD1_INTERRUPT) {
  					rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD1_INTERRUPT;
d4877cf22   Alex Deucher   drm/radeon/kms: e...
4037
4038
4039
  					queue_hotplug = true;
  					DRM_DEBUG("IH: HPD1
  ");
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
4040
4041
4042
  				}
  				break;
  			case 1:
6f34be50b   Alex Deucher   drm/radeon/kms: a...
4043
4044
  				if (rdev->irq.stat_regs.r600.disp_int & DC_HPD2_INTERRUPT) {
  					rdev->irq.stat_regs.r600.disp_int &= ~DC_HPD2_INTERRUPT;
d4877cf22   Alex Deucher   drm/radeon/kms: e...
4045
4046
4047
  					queue_hotplug = true;
  					DRM_DEBUG("IH: HPD2
  ");
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
4048
4049
4050
  				}
  				break;
  			case 4:
6f34be50b   Alex Deucher   drm/radeon/kms: a...
4051
4052
  				if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD3_INTERRUPT) {
  					rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD3_INTERRUPT;
d4877cf22   Alex Deucher   drm/radeon/kms: e...
4053
4054
4055
  					queue_hotplug = true;
  					DRM_DEBUG("IH: HPD3
  ");
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
4056
4057
4058
  				}
  				break;
  			case 5:
6f34be50b   Alex Deucher   drm/radeon/kms: a...
4059
4060
  				if (rdev->irq.stat_regs.r600.disp_int_cont & DC_HPD4_INTERRUPT) {
  					rdev->irq.stat_regs.r600.disp_int_cont &= ~DC_HPD4_INTERRUPT;
d4877cf22   Alex Deucher   drm/radeon/kms: e...
4061
4062
4063
  					queue_hotplug = true;
  					DRM_DEBUG("IH: HPD4
  ");
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
4064
4065
4066
  				}
  				break;
  			case 10:
6f34be50b   Alex Deucher   drm/radeon/kms: a...
4067
4068
  				if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD5_INTERRUPT) {
  					rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD5_INTERRUPT;
d4877cf22   Alex Deucher   drm/radeon/kms: e...
4069
4070
4071
  					queue_hotplug = true;
  					DRM_DEBUG("IH: HPD5
  ");
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
4072
4073
4074
  				}
  				break;
  			case 12:
6f34be50b   Alex Deucher   drm/radeon/kms: a...
4075
4076
  				if (rdev->irq.stat_regs.r600.disp_int_cont2 & DC_HPD6_INTERRUPT) {
  					rdev->irq.stat_regs.r600.disp_int_cont2 &= ~DC_HPD6_INTERRUPT;
d4877cf22   Alex Deucher   drm/radeon/kms: e...
4077
4078
4079
  					queue_hotplug = true;
  					DRM_DEBUG("IH: HPD6
  ");
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
4080
4081
4082
  				}
  				break;
  			default:
b042589ca   Alex Deucher   drm/radeon/kms/r6...
4083
4084
  				DRM_DEBUG("Unhandled interrupt: %d %d
  ", src_id, src_data);
e0df1ac5c   Alex Deucher   drm/radeon/kms: a...
4085
4086
4087
  				break;
  			}
  			break;
f122c6109   Alex Deucher   drm/radeon/kms: f...
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
4105
4106
4107
4108
4109
4110
  		case 21: /* hdmi */
  			switch (src_data) {
  			case 4:
  				if (rdev->irq.stat_regs.r600.hdmi0_status & HDMI0_AZ_FORMAT_WTRIG) {
  					rdev->irq.stat_regs.r600.hdmi0_status &= ~HDMI0_AZ_FORMAT_WTRIG;
  					queue_hdmi = true;
  					DRM_DEBUG("IH: HDMI0
  ");
  				}
  				break;
  			case 5:
  				if (rdev->irq.stat_regs.r600.hdmi1_status & HDMI0_AZ_FORMAT_WTRIG) {
  					rdev->irq.stat_regs.r600.hdmi1_status &= ~HDMI0_AZ_FORMAT_WTRIG;
  					queue_hdmi = true;
  					DRM_DEBUG("IH: HDMI1
  ");
  				}
  				break;
  			default:
  				DRM_ERROR("Unhandled interrupt: %d %d
  ", src_id, src_data);
  				break;
  			}
f2594933d   Christian Koenig   drm/radeon/kms: H...
4111
  			break;
858a41c85   Alex Deucher   drm/radeon: fix U...
4112
4113
4114
4115
4116
  		case 124: /* UVD */
  			DRM_DEBUG("IH: UVD int: 0x%08x
  ", src_data);
  			radeon_fence_process(rdev, R600_RING_TYPE_UVD_INDEX);
  			break;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4117
4118
4119
4120
4121
  		case 176: /* CP_INT in ring buffer */
  		case 177: /* CP_INT in IB1 */
  		case 178: /* CP_INT in IB2 */
  			DRM_DEBUG("IH: CP int: 0x%08x
  ", src_data);
7465280c0   Alex Deucher   drm/radeon/kms: a...
4122
  			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4123
4124
4125
4126
  			break;
  		case 181: /* CP EOP event */
  			DRM_DEBUG("IH: CP EOP
  ");
7465280c0   Alex Deucher   drm/radeon/kms: a...
4127
  			radeon_fence_process(rdev, RADEON_RING_TYPE_GFX_INDEX);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4128
  			break;
4d75658bf   Alex Deucher   drm/radeon/kms: A...
4129
4130
4131
4132
4133
  		case 224: /* DMA trap event */
  			DRM_DEBUG("IH: DMA trap
  ");
  			radeon_fence_process(rdev, R600_RING_TYPE_DMA_INDEX);
  			break;
4a6369e99   Alex Deucher   drm/radeon/kms: a...
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
  		case 230: /* thermal low to high */
  			DRM_DEBUG("IH: thermal low to high
  ");
  			rdev->pm.dpm.thermal.high_to_low = false;
  			queue_thermal = true;
  			break;
  		case 231: /* thermal high to low */
  			DRM_DEBUG("IH: thermal high to low
  ");
  			rdev->pm.dpm.thermal.high_to_low = true;
  			queue_thermal = true;
  			break;
2031f77ca   Alex Deucher   drm/radeon/kms: a...
4146
  		case 233: /* GUI IDLE */
303c805cb   Ilija Hadzic   drm/radeon: fix G...
4147
4148
  			DRM_DEBUG("IH: GUI idle
  ");
2031f77ca   Alex Deucher   drm/radeon/kms: a...
4149
  			break;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4150
  		default:
b042589ca   Alex Deucher   drm/radeon/kms/r6...
4151
4152
  			DRM_DEBUG("Unhandled interrupt: %d %d
  ", src_id, src_data);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4153
4154
4155
4156
  			break;
  		}
  
  		/* wptr/rptr are in bytes! */
0c45249f4   Jerome Glisse   drm/radeon/kms: r...
4157
4158
  		rptr += 16;
  		rptr &= rdev->ih.ptr_mask;
f55e03b97   Michel Dänzer   drm/radeon: Updat...
4159
  		WREG32(IH_RB_RPTR, rptr);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4160
  	}
d4877cf22   Alex Deucher   drm/radeon/kms: e...
4161
  	if (queue_hotplug)
32c87fca2   Tejun Heo   drm/radeon: use s...
4162
  		schedule_work(&rdev->hotplug_work);
f122c6109   Alex Deucher   drm/radeon/kms: f...
4163
4164
  	if (queue_hdmi)
  		schedule_work(&rdev->audio_work);
4a6369e99   Alex Deucher   drm/radeon/kms: a...
4165
4166
  	if (queue_thermal && rdev->pm.dpm_enabled)
  		schedule_work(&rdev->pm.dpm.thermal.work);
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4167
  	rdev->ih.rptr = rptr;
c20dc3698   Christian Koenig   drm/radeon: fix &...
4168
4169
4170
4171
4172
4173
  	atomic_set(&rdev->ih.lock, 0);
  
  	/* make sure wptr hasn't changed while processing */
  	wptr = r600_get_ih_wptr(rdev);
  	if (wptr != rptr)
  		goto restart_ih;
d8f60cfc9   Alex Deucher   drm/radeon/kms: A...
4174
4175
  	return IRQ_HANDLED;
  }
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
4176
4177
4178
4179
4180
  
  /*
   * Debugfs info
   */
  #if defined(CONFIG_DEBUG_FS)
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
  static int r600_debugfs_mc_info(struct seq_file *m, void *data)
  {
  	struct drm_info_node *node = (struct drm_info_node *) m->private;
  	struct drm_device *dev = node->minor->dev;
  	struct radeon_device *rdev = dev->dev_private;
  
  	DREG32_SYS(m, rdev, R_000E50_SRBM_STATUS);
  	DREG32_SYS(m, rdev, VM_L2_STATUS);
  	return 0;
  }
  
  static struct drm_info_list r600_mc_info_list[] = {
  	{"r600_mc_info", r600_debugfs_mc_info, 0, NULL},
3ce0a23d2   Jerome Glisse   drm/radeon/kms: a...
4194
4195
4196
4197
4198
4199
4200
4201
4202
4203
  };
  #endif
  
  int r600_debugfs_mc_info_init(struct radeon_device *rdev)
  {
  #if defined(CONFIG_DEBUG_FS)
  	return radeon_debugfs_add_files(rdev, r600_mc_info_list, ARRAY_SIZE(r600_mc_info_list));
  #else
  	return 0;
  #endif
771fe6b91   Jerome Glisse   drm/radeon: intro...
4204
  }
062b389c8   Jerome Glisse   drm/radeon/kms: f...
4205
4206
  
  /**
124764f17   Michel Dänzer   drm/radeon: s/ioc...
4207
   * r600_mmio_hdp_flush - flush Host Data Path cache via MMIO
062b389c8   Jerome Glisse   drm/radeon/kms: f...
4208
   * rdev: radeon device structure
062b389c8   Jerome Glisse   drm/radeon/kms: f...
4209
   *
124764f17   Michel Dänzer   drm/radeon: s/ioc...
4210
4211
4212
4213
   * Some R6XX/R7XX don't seem to take into account HDP flushes performed
   * through the ring buffer. This leads to corruption in rendering, see
   * http://bugzilla.kernel.org/show_bug.cgi?id=15186 . To avoid this, we
   * directly perform the HDP flush by writing the register through MMIO.
062b389c8   Jerome Glisse   drm/radeon/kms: f...
4214
   */
124764f17   Michel Dänzer   drm/radeon: s/ioc...
4215
  void r600_mmio_hdp_flush(struct radeon_device *rdev)
062b389c8   Jerome Glisse   drm/radeon/kms: f...
4216
  {
812d04691   Alex Deucher   drm/radeon/kms/r7...
4217
  	/* r7xx hw bug.  write to HDP_DEBUG1 followed by fb read
f3886f85c   Alex Deucher   drm/radeon/kms: d...
4218
4219
4220
  	 * rather than write to HDP_REG_COHERENCY_FLUSH_CNTL.
  	 * This seems to cause problems on some AGP cards. Just use the old
  	 * method for them.
812d04691   Alex Deucher   drm/radeon/kms/r7...
4221
  	 */
e488459a0   Alex Deucher   drm/radeon/kms: f...
4222
  	if ((rdev->family >= CHIP_RV770) && (rdev->family <= CHIP_RV740) &&
f3886f85c   Alex Deucher   drm/radeon/kms: d...
4223
  	    rdev->vram_scratch.ptr && !(rdev->flags & RADEON_IS_AGP)) {
87cbf8f2c   Alex Deucher   drm/radeon/kms: f...
4224
  		void __iomem *ptr = (void *)rdev->vram_scratch.ptr;
812d04691   Alex Deucher   drm/radeon/kms/r7...
4225
4226
4227
4228
4229
4230
  		u32 tmp;
  
  		WREG32(HDP_DEBUG1, 0);
  		tmp = readl((void __iomem *)ptr);
  	} else
  		WREG32(R_005480_HDP_MEM_COHERENCY_FLUSH_CNTL, 0x1);
062b389c8   Jerome Glisse   drm/radeon/kms: f...
4231
  }
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4232
4233
4234
  
  void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes)
  {
d5445a17e   Alex Deucher   drm/radeon: updat...
4235
  	u32 link_width_cntl, mask;
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
  
  	if (rdev->flags & RADEON_IS_IGP)
  		return;
  
  	if (!(rdev->flags & RADEON_IS_PCIE))
  		return;
  
  	/* x2 cards have a special sequence */
  	if (ASIC_IS_X2(rdev))
  		return;
d5445a17e   Alex Deucher   drm/radeon: updat...
4246
  	radeon_gui_idle(rdev);
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
  
  	switch (lanes) {
  	case 0:
  		mask = RADEON_PCIE_LC_LINK_WIDTH_X0;
  		break;
  	case 1:
  		mask = RADEON_PCIE_LC_LINK_WIDTH_X1;
  		break;
  	case 2:
  		mask = RADEON_PCIE_LC_LINK_WIDTH_X2;
  		break;
  	case 4:
  		mask = RADEON_PCIE_LC_LINK_WIDTH_X4;
  		break;
  	case 8:
  		mask = RADEON_PCIE_LC_LINK_WIDTH_X8;
  		break;
  	case 12:
d5445a17e   Alex Deucher   drm/radeon: updat...
4265
  		/* not actually supported */
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4266
4267
4268
  		mask = RADEON_PCIE_LC_LINK_WIDTH_X12;
  		break;
  	case 16:
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4269
4270
  		mask = RADEON_PCIE_LC_LINK_WIDTH_X16;
  		break;
d5445a17e   Alex Deucher   drm/radeon: updat...
4271
4272
4273
4274
  	default:
  		DRM_ERROR("invalid pcie lane request: %d
  ", lanes);
  		return;
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4275
  	}
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4276
  	link_width_cntl = RREG32_PCIE_PORT(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
d5445a17e   Alex Deucher   drm/radeon: updat...
4277
4278
4279
4280
  	link_width_cntl &= ~RADEON_PCIE_LC_LINK_WIDTH_MASK;
  	link_width_cntl |= mask << RADEON_PCIE_LC_LINK_WIDTH_SHIFT;
  	link_width_cntl |= (RADEON_PCIE_LC_RECONFIG_NOW |
  			    R600_PCIE_LC_RECONFIG_ARC_MISSING_ESCAPE);
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4281

492d2b61b   Alex Deucher   drm/radeon/kms: r...
4282
  	WREG32_PCIE_PORT(RADEON_PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
  }
  
  int r600_get_pcie_lanes(struct radeon_device *rdev)
  {
  	u32 link_width_cntl;
  
  	if (rdev->flags & RADEON_IS_IGP)
  		return 0;
  
  	if (!(rdev->flags & RADEON_IS_PCIE))
  		return 0;
  
  	/* x2 cards have a special sequence */
  	if (ASIC_IS_X2(rdev))
  		return 0;
d5445a17e   Alex Deucher   drm/radeon: updat...
4298
  	radeon_gui_idle(rdev);
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4299

492d2b61b   Alex Deucher   drm/radeon/kms: r...
4300
  	link_width_cntl = RREG32_PCIE_PORT(RADEON_PCIE_LC_LINK_WIDTH_CNTL);
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4301
4302
  
  	switch ((link_width_cntl & RADEON_PCIE_LC_LINK_WIDTH_RD_MASK) >> RADEON_PCIE_LC_LINK_WIDTH_RD_SHIFT) {
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4303
4304
4305
4306
4307
4308
4309
4310
  	case RADEON_PCIE_LC_LINK_WIDTH_X1:
  		return 1;
  	case RADEON_PCIE_LC_LINK_WIDTH_X2:
  		return 2;
  	case RADEON_PCIE_LC_LINK_WIDTH_X4:
  		return 4;
  	case RADEON_PCIE_LC_LINK_WIDTH_X8:
  		return 8;
d5445a17e   Alex Deucher   drm/radeon: updat...
4311
4312
4313
4314
  	case RADEON_PCIE_LC_LINK_WIDTH_X12:
  		/* not actually supported */
  		return 12;
  	case RADEON_PCIE_LC_LINK_WIDTH_X0:
3313e3d43   Alex Deucher   drm/radeon/kms: a...
4315
4316
4317
4318
4319
  	case RADEON_PCIE_LC_LINK_WIDTH_X16:
  	default:
  		return 16;
  	}
  }
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4320
4321
4322
4323
  static void r600_pcie_gen2_enable(struct radeon_device *rdev)
  {
  	u32 link_width_cntl, lanes, speed_cntl, training_cntl, tmp;
  	u16 link_cntl2;
d42dd579a   Alex Deucher   drm/radeon/kms: a...
4324
4325
  	if (radeon_pcie_gen2 == 0)
  		return;
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
  	if (rdev->flags & RADEON_IS_IGP)
  		return;
  
  	if (!(rdev->flags & RADEON_IS_PCIE))
  		return;
  
  	/* x2 cards have a special sequence */
  	if (ASIC_IS_X2(rdev))
  		return;
  
  	/* only RV6xx+ chips are supported */
  	if (rdev->family <= CHIP_R600)
  		return;
7e0e41963   Kleber Sacilotto de Souza   radeon: use max_b...
4339
4340
  	if ((rdev->pdev->bus->max_bus_speed != PCIE_SPEED_5_0GT) &&
  		(rdev->pdev->bus->max_bus_speed != PCIE_SPEED_8_0GT))
197bbb3d4   Dave Airlie   drm/radeon/kms: a...
4341
  		return;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4342
  	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
3691feea9   Alex Deucher   drm/radeon: check...
4343
4344
4345
4346
4347
  	if (speed_cntl & LC_CURRENT_DATA_RATE) {
  		DRM_INFO("PCIE gen 2 link speeds already enabled
  ");
  		return;
  	}
197bbb3d4   Dave Airlie   drm/radeon/kms: a...
4348
4349
  	DRM_INFO("enabling PCIE gen 2 link speeds, disable with radeon.pcie_gen2=0
  ");
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4350
4351
4352
4353
4354
  	/* 55 nm r6xx asics */
  	if ((rdev->family == CHIP_RV670) ||
  	    (rdev->family == CHIP_RV620) ||
  	    (rdev->family == CHIP_RV635)) {
  		/* advertise upconfig capability */
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4355
  		link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4356
  		link_width_cntl &= ~LC_UPCONFIGURE_DIS;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4357
4358
  		WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
  		link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4359
4360
4361
4362
4363
  		if (link_width_cntl & LC_RENEGOTIATION_SUPPORT) {
  			lanes = (link_width_cntl & LC_LINK_WIDTH_RD_MASK) >> LC_LINK_WIDTH_RD_SHIFT;
  			link_width_cntl &= ~(LC_LINK_WIDTH_MASK |
  					     LC_RECONFIG_ARC_MISSING_ESCAPE);
  			link_width_cntl |= lanes | LC_RECONFIG_NOW | LC_RENEGOTIATE_EN;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4364
  			WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4365
4366
  		} else {
  			link_width_cntl |= LC_UPCONFIGURE_DIS;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4367
  			WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4368
4369
  		}
  	}
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4370
  	speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
  	if ((speed_cntl & LC_OTHER_SIDE_EVER_SENT_GEN2) &&
  	    (speed_cntl & LC_OTHER_SIDE_SUPPORTS_GEN2)) {
  
  		/* 55 nm r6xx asics */
  		if ((rdev->family == CHIP_RV670) ||
  		    (rdev->family == CHIP_RV620) ||
  		    (rdev->family == CHIP_RV635)) {
  			WREG32(MM_CFGREGS_CNTL, 0x8);
  			link_cntl2 = RREG32(0x4088);
  			WREG32(MM_CFGREGS_CNTL, 0);
  			/* not supported yet */
  			if (link_cntl2 & SELECTABLE_DEEMPHASIS)
  				return;
  		}
  
  		speed_cntl &= ~LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_MASK;
  		speed_cntl |= (0x3 << LC_SPEED_CHANGE_ATTEMPTS_ALLOWED_SHIFT);
  		speed_cntl &= ~LC_VOLTAGE_TIMER_SEL_MASK;
  		speed_cntl &= ~LC_FORCE_DIS_HW_SPEED_CHANGE;
  		speed_cntl |= LC_FORCE_EN_HW_SPEED_CHANGE;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4391
  		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
  
  		tmp = RREG32(0x541c);
  		WREG32(0x541c, tmp | 0x8);
  		WREG32(MM_CFGREGS_CNTL, MM_WR_TO_CFG_EN);
  		link_cntl2 = RREG16(0x4088);
  		link_cntl2 &= ~TARGET_LINK_SPEED_MASK;
  		link_cntl2 |= 0x2;
  		WREG16(0x4088, link_cntl2);
  		WREG32(MM_CFGREGS_CNTL, 0);
  
  		if ((rdev->family == CHIP_RV670) ||
  		    (rdev->family == CHIP_RV620) ||
  		    (rdev->family == CHIP_RV635)) {
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4405
  			training_cntl = RREG32_PCIE_PORT(PCIE_LC_TRAINING_CNTL);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4406
  			training_cntl &= ~LC_POINT_7_PLUS_EN;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4407
  			WREG32_PCIE_PORT(PCIE_LC_TRAINING_CNTL, training_cntl);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4408
  		} else {
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4409
  			speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4410
  			speed_cntl &= ~LC_TARGET_LINK_SPEED_OVERRIDE_EN;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4411
  			WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4412
  		}
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4413
  		speed_cntl = RREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4414
  		speed_cntl |= LC_GEN2_EN_STRAP;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4415
  		WREG32_PCIE_PORT(PCIE_LC_SPEED_CNTL, speed_cntl);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4416
4417
  
  	} else {
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4418
  		link_width_cntl = RREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4419
4420
4421
4422
4423
  		/* XXX: only disable it if gen1 bridge vendor == 0x111d or 0x1106 */
  		if (1)
  			link_width_cntl |= LC_UPCONFIGURE_DIS;
  		else
  			link_width_cntl &= ~LC_UPCONFIGURE_DIS;
492d2b61b   Alex Deucher   drm/radeon/kms: r...
4424
  		WREG32_PCIE_PORT(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl);
9e46a48df   Alex Deucher   drm/radeon/kms: a...
4425
4426
  	}
  }
6759a0a7a   Marek Olšák   drm/radeon/kms: i...
4427
4428
  
  /**
d04188941   Alex Deucher   drm/radeon: switc...
4429
   * r600_get_gpu_clock_counter - return GPU clock counter snapshot
6759a0a7a   Marek Olšák   drm/radeon/kms: i...
4430
4431
4432
4433
4434
4435
   *
   * @rdev: radeon_device pointer
   *
   * Fetches a GPU clock counter snapshot (R6xx-cayman).
   * Returns the 64 bit clock counter snapshot.
   */
d04188941   Alex Deucher   drm/radeon: switc...
4436
  uint64_t r600_get_gpu_clock_counter(struct radeon_device *rdev)
6759a0a7a   Marek Olšák   drm/radeon/kms: i...
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
  {
  	uint64_t clock;
  
  	mutex_lock(&rdev->gpu_clock_mutex);
  	WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1);
  	clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) |
  	        ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL);
  	mutex_unlock(&rdev->gpu_clock_mutex);
  	return clock;
  }