Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
2340 Serge 1
 
2
3
 
2338 Serge 4
#include "drm.h"
5
#include "i915_drm.h"
6
#include "i915_drv.h"
7
#include "intel_drv.h"
8
9
 
10
#include 
11
#include 
12
#include 
13
#include 
14
15
 
16
17
 
2340 Serge 18
2338 Serge 19
 
20
{
21
    kobj_t     header;
22
23
 
24
    uint32_t   hot_x;
25
    uint32_t   hot_y;
26
27
 
28
    struct drm_i915_gem_object  *cobj;
29
}cursor_t;
30
31
 
32
#define CURSOR_HEIGHT 64
33
34
 
35
 
36
{
37
    int  x;
38
    int  y;
39
    int  width;
40
    int  height;
41
    int  bpp;
42
    int  vrefresh;
43
    int  pitch;
44
    int  lfb;
45
46
 
47
    struct drm_device    *ddev;
48
    struct drm_connector *connector;
49
    struct drm_crtc      *crtc;
50
51
 
52
53
 
54
    int       (*init_cursor)(cursor_t*);
55
    cursor_t* (__stdcall *select_cursor)(cursor_t*);
56
    void      (*show_cursor)(int show);
57
    void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
58
    void      (__stdcall *restore_cursor)(int x, int y);
59
    void      (*disable_mouse)(void);
60
    u32  mask_seqno;
2361 Serge 61
    u32  check_mouse;
3031 serge 62
    u32  check_m_pixel;
63
};
2338 Serge 64
65
 
66
 
67
struct drm_i915_gem_object *main_fb_obj;
4560 Serge 68
2338 Serge 69
 
2340 Serge 70
u32_t cmd_offset;
71
72
 
2351 Serge 73
int  sna_init();
74
75
 
2338 Serge 76
static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
77
static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
78
79
 
80
{};
81
82
 
83
{};
84
85
 
4560 Serge 86
 
3031 serge 87
{
88
    static char name[4];
89
90
 
91
    name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
92
    name[2] = (x[1] & 0x1F) + '@';
93
    name[3] = 0;
94
95
 
96
}
97
98
 
99
              videomode_t *reqmode, bool strict)
100
{
101
    drm_i915_private_t      *dev_priv   = dev->dev_private;
102
    struct drm_fb_helper    *fb_helper  = &dev_priv->fbdev->helper;
103
104
 
105
    struct drm_display_mode *mode       = NULL, *tmpmode;
106
    struct drm_framebuffer  *fb         = NULL;
107
    struct drm_crtc         *crtc;
108
    struct drm_encoder      *encoder;
109
    struct drm_mode_set     set;
110
    const char *con_name;
4371 Serge 111
    const char *enc_name;
112
    unsigned hdisplay, vdisplay;
3031 serge 113
    int stride;
4557 Serge 114
    int ret;
3031 serge 115
116
 
117
118
 
119
    {
120
        if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
121
            (drm_mode_height(tmpmode)   == reqmode->height) &&
122
            (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
123
        {
124
            mode = tmpmode;
125
            goto do_set;
126
        }
127
    };
128
129
 
130
    {
131
        list_for_each_entry(tmpmode, &connector->modes, head)
132
        {
133
            if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
134
                (drm_mode_height(tmpmode) == reqmode->height) )
135
            {
136
                mode = tmpmode;
137
                goto do_set;
138
            }
139
        };
140
    };
141
142
 
3037 serge 143
3031 serge 144
 
145
146
 
147
148
 
149
    crtc = encoder->crtc;
150
151
 
152
    enc_name = drm_get_encoder_name(encoder);
153
154
 
155
              reqmode->width, reqmode->height, crtc->base.id,
156
              con_name, enc_name);
157
158
 
159
160
 
161
    vdisplay = mode->vdisplay;
162
163
 
164
        swap(hdisplay, vdisplay);
165
166
 
167
168
 
169
    fb->height = reqmode->height;
170
171
 
