Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
3031 serge 1
#include 
2
#include 
3
#include 
2338 Serge 4
#include "i915_drv.h"
3031 serge 5
//#include "intel_drv.h"
2338 Serge 6
 
2325 Serge 7
#include 
8
#include 
9
#include 
10
#include 
11
#include 
12
#include 
13
 
2342 Serge 14
#include "bitmap.h"
2340 Serge 15
 
3255 Serge 16
struct pci_device {
17
    uint16_t    domain;
18
    uint8_t     bus;
19
    uint8_t     dev;
20
    uint8_t     func;
21
    uint16_t    vendor_id;
22
    uint16_t    device_id;
23
    uint16_t    subvendor_id;
24
    uint16_t    subdevice_id;
25
    uint32_t    device_class;
26
    uint8_t     revision;
27
};
28
 
4104 Serge 29
struct drm_device *main_device;
30
struct drm_file   *drm_file_handlers[256];
3033 serge 31
 
2344 Serge 32
void cpu_detect();
33
 
2340 Serge 34
void parse_cmdline(char *cmdline, char *log);
2338 Serge 35
int _stdcall display_handler(ioctl_t *io);
2325 Serge 36
int init_agp(void);
37
 
3120 serge 38
int srv_blit_bitmap(u32 hbitmap, int  dst_x, int dst_y,
2351 Serge 39
               int src_x, int src_y, u32 w, u32 h);
2340 Serge 40
 
2351 Serge 41
int blit_textured(u32 hbitmap, int  dst_x, int dst_y,
42
               int src_x, int src_y, u32 w, u32 h);
43
 
2361 Serge 44
int blit_tex(u32 hbitmap, int  dst_x, int dst_y,
45
             int src_x, int src_y, u32 w, u32 h);
46
 
3255 Serge 47
void get_pci_info(struct pci_device *dev);
48
int gem_getparam(struct drm_device *dev, void *data);
49
 
3277 Serge 50
int i915_mask_update(struct drm_device *dev, void *data,
51
            struct drm_file *file);
3255 Serge 52
 
3277 Serge 53
 
2325 Serge 54
static char  log[256];
55
 
3482 Serge 56
struct workqueue_struct *system_wq;
3764 Serge 57
int driver_wq_state;
3482 Serge 58
 
2344 Serge 59
int x86_clflush_size;
3482 Serge 60
unsigned int tsc_khz;
2344 Serge 61
 
2338 Serge 62
int i915_modeset = 1;
63
 
4126 Serge 64
typedef union __attribute__((packed))
65
{
66
    uint32_t val;
67
    struct
68
    {
69
        uint8_t   state;
70
        uint8_t   code;
71
        uint16_t  ctrl_key;
72
    };
73
}oskey_t;
74
 
75
static inline oskey_t get_key(void)
76
{
77
    oskey_t val;
78
    asm volatile("int $0x40":"=a"(val):"a"(2));
79
    return val;
80
};
81
 
82
void i915_dpms(struct drm_device *dev, int mode);
83
 
84
void i915_driver_thread()
85
{
86
    struct drm_i915_private *dev_priv = main_device->dev_private;
87
    struct workqueue_struct *cwq = dev_priv->wq;
88
    static int dpms = 1;
89
    static int dpms_lock = 0;
90
    oskey_t   key;
91
    unsigned long irqflags;
92
    int tmp;
93
 
94
    printf("%s\n",__FUNCTION__);
95
 
96
    asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(1),"c"(1));
97
    asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(4),"c"(0x46),"d"(0x330));
98
    asm volatile("int $0x40":"=a"(tmp):"a"(66),"b"(4),"c"(0xC6),"d"(0x330));
99
 
100
    while(driver_wq_state != 0)
