Subversion Repositories Kolibri OS

Rev

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

Rev 2160 Rev 2997
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 "drmP.h"
28
#include 
29
#include "drm_crtc_helper.h"
29
#include 
30
#include "radeon_drm.h"
30
#include 
31
#include "radeon_reg.h"
31
#include "radeon_reg.h"
32
#include "radeon.h"
32
#include "radeon.h"
33
#include "atom.h"
33
#include "atom.h"
-
 
34
 
-
 
35
#define RADEON_WAIT_IDLE_TIMEOUT 200
34
 
36
 
35
struct radeon_device *main_device;
37
struct radeon_device *main_device;
36
 
38
 
37
extern int irq_override;
39
extern int irq_override;
-
 
40
 
-
 
41
 
-
 
42
/**
-
 
43
 * radeon_driver_irq_handler_kms - irq handler for KMS
-
 
44
 *
-
 
45
 * @DRM_IRQ_ARGS: args
-
 
46
 *
-
 
47
 * This is the irq handler for the radeon KMS driver (all asics).
-
 
48
 * radeon_irq_process is a macro that points to the per-asic
-
 
49
 * irq handler callback.
38
 
50
 */
39
void irq_handler_kms()
51
void irq_handler_kms()
40
{
-
 
41
//    dbgprintf("%s\n",__FUNCTION__);
52
{
42
    radeon_irq_process(main_device);
53
    radeon_irq_process(main_device);
43
}
54
}
-
 
55
 
-
 
56
/**
-
 
57
 * radeon_driver_irq_preinstall_kms - drm irq preinstall callback
-
 
58
 *
44
 
59
 * @dev: drm dev pointer
-
 
60
 *
-
 
61
 * Gets the hw ready to enable irqs (all asics).
-
 
62
 * This function disables all interrupt sources on the GPU.
45
 
63
 */
46
static void radeon_irq_preinstall(struct radeon_device *rdev)
64
void radeon_irq_preinstall_kms(struct radeon_device *rdev)
-
 
65
{
47
{
66
	unsigned long irqflags;
-
 
67
    unsigned i;
48
    unsigned i;
68
 
49
 
-
 
50
    /* Disable *all* interrupts */
-
 
51
    rdev->irq.sw_int = false;
69
	spin_lock_irqsave(&rdev->irq.lock, irqflags);
52
    rdev->irq.gui_idle = false;
70
    /* Disable *all* interrupts */
53
    for (i = 0; i < rdev->num_crtc; i++)
71
	for (i = 0; i < RADEON_NUM_RINGS; i++)
54
        rdev->irq.crtc_vblank_int[i] = false;
72
		atomic_set(&rdev->irq.ring_int[i], 0);
-
 
73
	for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
55
    for (i = 0; i < 6; i++) {
74
		rdev->irq.hpd[i] = false;
-
 
75
	for (i = 0; i < RADEON_MAX_CRTCS; i++) {
-
 
76
        rdev->irq.crtc_vblank_int[i] = false;
56
        rdev->irq.hpd[i] = false;
77
		atomic_set(&rdev->irq.pflip[i], 0);
57
        rdev->irq.pflip[i] = false;
78
		rdev->irq.afmt[i] = false;
-
 
79
    }
58
    }
80
    radeon_irq_set(rdev);
59
    radeon_irq_set(rdev);
81
	spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
60
    /* Clear bits */
82
    /* Clear bits */
61
    radeon_irq_process(rdev);
83
    radeon_irq_process(rdev);
62
}
84
}
-
 
85
 
-
 
86
/**
-
 
87
 * radeon_driver_irq_postinstall_kms - drm irq preinstall callback
-
 
88
 *
-
 
89
 * @dev: drm dev pointer
-
 
90
 *
-
 
91
 * Handles stuff to be done after enabling irqs (all asics).
-
 
92
 * Returns 0 on success.
-
 
93
 */
63
 
94
 
