Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2351 Serge 1
/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
2
 */
3
/*
4
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
5
 * All Rights Reserved.
6
 *
7
 * Permission is hereby granted, free of charge, to any person obtaining a
8
 * copy of this software and associated documentation files (the
9
 * "Software"), to deal in the Software without restriction, including
10
 * without limitation the rights to use, copy, modify, merge, publish,
11
 * distribute, sub license, and/or sell copies of the Software, and to
12
 * permit persons to whom the Software is furnished to do so, subject to
13
 * the following conditions:
14
 *
15
 * The above copyright notice and this permission notice (including the
16
 * next paragraph) shall be included in all copies or substantial portions
17
 * of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
 *
27
 */
28
 
3746 Serge 29
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
3031 serge 30
 
31
#include 
32
#include 
33
#include 
2351 Serge 34
#include "i915_drv.h"
35
#include "i915_trace.h"
36
#include "intel_drv.h"
37
 
4104 Serge 38
#define assert_spin_locked(a)
39
 
3746 Serge 40
static const u32 hpd_ibx[] = {
41
	[HPD_CRT] = SDE_CRT_HOTPLUG,
42
	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG,
43
	[HPD_PORT_B] = SDE_PORTB_HOTPLUG,
44
	[HPD_PORT_C] = SDE_PORTC_HOTPLUG,
45
	[HPD_PORT_D] = SDE_PORTD_HOTPLUG
46
};
3031 serge 47
 
3746 Serge 48
static const u32 hpd_cpt[] = {
49
	[HPD_CRT] = SDE_CRT_HOTPLUG_CPT,
50
	[HPD_SDVO_B] = SDE_SDVOB_HOTPLUG_CPT,
51
	[HPD_PORT_B] = SDE_PORTB_HOTPLUG_CPT,
52
	[HPD_PORT_C] = SDE_PORTC_HOTPLUG_CPT,
53
	[HPD_PORT_D] = SDE_PORTD_HOTPLUG_CPT
54
};
55
 
56
static const u32 hpd_mask_i915[] = {
57
	[HPD_CRT] = CRT_HOTPLUG_INT_EN,
58
	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_EN,
59
	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_EN,
60
	[HPD_PORT_B] = PORTB_HOTPLUG_INT_EN,
61
	[HPD_PORT_C] = PORTC_HOTPLUG_INT_EN,
62
	[HPD_PORT_D] = PORTD_HOTPLUG_INT_EN
63
};
64
 
65
static const u32 hpd_status_gen4[] = {
66
	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
67
	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_G4X,
68
	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_G4X,
69
	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
70
	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
71
	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
72
};
73
 
74
static const u32 hpd_status_i915[] = { /* i915 and valleyview are the same */
75
	[HPD_CRT] = CRT_HOTPLUG_INT_STATUS,
76
	[HPD_SDVO_B] = SDVOB_HOTPLUG_INT_STATUS_I915,
77
	[HPD_SDVO_C] = SDVOC_HOTPLUG_INT_STATUS_I915,
78
	[HPD_PORT_B] = PORTB_HOTPLUG_INT_STATUS,
79
	[HPD_PORT_C] = PORTC_HOTPLUG_INT_STATUS,
80
	[HPD_PORT_D] = PORTD_HOTPLUG_INT_STATUS
81
};
82
 
83
 