4557 Serge 172
    {
173
        main_fb_obj->tiling_mode = I915_TILING_X;
4560 Serge 174
4280 Serge 175
 
4557 Serge 176
            for (stride = 512; stride < reqmode->width * 4; stride <<= 1);
177
        else
178
            stride = ALIGN(reqmode->width * 4, 512);
179
    }
180
    else
181
    {
182
        main_fb_obj->tiling_mode = I915_TILING_NONE;
4560 Serge 183
        stride = ALIGN(reqmode->width * 4, 64);
4557 Serge 184
    }
185
4280 Serge 186
 
4557 Serge 187
    fb->pitches[1]  =
188
    fb->pitches[2]  =
189
    fb->pitches[3]  = stride;
190
191
 
4560 Serge 192
4557 Serge 193
 
3031 serge 194
    fb->depth = 24;
195
196
 
197
    crtc->enabled = true;
198
    os_display->crtc = crtc;
199
200
 
4560 Serge 201
4280 Serge 202
 
3031 serge 203
    set.x = 0;
204
    set.y = 0;
205
    set.mode = mode;
206
    set.connectors = &connector;
207
    set.num_connectors = 1;
208
    set.fb = fb;
209
    ret = crtc->funcs->set_config(&set);
210
    mutex_unlock(&dev->mode_config.mutex);
211
212
 
213
    {
214
        os_display->width    = fb->width;
215
        os_display->height   = fb->height;
216
        os_display->vrefresh = drm_mode_vrefresh(mode);
217
218
 
219
220
 
3037 serge 221
                       fb->width, fb->height, fb->pitches[0]);
3031 serge 222
    }
223
    else
224
        DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
225
                   fb->width, fb->height, crtc);
226
227
 
228
}
229
230
 
2338 Serge 231
{
232
    struct drm_display_mode  *mode;
233
    int count = 0;
234
235
 
236
    {
237
        count++;
238
    };
239
    return count;
240
};
241
242
 
3031 serge 243
{
244
    struct drm_connector  *connector;
245
    struct drm_connector_helper_funcs *connector_funcs;
246
247
 
248
249
 
250
    {
251
        struct drm_encoder  *encoder;
252
        struct drm_crtc     *crtc;
253
254
 
255
            continue;
256
257
 
258
        encoder = connector_funcs->best_encoder(connector);
259
        if( encoder == NULL)
260
            continue;
261
262
 
263
264
 
265
266
 
3037 serge 267
                   connector, connector->base.id,
3031 serge 268
                   connector->status, connector->encoder,
269
                   crtc);
270
271
 
272
//            continue;
273
274
 
275
276
 
277
    };
278
279
 
280
};
281
282
 
4371 Serge 283
{
2338 Serge 284
    struct drm_connector *tmp = NULL;
4371 Serge 285
    struct drm_connector_helper_funcs *connector_funcs;
2338 Serge 286
    struct drm_encoder   *encoder;
4560 Serge 287
2338 Serge 288
 
4371 Serge 289
    {
2338 Serge 290
        if( tmp->status != connector_status_connected)
4371 Serge 291
            continue;
2338 Serge 292
293
 
4371 Serge 294
        encoder = connector_funcs->best_encoder(tmp);
295
        if( encoder == NULL)
2338 Serge 296
        {
297
            DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n",
3037 serge 298
                      tmp, tmp->base.id);
4371 Serge 299
            continue;
2338 Serge 300
        };
4371 Serge 301
2338 Serge 302
 
4371 Serge 303
304
 
4280 Serge 305
               tmp, tmp->base.id, tmp->status, tmp->encoder,
4371 Serge 306
               tmp->encoder->crtc, tmp->encoder->crtc->base.id );
307
2338 Serge 308
 
4371 Serge 309
    };
2338 Serge 310
311
 
4371 Serge 312
}
313
4280 Serge 314
 
4371 Serge 315
{
4398 Serge 316
    struct drm_crtc *tmp_crtc;
4560 Serge 317
    int crtc_mask = 1;
318
2338 Serge 319
 
4560 Serge 320
    {
321
        if (encoder->possible_crtcs & crtc_mask)
322
        {
2338 Serge 323
            encoder->crtc = tmp_crtc;
4371 Serge 324
            dbgprintf("CRTC %p\n", tmp_crtc);
325
            return tmp_crtc;
326
        };
2338 Serge 327
        crtc_mask <<= 1;
4560 Serge 328
    };
329
    return NULL;
4371 Serge 330
};
4398 Serge 331
2338 Serge 332
 
