Subversion Repositories Kolibri OS

Rev

Rev 2342 | Rev 2352 | 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
static const struct intel_device_info intel_i830_info = {
78
	.gen = 2, .is_mobile = 1, .cursor_needs_physical = 1,
79
	.has_overlay = 1, .overlay_needs_physical = 1,
80
};
81
 
82
static const struct intel_device_info intel_845g_info = {
83
	.gen = 2,
84
	.has_overlay = 1, .overlay_needs_physical = 1,
85
};
86
 
87
static const struct intel_device_info intel_i85x_info = {
88
	.gen = 2, .is_i85x = 1, .is_mobile = 1,
89
	.cursor_needs_physical = 1,
90
	.has_overlay = 1, .overlay_needs_physical = 1,
91
};
92
 
93
static const struct intel_device_info intel_i865g_info = {
94
	.gen = 2,
95
	.has_overlay = 1, .overlay_needs_physical = 1,
96
};
97
 
98
static const struct intel_device_info intel_i915g_info = {
99
	.gen = 3, .is_i915g = 1, .cursor_needs_physical = 1,
100
	.has_overlay = 1, .overlay_needs_physical = 1,
101
};
102
static const struct intel_device_info intel_i915gm_info = {
103
	.gen = 3, .is_mobile = 1,
104
	.cursor_needs_physical = 1,
105
	.has_overlay = 1, .overlay_needs_physical = 1,
106
	.supports_tv = 1,
107
};
108
static const struct intel_device_info intel_i945g_info = {
109
	.gen = 3, .has_hotplug = 1, .cursor_needs_physical = 1,
110
	.has_overlay = 1, .overlay_needs_physical = 1,
111
};
112
static const struct intel_device_info intel_i945gm_info = {
113
	.gen = 3, .is_i945gm = 1, .is_mobile = 1,
114
	.has_hotplug = 1, .cursor_needs_physical = 1,
115
	.has_overlay = 1, .overlay_needs_physical = 1,
116
	.supports_tv = 1,
117
};
118
 
119
static const struct intel_device_info intel_i965g_info = {
120
	.gen = 4, .is_broadwater = 1,
121
	.has_hotplug = 1,
122
	.has_overlay = 1,
123
};
124
 
125
static const struct intel_device_info intel_i965gm_info = {
126
	.gen = 4, .is_crestline = 1,
127
	.is_mobile = 1, .has_fbc = 1, .has_hotplug = 1,
128
	.has_overlay = 1,
129
	.supports_tv = 1,
130
};
131
 
132
static const struct intel_device_info intel_g33_info = {
133
	.gen = 3, .is_g33 = 1,
134
	.need_gfx_hws = 1, .has_hotplug = 1,
135
	.has_overlay = 1,
136
};
137
 
138
static const struct intel_device_info intel_g45_info = {
139
	.gen = 4, .is_g4x = 1, .need_gfx_hws = 1,
140
	.has_pipe_cxsr = 1, .has_hotplug = 1,
141
	.has_bsd_ring = 1,
142
};
143
 
144
static const struct intel_device_info intel_gm45_info = {
145
	.gen = 4, .is_g4x = 1,
146
	.is_mobile = 1, .need_gfx_hws = 1, .has_fbc = 1,
147
	.has_pipe_cxsr = 1, .has_hotplug = 1,
148
	.supports_tv = 1,
149
	.has_bsd_ring = 1,
150
};
151
 
152
static const struct intel_device_info intel_pineview_info = {
153
	.gen = 3, .is_g33 = 1, .is_pineview = 1, .is_mobile = 1,
154
	.need_gfx_hws = 1, .has_hotplug = 1,
155
	.has_overlay = 1,
156
};
157
 
158
static const struct intel_device_info intel_ironlake_d_info = {
159
	.gen = 5,
160
	.need_gfx_hws = 1, .has_pipe_cxsr = 1, .has_hotplug = 1,
161
	.has_bsd_ring = 1,
162
};
163
 
164
static const struct intel_device_info intel_ironlake_m_info = {
165
	.gen = 5, .is_mobile = 1,
166
	.need_gfx_hws = 1, .has_hotplug = 1,
167
	.has_fbc = 1,
168
	.has_bsd_ring = 1,
169
};
170
 
2325 Serge 171
static const struct intel_device_info intel_sandybridge_d_info = {
172
    .gen = 6,
2330 Serge 173
	.need_gfx_hws = 1, .has_hotplug = 1,
2325 Serge 174
    .has_bsd_ring = 1,
175
    .has_blt_ring = 1,
176
};
177
 
178
static const struct intel_device_info intel_sandybridge_m_info = {
2330 Serge 179
	.gen = 6, .is_mobile = 1,
180
	.need_gfx_hws = 1, .has_hotplug = 1,
2325 Serge 181
    .has_fbc      = 1,
182
    .has_bsd_ring = 1,
183
    .has_blt_ring = 1,
184
};
185
 
