Subversion Repositories Kolibri OS

Rev

Rev 1125 | Rev 1128 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1125 Rev 1126
1
/*
1
/*
2
 * Copyright 2008 Advanced Micro Devices, Inc.
2
 * Copyright 2008 Advanced Micro Devices, Inc.
3
 * Copyright 2008 Red Hat Inc.
3
 * Copyright 2008 Red Hat Inc.
4
 * Copyright 2009 Jerome Glisse.
4
 * Copyright 2009 Jerome Glisse.
5
 *
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a
6
 * Permission is hereby granted, free of charge, to any person obtaining a
7
 * copy of this software and associated documentation files (the "Software"),
7
 * copy of this software and associated documentation files (the "Software"),
8
 * to deal in the Software without restriction, including without limitation
8
 * to deal in the Software without restriction, including without limitation
9
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
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
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:
11
 * Software is furnished to do so, subject to the following conditions:
12
 *
12
 *
13
 * The above copyright notice and this permission notice shall be included in
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
14
 * all copies or substantial portions of the Software.
15
 *
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
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,
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
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
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,
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
21
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22
 * OTHER DEALINGS IN THE SOFTWARE.
22
 * OTHER DEALINGS IN THE SOFTWARE.
23
 *
23
 *
24
 * Authors: Dave Airlie
24
 * Authors: Dave Airlie
25
 *          Alex Deucher
25
 *          Alex Deucher
26
 *          Jerome Glisse
26
 *          Jerome Glisse
27
 */
27
 */
28
//#include 
28
//#include 
29
 
29
 
30
#include 
30
#include 
31
//#include 
31
#include 
32
#include "radeon_drm.h"
32
#include "radeon_drm.h"
33
#include "radeon_reg.h"
33
#include "radeon_reg.h"
34
#include "radeon.h"
34
#include "radeon.h"
35
#include "radeon_asic.h"
35
#include "radeon_asic.h"
36
#include "atom.h"
36
#include "atom.h"
37
 
37
 
38
#include 
38
#include 
39
 
39
 
40
int radeon_dynclks = -1;
40
int radeon_dynclks = -1;
41
int radeon_r4xx_atom = 0;
41
int radeon_r4xx_atom = 0;
42
int radeon_agpmode   = -1;
42
int radeon_agpmode   = -1;
43
int radeon_gart_size = 512; /* default gart size */
43
int radeon_gart_size = 512; /* default gart size */
44
int radeon_benchmarking = 0;
44
int radeon_benchmarking = 0;
45
int radeon_connector_table = 0;
45
int radeon_connector_table = 0;
46
 
46
 
47
 
47
 
48
/*
48
/*
49
 * Clear GPU surface registers.
49
 * Clear GPU surface registers.
50
 */
50
 */
51
static void radeon_surface_init(struct radeon_device *rdev)
51
static void radeon_surface_init(struct radeon_device *rdev)
52
{
52
{
53
    dbgprintf("%s\n",__FUNCTION__);
53
    dbgprintf("%s\n",__FUNCTION__);
54
 
54
 
55
    /* FIXME: check this out */
55
    /* FIXME: check this out */
56
    if (rdev->family < CHIP_R600) {
56
    if (rdev->family < CHIP_R600) {
57
        int i;
57
        int i;
58
 
58
 
59
        for (i = 0; i < 8; i++) {
59
        for (i = 0; i < 8; i++) {
60
            WREG32(RADEON_SURFACE0_INFO +
60
            WREG32(RADEON_SURFACE0_INFO +
61
                   i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO),
61
                   i * (RADEON_SURFACE1_INFO - RADEON_SURFACE0_INFO),
62
                   0);
62
                   0);
63
        }
63
        }
64
    }
64
    }
65
}
65
}
66
 
66
 
67
/*
67
/*
68
 * GPU scratch registers helpers function.
68
 * GPU scratch registers helpers function.
69
 */
69
 */
70
static void radeon_scratch_init(struct radeon_device *rdev)
70
static void radeon_scratch_init(struct radeon_device *rdev)
71
{
71
{
72
    int i;
72
    int i;
73
 
73
 
74
    /* FIXME: check this out */
74
    /* FIXME: check this out */
75
    if (rdev->family < CHIP_R300) {
75
    if (rdev->family < CHIP_R300) {
76
        rdev->scratch.num_reg = 5;
76
        rdev->scratch.num_reg = 5;
77
    } else {
77
    } else {
78
        rdev->scratch.num_reg = 7;
78
        rdev->scratch.num_reg = 7;
79
    }
79
    }
80
    for (i = 0; i < rdev->scratch.num_reg; i++) {
80
    for (i = 0; i < rdev->scratch.num_reg; i++) {
81
        rdev->scratch.free[i] = true;
81
        rdev->scratch.free[i] = true;
82
        rdev->scratch.reg[i] = RADEON_SCRATCH_REG0 + (i * 4);
82
        rdev->scratch.reg[i] = RADEON_SCRATCH_REG0 + (i * 4);
83
    }
83
    }
84
}
84
}
85
 
