x86: Fix code patching for paravirt-alternatives on 486
[linux-block.git] / drivers / gpu / drm / radeon / rs690.c
CommitLineData
771fe6b9
JG
1/*
2 * Copyright 2008 Advanced Micro Devices, Inc.
3 * Copyright 2008 Red Hat Inc.
4 * Copyright 2009 Jerome Glisse.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 * OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors: Dave Airlie
25 * Alex Deucher
26 * Jerome Glisse
27 */
28#include "drmP.h"
29#include "radeon_reg.h"
30#include "radeon.h"
c93bb85b
JG
31#include "rs690r.h"
32#include "atom.h"
33#include "atom-bits.h"
771fe6b9
JG
34
35/* rs690,rs740 depends on : */
36void r100_hdp_reset(struct radeon_device *rdev);
37int r300_mc_wait_for_idle(struct radeon_device *rdev);
38void r420_pipes_init(struct radeon_device *rdev);
39void rs400_gart_disable(struct radeon_device *rdev);
40int rs400_gart_enable(struct radeon_device *rdev);
41void rs400_gart_adjust_size(struct radeon_device *rdev);
42void rs600_mc_disable_clients(struct radeon_device *rdev);
43void rs600_disable_vga(struct radeon_device *rdev);
44
45/* This files gather functions specifics to :
46 * rs690,rs740
47 *
48 * Some of these functions might be used by newer ASICs.
49 */
50void rs690_gpu_init(struct radeon_device *rdev);
51int rs690_mc_wait_for_idle(struct radeon_device *rdev);
52
53
54/*
55 * MC functions.
56 */
57int rs690_mc_init(struct radeon_device *rdev)
58{
59 uint32_t tmp;
60 int r;
61
62 if (r100_debugfs_rbbm_init(rdev)) {
63 DRM_ERROR("Failed to register debugfs file for RBBM !\n");
64 }
65
66 rs690_gpu_init(rdev);
67 rs400_gart_disable(rdev);
68
69 /* Setup GPU memory space */
7a50f01a 70 rdev->mc.gtt_location = rdev->mc.mc_vram_size;
771fe6b9
JG
71 rdev->mc.gtt_location += (rdev->mc.gtt_size - 1);
72 rdev->mc.gtt_location &= ~(rdev->mc.gtt_size - 1);
73 rdev->mc.vram_location = 0xFFFFFFFFUL;
74 r = radeon_mc_setup(rdev);
75 if (r) {
76 return r;
77 }
78
79 /* Program GPU memory space */
80 rs600_mc_disable_clients(rdev);
81 if (rs690_mc_wait_for_idle(rdev)) {
82 printk(KERN_WARNING "Failed to wait MC idle while "
83 "programming pipes. Bad things might happen.\n");
84 }
7a50f01a 85 tmp = rdev->mc.vram_location + rdev->mc.mc_vram_size - 1;
771fe6b9
JG
86 tmp = REG_SET(RS690_MC_FB_TOP, tmp >> 16);
87 tmp |= REG_SET(RS690_MC_FB_START, rdev->mc.vram_location >> 16);
88 WREG32_MC(RS690_MCCFG_FB_LOCATION, tmp);
89 /* FIXME: Does this reg exist on RS480,RS740 ? */
90 WREG32(0x310, rdev->mc.vram_location);
91 WREG32(RS690_HDP_FB_LOCATION, rdev->mc.vram_location >> 16);
92 return 0;
93}
94
95void rs690_mc_fini(struct radeon_device *rdev)
96{
97 rs400_gart_disable(rdev);
98 radeon_gart_table_ram_free(rdev);
99 radeon_gart_fini(rdev);
100}
101
102
103/*
104 * Global GPU functions
105 */
106int rs690_mc_wait_for_idle(struct radeon_device *rdev)
107{
108 unsigned i;
109 uint32_t tmp;
110
111 for (i = 0; i < rdev->usec_timeout; i++) {
112 /* read MC_STATUS */
113 tmp = RREG32_MC(RS690_MC_STATUS);
114 if (tmp & RS690_MC_STATUS_IDLE) {
115 return 0;
116 }
117 DRM_UDELAY(1);
118 }
119 return -1;
120}
121
122void rs690_errata(struct radeon_device *rdev)
123{
124 rdev->pll_errata = 0;
125}
126
127void rs690_gpu_init(struct radeon_device *rdev)
128{
129 /* FIXME: HDP same place on rs690 ? */
130 r100_hdp_reset(rdev);
131 rs600_disable_vga(rdev);
132 /* FIXME: is this correct ? */
133 r420_pipes_init(rdev);
134 if (rs690_mc_wait_for_idle(rdev)) {
135 printk(KERN_WARNING "Failed to wait MC idle while "
136 "programming pipes. Bad things might happen.\n");
137 }
138}
139
140
141/*
142 * VRAM info.
143 */
c93bb85b
JG
144void rs690_pm_info(struct radeon_device *rdev)
145{
146 int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo);
147 struct _ATOM_INTEGRATED_SYSTEM_INFO *info;
148 struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *info_v2;
149 void *ptr;
150 uint16_t data_offset;
151 uint8_t frev, crev;
152 fixed20_12 tmp;
153
154 atom_parse_data_header(rdev->mode_info.atom_context, index, NULL,
155 &frev, &crev, &data_offset);
156 ptr = rdev->mode_info.atom_context->bios + data_offset;
157 info = (struct _ATOM_INTEGRATED_SYSTEM_INFO *)ptr;
158 info_v2 = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 *)ptr;
159 /* Get various system informations from bios */
160 switch (crev) {
161 case 1:
162 tmp.full = rfixed_const(100);
163 rdev->pm.igp_sideport_mclk.full = rfixed_const(info->ulBootUpMemoryClock);
164 rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
165 rdev->pm.igp_system_mclk.full = rfixed_const(le16_to_cpu(info->usK8MemoryClock));
166 rdev->pm.igp_ht_link_clk.full = rfixed_const(le16_to_cpu(info->usFSBClock));
167 rdev->pm.igp_ht_link_width.full = rfixed_const(info->ucHTLinkWidth);
168 break;
169 case 2:
170 tmp.full = rfixed_const(100);
171 rdev->pm.igp_sideport_mclk.full = rfixed_const(info_v2->ulBootUpSidePortClock);
172 rdev->pm.igp_sideport_mclk.full = rfixed_div(rdev->pm.igp_sideport_mclk, tmp);
173 rdev->pm.igp_system_mclk.full = rfixed_const(info_v2->ulBootUpUMAClock);
174 rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
175 rdev->pm.igp_ht_link_clk.full = rfixed_const(info_v2->ulHTLinkFreq);
176 rdev->pm.igp_ht_link_clk.full = rfixed_div(rdev->pm.igp_ht_link_clk, tmp);
177 rdev->pm.igp_ht_link_width.full = rfixed_const(le16_to_cpu(info_v2->usMinHTLinkWidth));
178 break;
179 default:
180 tmp.full = rfixed_const(100);
181 /* We assume the slower possible clock ie worst case */
182 /* DDR 333Mhz */
183 rdev->pm.igp_sideport_mclk.full = rfixed_const(333);
184 /* FIXME: system clock ? */
185 rdev->pm.igp_system_mclk.full = rfixed_const(100);
186 rdev->pm.igp_system_mclk.full = rfixed_div(rdev->pm.igp_system_mclk, tmp);
187 rdev->pm.igp_ht_link_clk.full = rfixed_const(200);
188 rdev->pm.igp_ht_link_width.full = rfixed_const(8);
189 DRM_ERROR("No integrated system info for your GPU, using safe default\n");
190 break;
191 }
192 /* Compute various bandwidth */
193 /* k8_bandwidth = (memory_clk / 2) * 2 * 8 * 0.5 = memory_clk * 4 */
194 tmp.full = rfixed_const(4);
195 rdev->pm.k8_bandwidth.full = rfixed_mul(rdev->pm.igp_system_mclk, tmp);
196 /* ht_bandwidth = ht_clk * 2 * ht_width / 8 * 0.8
197 * = ht_clk * ht_width / 5
198 */
199 tmp.full = rfixed_const(5);
200 rdev->pm.ht_bandwidth.full = rfixed_mul(rdev->pm.igp_ht_link_clk,
201 rdev->pm.igp_ht_link_width);
202 rdev->pm.ht_bandwidth.full = rfixed_div(rdev->pm.ht_bandwidth, tmp);
203 if (tmp.full < rdev->pm.max_bandwidth.full) {
204 /* HT link is a limiting factor */
205 rdev->pm.max_bandwidth.full = tmp.full;
206 }
207 /* sideport_bandwidth = (sideport_clk / 2) * 2 * 2 * 0.7
208 * = (sideport_clk * 14) / 10
209 */
210 tmp.full = rfixed_const(14);
211 rdev->pm.sideport_bandwidth.full = rfixed_mul(rdev->pm.igp_sideport_mclk, tmp);
212 tmp.full = rfixed_const(10);
213 rdev->pm.sideport_bandwidth.full = rfixed_div(rdev->pm.sideport_bandwidth, tmp);
214}
215
771fe6b9
JG
216void rs690_vram_info(struct radeon_device *rdev)
217{
218 uint32_t tmp;
c93bb85b 219 fixed20_12 a;
771fe6b9
JG
220
221 rs400_gart_adjust_size(rdev);
222 /* DDR for all card after R300 & IGP */
223 rdev->mc.vram_is_ddr = true;
224 /* FIXME: is this correct for RS690/RS740 ? */
225 tmp = RREG32(RADEON_MEM_CNTL);
226 if (tmp & R300_MEM_NUM_CHANNELS_MASK) {
227 rdev->mc.vram_width = 128;
228 } else {
229 rdev->mc.vram_width = 64;
230 }
7a50f01a
DA
231 rdev->mc.real_vram_size = RREG32(RADEON_CONFIG_MEMSIZE);
232 rdev->mc.mc_vram_size = rdev->mc.real_vram_size;
771fe6b9
JG
233
234 rdev->mc.aper_base = drm_get_resource_start(rdev->ddev, 0);
235 rdev->mc.aper_size = drm_get_resource_len(rdev->ddev, 0);
c93bb85b
JG
236 rs690_pm_info(rdev);
237 /* FIXME: we should enforce default clock in case GPU is not in
238 * default setup
239 */
240 a.full = rfixed_const(100);
241 rdev->pm.sclk.full = rfixed_const(rdev->clock.default_sclk);
242 rdev->pm.sclk.full = rfixed_div(rdev->pm.sclk, a);
243 a.full = rfixed_const(16);
244 /* core_bandwidth = sclk(Mhz) * 16 */
245 rdev->pm.core_bandwidth.full = rfixed_div(rdev->pm.sclk, a);
246}
247
248void rs690_line_buffer_adjust(struct radeon_device *rdev,
249 struct drm_display_mode *mode1,
250 struct drm_display_mode *mode2)
251{
252 u32 tmp;
253
254 /*
255 * Line Buffer Setup
256 * There is a single line buffer shared by both display controllers.
257 * DC_LB_MEMORY_SPLIT controls how that line buffer is shared between
258 * the display controllers. The paritioning can either be done
259 * manually or via one of four preset allocations specified in bits 1:0:
260 * 0 - line buffer is divided in half and shared between crtc
261 * 1 - D1 gets 3/4 of the line buffer, D2 gets 1/4
262 * 2 - D1 gets the whole buffer
263 * 3 - D1 gets 1/4 of the line buffer, D2 gets 3/4
264 * Setting bit 2 of DC_LB_MEMORY_SPLIT controls switches to manual
265 * allocation mode. In manual allocation mode, D1 always starts at 0,
266 * D1 end/2 is specified in bits 14:4; D2 allocation follows D1.
267 */
268 tmp = RREG32(DC_LB_MEMORY_SPLIT) & ~DC_LB_MEMORY_SPLIT_MASK;
269 tmp &= ~DC_LB_MEMORY_SPLIT_SHIFT_MODE;
270 /* auto */
271 if (mode1 && mode2) {
272 if (mode1->hdisplay > mode2->hdisplay) {
273 if (mode1->hdisplay > 2560)
274 tmp |= DC_LB_MEMORY_SPLIT_D1_3Q_D2_1Q;
275 else
276 tmp |= DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
277 } else if (mode2->hdisplay > mode1->hdisplay) {
278 if (mode2->hdisplay > 2560)
279 tmp |= DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
280 else
281 tmp |= DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
282 } else
283 tmp |= AVIVO_DC_LB_MEMORY_SPLIT_D1HALF_D2HALF;
284 } else if (mode1) {
285 tmp |= DC_LB_MEMORY_SPLIT_D1_ONLY;
286 } else if (mode2) {
287 tmp |= DC_LB_MEMORY_SPLIT_D1_1Q_D2_3Q;
288 }
289 WREG32(DC_LB_MEMORY_SPLIT, tmp);
771fe6b9
JG
290}
291
c93bb85b
JG
292struct rs690_watermark {
293 u32 lb_request_fifo_depth;
294 fixed20_12 num_line_pair;
295 fixed20_12 estimated_width;
296 fixed20_12 worst_case_latency;
297 fixed20_12 consumption_rate;
298 fixed20_12 active_time;
299 fixed20_12 dbpp;
300 fixed20_12 priority_mark_max;
301 fixed20_12 priority_mark;
302 fixed20_12 sclk;
303};
304
305void rs690_crtc_bandwidth_compute(struct radeon_device *rdev,
306 struct radeon_crtc *crtc,
307 struct rs690_watermark *wm)
308{
309 struct drm_display_mode *mode = &crtc->base.mode;
310 fixed20_12 a, b, c;
311 fixed20_12 pclk, request_fifo_depth, tolerable_latency, estimated_width;
312 fixed20_12 consumption_time, line_time, chunk_time, read_delay_latency;
313 /* FIXME: detect IGP with sideport memory, i don't think there is any
314 * such product available
315 */
316 bool sideport = false;
317
318 if (!crtc->base.enabled) {
319 /* FIXME: wouldn't it better to set priority mark to maximum */
320 wm->lb_request_fifo_depth = 4;
321 return;
322 }
323
324 if (crtc->vsc.full > rfixed_const(2))
325 wm->num_line_pair.full = rfixed_const(2);
326 else
327 wm->num_line_pair.full = rfixed_const(1);
328
329 b.full = rfixed_const(mode->crtc_hdisplay);
330 c.full = rfixed_const(256);
331 a.full = rfixed_mul(wm->num_line_pair, b);
332 request_fifo_depth.full = rfixed_div(a, c);
333 if (a.full < rfixed_const(4)) {
334 wm->lb_request_fifo_depth = 4;
335 } else {
336 wm->lb_request_fifo_depth = rfixed_trunc(request_fifo_depth);
337 }
338
339 /* Determine consumption rate
340 * pclk = pixel clock period(ns) = 1000 / (mode.clock / 1000)
341 * vtaps = number of vertical taps,
342 * vsc = vertical scaling ratio, defined as source/destination
343 * hsc = horizontal scaling ration, defined as source/destination
344 */
345 a.full = rfixed_const(mode->clock);
346 b.full = rfixed_const(1000);
347 a.full = rfixed_div(a, b);
348 pclk.full = rfixed_div(b, a);
349 if (crtc->rmx_type != RMX_OFF) {
350 b.full = rfixed_const(2);
351 if (crtc->vsc.full > b.full)
352 b.full = crtc->vsc.full;
353 b.full = rfixed_mul(b, crtc->hsc);
354 c.full = rfixed_const(2);
355 b.full = rfixed_div(b, c);
356 consumption_time.full = rfixed_div(pclk, b);
357 } else {
358 consumption_time.full = pclk.full;
359 }
360 a.full = rfixed_const(1);
361 wm->consumption_rate.full = rfixed_div(a, consumption_time);
362
363
364 /* Determine line time
365 * LineTime = total time for one line of displayhtotal
366 * LineTime = total number of horizontal pixels
367 * pclk = pixel clock period(ns)
368 */
369 a.full = rfixed_const(crtc->base.mode.crtc_htotal);
370 line_time.full = rfixed_mul(a, pclk);
371
372 /* Determine active time
373 * ActiveTime = time of active region of display within one line,
374 * hactive = total number of horizontal active pixels
375 * htotal = total number of horizontal pixels
376 */
377 a.full = rfixed_const(crtc->base.mode.crtc_htotal);
378 b.full = rfixed_const(crtc->base.mode.crtc_hdisplay);
379 wm->active_time.full = rfixed_mul(line_time, b);
380 wm->active_time.full = rfixed_div(wm->active_time, a);
381
382 /* Maximun bandwidth is the minimun bandwidth of all component */
383 rdev->pm.max_bandwidth = rdev->pm.core_bandwidth;
384 if (sideport) {
385 if (rdev->pm.max_bandwidth.full > rdev->pm.sideport_bandwidth.full &&
386 rdev->pm.sideport_bandwidth.full)
387 rdev->pm.max_bandwidth = rdev->pm.sideport_bandwidth;
388 read_delay_latency.full = rfixed_const(370 * 800 * 1000);
389 read_delay_latency.full = rfixed_div(read_delay_latency,
390 rdev->pm.igp_sideport_mclk);
391 } else {
392 if (rdev->pm.max_bandwidth.full > rdev->pm.k8_bandwidth.full &&
393 rdev->pm.k8_bandwidth.full)
394 rdev->pm.max_bandwidth = rdev->pm.k8_bandwidth;
395 if (rdev->pm.max_bandwidth.full > rdev->pm.ht_bandwidth.full &&
396 rdev->pm.ht_bandwidth.full)
397 rdev->pm.max_bandwidth = rdev->pm.ht_bandwidth;
398 read_delay_latency.full = rfixed_const(5000);
399 }
400
401 /* sclk = system clocks(ns) = 1000 / max_bandwidth / 16 */
402 a.full = rfixed_const(16);
403 rdev->pm.sclk.full = rfixed_mul(rdev->pm.max_bandwidth, a);
404 a.full = rfixed_const(1000);
405 rdev->pm.sclk.full = rfixed_div(a, rdev->pm.sclk);
406 /* Determine chunk time
407 * ChunkTime = the time it takes the DCP to send one chunk of data
408 * to the LB which consists of pipeline delay and inter chunk gap
409 * sclk = system clock(ns)
410 */
411 a.full = rfixed_const(256 * 13);
412 chunk_time.full = rfixed_mul(rdev->pm.sclk, a);
413 a.full = rfixed_const(10);
414 chunk_time.full = rfixed_div(chunk_time, a);
415
416 /* Determine the worst case latency
417 * NumLinePair = Number of line pairs to request(1=2 lines, 2=4 lines)
418 * WorstCaseLatency = worst case time from urgent to when the MC starts
419 * to return data
420 * READ_DELAY_IDLE_MAX = constant of 1us
421 * ChunkTime = time it takes the DCP to send one chunk of data to the LB
422 * which consists of pipeline delay and inter chunk gap
423 */
424 if (rfixed_trunc(wm->num_line_pair) > 1) {
425 a.full = rfixed_const(3);
426 wm->worst_case_latency.full = rfixed_mul(a, chunk_time);
427 wm->worst_case_latency.full += read_delay_latency.full;
428 } else {
429 a.full = rfixed_const(2);
430 wm->worst_case_latency.full = rfixed_mul(a, chunk_time);
431 wm->worst_case_latency.full += read_delay_latency.full;
432 }
433
434 /* Determine the tolerable latency
435 * TolerableLatency = Any given request has only 1 line time
436 * for the data to be returned
437 * LBRequestFifoDepth = Number of chunk requests the LB can
438 * put into the request FIFO for a display
439 * LineTime = total time for one line of display
440 * ChunkTime = the time it takes the DCP to send one chunk
441 * of data to the LB which consists of
442 * pipeline delay and inter chunk gap
443 */
444 if ((2+wm->lb_request_fifo_depth) >= rfixed_trunc(request_fifo_depth)) {
445 tolerable_latency.full = line_time.full;
446 } else {
447 tolerable_latency.full = rfixed_const(wm->lb_request_fifo_depth - 2);
448 tolerable_latency.full = request_fifo_depth.full - tolerable_latency.full;
449 tolerable_latency.full = rfixed_mul(tolerable_latency, chunk_time);
450 tolerable_latency.full = line_time.full - tolerable_latency.full;
451 }
452 /* We assume worst case 32bits (4 bytes) */
453 wm->dbpp.full = rfixed_const(4 * 8);
454
455 /* Determine the maximum priority mark
456 * width = viewport width in pixels
457 */
458 a.full = rfixed_const(16);
459 wm->priority_mark_max.full = rfixed_const(crtc->base.mode.crtc_hdisplay);
460 wm->priority_mark_max.full = rfixed_div(wm->priority_mark_max, a);
461
462 /* Determine estimated width */
463 estimated_width.full = tolerable_latency.full - wm->worst_case_latency.full;
464 estimated_width.full = rfixed_div(estimated_width, consumption_time);
465 if (rfixed_trunc(estimated_width) > crtc->base.mode.crtc_hdisplay) {
466 wm->priority_mark.full = rfixed_const(10);
467 } else {
468 a.full = rfixed_const(16);
469 wm->priority_mark.full = rfixed_div(estimated_width, a);
470 wm->priority_mark.full = wm->priority_mark_max.full - wm->priority_mark.full;
471 }
472}
473
474void rs690_bandwidth_update(struct radeon_device *rdev)
475{
476 struct drm_display_mode *mode0 = NULL;
477 struct drm_display_mode *mode1 = NULL;
478 struct rs690_watermark wm0;
479 struct rs690_watermark wm1;
480 u32 tmp;
481 fixed20_12 priority_mark02, priority_mark12, fill_rate;
482 fixed20_12 a, b;
483
484 if (rdev->mode_info.crtcs[0]->base.enabled)
485 mode0 = &rdev->mode_info.crtcs[0]->base.mode;
486 if (rdev->mode_info.crtcs[1]->base.enabled)
487 mode1 = &rdev->mode_info.crtcs[1]->base.mode;
488 /*
489 * Set display0/1 priority up in the memory controller for
490 * modes if the user specifies HIGH for displaypriority
491 * option.
492 */
493 if (rdev->disp_priority == 2) {
494 tmp = RREG32_MC(MC_INIT_MISC_LAT_TIMER);
495 tmp &= ~MC_DISP1R_INIT_LAT_MASK;
496 tmp &= ~MC_DISP0R_INIT_LAT_MASK;
497 if (mode1)
498 tmp |= (1 << MC_DISP1R_INIT_LAT_SHIFT);
499 if (mode0)
500 tmp |= (1 << MC_DISP0R_INIT_LAT_SHIFT);
501 WREG32_MC(MC_INIT_MISC_LAT_TIMER, tmp);
502 }
503 rs690_line_buffer_adjust(rdev, mode0, mode1);
504
505 if ((rdev->family == CHIP_RS690) || (rdev->family == CHIP_RS740))
506 WREG32(DCP_CONTROL, 0);
507 if ((rdev->family == CHIP_RS780) || (rdev->family == CHIP_RS880))
508 WREG32(DCP_CONTROL, 2);
509
510 rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[0], &wm0);
511 rs690_crtc_bandwidth_compute(rdev, rdev->mode_info.crtcs[1], &wm1);
512
513 tmp = (wm0.lb_request_fifo_depth - 1);
514 tmp |= (wm1.lb_request_fifo_depth - 1) << 16;
515 WREG32(LB_MAX_REQ_OUTSTANDING, tmp);
516
517 if (mode0 && mode1) {
518 if (rfixed_trunc(wm0.dbpp) > 64)
519 a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair);
520 else
521 a.full = wm0.num_line_pair.full;
522 if (rfixed_trunc(wm1.dbpp) > 64)
523 b.full = rfixed_mul(wm1.dbpp, wm1.num_line_pair);
524 else
525 b.full = wm1.num_line_pair.full;
526 a.full += b.full;
527 fill_rate.full = rfixed_div(wm0.sclk, a);
528 if (wm0.consumption_rate.full > fill_rate.full) {
529 b.full = wm0.consumption_rate.full - fill_rate.full;
530 b.full = rfixed_mul(b, wm0.active_time);
531 a.full = rfixed_mul(wm0.worst_case_latency,
532 wm0.consumption_rate);
533 a.full = a.full + b.full;
534 b.full = rfixed_const(16 * 1000);
535 priority_mark02.full = rfixed_div(a, b);
536 } else {
537 a.full = rfixed_mul(wm0.worst_case_latency,
538 wm0.consumption_rate);
539 b.full = rfixed_const(16 * 1000);
540 priority_mark02.full = rfixed_div(a, b);
541 }
542 if (wm1.consumption_rate.full > fill_rate.full) {
543 b.full = wm1.consumption_rate.full - fill_rate.full;
544 b.full = rfixed_mul(b, wm1.active_time);
545 a.full = rfixed_mul(wm1.worst_case_latency,
546 wm1.consumption_rate);
547 a.full = a.full + b.full;
548 b.full = rfixed_const(16 * 1000);
549 priority_mark12.full = rfixed_div(a, b);
550 } else {
551 a.full = rfixed_mul(wm1.worst_case_latency,
552 wm1.consumption_rate);
553 b.full = rfixed_const(16 * 1000);
554 priority_mark12.full = rfixed_div(a, b);
555 }
556 if (wm0.priority_mark.full > priority_mark02.full)
557 priority_mark02.full = wm0.priority_mark.full;
558 if (rfixed_trunc(priority_mark02) < 0)
559 priority_mark02.full = 0;
560 if (wm0.priority_mark_max.full > priority_mark02.full)
561 priority_mark02.full = wm0.priority_mark_max.full;
562 if (wm1.priority_mark.full > priority_mark12.full)
563 priority_mark12.full = wm1.priority_mark.full;
564 if (rfixed_trunc(priority_mark12) < 0)
565 priority_mark12.full = 0;
566 if (wm1.priority_mark_max.full > priority_mark12.full)
567 priority_mark12.full = wm1.priority_mark_max.full;
568 WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
569 WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
570 WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
571 WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
572 } else if (mode0) {
573 if (rfixed_trunc(wm0.dbpp) > 64)
574 a.full = rfixed_mul(wm0.dbpp, wm0.num_line_pair);
575 else
576 a.full = wm0.num_line_pair.full;
577 fill_rate.full = rfixed_div(wm0.sclk, a);
578 if (wm0.consumption_rate.full > fill_rate.full) {
579 b.full = wm0.consumption_rate.full - fill_rate.full;
580 b.full = rfixed_mul(b, wm0.active_time);
581 a.full = rfixed_mul(wm0.worst_case_latency,
582 wm0.consumption_rate);
583 a.full = a.full + b.full;
584 b.full = rfixed_const(16 * 1000);
585 priority_mark02.full = rfixed_div(a, b);
586 } else {
587 a.full = rfixed_mul(wm0.worst_case_latency,
588 wm0.consumption_rate);
589 b.full = rfixed_const(16 * 1000);
590 priority_mark02.full = rfixed_div(a, b);
591 }
592 if (wm0.priority_mark.full > priority_mark02.full)
593 priority_mark02.full = wm0.priority_mark.full;
594 if (rfixed_trunc(priority_mark02) < 0)
595 priority_mark02.full = 0;
596 if (wm0.priority_mark_max.full > priority_mark02.full)
597 priority_mark02.full = wm0.priority_mark_max.full;
598 WREG32(D1MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark02));
599 WREG32(D1MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark02));
600 WREG32(D2MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
601 WREG32(D2MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
602 } else {
603 if (rfixed_trunc(wm1.dbpp) > 64)
604 a.full = rfixed_mul(wm1.dbpp, wm1.num_line_pair);
605 else
606 a.full = wm1.num_line_pair.full;
607 fill_rate.full = rfixed_div(wm1.sclk, a);
608 if (wm1.consumption_rate.full > fill_rate.full) {
609 b.full = wm1.consumption_rate.full - fill_rate.full;
610 b.full = rfixed_mul(b, wm1.active_time);
611 a.full = rfixed_mul(wm1.worst_case_latency,
612 wm1.consumption_rate);
613 a.full = a.full + b.full;
614 b.full = rfixed_const(16 * 1000);
615 priority_mark12.full = rfixed_div(a, b);
616 } else {
617 a.full = rfixed_mul(wm1.worst_case_latency,
618 wm1.consumption_rate);
619 b.full = rfixed_const(16 * 1000);
620 priority_mark12.full = rfixed_div(a, b);
621 }
622 if (wm1.priority_mark.full > priority_mark12.full)
623 priority_mark12.full = wm1.priority_mark.full;
624 if (rfixed_trunc(priority_mark12) < 0)
625 priority_mark12.full = 0;
626 if (wm1.priority_mark_max.full > priority_mark12.full)
627 priority_mark12.full = wm1.priority_mark_max.full;
628 WREG32(D1MODE_PRIORITY_A_CNT, MODE_PRIORITY_OFF);
629 WREG32(D1MODE_PRIORITY_B_CNT, MODE_PRIORITY_OFF);
630 WREG32(D2MODE_PRIORITY_A_CNT, rfixed_trunc(priority_mark12));
631 WREG32(D2MODE_PRIORITY_B_CNT, rfixed_trunc(priority_mark12));
632 }
633}
771fe6b9
JG
634
635/*
636 * Indirect registers accessor
637 */
638uint32_t rs690_mc_rreg(struct radeon_device *rdev, uint32_t reg)
639{
640 uint32_t r;
641
642 WREG32(RS690_MC_INDEX, (reg & RS690_MC_INDEX_MASK));
643 r = RREG32(RS690_MC_DATA);
644 WREG32(RS690_MC_INDEX, RS690_MC_INDEX_MASK);
645 return r;
646}
647
648void rs690_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
649{
650 WREG32(RS690_MC_INDEX,
651 RS690_MC_INDEX_WR_EN | ((reg) & RS690_MC_INDEX_MASK));
652 WREG32(RS690_MC_DATA, v);
653 WREG32(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK);
654}
616b8434
JG
655
656static const unsigned rs690_reg_safe_bm[219] = {
657 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
658 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
659 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
660 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
661 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
662 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
663 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
664 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
665 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
666 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
667 0x17FF1FFF,0xFFFFFFFC,0xFFFFFFFF,0xFF30FFBF,
668 0xFFFFFFF8,0xC3E6FFFF,0xFFFFF6DF,0xFFFFFFFF,
669 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
670 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
671 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFF03F,
672 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
673 0xFFFFFFFF,0xFFFFEFCE,0xF00EBFFF,0x007C0000,
674 0xF0000078,0xFF000009,0xFFFFFFFF,0xFFFFFFFF,
675 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
676 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
677 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
678 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
679 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
680 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
681 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
682 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
683 0xFFFFF7FF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
684 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
685 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
686 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
687 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
688 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
689 0xFFFFFC78,0xFFFFFFFF,0xFFFFFFFE,0xFFFFFFFF,
690 0x38FF8F50,0xFFF88082,0xF000000C,0xFAE009FF,
691 0x0000FFFF,0xFFFFFFFF,0xFFFFFFFF,0x00000000,
692 0x00000000,0x0000C100,0x00000000,0x00000000,
693 0x00000000,0x00000000,0x00000000,0x00000000,
694 0x00000000,0xFFFF0000,0xFFFFFFFF,0xFF80FFFF,
695 0x00000000,0x00000000,0x00000000,0x00000000,
696 0x0003FC01,0xFFFFFFF8,0xFE800B19,0xFFFFFFFF,
697 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
698 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
699 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
700 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
701 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
702 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
703 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
704 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
705 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
706 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
707 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
708 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
709 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
710 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
711 0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,
712};
713
714int rs690_init(struct radeon_device *rdev)
715{
716 rdev->config.r300.reg_safe_bm = rs690_reg_safe_bm;
717 rdev->config.r300.reg_safe_bm_size = ARRAY_SIZE(rs690_reg_safe_bm);
718 return 0;
719}