2339 Serge 186
static const struct intel_device_info intel_ivybridge_d_info = {
187
	.is_ivybridge = 1, .gen = 7,
188
	.need_gfx_hws = 1, .has_hotplug = 1,
189
	.has_bsd_ring = 1,
190
	.has_blt_ring = 1,
191
};
2325 Serge 192
 
2339 Serge 193
static const struct intel_device_info intel_ivybridge_m_info = {
194
	.is_ivybridge = 1, .gen = 7, .is_mobile = 1,
195
	.need_gfx_hws = 1, .has_hotplug = 1,
196
	.has_fbc = 0,	/* FBC is not enabled on Ivybridge mobile yet */
197
	.has_bsd_ring = 1,
198
	.has_blt_ring = 1,
199
};
200
 
2325 Serge 201
static const struct pci_device_id pciidlist[] = {       /* aka */
2339 Serge 202
	INTEL_VGA_DEVICE(0x2582, &intel_i915g_info),		/* I915_G */
203
	INTEL_VGA_DEVICE(0x258a, &intel_i915g_info),		/* E7221_G */
204
	INTEL_VGA_DEVICE(0x2592, &intel_i915gm_info),		/* I915_GM */
205
	INTEL_VGA_DEVICE(0x2772, &intel_i945g_info),		/* I945_G */
206
	INTEL_VGA_DEVICE(0x27a2, &intel_i945gm_info),		/* I945_GM */
207
	INTEL_VGA_DEVICE(0x27ae, &intel_i945gm_info),		/* I945_GME */
208
	INTEL_VGA_DEVICE(0x2972, &intel_i965g_info),		/* I946_GZ */
209
	INTEL_VGA_DEVICE(0x2982, &intel_i965g_info),		/* G35_G */
210
	INTEL_VGA_DEVICE(0x2992, &intel_i965g_info),		/* I965_Q */
211
	INTEL_VGA_DEVICE(0x29a2, &intel_i965g_info),		/* I965_G */
212
	INTEL_VGA_DEVICE(0x29b2, &intel_g33_info),		/* Q35_G */
213
	INTEL_VGA_DEVICE(0x29c2, &intel_g33_info),		/* G33_G */
214
	INTEL_VGA_DEVICE(0x29d2, &intel_g33_info),		/* Q33_G */
215
	INTEL_VGA_DEVICE(0x2a02, &intel_i965gm_info),		/* I965_GM */
216
	INTEL_VGA_DEVICE(0x2a12, &intel_i965gm_info),		/* I965_GME */
217
	INTEL_VGA_DEVICE(0x2a42, &intel_gm45_info),		/* GM45_G */
218
	INTEL_VGA_DEVICE(0x2e02, &intel_g45_info),		/* IGD_E_G */
219
	INTEL_VGA_DEVICE(0x2e12, &intel_g45_info),		/* Q45_G */
220
	INTEL_VGA_DEVICE(0x2e22, &intel_g45_info),		/* G45_G */
221
	INTEL_VGA_DEVICE(0x2e32, &intel_g45_info),		/* G41_G */
222
	INTEL_VGA_DEVICE(0x2e42, &intel_g45_info),		/* B43_G */
223
	INTEL_VGA_DEVICE(0x2e92, &intel_g45_info),		/* B43_G.1 */
224
	INTEL_VGA_DEVICE(0xa001, &intel_pineview_info),
225
	INTEL_VGA_DEVICE(0xa011, &intel_pineview_info),
226
	INTEL_VGA_DEVICE(0x0042, &intel_ironlake_d_info),
227
	INTEL_VGA_DEVICE(0x0046, &intel_ironlake_m_info),
2325 Serge 228
    INTEL_VGA_DEVICE(0x0102, &intel_sandybridge_d_info),
229
    INTEL_VGA_DEVICE(0x0112, &intel_sandybridge_d_info),
230
    INTEL_VGA_DEVICE(0x0122, &intel_sandybridge_d_info),
231
    INTEL_VGA_DEVICE(0x0106, &intel_sandybridge_m_info),
232
    INTEL_VGA_DEVICE(0x0116, &intel_sandybridge_m_info),
233
    INTEL_VGA_DEVICE(0x0126, &intel_sandybridge_m_info),
234
    INTEL_VGA_DEVICE(0x010A, &intel_sandybridge_d_info),
2339 Serge 235
	INTEL_VGA_DEVICE(0x0156, &intel_ivybridge_m_info), /* GT1 mobile */
236
	INTEL_VGA_DEVICE(0x0166, &intel_ivybridge_m_info), /* GT2 mobile */
237
	INTEL_VGA_DEVICE(0x0152, &intel_ivybridge_d_info), /* GT1 desktop */
238
	INTEL_VGA_DEVICE(0x0162, &intel_ivybridge_d_info), /* GT2 desktop */
239
	INTEL_VGA_DEVICE(0x015a, &intel_ivybridge_d_info), /* GT1 server */
2325 Serge 240
    {0, 0, 0}
241
};
242
 