101
    {
102
        key = get_key();
103
 
104
        if( (key.val != 1) && (key.state == 0x02))
105
        {
106
            if(key.code == 0x46 && dpms_lock == 0)
107
            {
108
                dpms_lock = 1;
109
                if(dpms == 1)
110
                {
111
                    i915_dpms(main_device, DRM_MODE_DPMS_OFF);
112
                    printf("dpms off\n");
113
                }
114
                else
115
                {
116
                    i915_dpms(main_device, DRM_MODE_DPMS_ON);
117
                    printf("dpms on\n");
118
                };
119
                dpms ^= 1;
120
                }
121
            else if(key.code == 0xC6)
122
                dpms_lock = 0;
123
        };
124
 
125
        spin_lock_irqsave(&cwq->lock, irqflags);
126
 
127
        while (!list_empty(&cwq->worklist))
128
        {
129
            struct work_struct *work = list_entry(cwq->worklist.next,
130
                                        struct work_struct, entry);
131
            work_func_t f = work->func;
132
            list_del_init(cwq->worklist.next);
133
 
134
            spin_unlock_irqrestore(&cwq->lock, irqflags);
135
            f(work);
136
            spin_lock_irqsave(&cwq->lock, irqflags);
137
        }
138
 
139
        spin_unlock_irqrestore(&cwq->lock, irqflags);
140
 
141
        delay(1);
142
    };
143
 
144
    asm volatile ("int $0x40"::"a"(-1));
145
}
146
 
3480 Serge 147
u32_t  __attribute__((externally_visible)) drvEntry(int action, char *cmdline)
2325 Serge 148
{
4104 Serge 149
    int err = 0;
2325 Serge 150
 
151
    if(action != 1)
3764 Serge 152
    {
153
        driver_wq_state = 0;
2325 Serge 154
        return 0;
3764 Serge 155
    };
2325 Serge 156
 
157
    if( GetService("DISPLAY") != 0 )
158
        return 0;
159
 
2340 Serge 160
    if( cmdline && *cmdline )
161
        parse_cmdline(cmdline, log);
2325 Serge 162
 
163
    if(!dbg_open(log))
164
    {
4126 Serge 165
        strcpy(log, "/tmp1/1/i915.log");
2325 Serge 166
 
167
        if(!dbg_open(log))
168
        {
169
            printf("Can't open %s\nExit\n", log);
170
            return 0;
171
        };
172
    }
4104 Serge 173
    dbgprintf(" i915 v3.12-6\n cmdline: %s\n", cmdline);
2325 Serge 174
 
2351 Serge 175
    cpu_detect();
3480 Serge 176
//    dbgprintf("\ncache line size %d\n", x86_clflush_size);
2351 Serge 177
 
2325 Serge 178
    enum_pci_devices();
179
 
180
    err = i915_init();
2338 Serge 181
    if(err)
182
    {
3298 Serge 183
        dbgprintf("Epic Fail :(\n");
184
        return 0;
2338 Serge 185
    };
4104 Serge 186
    init_display_kms(main_device);
2325 Serge 187
 
2338 Serge 188
    err = RegService("DISPLAY", display_handler);
2325 Serge 189
 
2338 Serge 190
    if( err != 0)
191
        dbgprintf("Set DISPLAY handler\n");
192
 
3764 Serge 193
    driver_wq_state = 1;
4104 Serge 194
 
4126 Serge 195
    CreateKernelThread(i915_driver_thread);
3482 Serge 196
 
2325 Serge 197
    return err;
198
};
199
 
3480 Serge 200
 
2344 Serge 201
#define CURRENT_API     0x0200      /*      2.00     */
202
#define COMPATIBLE_API  0x0100      /*      1.00     */
2338 Serge 203
 
2344 Serge 204
#define API_VERSION     (COMPATIBLE_API << 16) | CURRENT_API
2351 Serge 205
#define DISPLAY_VERSION  API_VERSION
2338 Serge 206
 
207
 
2352 Serge 208
#define SRV_GETVERSION          0
209
#define SRV_ENUM_MODES          1
210
#define SRV_SET_MODE            2
211
#define SRV_GET_CAPS            3
2342 Serge 212
 
