Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2004 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
 */
2997 Serge 28
#include 
29
#include 
30
#include 
2004 serge 31
#include "radeon_reg.h"
32
#include "radeon.h"
33
#include "atom.h"
34
 
2997 Serge 35
#define RADEON_WAIT_IDLE_TIMEOUT 200
36
 
2007 serge 37
struct radeon_device *main_device;
2004 serge 38
 
2160 serge 39
extern int irq_override;
2004 serge 40
 
2997 Serge 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.
50
 */
2004 serge 51
void irq_handler_kms()
52
{
53
    radeon_irq_process(main_device);
54
}
55
 
2997 Serge 56
/**
57
 * radeon_driver_irq_preinstall_kms - drm irq preinstall callback
58
 *
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.
63
 */
64
void radeon_irq_preinstall_kms(struct radeon_device *rdev)
2004 serge 65
{
2997 Serge 66
	unsigned long irqflags;
2004 serge 67
    unsigned i;
68
 
2997 Serge 69
	spin_lock_irqsave(&rdev->irq.lock, irqflags);
2004 serge 70
    /* Disable *all* interrupts */
2997 Serge 71
	for (i = 0; i < RADEON_NUM_RINGS; i++)
72
		atomic_set(&rdev->irq.ring_int[i], 0);
73
	for (i = 0; i < RADEON_MAX_HPD_PINS; i++)
74
		rdev->irq.hpd[i] = false;
75
	for (i = 0; i < RADEON_MAX_CRTCS; i++) {
2004 serge 76
        rdev->irq.crtc_vblank_int[i] = false;
2997 Serge 77
		atomic_set(&rdev->irq.pflip[i], 0);
78
		rdev->irq.afmt[i] = false;
2004 serge 79
    }
80
    radeon_irq_set(rdev);
2997 Serge 81
	spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
2004 serge 82
    /* Clear bits */
83
    radeon_irq_process(rdev);
84
}
85
 
2997 Serge 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
 */
94
 
95
int radeon_driver_irq_postinstall_kms(struct radeon_device *rdev)
2004 serge 96
{
97
//    struct radeon_device *rdev = dev->dev_private;
98
 
99
//    dev->max_vblank_count = 0x001fffff;
2997 Serge 100
 
2004 serge 101
    radeon_irq_set(rdev);
102
    return 0;
103
}
104
 
2997 Serge 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.
112
 */
2004 serge 113
int radeon_irq_kms_init(struct radeon_device *rdev)
114
{
115
    int irq_line;
116
	int r = 0;
117
 
118
    ENTER();
119
 
2997 Serge 120
//    INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);
121
//	INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi);
2004 serge 122
 
2997 Serge 123
	spin_lock_init(&rdev->irq.lock);
2004 serge 124
//   r = drm_vblank_init(rdev->ddev, rdev->num_crtc);
125
//   if (r) {
126
//       return r;
127
//   }
2997 Serge 128
	/* enable msi */
129
	rdev->msi_enabled = 0;
2004 serge 130
 
2997 Serge 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
//	}
2004 serge 138
    rdev->irq.installed = true;
139
    main_device = rdev;
140
 
2997 Serge 141
    radeon_irq_preinstall_kms(rdev);
2004 serge 142
 
2160 serge 143
    if (irq_override)
144
        irq_line = irq_override;
145
    else
146
        irq_line = rdev->pdev->irq;
2004 serge 147
 
148
    dbgprintf("%s install irq %d\n", __FUNCTION__, irq_line);
149
 
150
    AttachIntHandler(irq_line, irq_handler_kms, 2);
151
 
152
//   r = drm_irq_install(rdev->ddev);
153
 
2997 Serge 154
    r = radeon_driver_irq_postinstall_kms(rdev);
2004 serge 155
    if (r) {
156
       rdev->irq.installed = false;
157
        LEAVE();
158
       return r;
159
   }
160
	DRM_INFO("radeon: irq initialized.\n");
161
	return 0;
162
}
163
 
2997 Serge 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
}
2004 serge 182
 
2997 Serge 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
191
 * a particular ring.
192
 */
193
void radeon_irq_kms_sw_irq_get(struct radeon_device *rdev, int ring)
2004 serge 194
{
195
	unsigned long irqflags;
196
 
2997 Serge 197
	if (!rdev->ddev->irq_enabled)
198
		return;
199
 
200
	if (atomic_inc_return(&rdev->irq.ring_int[ring]) == 1) {
201
		spin_lock_irqsave(&rdev->irq.lock, irqflags);
2004 serge 202
		radeon_irq_set(rdev);
2997 Serge 203
		spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
2004 serge 204
	}
205
}
206
 
2997 Serge 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
215
 * a particular ring.
216
 */
217
void radeon_irq_kms_sw_irq_put(struct radeon_device *rdev, int ring)
2004 serge 218
{
219
	unsigned long irqflags;
220
 
2997 Serge 221
	if (!rdev->ddev->irq_enabled)
222
		return;
223
 
224
	if (atomic_dec_and_test(&rdev->irq.ring_int[ring])) {
225
		spin_lock_irqsave(&rdev->irq.lock, irqflags);
2004 serge 226
		radeon_irq_set(rdev);
2997 Serge 227
		spin_unlock_irqrestore(&rdev->irq.lock, irqflags);
2004 serge 228
	}
229
}
230