2326 Serge 243
#define INTEL_PCH_DEVICE_ID_MASK        0xff00
244
#define INTEL_PCH_IBX_DEVICE_ID_TYPE    0x3b00
245
#define INTEL_PCH_CPT_DEVICE_ID_TYPE    0x1c00
246
#define INTEL_PCH_PPT_DEVICE_ID_TYPE    0x1e00
2325 Serge 247
 
2342 Serge 248
void intel_detect_pch(struct drm_device *dev)
2326 Serge 249
{
250
    struct drm_i915_private *dev_priv = dev->dev_private;
251
    struct pci_dev *pch;
252
 
253
    /*
254
     * The reason to probe ISA bridge instead of Dev31:Fun0 is to
255
     * make graphics device passthrough work easy for VMM, that only
256
     * need to expose ISA bridge to let driver know the real hardware
257
     * underneath. This is a requirement from virtualization team.
258
     */
259
    pch = pci_get_class(PCI_CLASS_BRIDGE_ISA << 8, NULL);
260
    if (pch) {
261
        if (pch->vendor == PCI_VENDOR_ID_INTEL) {
262
            int id;
263
            id = pch->device & INTEL_PCH_DEVICE_ID_MASK;
264
 
265
            if (id == INTEL_PCH_IBX_DEVICE_ID_TYPE) {
266
                dev_priv->pch_type = PCH_IBX;
267
                DRM_DEBUG_KMS("Found Ibex Peak PCH\n");
268
            } else if (id == INTEL_PCH_CPT_DEVICE_ID_TYPE) {
269
                dev_priv->pch_type = PCH_CPT;
270
                DRM_DEBUG_KMS("Found CougarPoint PCH\n");
271
            } else if (id == INTEL_PCH_PPT_DEVICE_ID_TYPE) {
272
                /* PantherPoint is CPT compatible */
273
                dev_priv->pch_type = PCH_CPT;
274
                DRM_DEBUG_KMS("Found PatherPoint PCH\n");
275
            }
276
        }
277
    }
278
}
279
 
2342 Serge 280
void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
2326 Serge 281
{
282
    int count;
283
 
284
    count = 0;
285
    while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1))
286
        udelay(10);
287
 
288
    I915_WRITE_NOTRACE(FORCEWAKE, 1);
289
    POSTING_READ(FORCEWAKE);
290
 
291
    count = 0;
292
    while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_ACK) & 1) == 0)
293
        udelay(10);
294
}
295
 
2342 Serge 296
void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv)
297
{
298
	int count;
299
 
300
	count = 0;
301
	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1))
302
		udelay(10);
303
 
304
	I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 1);
305
	POSTING_READ(FORCEWAKE_MT);
306
 
307
	count = 0;
308
	while (count++ < 50 && (I915_READ_NOTRACE(FORCEWAKE_MT_ACK) & 1) == 0)
309
		udelay(10);
310
}
311
 
2326 Serge 312
/*
313
 * Generally this is called implicitly by the register read function. However,
314
 * if some sequence requires the GT to not power down then this function should
315
 * be called at the beginning of the sequence followed by a call to
316
 * gen6_gt_force_wake_put() at the end of the sequence.
317
 */
318
void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv)
319
{
2342 Serge 320
	unsigned long irqflags;
2326 Serge 321
 
2342 Serge 322
	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
323
	if (dev_priv->forcewake_count++ == 0)
324
		dev_priv->display.force_wake_get(dev_priv);
325
	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
2326 Serge 326
}
327
 
2342 Serge 328
void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
2326 Serge 329
{
330
    I915_WRITE_NOTRACE(FORCEWAKE, 0);
331
    POSTING_READ(FORCEWAKE);
332
}
333
 
2342 Serge 334
void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv)
335
{
336
	I915_WRITE_NOTRACE(FORCEWAKE_MT, (1<<16) | 0);
337
	POSTING_READ(FORCEWAKE_MT);
338
}
339
 
2326 Serge 340
/*
341
 * see gen6_gt_force_wake_get()
342
 */
343
void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
344
{
2342 Serge 345
	unsigned long irqflags;
2326 Serge 346
 
2342 Serge 347
	spin_lock_irqsave(&dev_priv->gt_lock, irqflags);
348
	if (--dev_priv->forcewake_count == 0)
349
		dev_priv->display.force_wake_put(dev_priv);
350
	spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
2326 Serge 351
}
352
 