2352 Serge 213
#define SRV_CREATE_SURFACE      10
214
#define SRV_DESTROY_SURFACE     11
215
#define SRV_LOCK_SURFACE        12
216
#define SRV_UNLOCK_SURFACE      13
3039 serge 217
#define SRV_RESIZE_SURFACE      14
3120 serge 218
#define SRV_BLIT_BITMAP         15
219
#define SRV_BLIT_TEXTURE        16
220
#define SRV_BLIT_VIDEO          17
2344 Serge 221
 
3290 Serge 222
 
3260 Serge 223
#define SRV_GET_PCI_INFO            20
4104 Serge 224
#define SRV_GET_PARAM               21
225
#define SRV_I915_GEM_CREATE         22
226
#define SRV_DRM_GEM_CLOSE           23
227
#define SRV_I915_GEM_PIN            24
3260 Serge 228
#define SRV_I915_GEM_SET_CACHEING   25
229
#define SRV_I915_GEM_GET_APERTURE   26
230
#define SRV_I915_GEM_PWRITE         27
231
#define SRV_I915_GEM_BUSY           28
232
#define SRV_I915_GEM_SET_DOMAIN     29
3263 Serge 233
#define SRV_I915_GEM_MMAP           30
3480 Serge 234
#define SRV_I915_GEM_MMAP_GTT       31
3263 Serge 235
#define SRV_I915_GEM_THROTTLE       32
236
#define SRV_FBINFO                  33
237
#define SRV_I915_GEM_EXECBUFFER2    34
3290 Serge 238
#define SRV_MASK_UPDATE             35
3260 Serge 239
 
3263 Serge 240
 
241
 
2338 Serge 242
#define check_input(size) \
243
    if( unlikely((inp==NULL)||(io->inp_size != (size))) )   \
244
        break;
245
 
246
#define check_output(size) \
247
    if( unlikely((outp==NULL)||(io->out_size != (size))) )   \
248
        break;
249
 
