Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2325 Serge 1
/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
2
 */
3
/*
4
 *
5
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6
 * All Rights Reserved.
7
 *
8
 * Permission is hereby granted, free of charge, to any person obtaining a
9
 * copy of this software and associated documentation files (the
10
 * "Software"), to deal in the Software without restriction, including
11
 * without limitation the rights to use, copy, modify, merge, publish,
12
 * distribute, sub license, and/or sell copies of the Software, and to
13
 * permit persons to whom the Software is furnished to do so, subject to
14
 * the following conditions:
15
 *
16
 * The above copyright notice and this permission notice (including the
17
 * next paragraph) shall be included in all copies or substantial portions
18
 * of the Software.
19
 *
20
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27
 *
28
 */
29
 
2330 Serge 30
//#include 
31
#include "drmP.h"
32
#include "drm.h"
33
#include "i915_drm.h"
34
#include "i915_drv.h"
35
#include "intel_drv.h"
2325 Serge 36
 
2330 Serge 37
 
2325 Serge 38
#include 
39
#include 
40
#include 
41
#include 
42
#include 
43
 
44
#include 
45
 
2330 Serge 46
#define __read_mostly
2327 Serge 47
 
2338 Serge 48
int init_display_kms(struct drm_device *dev);
2330 Serge 49
 
2340 Serge 50
struct drm_device *main_device;
2338 Serge 51
 
2332 Serge 52
int i915_panel_ignore_lid __read_mostly         =  0;
2330 Serge 53
 
2332 Serge 54
unsigned int i915_powersave  __read_mostly      =  0;
2330 Serge 55
 
2342 Serge 56
unsigned int i915_enable_rc6 __read_mostly      = -1;
2330 Serge 57
 
2336 Serge 58
unsigned int i915_enable_fbc __read_mostly      =  0;
2330 Serge 59
 
60
unsigned int i915_lvds_downclock  __read_mostly =  0;
61
 
2332 Serge 62
unsigned int i915_panel_use_ssc __read_mostly   =  1;
2330 Serge 63
 
2332 Serge 64
int i915_vbt_sdvo_panel_type __read_mostly      = -1;
2330 Serge 65
 
2326 Serge 66
#define PCI_VENDOR_ID_INTEL        0x8086
67
 
2325 Serge 68
#define INTEL_VGA_DEVICE(id, info) {        \
2342 Serge 69
	.class = PCI_BASE_CLASS_DISPLAY << 16,	\
2325 Serge 70
    .class_mask = 0xff0000,                 \
71
    .vendor = 0x8086,                       \
72
    .device = id,                           \
73
    .subvendor = PCI_ANY_ID,                \
74
    .subdevice = PCI_ANY_ID,                \
75
    .driver_data = (unsigned long) info }
76
 
2339 Serge 77
 
78
static const struct intel_device_info intel_i915g_info = {
79
	.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1,
80
	.has_overlay = 1, .overlay_needs_physical = 1,
81
};
82
static const struct intel_device_info intel_i915gm_info = {
83
	.gen = 3, .is_mobile = 1,
84
	.cursor_needs_physical = 1,
85
	.has_overlay = 1, .overlay_needs_physical = 1,
86
	.supports_tv = 1,
87
};
88
static const struct intel_device_info intel_i945g_info = {
89
	.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1,
90
	.has_overlay = 1, .overlay_needs_physical = 1,
91
};
92
static const struct intel_device_info intel_i945gm_info = {
93
	.gen = 3, .is_i945gm = 1, .is_mobile = 1,
94
	.has_hotplug = 1, .cursor_needs_physical = 1,
95
	.has_overlay = 1, .overlay_needs_physical = 1,
96
	.supports_tv = 1,
97
};
98
 
99
static const struct intel_device_info intel_i965g_info = {
100
	.gen = 4, .is_broadwater = 1,
101
	.has_hotplug = 1,
102
	.has_overlay = 1,
103
};
104
 
105
static const struct intel_device_info intel_i965gm_info = {
106
	.gen = 4, .is_crestline = 1,
107
	.is_mobile = 1, .has_fbc = 1, .has_hotplug = 1,
108
	.has_overlay = 1,
109
	.supports_tv = 1,
110
};
111
 