4371 Serge 333
{
334
    struct drm_display_mode *mode;
335
336
 
337
    {
338
        DRM_DEBUG_KMS("check mode w:%d h:%d %dHz\n",
4389 Serge 339
                drm_mode_width(mode), drm_mode_height(mode),
4371 Serge 340
                drm_mode_vrefresh(mode));
341
342
 
343
            os_display->height == drm_mode_height(mode) &&
344
            drm_mode_vrefresh(mode) == 60)
345
        {
346
            usermode->width  = os_display->width;
347
            usermode->height = os_display->height;
348
            usermode->freq   = 60;
349
            return 1;
350
        }
351
    }
352
    return 0;
353
}
354
355
 
356
{
357
    struct drm_connector    *connector;
358
    struct drm_connector_helper_funcs *connector_funcs;
359
    struct drm_encoder      *encoder;
360
    struct drm_crtc         *crtc;
361
    struct drm_framebuffer  *fb;
362
363
 
364
    u32_t      ifl;
365
    int        err;
366
367
 
368
369
 
370
    if(connector == NULL)
371
    {
372
        DRM_DEBUG_KMS("No active connectors!\n");
373
        mutex_unlock(&dev->mode_config.mutex);
374
        return -1;
375
    };
376
377
 
378
    crtc = encoder->crtc;
379
380
 
381
        crtc = get_possible_crtc(dev, encoder);
382
383
 
2338 Serge 384
    {
385
        DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id);
4280 Serge 386
        mutex_unlock(&dev->mode_config.mutex);
387
        return -1;
2338 Serge 388
    };
389
390
 
4280 Serge 391
2338 Serge 392
 
393
    os_display->ddev = dev;
394
    os_display->connector = connector;
395
    os_display->crtc = crtc;
396
397
 
398
399
 
400
 
401
    {
402
        struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
403
404
 
405
        {
406
            init_cursor(cursor);
407
        };
408
409
 
410
        os_display->init_cursor    = init_cursor;
411
        os_display->select_cursor  = select_cursor_kms;
412
        os_display->show_cursor    = NULL;
413
        os_display->move_cursor    = move_cursor_kms;
414
        os_display->restore_cursor = restore_cursor;
415
        os_display->disable_mouse  = disable_mouse;
416
417
 
418
        intel_crtc->cursor_y = os_display->height/2;
419
420
 
421
    };
422
    safe_sti(ifl);
423
424
 
4280 Serge 425
        (usermode->height == 0))
426
    {
427
        if( !get_boot_mode(connector, usermode))
4371 Serge 428
        {
429
            struct drm_display_mode *mode;
4560 Serge 430
4280 Serge 431
 
432
            usermode->width  = drm_mode_width(mode);
433
            usermode->height = drm_mode_height(mode);
434
            usermode->freq   = drm_mode_vrefresh(mode);
435
        };
436
    };
437
438
 
439
440
 
441
442
 
3243 Serge 443
    err = init_bitmaps();
2342 Serge 444
#endif
3243 Serge 445
2340 Serge 446
 
4280 Serge 447
448
 
2338 Serge 449
};
450
451
 
452
 
453
{
454
    int err = -1;
455
456
 
3031 serge 457
2338 Serge 458
 
459
    {
460
        *count = os_display->supported_modes;
461
        err = 0;
462
    }
463
    else if( mode != NULL )
464
    {
465
        struct drm_display_mode  *drmmode;
466
        int i = 0;
467
468
 
469
            *count = os_display->supported_modes;
470
471
 
472
        {
473
            if( i < *count)
474
            {
475
                mode->width  = drm_mode_width(drmmode);
476
                mode->height = drm_mode_height(drmmode);
477
                mode->bpp    = 32;
478
                mode->freq   = drm_mode_vrefresh(drmmode);
479
                i++;
480
                mode++;
481
            }
482
            else break;
483
        };
484
        *count = i;
485
        err = 0;
486
    };
487
    return err;
488
};
489
490
 