250
int _stdcall display_handler(ioctl_t *io)
251
{
3255 Serge 252
    struct drm_file *file;
253
 
2338 Serge 254
    int    retval = -1;
255
    u32_t *inp;
256
    u32_t *outp;
257
 
258
    inp = io->input;
259
    outp = io->output;
260
 
3255 Serge 261
    file = drm_file_handlers[0];
262
 
2338 Serge 263
    switch(io->io_code)
264
    {
265
        case SRV_GETVERSION:
266
            check_output(4);
2344 Serge 267
            *outp  = DISPLAY_VERSION;
2338 Serge 268
            retval = 0;
269
            break;
270
 
271
        case SRV_ENUM_MODES:
3031 serge 272
//            dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n",
273
//                       inp, io->inp_size, io->out_size );
2340 Serge 274
            check_output(4);
2338 Serge 275
//            check_input(*outp * sizeof(videomode_t));
276
            if( i915_modeset)
277
                retval = get_videomodes((videomode_t*)inp, outp);
278
            break;
279
 
280
        case SRV_SET_MODE:
3031 serge 281
//            dbgprintf("SRV_SET_MODE inp %x inp_size %x\n",
282
//                       inp, io->inp_size);
2338 Serge 283
            check_input(sizeof(videomode_t));
284
            if( i915_modeset )
285
                retval = set_user_mode((videomode_t*)inp);
286
            break;
3033 serge 287
 
2351 Serge 288
        case SRV_GET_CAPS:
289
            retval = get_driver_caps((hwcaps_t*)inp);
290
            break;
291
 
2344 Serge 292
        case SRV_CREATE_SURFACE:
293
//            check_input(8);
3243 Serge 294
//            retval = create_surface(main_device, (struct io_call_10*)inp);
2338 Serge 295
            break;
296
 
2352 Serge 297
        case SRV_LOCK_SURFACE:
3243 Serge 298
//            retval = lock_surface((struct io_call_12*)inp);
2352 Serge 299
            break;
2342 Serge 300
 
3039 serge 301
        case SRV_RESIZE_SURFACE:
3243 Serge 302
//            retval = resize_surface((struct io_call_14*)inp);
3039 serge 303
            break;
304
 
3255 Serge 305
        case SRV_BLIT_BITMAP:
3243 Serge 306
//            srv_blit_bitmap( inp[0], inp[1], inp[2],
307
//                        inp[3], inp[4], inp[5], inp[6]);
3033 serge 308
 
309
//            blit_tex( inp[0], inp[1], inp[2],
2351 Serge 310
//                    inp[3], inp[4], inp[5], inp[6]);
311
 
3255 Serge 312
            break;
2338 Serge 313
 
3260 Serge 314
        case SRV_GET_PCI_INFO:
3255 Serge 315
            get_pci_info((struct pci_device *)inp);
2338 Serge 316
            retval = 0;
317
            break;
3031 serge 318
 
3255 Serge 319
        case SRV_GET_PARAM:
320
            retval = gem_getparam(main_device, inp);
321
            break;
322
 
323
        case SRV_I915_GEM_CREATE:
324
            retval = i915_gem_create_ioctl(main_device, inp, file);
325
            break;
326
 
327
        case SRV_DRM_GEM_CLOSE:
328
            retval = drm_gem_close_ioctl(main_device, inp, file);
329
            break;
330
 
331
        case SRV_I915_GEM_PIN:
332
            retval = i915_gem_pin_ioctl(main_device, inp, file);
333
            break;
3260 Serge 334
 
335
        case SRV_I915_GEM_SET_CACHEING:
336
            retval = i915_gem_set_caching_ioctl(main_device, inp, file);
337
            break;
338
 
339
        case SRV_I915_GEM_GET_APERTURE:
340
            retval = i915_gem_get_aperture_ioctl(main_device, inp, file);
341
            break;
342
 
343
        case SRV_I915_GEM_PWRITE:
344
            retval = i915_gem_pwrite_ioctl(main_device, inp, file);
345
            break;
346
 
347
        case SRV_I915_GEM_BUSY:
348
            retval = i915_gem_busy_ioctl(main_device, inp, file);
349
            break;
350
 
351
        case SRV_I915_GEM_SET_DOMAIN:
352
            retval = i915_gem_set_domain_ioctl(main_device, inp, file);
353
            break;
354
 
3263 Serge 355
        case SRV_I915_GEM_THROTTLE:
356
            retval = i915_gem_throttle_ioctl(main_device, inp, file);
357
            break;
358
 
359
        case SRV_I915_GEM_MMAP:
360
            retval = i915_gem_mmap_ioctl(main_device, inp, file);
361
            break;
362
 
3480 Serge 363
        case SRV_I915_GEM_MMAP_GTT:
364
            retval = i915_gem_mmap_gtt_ioctl(main_device, inp, file);
365
            break;
366
 
367
 
3263 Serge 368
        case SRV_FBINFO:
369
            retval = i915_fbinfo(inp);
370
            break;
371
 
372
        case SRV_I915_GEM_EXECBUFFER2:
373
            retval = i915_gem_execbuffer2(main_device, inp, file);
374
            break;
375
 
3290 Serge 376
        case SRV_MASK_UPDATE:
377
            retval = i915_mask_update(main_device, inp, file);
378
            break;
379
 
2338 Serge 380
    };
381
 
382
    return retval;
383
}
384
 
385
 
2325 Serge 386
#define PCI_CLASS_REVISION      0x08
387
#define PCI_CLASS_DISPLAY_VGA   0x0300
388
#define PCI_CLASS_BRIDGE_HOST   0x0600
2326 Serge 389
#define PCI_CLASS_BRIDGE_ISA    0x0601
2325 Serge 390
 
