Subversion Repositories Kolibri OS

Rev

Rev 6937 | Details | Compare with Previous | Last modification | View Log | RSS feed

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