85
 
86
int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg)
86
int radeon_scratch_get(struct radeon_device *rdev, uint32_t *reg)
87
{
87
{
88
	int i;
88
	int i;
89
 
89
 
90
	for (i = 0; i < rdev->scratch.num_reg; i++) {
90
	for (i = 0; i < rdev->scratch.num_reg; i++) {
91
		if (rdev->scratch.free[i]) {
91
		if (rdev->scratch.free[i]) {
92
			rdev->scratch.free[i] = false;
92
			rdev->scratch.free[i] = false;
93
			*reg = rdev->scratch.reg[i];
93
			*reg = rdev->scratch.reg[i];
94
			return 0;
94
			return 0;
95
		}
95
		}
96
	}
96
	}
97
	return -EINVAL;
97
	return -EINVAL;
98
}
98
}
99
 
99
 
100
void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
100
void radeon_scratch_free(struct radeon_device *rdev, uint32_t reg)
101
{
101
{
102
	int i;
102
	int i;
103
 
103
 
104
	for (i = 0; i < rdev->scratch.num_reg; i++) {
104
	for (i = 0; i < rdev->scratch.num_reg; i++) {
105
		if (rdev->scratch.reg[i] == reg) {
105
		if (rdev->scratch.reg[i] == reg) {
106
			rdev->scratch.free[i] = true;
106
			rdev->scratch.free[i] = true;
107
			return;
107
			return;
108
		}
108
		}
109
	}
109
	}
110
}
110
}
111
 
111
 
112
/*
112
/*
113
 * MC common functions
113
 * MC common functions
114
 */
114
 */
115
int radeon_mc_setup(struct radeon_device *rdev)
115
int radeon_mc_setup(struct radeon_device *rdev)
116
{
116
{
117
	uint32_t tmp;
117
	uint32_t tmp;
118
 
118
 
119
	/* Some chips have an "issue" with the memory controller, the
119
	/* Some chips have an "issue" with the memory controller, the
120
	 * location must be aligned to the size. We just align it down,
120
	 * location must be aligned to the size. We just align it down,
121
	 * too bad if we walk over the top of system memory, we don't
121
	 * too bad if we walk over the top of system memory, we don't
122
	 * use DMA without a remapped anyway.
122
	 * use DMA without a remapped anyway.
123
	 * Affected chips are rv280, all r3xx, and all r4xx, but not IGP
123
	 * Affected chips are rv280, all r3xx, and all r4xx, but not IGP
124
	 */
124
	 */
125
	/* FGLRX seems to setup like this, VRAM a 0, then GART.
125
	/* FGLRX seems to setup like this, VRAM a 0, then GART.
126
	 */
126
	 */
127
/*
127
	/*
128
	 * Note: from R6xx the address space is 40bits but here we only
128
	 * Note: from R6xx the address space is 40bits but here we only
129
	 * use 32bits (still have to see a card which would exhaust 4G
129
	 * use 32bits (still have to see a card which would exhaust 4G
130
	 * address space).
130
	 * address space).
131
	 */
131
	 */
132
	if (rdev->mc.vram_location != 0xFFFFFFFFUL) {
132
	if (rdev->mc.vram_location != 0xFFFFFFFFUL) {
133
		/* vram location was already setup try to put gtt after
133
		/* vram location was already setup try to put gtt after
134
		 * if it fits */
134
		 * if it fits */
135
		tmp = rdev->mc.vram_location + rdev->mc.vram_size;
135
		tmp = rdev->mc.vram_location + rdev->mc.vram_size;
136
		tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
136
		tmp = (tmp + rdev->mc.gtt_size - 1) & ~(rdev->mc.gtt_size - 1);
137
		if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
137
		if ((0xFFFFFFFFUL - tmp) >= rdev->mc.gtt_size) {
138
			rdev->mc.gtt_location = tmp;
138
			rdev->mc.gtt_location = tmp;
139
		} else {
139
		} else {
140
			if (rdev->mc.gtt_size >= rdev->mc.vram_location) {
140
			if (rdev->mc.gtt_size >= rdev->mc.vram_location) {
141
				printk(KERN_ERR "[drm] GTT too big to fit "
141
				printk(KERN_ERR "[drm] GTT too big to fit "
142
				       "before or after vram location.\n");
142
				       "before or after vram location.\n");
143
				return -EINVAL;
143
				return -EINVAL;
144
			}
144
			}
145
			rdev->mc.gtt_location = 0;
145
			rdev->mc.gtt_location = 0;
146
		}
146
		}
147
	} else if (rdev->mc.gtt_location != 0xFFFFFFFFUL) {
147
	} else if (rdev->mc.gtt_location != 0xFFFFFFFFUL) {
148
		/* gtt location was already setup try to put vram before
148
		/* gtt location was already setup try to put vram before
149
		 * if it fits */
149
		 * if it fits */
150
		if (rdev->mc.vram_size < rdev->mc.gtt_location) {
150
		if (rdev->mc.vram_size < rdev->mc.gtt_location) {
151
			rdev->mc.vram_location = 0;
151
			rdev->mc.vram_location = 0;
152
		} else {
152
		} else {
153
			tmp = rdev->mc.gtt_location + rdev->mc.gtt_size;
153
			tmp = rdev->mc.gtt_location + rdev->mc.gtt_size;
154
			tmp += (rdev->mc.vram_size - 1);
154
			tmp += (rdev->mc.vram_size - 1);
155
			tmp &= ~(rdev->mc.vram_size - 1);
155
			tmp &= ~(rdev->mc.vram_size - 1);
156
			if ((0xFFFFFFFFUL - tmp) >= rdev->mc.vram_size) {
156
			if ((0xFFFFFFFFUL - tmp) >= rdev->mc.vram_size) {
157
				rdev->mc.vram_location = tmp;
157
				rdev->mc.vram_location = tmp;
158
			} else {
158
			} else {
159
				printk(KERN_ERR "[drm] vram too big to fit "
159
				printk(KERN_ERR "[drm] vram too big to fit "
160
				       "before or after GTT location.\n");
160
				       "before or after GTT location.\n");
161
				return -EINVAL;
161
				return -EINVAL;
162
			}
162
			}
163
		}
163
		}
164
	} else {
164
	} else {
165
		rdev->mc.vram_location = 0;
165
		rdev->mc.vram_location = 0;
166
		rdev->mc.gtt_location = rdev->mc.vram_size;
166
		rdev->mc.gtt_location = rdev->mc.vram_size;
167
	}
167
	}
168
	DRM_INFO("radeon: VRAM %uM\n", rdev->mc.vram_size >> 20);
168
	DRM_INFO("radeon: VRAM %uM\n", rdev->mc.vram_size >> 20);
169
	DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
169
	DRM_INFO("radeon: VRAM from 0x%08X to 0x%08X\n",
170
		 rdev->mc.vram_location,
170
		 rdev->mc.vram_location,
171
		 rdev->mc.vram_location + rdev->mc.vram_size - 1);
171
		 rdev->mc.vram_location + rdev->mc.vram_size - 1);