64
int radeon_driver_irq_postinstall(struct radeon_device *rdev)
95
int radeon_driver_irq_postinstall_kms(struct radeon_device *rdev)
65
{
96
{
66
//    struct radeon_device *rdev = dev->dev_private;
97
//    struct radeon_device *rdev = dev->dev_private;
67
 
98
 
68
//    dev->max_vblank_count = 0x001fffff;
99
//    dev->max_vblank_count = 0x001fffff;
69
    rdev->irq.sw_int = true;
-
 
-
 
100
 
70
    radeon_irq_set(rdev);
101
    radeon_irq_set(rdev);
71
    return 0;
102
    return 0;
72
}
103
}
-
 
104
 
-
 
105
/**
-
 
106
 * radeon_irq_kms_init - init driver interrupt info
-
 
107
 *
-
 
108
 * @rdev: radeon device pointer
-
 
109
 *
-
 
110
 * Sets up the work irq handlers, vblank init, MSIs, etc. (all asics).
-
 
111
 * Returns 0 for success, error for failure.
73
 
112
 */
74
int radeon_irq_kms_init(struct radeon_device *rdev)
113
int radeon_irq_kms_init(struct radeon_device *rdev)
75
{
-
 
76
	int i;
114
{
77
    int irq_line;
115
    int irq_line;
78
	int r = 0;
116
	int r = 0;
79
 
117
 
80
    ENTER();
118
    ENTER();
81
 
119
 
82
//   INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
120
//    INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
-
 
121
//	INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
83
 
122
 
84
	spin_lock_init(&rdev->irq.sw_lock);
-
 
85
	for (i = 0; i < rdev->num_crtc; i++)
-
 
86
		spin_lock_init(&rdev->irq.pflip_lock[i]);
123
	spin_lock_init(&rdev->irq.lock);
87
//   r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
124
//   r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
88
//   if (r) {
125
//   if (r) {
89
//       return r;
126
//       return r;
90
//   }
127
//   }
91
 
-
 
-
 
128
	/* enable msi */
92
	rdev->msi_enabled = 0;
129
	rdev->msi_enabled = 0;
-
 
130
 
-
 
131
//	if (radeon_msi_ok(rdev)) {
-
 
132
//		int ret = pci_enable_msi(rdev->pdev);
-
 
133
//		if (!ret) {
-
 
134
//			rdev->msi_enabled = 1;
-
 
135
//			dev_info(rdev->dev, "radeon: using MSI.\n");
-
 
136
//		}
-
 
137
//	}
93
    rdev->irq.installed = true;
138
    rdev->irq.installed = true;
94
    main_device = rdev;
139
    main_device = rdev;
95
 
140
 
96
    radeon_irq_preinstall(rdev);
141
    radeon_irq_preinstall_kms(rdev);
97
 
142
 
98
    if (irq_override)
143
    if (irq_override)
99
        irq_line = irq_override;
144
        irq_line = irq_override;
100
    else
145
    else
101
        irq_line = rdev->pdev->irq;
146
        irq_line = rdev->pdev->irq;
102
 
147
 
103
    dbgprintf("%s install irq %d\n", __FUNCTION__, irq_line);
148
    dbgprintf("%s install irq %d\n", __FUNCTION__, irq_line);
104
 
149
 
105
    AttachIntHandler(irq_line, irq_handler_kms, 2);
150
    AttachIntHandler(irq_line, irq_handler_kms, 2);
106
 
151
 
107
//   r = drm_irq_install(rdev->ddev);
152
//   r = drm_irq_install(rdev->ddev);
108
 
153
 
109
    r = radeon_driver_irq_postinstall(rdev);
154
    r = radeon_driver_irq_postinstall_kms(rdev);
110
    if (r) {
155
    if (r) {
111
       rdev->irq.installed = false;
156
       rdev->irq.installed = false;
112
        LEAVE();
157
        LEAVE();
113
       return r;
158
       return r;
114
   }
159
   }
115
 
-
 
116
	DRM_INFO("radeon: irq initialized.\n");
160
	DRM_INFO("radeon: irq initialized.\n");
117
	return 0;
161
	return 0;
118
}
162
}
-
 