112
static const struct intel_device_info intel_g33_info = {
113
	.gen = 3, .is_g33 = 1,
114
	.need_gfx_hws = 1, .has_hotplug = 1,
115
	.has_overlay = 1,
116
};
117
 
118
static const struct intel_device_info intel_g45_info = {
119
	.gen = 4, .is_g4x = 1, .need_gfx_hws = 1,
120
	.has_pipe_cxsr = 1, .has_hotplug = 1,
121
	.has_bsd_ring = 1,
122
};
123
 
124
static const struct intel_device_info intel_gm45_info = {
125
	.gen = 4, .is_g4x = 1,
126
	.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1,
127
	.has_pipe_cxsr = 1, .has_hotplug = 1,
128
	.supports_tv = 1,
129
	.has_bsd_ring = 1,
130
};
131
 
132
static const struct intel_device_info intel_pineview_info = {
133
	.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1,
134
	.need_gfx_hws = 1, .has_hotplug = 1,
135
	.has_overlay = 1,
136
};
137
 
138
static const struct intel_device_info intel_ironlake_d_info = {
139
	.gen = 5,
140
	.need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1,
141
	.has_bsd_ring = 1,
142
};
143
 
144
static const struct intel_device_info intel_ironlake_m_info = {
145
	.gen = 5, .is_mobile = 1,
146
	.need_gfx_hws = 1, .has_hotplug = 1,
147
	.has_fbc = 1,
148
	.has_bsd_ring = 1,
149
};
150
 
2325 Serge 151
static const struct intel_device_info intel_sandybridge_d_info = {
152
    .gen = 6,
2330 Serge 153
	.need_gfx_hws = 1, .has_hotplug = 1,
2325 Serge 154
    .has_bsd_ring = 1,
155
    .has_blt_ring = 1,
156
};
157
 
158
static const struct intel_device_info intel_sandybridge_m_info = {
2330 Serge 159
	.gen = 6, .is_mobile = 1,
160
	.need_gfx_hws = 1, .has_hotplug = 1,
2325 Serge 161
    .has_fbc      = 1,
162
    .has_bsd_ring = 1,
163
    .has_blt_ring = 1,
164
};
165
 
2339 Serge 166
static const struct intel_device_info intel_ivybridge_d_info = {
167
	.is_ivybridge = 1, .gen = 7,
168
	.need_gfx_hws = 1, .has_hotplug = 1,
169
	.has_bsd_ring = 1,
170
	.has_blt_ring = 1,
171
};
2325 Serge 172
 
2339 Serge 173
static const struct intel_device_info intel_ivybridge_m_info = {
174
	.is_ivybridge = 1, .gen = 7, .is_mobile = 1,
175
	.need_gfx_hws = 1, .has_hotplug = 1,
176
	.has_fbc = 0,	/* FBC is not enabled on Ivybridge mobile yet */
177
	.has_bsd_ring = 1,
178
	.has_blt_ring = 1,
179
};
180
 
2325 Serge 181
static const struct pci_device_id pciidlist[] = {       /* aka */
2339 Serge 182
	INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),		/* I915_G */
183
	INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),		/* E7221_G */
184
	INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),		/* I915_GM */
185
	INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),		/* I945_G */
186
	INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),		/* I945_GM */
187
	INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),		/* I945_GME */
188
	INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),		/* I946_GZ */
189
	INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),		/* G35_G */
190
	INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),		/* I965_Q */
191
	INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),		/* I965_G */
192
	INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),		/* Q35_G */
193
	INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),		/* G33_G */
194
	INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),		/* Q33_G */
195
	INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),		/* I965_GM */
196
	INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),		/* I965_GME */
197
	INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),		/* GM45_G */
198
	INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),		/* IGD_E_G */
199
	INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),		/* Q45_G */
200
	INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),		/* G45_G */
201
	INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),		/* G41_G */
202
	INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),		/* B43_G */
203
	INTEL_VGA_DEVICE(0x2e92, &intel_g45_info),		/* B43_G.1 */
204
	INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
205
	INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
206
	INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
207
	INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
2325 Serge 208
    INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