491
{
492
    int err = -1;
493
494
 
3031 serge 495
//               mode->width, mode->height, mode->freq);
496
2338 Serge 497
 
498
        (mode->height != 0)  &&
499
        (mode->freq   != 0 ) &&
500
        ( (mode->width   != os_display->width)  ||
501
          (mode->height  != os_display->height) ||
502
          (mode->freq    != os_display->vrefresh) ) )
503
    {
504
        if( set_mode(os_display->ddev, os_display->connector, mode, true) )
505
            err = 0;
506
    };
507
508
 
509
};
510
511
 
4126 Serge 512
{
513
    const struct drm_connector_funcs *f = os_display->connector->funcs;
4371 Serge 514
4126 Serge 515
 
516
};
517
518
 
2338 Serge 519
{
520
    list_del(&cursor->list);
3037 serge 521
2342 Serge 522
 
3037 serge 523
524
 
525
    drm_gem_object_unreference(&cursor->cobj->base);
526
    mutex_unlock(&main_device->struct_mutex);
527
528
 
2338 Serge 529
};
530
531
 
532
{
533
    struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
534
    struct drm_i915_gem_object *obj;
535
    uint32_t *bits;
536
    uint32_t *src;
537
    void     *mapped;
3037 serge 538
2338 Serge 539
 
540
    int       ret;
541
542
 
543
    {
544
        bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4);
545
        if (unlikely(bits == NULL))
546
            return ENOMEM;
547
        cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
548
    }
549
    else
550
    {
551
        obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4);
552
        if (unlikely(obj == NULL))
553
            return -ENOMEM;
554
555
 
4104 Serge 556
        if (ret) {
2338 Serge 557
            drm_gem_object_unreference(&obj->base);
2344 Serge 558
            return ret;
2338 Serge 559
        }
560
561
 
4104 Serge 562
        if (ret)
563
        {
564
            i915_gem_object_unpin(obj);
565
            drm_gem_object_unreference(&obj->base);
566
            return ret;
567
        }
568
/* You don't need to worry about fragmentation issues.
2338 Serge 569
 * GTT space is continuous. I guarantee it.                           */
570
571
 
4104 Serge 572
                    CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW);
2338 Serge 573
574
 
575
        {
576
            i915_gem_object_unpin(obj);
2344 Serge 577
            drm_gem_object_unreference(&obj->base);
578
            return -ENOMEM;
2338 Serge 579
        };
580
        cursor->cobj = obj;
581
    };
582
583
 
584
585
 
586
    {
587
        for(j = 0; j < 32; j++)
588
            *bits++ = *src++;
589
        for(j = 32; j < CURSOR_WIDTH; j++)
590
            *bits++ = 0;
591
    }
592
    for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
593
        *bits++ = 0;
594
595
 
3037 serge 596
597
 
2338 Serge 598
599
 
2340 Serge 600
2338 Serge 601
 
602
603
 
604
605
 
606
}
607
608
 
609
 
610
{
611
    struct drm_crtc *crtc = os_display->crtc;
4557 Serge 612
    x-= cursor->hot_x;
613
    y-= cursor->hot_y;
614
2338 Serge 615
 
4557 Serge 616
        crtc->funcs->cursor_move(crtc, x, y);
617
2338 Serge 618
 
619
620
 
621
 
622
{
623
    struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
624
    struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc);
625
    cursor_t *old;
626
627
 
628
    os_display->cursor = cursor;
629
630
 
4557 Serge 631
632
 
2338 Serge 633
       intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj);
4104 Serge 634
    else
2338 Serge 635
        intel_crtc->cursor_addr = (addr_t)cursor->cobj;
2352 Serge 636
2338 Serge 637
 
638
    intel_crtc->cursor_height = 32;
639
640
 
641
    return old;
642
};
643
644
 