391
int pci_scan_filter(u32_t id, u32_t busnr, u32_t devfn)
392
{
393
    u16_t vendor, device;
394
    u32_t class;
395
    int   ret = 0;
396
 
397
    vendor   = id & 0xffff;
398
    device   = (id >> 16) & 0xffff;
399
 
400
    if(vendor == 0x8086)
401
    {
402
        class = PciRead32(busnr, devfn, PCI_CLASS_REVISION);
403
        class >>= 16;
404
 
405
        if( (class == PCI_CLASS_DISPLAY_VGA) ||
2326 Serge 406
            (class == PCI_CLASS_BRIDGE_HOST) ||
407
            (class == PCI_CLASS_BRIDGE_ISA))
2325 Serge 408
            ret = 1;
409
    }
410
    return ret;
411
};
2340 Serge 412
 
413
 
414
static char* parse_path(char *p, char *log)
415
{
416
    char  c;
417
 
418
    while( (c = *p++) == ' ');
419
        p--;
420
    while( (c = *log++ = *p++) && (c != ' '));
421
    *log = 0;
422
 
423
    return p;
424
};
425
 
426
void parse_cmdline(char *cmdline, char *log)
427
{
428
    char *p = cmdline;
429
 
430
    char c = *p++;
431
 
432
    while( c )
433
    {
434
        if( c == '-')
435
        {
436
            switch(*p++)
437
            {
438
                case 'l':
439
                    p = parse_path(p, log);
440
                    break;
441
            };
442
        };
443
        c = *p++;
444
    };
445
};
446
 
2351 Serge 447
 
2344 Serge 448
static inline void __cpuid(unsigned int *eax, unsigned int *ebx,
2351 Serge 449
                unsigned int *ecx, unsigned int *edx)
2344 Serge 450
{
451
    /* ecx is often an input as well as an output. */
2351 Serge 452
    asm volatile("cpuid"
2344 Serge 453
        : "=a" (*eax),
454
          "=b" (*ebx),
455
          "=c" (*ecx),
456
          "=d" (*edx)
2351 Serge 457
        : "0" (*eax), "2" (*ecx)
458
        : "memory");
2344 Serge 459
}
460
 
2351 Serge 461
 
462
 
2344 Serge 463
static inline void cpuid(unsigned int op,
464
                         unsigned int *eax, unsigned int *ebx,
465
                         unsigned int *ecx, unsigned int *edx)
466
{
467
        *eax = op;
468
        *ecx = 0;
469
        __cpuid(eax, ebx, ecx, edx);
470
}
471
 
472
void cpu_detect()
473
{
474
    u32 junk, tfms, cap0, misc;
475
 
476
    cpuid(0x00000001, &tfms, &misc, &junk, &cap0);
477
 
478
    if (cap0 & (1<<19))
479
    {
480
        x86_clflush_size = ((misc >> 8) & 0xff) * 8;
481
    }
3482 Serge 482
 
483
    tsc_khz = (unsigned int)(GetCpuFreq()/1000);
2344 Serge 484
}
485
 
3243 Serge 486
 
487
int get_driver_caps(hwcaps_t *caps)
488
{
489
    int ret = 0;
490
 
491
    switch(caps->idx)
492
    {
493
        case 0:
494
            caps->opt[0] = 0;
495
            caps->opt[1] = 0;
496
            break;
497
 
498
        case 1:
499
            caps->cap1.max_tex_width  = 4096;
500
            caps->cap1.max_tex_height = 4096;
501
            break;
502
        default:
503
            ret = 1;
504
    };
505
    caps->idx = 1;
506
    return ret;
507
}
508
 
3255 Serge 509
 
510
void get_pci_info(struct pci_device *dev)
511
{
512
    struct pci_dev *pdev = main_device->pdev;
513
 
514
    memset(dev, sizeof(*dev), 0);
515
 
516
    dev->domain     = 0;
517
    dev->bus        = pdev->busnr;
518
    dev->dev        = pdev->devfn >> 3;
519
    dev->func       = pdev->devfn & 7;
520
    dev->vendor_id  = pdev->vendor;
521
    dev->device_id  = pdev->device;
522
    dev->revision   = pdev->revision;
523
};