172
	DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20);
172
	DRM_INFO("radeon: GTT %uM\n", rdev->mc.gtt_size >> 20);
173
	DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
173
	DRM_INFO("radeon: GTT from 0x%08X to 0x%08X\n",
174
		 rdev->mc.gtt_location,
174
		 rdev->mc.gtt_location,
175
		 rdev->mc.gtt_location + rdev->mc.gtt_size - 1);
175
		 rdev->mc.gtt_location + rdev->mc.gtt_size - 1);
176
	return 0;
176
	return 0;
177
}
177
}
178
 
178
 
179
 
179
 
180
/*
180
/*
181
 * GPU helpers function.
181
 * GPU helpers function.
182
 */
182
 */
183
static bool radeon_card_posted(struct radeon_device *rdev)
183
static bool radeon_card_posted(struct radeon_device *rdev)
184
{
184
{
185
	uint32_t reg;
185
	uint32_t reg;
186
 
186
 
187
    dbgprintf("%s\n",__FUNCTION__);
187
    dbgprintf("%s\n",__FUNCTION__);
188
 
188
 
189
	/* first check CRTCs */
189
	/* first check CRTCs */
190
	if (ASIC_IS_AVIVO(rdev)) {
190
	if (ASIC_IS_AVIVO(rdev)) {
191
		reg = RREG32(AVIVO_D1CRTC_CONTROL) |
191
		reg = RREG32(AVIVO_D1CRTC_CONTROL) |
192
		      RREG32(AVIVO_D2CRTC_CONTROL);
192
		      RREG32(AVIVO_D2CRTC_CONTROL);
193
		if (reg & AVIVO_CRTC_EN) {
193
		if (reg & AVIVO_CRTC_EN) {
194
			return true;
194
			return true;
195
		}
195
		}
196
	} else {
196
	} else {
197
		reg = RREG32(RADEON_CRTC_GEN_CNTL) |
197
		reg = RREG32(RADEON_CRTC_GEN_CNTL) |
198
		      RREG32(RADEON_CRTC2_GEN_CNTL);
198
		      RREG32(RADEON_CRTC2_GEN_CNTL);
199
		if (reg & RADEON_CRTC_EN) {
199
		if (reg & RADEON_CRTC_EN) {
200
			return true;
200
			return true;
201
		}
201
		}
202
	}
202
	}
203
 
203
 
204
	/* then check MEM_SIZE, in case the crtcs are off */
204
	/* then check MEM_SIZE, in case the crtcs are off */
205
	if (rdev->family >= CHIP_R600)
205
	if (rdev->family >= CHIP_R600)
206
		reg = RREG32(R600_CONFIG_MEMSIZE);
206
		reg = RREG32(R600_CONFIG_MEMSIZE);
207
	else
207
	else
208
		reg = RREG32(RADEON_CONFIG_MEMSIZE);
208
		reg = RREG32(RADEON_CONFIG_MEMSIZE);