4371 Serge 645
{
3263 Serge 646
    struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
4389 Serge 647
    struct intel_crtc *crtc = to_intel_crtc(os_display->crtc);
648
649
 
4371 Serge 650
2340 Serge 651
 
4371 Serge 652
    fb->width  = os_display->width;
3263 Serge 653
    fb->height = os_display->height;
654
    fb->pitch  = obj->stride;
4371 Serge 655
    fb->tiling = obj->tiling_mode;
656
    fb->crtc   = crtc->base.base.id;
4389 Serge 657
    fb->pipe   = crtc->pipe;
658
2340 Serge 659
 
3263 Serge 660
}
4371 Serge 661
3263 Serge 662
 
4371 Serge 663
 
3277 Serge 664
{
665
    int left;
666
    int top;
667
    int right;
668
    int bottom;
669
}rect_t;
670
3263 Serge 671
 
3277 Serge 672
 
673
674
 
675
{
676
    u32_t   addr;
677
678
 
679
    addr+= sizeof(display_t);            /*  shoot me  */
680
    return *(u32_t*)addr;
681
}
682
683
 
684
685
 
686
            struct drm_file *file)
687
{
688
    struct drm_i915_mask *mask = data;
689
    struct drm_gem_object *obj;
690
    static unsigned int mask_seqno[256];
691
    rect_t winrc;
692
    u32    slot;
693
    int    ret=0;
4371 Serge 694
3277 Serge 695
 
696
    if (obj == NULL)
697
        return -ENOENT;
698
699
 
700
        drm_gem_object_unreference_unlocked(obj);
701
        return -EINVAL;
702
    }
703
704
 
705
    {
706
//        static warn_count;
3298 Serge 707
3277 Serge 708
 
3290 Serge 709
        mask->height   = winrc.bottom - winrc.top + 1;
710
        mask->bo_pitch = (mask->width+15) & ~15;
711
712
 
3298 Serge 713
        if(warn_count < 1)
3277 Serge 714
        {
715
            printf("left %d top %d right %d bottom %d\n",
716
                    winrc.left, winrc.top, winrc.right, winrc.bottom);
717
            printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size);
718
            warn_count++;
719
        };
720
#endif
3298 Serge 721
722
 
4104 Serge 723
3277 Serge 724
 
3290 Serge 725
 
3277 Serge 726
727
 
728
    {
729
        u8* src_offset;
730
        u8* dst_offset;
731
        u32 ifl;
732
733
 
734
        if (ret)
735
            goto err1;
4371 Serge 736
3277 Serge 737
 
738
        if(ret != 0 )
4398 Serge 739
        {
3277 Serge 740
            dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__);
4371 Serge 741
            goto err2;
742
        };
3277 Serge 743
744
 
745
746
 
747
748
 
749
 
750
        src_offset+= get_display_map();
751
        dst_offset = (u8*)mask->bo_map;
752
753
 
3290 Serge 754
3277 Serge 755
 
756
        {
757
            mask_seqno[slot] = os_display->mask_seqno;
758
759
 
760
761
 
762
            "movd       %[slot],   %%xmm6         \n"
4560 Serge 763
            "punpckldq  %%xmm6, %%xmm6            \n"
3277 Serge 764
            "punpcklqdq %%xmm6, %%xmm6            \n"
765
            :: [slot]  "m" (slot)
766
            :"xmm6");
767
768
 