3031 serge 84
#define pr_err(fmt, ...) \
85
        printk(KERN_ERR pr_fmt(fmt), ##__VA_ARGS__)
86
 
87
 
2352 Serge 88
#define DRM_WAKEUP( queue ) wake_up( queue )
89
#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
90
 
2351 Serge 91
#define MAX_NOPID ((u32)~0)
92
 
93
 
94
 
95
/* For display hotplug interrupt */
96
static void
97
ironlake_enable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
98
{
4104 Serge 99
	assert_spin_locked(&dev_priv->irq_lock);
100
 
101
	if (dev_priv->pc8.irqs_disabled) {
102
		WARN(1, "IRQs disabled\n");
103
		dev_priv->pc8.regsave.deimr &= ~mask;
104
		return;
105
	}
106
 
2351 Serge 107
    if ((dev_priv->irq_mask & mask) != 0) {
108
        dev_priv->irq_mask &= ~mask;
109
        I915_WRITE(DEIMR, dev_priv->irq_mask);
110
        POSTING_READ(DEIMR);
111
    }
112
}
113
 
3746 Serge 114
static void
2351 Serge 115
ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
116
{
4104 Serge 117
	assert_spin_locked(&dev_priv->irq_lock);
118
 
119
	if (dev_priv->pc8.irqs_disabled) {
120
		WARN(1, "IRQs disabled\n");
121
		dev_priv->pc8.regsave.deimr |= mask;
122
		return;
123
	}
124
 
2351 Serge 125
    if ((dev_priv->irq_mask & mask) != mask) {
126
        dev_priv->irq_mask |= mask;
127
        I915_WRITE(DEIMR, dev_priv->irq_mask);
128
        POSTING_READ(DEIMR);
129
    }
130
}
3031 serge 131
 
4104 Serge 132
/**
133
 * ilk_update_gt_irq - update GTIMR
134
 * @dev_priv: driver private
135
 * @interrupt_mask: mask of interrupt bits to update
136
 * @enabled_irq_mask: mask of interrupt bits to enable
137
 */
138
static void ilk_update_gt_irq(struct drm_i915_private *dev_priv,
139
			      uint32_t interrupt_mask,
140
			      uint32_t enabled_irq_mask)
141
{
142
	assert_spin_locked(&dev_priv->irq_lock);
143
 
144
	if (dev_priv->pc8.irqs_disabled) {
145
		WARN(1, "IRQs disabled\n");
146
		dev_priv->pc8.regsave.gtimr &= ~interrupt_mask;
147
		dev_priv->pc8.regsave.gtimr |= (~enabled_irq_mask &
148
						interrupt_mask);
149
		return;
150
	}
151
 
152
	dev_priv->gt_irq_mask &= ~interrupt_mask;
153
	dev_priv->gt_irq_mask |= (~enabled_irq_mask & interrupt_mask);
154
	I915_WRITE(GTIMR, dev_priv->gt_irq_mask);
155
	POSTING_READ(GTIMR);
156
}
157
 
158
void ilk_enable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
159
{
160
	ilk_update_gt_irq(dev_priv, mask, mask);
161
}
162
 
163
void ilk_disable_gt_irq(struct drm_i915_private *dev_priv, uint32_t mask)
164
{
165
	ilk_update_gt_irq(dev_priv, mask, 0);
166
}
167
 
168
/**
169
  * snb_update_pm_irq - update GEN6_PMIMR
170
  * @dev_priv: driver private
171
  * @interrupt_mask: mask of interrupt bits to update
172
  * @enabled_irq_mask: mask of interrupt bits to enable
173
  */
174
static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
175
			      uint32_t interrupt_mask,
176
			      uint32_t enabled_irq_mask)
177
{
178
	uint32_t new_val;
179
 
180
	assert_spin_locked(&dev_priv->irq_lock);
181
 
182
	if (dev_priv->pc8.irqs_disabled) {
183
		WARN(1, "IRQs disabled\n");
184
		dev_priv->pc8.regsave.gen6_pmimr &= ~interrupt_mask;
185
		dev_priv->pc8.regsave.gen6_pmimr |= (~enabled_irq_mask &
186
						     interrupt_mask);
187
		return;
188
	}
189
 
190
	new_val = dev_priv->pm_irq_mask;
191
	new_val &= ~interrupt_mask;
192
	new_val |= (~enabled_irq_mask & interrupt_mask);
193
 
194
	if (new_val != dev_priv->pm_irq_mask) {
195
		dev_priv->pm_irq_mask = new_val;
196
		I915_WRITE(GEN6_PMIMR, dev_priv->pm_irq_mask);
197
		POSTING_READ(GEN6_PMIMR);
198
	}
199
}
200
 
201
void snb_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
202
{
203
	snb_update_pm_irq(dev_priv, mask, mask);
204
}
205
 
206
void snb_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
207
{
208
	snb_update_pm_irq(dev_priv, mask, 0);
209
}
210
 
211
static bool ivb_can_enable_err_int(struct drm_device *dev)
212
{
213
	struct drm_i915_private *dev_priv = dev->dev_private;
214
	struct intel_crtc *crtc;
215
	enum pipe pipe;
216
 
217
	assert_spin_locked(&dev_priv->irq_lock);
218
 
219
	for_each_pipe(pipe) {
220
		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
221
 
222
		if (crtc->cpu_fifo_underrun_disabled)
223
			return false;
224
	}
225
 
226
	return true;
227
}
228
 
229
static bool cpt_can_enable_serr_int(struct drm_device *dev)
230
{
231
	struct drm_i915_private *dev_priv = dev->dev_private;
232
	enum pipe pipe;
233
	struct intel_crtc *crtc;
234
 
235
	assert_spin_locked(&dev_priv->irq_lock);
236
 
237
	for_each_pipe(pipe) {
238
		crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
239
 
240
		if (crtc->pch_fifo_underrun_disabled)
241
			return false;
242
	}
243
 
244
	return true;
245
}
246
 
247
static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev,
248
						 enum pipe pipe, bool enable)
249
{
250
	struct drm_i915_private *dev_priv = dev->dev_private;
251
	uint32_t bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN :
252
					  DE_PIPEB_FIFO_UNDERRUN;
253
 
254
	if (enable)