163
 
-
 
164
/**
-
 
165
 * radeon_irq_kms_fini - tear down driver interrrupt info
-
 
166
 *
-
 
167
 * @rdev: radeon device pointer
-
 
168
 *
-
 
169
 * Tears down the work irq handlers, vblank handlers, MSIs, etc. (all asics).
-
 
170
 */
-
 
171
void radeon_irq_kms_fini(struct radeon_device *rdev)
-
 
172
{
-
 
173
//	drm_vblank_cleanup(rdev->ddev);
-
 
174
	if (rdev->irq.installed) {
-
 
175
//		drm_irq_uninstall(rdev->ddev);
-
 
176
		rdev->irq.installed = false;
-
 
177
//       if (rdev->msi_enabled)
-
 
178
//			pci_disable_msi(rdev->pdev);
-
 
179
	}
-
 
180
//	flush_work(&rdev->hotplug_work);
-
 
181
}
-
 
182
 
-
 
183
/**
-
 
184
 * radeon_irq_kms_sw_irq_get - enable software interrupt
-
 
185
 *
-
 
186
 * @rdev: radeon device pointer
-
 
187
 * @ring: ring whose interrupt you want to enable
-
 
188
 *
-
 
189
 * Enables the software interrupt for a specific ring (all asics).
-
 
190
 * The software interrupt is generally used to signal a fence on
119
 
191
 * a particular ring.
120
 
192
 */
121
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev)
193
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring)
122
{
194
{
123
	unsigned long irqflags;
195
	unsigned long irqflags;
124
 
196
 
-
 
197
	if (!rdev->ddev->irq_enabled)
-
 
198
		return;
125
	spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
199
 
126
	if (rdev->ddev->irq_enabled && (++rdev->irq.sw_refcount == 1)) {
200
	if (atomic_inc_return(&rdev->irq.ring_int[ring]) == 1) {
127
		rdev->irq.sw_int = true;
201
		spin_lock_irqsave(&rdev->irq.lock, irqflags);
-
 
202
		radeon_irq_set(rdev);
128
		radeon_irq_set(rdev);
203
		spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
129
	}
-
 
130
	spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
204
	}
-
 
205
}
-
 
206
 
-
 
207
/**
-
 
208
 * radeon_irq_kms_sw_irq_put - disable software interrupt
-
 
209
 *
-
 
210
 * @rdev: radeon device pointer
-
 
211
 * @ring: ring whose interrupt you want to disable
-
 
212
 *
-
 
213
 * Disables the software interrupt for a specific ring (all asics).
-
 
214
 * The software interrupt is generally used to signal a fence on
131
}
215
 * a particular ring.
132
 
216
 */
133
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev)
217
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring)
134
{
218
{
135
	unsigned long irqflags;
219
	unsigned long irqflags;
136
 
220
 
137
	spin_lock_irqsave(&rdev->irq.sw_lock, irqflags);
221
	if (!rdev->ddev->irq_enabled)
-
 
222
		return;
138
	BUG_ON(rdev->ddev->irq_enabled && rdev->irq.sw_refcount <= 0);
223
 
139
	if (rdev->ddev->irq_enabled && (--rdev->irq.sw_refcount == 0)) {
224
	if (atomic_dec_and_test(&rdev->irq.ring_int[ring])) {
140
		rdev->irq.sw_int = false;
225
		spin_lock_irqsave(&rdev->irq.lock, irqflags);
-
 
226
		radeon_irq_set(rdev);
141
		radeon_irq_set(rdev);
227
		spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
142
	}
-
 
143
	spin_unlock_irqrestore(&rdev->irq.sw_lock, irqflags);
228
	}
144
}
229
}