Subversion Repositories Kolibri OS

Rev

Rev 1120 | Rev 1125 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1117 serge 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 
1123 serge 29
 
30
#include 
1117 serge 31
//#include 
32
#include "radeon_drm.h"
33
#include "radeon_reg.h"
34
#include "radeon.h"
35
#include "radeon_asic.h"
36
#include "atom.h"
37
 
38
#include 
39
 
1123 serge 40
int radeon_modeset = -1;
1117 serge 41
int radeon_dynclks = -1;
1123 serge 42
int radeon_r4xx_atom = 0;
43
int radeon_agpmode = 0;
44
int radeon_vram_limit = 0;
1117 serge 45
int radeon_gart_size = 512; /* default gart size */
1123 serge 46
int radeon_benchmarking = 0;
47
int radeon_connector_table = 0;
1117 serge 48
 
49
 
50
/*
51
 * Clear GPU surface registers.
52
 */
53
static void radeon_surface_init(struct radeon_device *rdev)
54
{
1120 serge 55
    dbgprintf("%s\n",__FUNCTION__);
1117 serge 56
 
57
    /* FIXME: check this out */
58
    if (rdev->family < CHIP_R600) {
59
        int i;
60
 
61
        for (i = 0; i < 8; i++) {
62
            WREG32(RADEON_SURFACE0_INFO +
63
                   i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO),
64
                   0);
65
        }
66
    }
67
}
68
 
69
/*
70
 * GPU scratch registers helpers function.
71
 */
72
static void radeon_scratch_init(struct radeon_device *rdev)
73
{
74
    int i;
75
 
76
    /* FIXME: check this out */
77
    if (rdev->family < CHIP_R300) {
78
        rdev->scratch.num_reg = 5;
79
    } else {
80
        rdev->scratch.num_reg = 7;
81
    }
82
    for (i = 0; i < rdev->scratch.num_reg; i++) {
83
        rdev->scratch.free[i] = true;
84
        rdev->scratch.reg[i] = RADEON_SCRATCH_REG0 + (i * 4);
85
    }
86
}
87
 
88
int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg)
89
{
90
	int i;
91
 
92
	for (i = 0; i < rdev->scratch.num_reg; i++) {
93
		if (rdev->scratch.free[i]) {
94
			rdev->scratch.free[i] = false;
95
			*reg = rdev->scratch.reg[i];
96
			return 0;
97
		}
98
	}
99
	return -EINVAL;
100
}
101
 
102
void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
103
{
104
	int i;
105
 
106
	for (i = 0; i < rdev->scratch.num_reg; i++) {
107
		if (rdev->scratch.reg[i] == reg) {
108
			rdev->scratch.free[i] = true;
109
			return;
110
		}
111
	}
112
}
113
 
114
/*
115
 * MC common functions
116
 */
117
int radeon_mc_setup(struct radeon_device *rdev)
118
{
119
	uint32_t tmp;
120
 
121
	/* Some chips have an "issue" with the memory controller, the
122
	 * location must be aligned to the size. We just align it down,
123
	 * too bad if we walk over the top of system memory, we don't
124
	 * use DMA without a remapped anyway.
125
	 * Affected chips are rv280, all r3xx, and all r4xx, but not IGP
126
	 */
127
	/* FGLRX seems to setup like this, VRAM a 0, then GART.
128
	 */
129
/*
130
	 * Note: from R6xx the address space is 40bits but here we only
131
	 * use 32bits (still have to see a card which would exhaust 4G
132
	 * address space).
133
	 */
134
	if (rdev->mc.vram_location != 0xFFFFFFFFUL) {
135
		/* vram location was already setup try to put gtt after
136
		 * if it fits */
137
		tmp = rdev->mc.vram_location + rdev->mc.vram_size;
138
		tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
139
		if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
140
			rdev->mc.gtt_location = tmp;
141
		} else {
142
			if (rdev->mc.gtt_size >= rdev->mc.vram_location) {
143
				printk(KERN_ERR "[drm] GTT too big to fit "
144
				       "before or after vram location.\n");
145
				return -EINVAL;
146
			}
147
			rdev->mc.gtt_location = 0;
148
		}
149
	} else if (rdev->mc.gtt_location != 0xFFFFFFFFUL) {
150
		/* gtt location was already setup try to put vram before
151
		 * if it fits */
152
		if (rdev->mc.vram_size < rdev->mc.gtt_location) {
153
			rdev->mc.vram_location = 0;
154
		} else {
155
			tmp = rdev->mc.gtt_location + rdev->mc.gtt_size;
156
			tmp += (rdev->mc.vram_size - 1);
157
			tmp &= ~(rdev->mc.vram_size - 1);
158
			if ((0xFFFFFFFFUL - tmp) >= rdev->mc.vram_size) {
159
				rdev->mc.vram_location = tmp;
160
			} else {
161
				printk(KERN_ERR "[drm] vram too big to fit "
162
				       "before or after GTT location.\n");
163
				return -EINVAL;
164
			}
165
		}
166
	} else {
167
		rdev->mc.vram_location = 0;
168
		rdev->mc.gtt_location = rdev->mc.vram_size;
169
	}