353
void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
354
{
2342 Serge 355
	if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
2326 Serge 356
        int loop = 500;
357
        u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
358
        while (fifo <= GT_FIFO_NUM_RESERVED_ENTRIES && loop--) {
359
            udelay(10);
360
            fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
361
        }
362
//        WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES);
363
        dev_priv->gt_fifo_count = fifo;
364
    }
365
    dev_priv->gt_fifo_count--;
366
}
367
 
368
 
369
 
370
 
371
 
2325 Serge 372
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent);
373
 
374
int i915_init(void)
375
{
376
    static pci_dev_t device;
377
    const struct pci_device_id  *ent;
378
    int  err;
379
 
380
    if( init_agp() != 0)
381
    {
382
        DRM_ERROR("drm/i915 can't work without intel_agp module!\n");
383
        return 0;
384
    };
385
 
386
    ent = find_pci_device(&device, pciidlist);
387
 
388
    if( unlikely(ent == NULL) )
389
    {
390
        dbgprintf("device not found\n");
391
        return 0;
392
    };
393
 
394
    dbgprintf("device %x:%x\n", device.pci_dev.vendor,
395
                                device.pci_dev.device);
396
 
397
    err = drm_get_dev(&device.pci_dev, ent);
398
 
399
    return err;
400
}
401
 
402
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent)
403
{
2340 Serge 404
    struct drm_device *dev;
2325 Serge 405
    int ret;
406
 
407
    ENTER();
408
 
409
    dev = kzalloc(sizeof(*dev), 0);
410
    if (!dev)
411
        return -ENOMEM;
412
 
413
 //   ret = pci_enable_device(pdev);
414
 //   if (ret)
415
 //       goto err_g1;
416
 
417
 //   pci_set_master(pdev);
418
 
419
 //   if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
420
 //       printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
421
 //       goto err_g2;
422
 //   }
423
 
424
    dev->pdev = pdev;
425
    dev->pci_device = pdev->device;
426
    dev->pci_vendor = pdev->vendor;
427
 
428
    INIT_LIST_HEAD(&dev->filelist);
429
    INIT_LIST_HEAD(&dev->ctxlist);
430
    INIT_LIST_HEAD(&dev->vmalist);
431
    INIT_LIST_HEAD(&dev->maplist);
432
 
433
    spin_lock_init(&dev->count_lock);
434
    mutex_init(&dev->struct_mutex);
435
    mutex_init(&dev->ctxlist_mutex);
436
 
2336 Serge 437
    ret = i915_driver_load(dev, ent->driver_data );
2325 Serge 438
 
2338 Serge 439
    if (ret)
440
        goto err_g4;
2330 Serge 441
 
2338 Serge 442
    ret = init_display_kms(dev);
2336 Serge 443
 
2338 Serge 444
    if (ret)
445
        goto err_g4;
2336 Serge 446
 
2325 Serge 447
    LEAVE();
448
 
449
    return 0;
450
 
451
err_g4:
452
//    drm_put_minor(&dev->primary);
453
//err_g3:
454
//    if (drm_core_check_feature(dev, DRIVER_MODESET))
455
//        drm_put_minor(&dev->control);
456
//err_g2:
457
//    pci_disable_device(pdev);
458
//err_g1:
459
    free(dev);
460
 
461
    LEAVE();
462
 
463
    return ret;
464
}
465
 
466
 
2342 Serge 467
#define __i915_read(x, y) \
468
u##x i915_read##x(struct drm_i915_private *dev_priv, u32 reg) { \
469
	u##x val = 0; \
470
	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
471
		unsigned long irqflags; \
472
		spin_lock_irqsave(&dev_priv->gt_lock, irqflags); \
473
		if (dev_priv->forcewake_count == 0) \
474
			dev_priv->display.force_wake_get(dev_priv); \
475
		val = read##y(dev_priv->regs + reg); \
476
		if (dev_priv->forcewake_count == 0) \
477
			dev_priv->display.force_wake_put(dev_priv); \
478
		spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags); \
479
	} else { \
480
		val = read##y(dev_priv->regs + reg); \
481
	} \
482
	return val; \
483
}
484
 
485
__i915_read(8, b)
486
__i915_read(16, w)
487
__i915_read(32, l)
488
__i915_read(64, q)
489
#undef __i915_read
490
 
491
#define __i915_write(x, y) \
492
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
493
	if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
494
		__gen6_gt_wait_for_fifo(dev_priv); \
495
	} \
496
	write##y(val, dev_priv->regs + reg); \
497
}
498
__i915_write(8, b)
499
__i915_write(16, w)
500
__i915_write(32, l)
501
__i915_write(64, q)
502
#undef __i915_write