Subversion Repositories Kolibri OS

Rev

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