769
            {
770
                int tmp_w = mask->width;
4398 Serge 771
3277 Serge 772
 
773
                u8* tmp_dst = dst_offset;
774
775
 
776
                dst_offset+= mask->bo_pitch;
777
778
 
779
                {
780
                    __asm__ __volatile__ (
781
                    "movdqu     (%0),   %%xmm0            \n"
782
                    "movdqu   16(%0),   %%xmm1            \n"
783
                    "movdqu   32(%0),   %%xmm2            \n"
784
                    "movdqu   48(%0),   %%xmm3            \n"
785
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
786
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
787
                    "pcmpeqb    %%xmm6, %%xmm2            \n"
788
                    "pcmpeqb    %%xmm6, %%xmm3            \n"
789
                    "movdqa     %%xmm0,   (%%edi)         \n"
790
                    "movdqa     %%xmm1, 16(%%edi)         \n"
791
                    "movdqa     %%xmm2, 32(%%edi)         \n"
792
                    "movdqa     %%xmm3, 48(%%edi)         \n"
793
794
 
795
                    :"xmm0","xmm1","xmm2","xmm3");
796
                    tmp_w -= 64;
797
                    tmp_src += 64;
798
                    tmp_dst += 64;
799
                }
800
801
 
802
                {
803
                    __asm__ __volatile__ (
804
                    "movdqu     (%0),   %%xmm0            \n"
805
                    "movdqu   16(%0),   %%xmm1            \n"
806
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
807
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
808
                    "movdqa     %%xmm0,   (%%edi)         \n"
809
                    "movdqa     %%xmm1, 16(%%edi)         \n"
810
811
 
812
                    :"xmm0","xmm1");
813
                    tmp_w -= 32;
814
                    tmp_src += 32;
815
                    tmp_dst += 32;
816
                }
817
818
 
4398 Serge 819
                {
3277 Serge 820
                    __asm__ __volatile__ (
821
                    "movdqu     (%0),   %%xmm0            \n"
822
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
823
                    "movdqa     %%xmm0,   (%%edi)         \n"
824
                    :: "r" (tmp_src), "D" (tmp_dst)
825
                    :"xmm0");
826
                    tmp_w -= 16;
827
                    tmp_src += 16;
828
                    tmp_dst += 16;
829
                }
830
4398 Serge 831
 
832
                {
833
                    __asm__ __volatile__ (
834
                    "movq       (%0),   %%xmm0            \n"
835
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
836
                    "movq       %%xmm0,   (%%edi)         \n"
837
                    :: "r" (tmp_src), "D" (tmp_dst)
838
                    :"xmm0");
839
                    tmp_w -= 8;
840
                    tmp_src += 8;
841
                    tmp_dst += 8;
842
                }
843
                if( tmp_w >= 4 )
844
                {
845
                    __asm__ __volatile__ (
846
                    "movd       (%0),   %%xmm0            \n"
847
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
848
                    "movd       %%xmm0,   (%%edi)         \n"
849
                    :: "r" (tmp_src), "D" (tmp_dst)
850
                    :"xmm0");
851
                    tmp_w -= 4;
852
                    tmp_src += 4;
853
                    tmp_dst += 4;
854
                }
855
                while(tmp_w--)
856
                    *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
857
            };
3277 Serge 858
        };
859
        safe_sti(ifl);
860
4371 Serge 861
 
862
    }
4539 Serge 863
864
 
865
    mutex_unlock(&dev->struct_mutex);
866
err1:
867
    drm_gem_object_unreference(obj);
868
869
 
870
}
871
872
 
873
            struct drm_file *file)
874
{
875
    struct drm_i915_mask_update *mask = data;
876
    struct drm_gem_object *obj;
877
    static unsigned int mask_seqno[256];
878
    static warn_count;
879
880
 
881
    u32    winw,winh;
882
    u32    ml,mt,mr,mb;
883
    u32    slot;
884
    int    ret = 0;
885
    slot = *((u8*)CURRENT_TASK);
886
887
 
888
        return 0;
889
890
 
891
    win.right+= 1;
892
    win.bottom+=  1;
893
894
 
895
    winh = win.bottom - win.top;
896
897
 
898
       mask->dy >= winh)
899
       return 1;
900
901
 
902
    mt = win.top  + mask->dy;
903
    mr = ml + mask->width;
904
    mb = mt + mask->height;
905
906
 
907
        mr < win.left   || mb < win.top )
908
        return 1;
909
910
 
911
        mr = win.right;
912
913
 
914
        mb = win.bottom;
915
916
 
917
    mask->height = mb - mt;
918
919
 
920
        mask->height== 0 )
921
        return 1;
922
923
 
924
    if (obj == NULL)
925
        return -ENOENT;
926
927
 
928
        drm_gem_object_unreference_unlocked(obj);
929
        return -EINVAL;
930
    }
931
932
 
4560 Serge 933
    if(warn_count < 1000)
4539 Serge 934
    {
935
        printf("left %d top %d right %d bottom %d\n",
936
                ml, mt, mr, mb);
937
        warn_count++;
938
    };
