Subversion Repositories Kolibri OS

Rev

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