170
	DRM_INFO("radeon: VRAM %uM\n", rdev->mc.vram_size >> 20);
171
	DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
172
		 rdev->mc.vram_location,
173
		 rdev->mc.vram_location + rdev->mc.vram_size - 1);
174
	DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20);
175
	DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
176
		 rdev->mc.gtt_location,
177
		 rdev->mc.gtt_location + rdev->mc.gtt_size - 1);
178
	return 0;
179
}
180
 
181
 
182
/*
183
 * GPU helpers function.
184
 */
185
static bool radeon_card_posted(struct radeon_device *rdev)
186
{
187
	uint32_t reg;
188
 
1120 serge 189
    dbgprintf("%s\n",__FUNCTION__);
1117 serge 190
 
191
	/* first check CRTCs */
192
	if (ASIC_IS_AVIVO(rdev)) {
193
		reg = RREG32(AVIVO_D1CRTC_CONTROL) |
194
		      RREG32(AVIVO_D2CRTC_CONTROL);
195
		if (reg & AVIVO_CRTC_EN) {
196
			return true;
197
		}
198
	} else {
199
		reg = RREG32(RADEON_CRTC_GEN_CNTL) |
200
		      RREG32(RADEON_CRTC2_GEN_CNTL);
201
		if (reg & RADEON_CRTC_EN) {
202
			return true;
203
		}
204
	}
205
 
206
	/* then check MEM_SIZE, in case the crtcs are off */
207
	if (rdev->family >= CHIP_R600)
208
		reg = RREG32(R600_CONFIG_MEMSIZE);
209
	else
210
		reg = RREG32(RADEON_CONFIG_MEMSIZE);
211
 
212
	if (reg)
213
		return true;
214
 
215
	return false;
216
 
217
}
218
 
219
 
220
/*
221
 * Registers accessors functions.
222
 */
223
uint32_t radeon_invalid_rreg(struct radeon_device *rdev, uint32_t reg)
224
{
225
    DRM_ERROR("Invalid callback to read register 0x%04X\n", reg);
226
    BUG_ON(1);
227
    return 0;
228
}
229
 
230
void radeon_invalid_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v)
231
{
232
    DRM_ERROR("Invalid callback to write register 0x%04X with 0x%08X\n",
233
          reg, v);
234
    BUG_ON(1);
235
}
236
 
237
void radeon_register_accessor_init(struct radeon_device *rdev)
238
{
239
 
1120 serge 240
    dbgprintf("%s\n",__FUNCTION__);
1117 serge 241
 
242
    rdev->mm_rreg = &r100_mm_rreg;
243
    rdev->mm_wreg = &r100_mm_wreg;
244
    rdev->mc_rreg = &radeon_invalid_rreg;
245
    rdev->mc_wreg = &radeon_invalid_wreg;
246
    rdev->pll_rreg = &radeon_invalid_rreg;
247
    rdev->pll_wreg = &radeon_invalid_wreg;
248
    rdev->pcie_rreg = &radeon_invalid_rreg;
249
    rdev->pcie_wreg = &radeon_invalid_wreg;
250
    rdev->pciep_rreg = &radeon_invalid_rreg;
251
    rdev->pciep_wreg = &radeon_invalid_wreg;
252
 
253
    /* Don't change order as we are overridding accessor. */
254
    if (rdev->family < CHIP_RV515) {
255
//        rdev->pcie_rreg = &rv370_pcie_rreg;
256
//        rdev->pcie_wreg = &rv370_pcie_wreg;
257
    }
258
    if (rdev->family >= CHIP_RV515) {