939
#endif
940
941
 
942
 
943
944
 
945
        u8* src_offset;
946
        u8* dst_offset;
947
        u32 ifl;
948
949
 
950
        if (ret)
951
            goto err1;
952
953
 
954
955
 
956
        src_offset+= get_display_map();
957
        dst_offset = (u8*)mask->bo_map;
958
959
 
960
961
 
962
        {
4371 Serge 963
            mask_seqno[slot] = os_display->mask_seqno;
4539 Serge 964
965
 
966
967
 
968
            "movd       %[slot],   %%xmm6         \n"
969
            "punpckldq  %%xmm6, %%xmm6            \n"
970
            "punpcklqdq %%xmm6, %%xmm6            \n"
971
            :: [slot]  "m" (slot)
972
            :"xmm6");
973
974
 
975
            {
976
                int tmp_w = mask->width;
977
978
 
979
                u8* tmp_dst = dst_offset;
980
981
 
982
                dst_offset+= mask->bo_pitch;
983
984
 
985
                {
986
                    __asm__ __volatile__ (
987
                    "movdqu     (%0),   %%xmm0            \n"
988
                    "movdqu   16(%0),   %%xmm1            \n"
989
                    "movdqu   32(%0),   %%xmm2            \n"
990
                    "movdqu   48(%0),   %%xmm3            \n"
991
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
992
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
993
                    "pcmpeqb    %%xmm6, %%xmm2            \n"
994
                    "pcmpeqb    %%xmm6, %%xmm3            \n"
995
                    "movdqa     %%xmm0,   (%%edi)         \n"
996
                    "movdqa     %%xmm1, 16(%%edi)         \n"
997
                    "movdqa     %%xmm2, 32(%%edi)         \n"
998
                    "movdqa     %%xmm3, 48(%%edi)         \n"
999
1000
 
1001
                    :"xmm0","xmm1","xmm2","xmm3");
1002
                    tmp_w -= 64;
1003
                    tmp_src += 64;
1004
                    tmp_dst += 64;
1005
                }
1006
1007
 
1008
                {
1009
                    __asm__ __volatile__ (
1010
                    "movdqu     (%0),   %%xmm0            \n"
1011
                    "movdqu   16(%0),   %%xmm1            \n"
1012
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1013
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
1014
                    "movdqa     %%xmm0,   (%%edi)         \n"
1015
                    "movdqa     %%xmm1, 16(%%edi)         \n"
1016
1017
 
1018
                    :"xmm0","xmm1");
1019
                    tmp_w -= 32;
1020
                    tmp_src += 32;
1021
                    tmp_dst += 32;
1022
                }
1023
1024
 
1025
                {
1026
                    __asm__ __volatile__ (
1027
                    "movdqu     (%0),   %%xmm0            \n"
1028
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1029
                    "movdqa     %%xmm0,   (%%edi)         \n"
1030
                    :: "r" (tmp_src), "D" (tmp_dst)
1031
                    :"xmm0");
1032
                    tmp_w -= 16;
1033
                    tmp_src += 16;
1034
                    tmp_dst += 16;
1035
                }
1036
1037
 
1038
                {
1039
                    __asm__ __volatile__ (
1040
                    "movq       (%0),   %%xmm0            \n"
1041
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1042
                    "movq       %%xmm0,   (%%edi)         \n"
1043
                    :: "r" (tmp_src), "D" (tmp_dst)
1044
                    :"xmm0");
1045
                    tmp_w -= 8;
1046
                    tmp_src += 8;
1047
                    tmp_dst += 8;
1048
                }
1049
                if( tmp_w >= 4 )
1050
                {
4560 Serge 1051
                    __asm__ __volatile__ (
4539 Serge 1052
                    "movd       (%0),   %%xmm0            \n"
1053
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1054
                    "movd       %%xmm0,   (%%edi)         \n"
1055
                    :: "r" (tmp_src), "D" (tmp_dst)
1056
                    :"xmm0");
1057
                    tmp_w -= 4;
1058
                    tmp_src += 4;
1059
                    tmp_dst += 4;
1060
                }
1061
                while(tmp_w--)
1062
                    *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
1063
            };