209
    INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info),
210
    INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info),
211
    INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
212
    INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info),
213
    INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
214
    INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info),
2339 Serge 215
	INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */
216
	INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */
217
	INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */
218
	INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */
219
	INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */
2325 Serge 220
    {0, 0, 0}
221
};
222
 
2326 Serge 223
#define INTEL_PCH_DEVICE_ID_MASK        0xff00
224
#define INTEL_PCH_IBX_DEVICE_ID_TYPE    0x3b00
225
#define INTEL_PCH_CPT_DEVICE_ID_TYPE    0x1c00
226
#define INTEL_PCH_PPT_DEVICE_ID_TYPE    0x1e00
2325 Serge 227
 
2342 Serge 228
void intel_detect_pch(struct drm_device *dev)
2326 Serge 229
{
230
    struct drm_i915_private *dev_priv = dev->dev_private;
231
    struct pci_dev *pch;
232
 
233
    /*
234
     * The reason to probe ISA bridge instead of Dev31:Fun0 is to
235
     * make graphics device passthrough work easy for VMM, that only
236
     * need to expose ISA bridge to let driver know the real hardware
237
     * underneath. This is a requirement from virtualization team.
238
     */
239
    pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
240
    if (pch) {
241
        if (pch->vendor == PCI_VENDOR_ID_INTEL) {
242
            int id;
243
            id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
244
 
245
            if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
246
                dev_priv->pch_type = PCH_IBX;
247
                DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
248
            } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
249
                dev_priv->pch_type = PCH_CPT;
250
                DRM_DEBUG_KMS("Found CougarPoint PCH\n");
251
            } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
252
                /* PantherPoint is CPT compatible */
253
                dev_priv->pch_type = PCH_CPT;
254
                DRM_DEBUG_KMS("Found PatherPoint PCH\n");
255
            }
256
        }
257
    }
258
}
259
 
2342 Serge 260
void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
2326 Serge 261
{
262
    int count;
263
 
264
    count = 0;
265
    while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
266
        udelay(10);
267
 
268
    I915_WRITE_NOTRACE(FORCEWAKE, 1);
269
    POSTING_READ(FORCEWAKE);
270
 
271
    count = 0;
272
    while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0)
273
        udelay(10);
274
}
275
 
2342 Serge 276
void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
277
{
278
	int count;
279
 
280
	count = 0;
281
	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
282
		udelay(10);
283
 
284
	I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1);
285
	POSTING_READ(FORCEWAKE_MT);
286
 
287
	count = 0;
288
	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
289
		udelay(10);
290
}
291
 
2326 Serge 292
/*
293
 * Generally this is called implicitly by the register read function. However,
294
 * if some sequence requires the GT to not power down then this function should
295
 * be called at the beginning of the sequence followed by a call to
296
 * gen6_gt_force_wake_put() at the end of the sequence.
297
 */
298
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
299
{
2342 Serge 300
	unsigned long irqflags;
2326 Serge 301
 
2342 Serge 302
	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
303
	if (dev_priv->forcewake_count++ == 0)
304
		dev_priv->display.force_wake_get(dev_priv);
305
	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
2326 Serge 306
}
307
 
2342 Serge 308
void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
2326 Serge 309
{
310
    I915_WRITE_NOTRACE(FORCEWAKE, 0);
311
    POSTING_READ(FORCEWAKE);
312
}
313
 
2342 Serge 314
void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
315
{
316
	I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
317
	POSTING_READ(FORCEWAKE_MT);
318
}
319
 
2326 Serge 320
/*
321
 * see gen6_gt_force_wake_get()
322
 */
323
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
324
{
2342 Serge 325
	unsigned long irqflags;
2326 Serge 326
 
2342 Serge 327
	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
328
	if (--dev_priv->forcewake_count == 0)
329
		dev_priv->display.force_wake_put(dev_priv);
330
	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
2326 Serge 331
}
332
 
333
void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
334
{
2342 Serge 335
	if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
2326 Serge 336
        int loop = 500;
337
        u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
338
        while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
339
            udelay(10);
340
            fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
341
        }
342
//        WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES);
343
        dev_priv->gt_fifo_count = fifo;