1064
        };
4371 Serge 1065
        safe_sti(ifl);
4539 Serge 1066
1067
 
1068
    }
3277 Serge 1069
#endif
4539 Serge 1070
3277 Serge 1071
 
4371 Serge 1072
    mutex_unlock(&dev->struct_mutex);
1073
err1:
1074
    drm_gem_object_unreference(obj);
3277 Serge 1075
1076
 
4371 Serge 1077
}
3277 Serge 1078
1079
 
1080
 
1081
 
2360 Serge 1082
 
1083
 
1084
 
1085
 
1086
 
1087
 
1088
 
1089
 
3031 serge 1090
2360 Serge 1091
 
3031 serge 1092
{
1093
    u32 tmp = GetTimerTicks();
1094
2360 Serge 1095
 
3031 serge 1096
    ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
1097
}
1098
2360 Serge 1099
 
4104 Serge 1100
{
3031 serge 1101
    while (nsec >= NSEC_PER_SEC) {
4104 Serge 1102
        /*
1103
         * The following asm() prevents the compiler from
1104
         * optimising this loop into a modulo operation. See
1105
         * also __iter_div_u64_rem() in include/linux/time.h
1106
         */
1107
        asm("" : "+rm"(nsec));
1108
        nsec -= NSEC_PER_SEC;
1109
        ++sec;
1110
    }
1111
    while (nsec < 0) {
1112
        asm("" : "+rm"(nsec));
1113
        nsec += NSEC_PER_SEC;
1114
        --sec;
1115
    }
1116
    ts->tv_sec = sec;
1117
    ts->tv_nsec = nsec;
1118
}
3031 serge 1119
2360 Serge 1120
 
3480 Serge 1121
prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
1122
{
1123
    unsigned long flags;
1124
3031 serge 1125
 
3480 Serge 1126
    spin_lock_irqsave(&q->lock, flags);
1127
    if (list_empty(&wait->task_list))
1128
            __add_wait_queue(q, wait);
1129
    spin_unlock_irqrestore(&q->lock, flags);
1130
}
1131
1132
 
1133
 * finish_wait - clean up after waiting in a queue
1134
 * @q: waitqueue waited on
1135
 * @wait: wait descriptor
1136
 *
1137
 * Sets current thread back to running state and removes
1138
 * the wait descriptor from the given waitqueue if still
1139
 * queued.
1140
 */
1141
void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
1142
{
1143
    unsigned long flags;
1144
1145
 
1146
    /*
1147
     * We can check for list emptiness outside the lock
1148
     * IFF:
1149
     *  - we use the "careful" check that verifies both
1150
     *    the next and prev pointers, so that there cannot
1151
     *    be any half-pending updates in progress on other
1152
     *    CPU's that we haven't seen yet (and that might
1153
     *    still change the stack area.
1154
     * and
1155
     *  - all other users take the lock (ie we can only
1156
     *    have _one_ other CPU that looks at or modifies
1157
     *    the list).
1158
     */
1159
    if (!list_empty_careful(&wait->task_list)) {
1160
            spin_lock_irqsave(&q->lock, flags);
1161
            list_del_init(&wait->task_list);
1162
            spin_unlock_irqrestore(&q->lock, flags);
1163
    }
1164
1165
 
1166
}
1167
1168
 
1169
{
1170
    list_del_init(&wait->task_list);
1171
    return 1;
1172
}
1173
1174
 
3482 Serge 1175
{
1176
    unsigned int res = w - ((w >> 1) & 0x5555);
1177
    res = (res & 0x3333) + ((res >> 2) & 0x3333);
1178
    res = (res + (res >> 4)) & 0x0F0F;
1179
    return (res + (res >> 8)) & 0x00FF;
1180
}
1181
3480 Serge 1182
 
1183
 
3482 Serge 1184
{
1185
    unsigned long j0 = GetTimerTicks();
1186
3480 Serge 1187
 
3482 Serge 1188
    return round_jiffies_common(j + j0, true) - j0;
1189
}
1190
3480 Serge 1191
 
3482 Serge 1192