344
    }
345
    dev_priv->gt_fifo_count--;
346
}
347
 
348
 
349
 
350
 
351
 
2325 Serge 352
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent);
353
 
354
int i915_init(void)
355
{
356
    static pci_dev_t device;
357
    const struct pci_device_id  *ent;
358
    int  err;
359
 
360
    if( init_agp() != 0)
361
    {
362
        DRM_ERROR("drm/i915 can't work without intel_agp module!\n");
363
        return 0;
364
    };
365
 
366
    ent = find_pci_device(&device, pciidlist);
367
 
368
    if( unlikely(ent == NULL) )
369
    {
370
        dbgprintf("device not found\n");
371
        return 0;
372
    };
373
 
374
    dbgprintf("device %x:%x\n", device.pci_dev.vendor,
375
                                device.pci_dev.device);
376
 
377
    err = drm_get_dev(&device.pci_dev, ent);
378
 
379
    return err;
380
}
381
 
382
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
383
{
2340 Serge 384
    struct drm_device *dev;
2325 Serge 385
    int ret;
386
 
387
    ENTER();
388
 
389
    dev = kzalloc(sizeof(*dev), 0);
390
    if (!dev)
391
        return -ENOMEM;
392
 
393
 //   ret = pci_enable_device(pdev);
394
 //   if (ret)
395
 //       goto err_g1;
396
 
397
 //   pci_set_master(pdev);
398
 
399
 //   if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
400
 //       printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
401
 //       goto err_g2;
402
 //   }
403
 
404
    dev->pdev = pdev;
405
    dev->pci_device = pdev->device;
406
    dev->pci_vendor = pdev->vendor;
407
 
408
    INIT_LIST_HEAD(&dev->filelist);
409
    INIT_LIST_HEAD(&dev->ctxlist);
410
    INIT_LIST_HEAD(&dev->vmalist);
411
    INIT_LIST_HEAD(&dev->maplist);
412
 
413
    spin_lock_init(&dev->count_lock);
414
    mutex_init(&dev->struct_mutex);
415
    mutex_init(&dev->ctxlist_mutex);
416
 
2336 Serge 417
    ret = i915_driver_load(dev, ent->driver_data );
2325 Serge 418
 
2338 Serge 419
    if (ret)
420
        goto err_g4;
2330 Serge 421
 
2338 Serge 422
    ret = init_display_kms(dev);
2336 Serge 423
 
2338 Serge 424
    if (ret)
425
        goto err_g4;
2336 Serge 426
 
2325 Serge 427
    LEAVE();
428
 
429
    return 0;
430
 
431
err_g4:
432
//    drm_put_minor(&dev->primary);
433
//err_g3:
434
//    if (drm_core_check_feature(dev, DRIVER_MODESET))
435
//        drm_put_minor(&dev->control);
436
//err_g2:
437
//    pci_disable_device(pdev);
438
//err_g1:
439
    free(dev);
440
 
441
    LEAVE();
442
 
443
    return ret;
444
}
445
 
446
 
2342 Serge 447
#define __i915_read(x, y) \
448
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
449
	u##x val = 0; \
450
	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
451
		unsigned long irqflags; \
452
		spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
453
		if (dev_priv->forcewake_count == 0) \
454
			dev_priv->display.force_wake_get(dev_priv); \
455
		val = read##y(dev_priv->regs + reg); \
456
		if (dev_priv->forcewake_count == 0) \
457
			dev_priv->display.force_wake_put(dev_priv); \
458
		spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
459
	} else { \
460
		val = read##y(dev_priv->regs + reg); \
461
	} \
462
	return val; \
463
}
464
 
465
__i915_read(8, b)
466
__i915_read(16, w)
467
__i915_read(32, l)
468
__i915_read(64, q)
469
#undef __i915_read
470
 
471
#define __i915_write(x, y) \
472
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
473
	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
474
		__gen6_gt_wait_for_fifo(dev_priv); \
475
	} \
476
	write##y(val, dev_priv->regs + reg); \
477
}
478
__i915_write(8, b)
479
__i915_write(16, w)
480
__i915_write(32, l)
481
__i915_write(64, q)
482
#undef __i915_write