Subversion Repositories Kolibri OS

Rev

Rev 6660 | Go to most recent revision | 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;
6283 serge 545
ENTER();
4371 Serge 546
 
6283 serge 547
    drm_for_each_plane(plane, dev)
548
    {
549
        drm_plane_helper_disable(plane);
550
    };
551
 
4371 Serge 552
    mutex_lock(&dev->mode_config.mutex);
5060 serge 553
    ret = choose_config(dev, &connector, &crtc);
554
    if(ret)
4371 Serge 555
    {
6088 serge 556
        mutex_unlock(&dev->mode_config.mutex);
4371 Serge 557
        DRM_DEBUG_KMS("No active connectors!\n");
558
        return -1;
559
    };
560
 
2338 Serge 561
    os_display = GetDisplay();
562
    os_display->ddev = dev;
563
    os_display->connector = connector;
564
    os_display->crtc = crtc;
565
    os_display->supported_modes = count_connector_modes(connector);
6088 serge 566
    mutex_unlock(&dev->mode_config.mutex);
2338 Serge 567
 
6283 serge 568
    init_system_cursors(dev);
6088 serge 569
 
570
    ret = -1;
571
 
572
    if(connector->cmdline_mode.specified == true)
573
        ret = set_cmdline_mode(dev, connector);
574
 
575
    if(ret !=0)
4280 Serge 576
    {
6088 serge 577
        mutex_lock(&dev->mode_config.mutex);
578
 
579
        if( (usermode->width == 0) ||
580
            (usermode->height == 0))
4371 Serge 581
        {
6088 serge 582
            if( !get_boot_mode(connector, usermode))
583
            {
584
                struct drm_display_mode *mode;
4280 Serge 585
 
6088 serge 586
                mode = list_entry(connector->modes.next, typeof(*mode), head);
587
                usermode->width  = mode->hdisplay;
588
                usermode->height = mode->vdisplay;
589
                usermode->freq   = drm_mode_vrefresh(mode);
590
            };
4280 Serge 591
        };
6088 serge 592
        mutex_unlock(&dev->mode_config.mutex);
593
 
594
        set_mode(dev, os_display->connector, os_display->crtc, usermode, false);
4280 Serge 595
    };
596
 
6283 serge 597
LEAVE();
2340 Serge 598
 
6088 serge 599
    return ret;
2338 Serge 600
};
601
 
602
 
6088 serge 603
int set_cmdline_mode_ext(struct drm_device *dev, const char *cmdline)
604
{
605
    struct drm_connector_helper_funcs *connector_funcs;
606
    struct drm_connector    *connector;
6103 serge 607
    struct drm_cmdline_mode cmd_mode = {0};
6088 serge 608
    struct drm_display_mode *mode;
609
    char *mode_option;
610
    int retval = 0;
611
    char  con_edid[128];
612
 
613
    if((cmdline == NULL) || (*cmdline == 0))
614
        return EINVAL;
615
 
616
    mutex_lock(&dev->mode_config.mutex);
617
    connector = get_cmdline_connector(dev, cmdline);
618
    mutex_unlock(&dev->mode_config.mutex);
619
 
620
    if(connector == NULL)
621
        return EINVAL;
622
 
623
    mode_option = __builtin_strchr(cmdline,':');
624
    if(mode_option == NULL)
625
        return EINVAL;
626
 
627
    mode_option++;
628
 
629
    if( !drm_mode_parse_command_line_for_connector(mode_option, connector, &cmd_mode))
630
        return EINVAL;
631
 
632
    DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n",
633
                   connector->name,
634
                   cmd_mode.xres, cmd_mode.yres,
635
                   cmd_mode.refresh_specified ? cmd_mode.refresh : 60,
636
                   cmd_mode.rb ? " reduced blanking" : "",
637
                   cmd_mode.margins ? " with margins" : "",
638
                   cmd_mode.interlace ?  " interlaced" : "");
639
 
640
    mode = drm_mode_create_from_cmdline_mode(dev, &cmd_mode);
641
    if(mode == NULL)
642
        return EINVAL;
643
 
644
    memcpy(con_edid, connector->edid_blob_ptr->data, 128);
645
    DRM_DEBUG_KMS("connector: %s monitor: %s model %x serial number %u\n",
646
            connector->name,
647
            manufacturer_name(con_edid + 0x08),
648
            (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
649
            (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
650
            + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
651
 
652
    retval = set_mode_ex(dev, connector, mode);
653
 
654
    drm_mode_destroy(dev, mode);
655
 
656
    return retval;
657
}
658
 
6103 serge 659
void list_connectors(struct drm_device *dev)
660
{
661
    struct drm_connector *connector;
662
    char  con_edid[128];
663
 
664
    mutex_lock(&dev->mode_config.mutex);
665
    list_for_each_entry(connector, &dev->mode_config.connector_list, head)
666
    {
667
        if( connector->status != connector_status_connected)
668
            continue;
669
 
670
        memcpy(con_edid, connector->edid_blob_ptr->data, 128);
671
 
672
        if(connector ==  os_display->connector)
673
        {
674
            printf("%s mode %dx%d connected %s model %x serial number %u\n",
675
                   connector->name, os_display->width, os_display->height,
676
                   manufacturer_name(con_edid + 0x08),
677
                   (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
678
                   (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
679
                   + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
680
            continue;
681
        }
682
        else
683
        {
684
            printf("%s connected: %s model %x serial number %u\n",
685
                connector->name, manufacturer_name(con_edid + 0x08),
686
                (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
687
                (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
688
                + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
689
        }
690
    };
691
    mutex_unlock(&dev->mode_config.mutex);
692
}
693
 
694
int list_connector_modes(struct drm_device *dev, const char* name)
695
{
696
    struct drm_connector *connector;
697
    struct drm_display_mode  *drmmode;
698
 
699
    mutex_lock(&dev->mode_config.mutex);
700
 
701
    connector = get_cmdline_connector(dev, name);
702
    if(connector == NULL)
703
    {
704
        mutex_unlock(&dev->mode_config.mutex);
705
        return EINVAL;
706
    };
707
 
708
    printf("connector %s probed modes :\n", connector->name);
709
 
710
    list_for_each_entry(drmmode, &connector->modes, head)
711
    {
712
        printf("%dx%d@%d\n", drmmode->hdisplay, drmmode->vdisplay, drm_mode_vrefresh(drmmode));
713
    };
714
 
715
    mutex_unlock(&dev->mode_config.mutex);
716
    return 0;
717
};
718
 
2338 Serge 719
int get_videomodes(videomode_t *mode, int *count)
720
{
721
    int err = -1;
722
 
3031 serge 723
//    dbgprintf("mode %x count %d\n", mode, *count);
2338 Serge 724
 
725
    if( *count == 0 )
726
    {
727
        *count = os_display->supported_modes;
728
        err = 0;
729
    }
730
    else if( mode != NULL )
731
    {
732
        struct drm_display_mode  *drmmode;
733
        int i = 0;
734
 
735
        if( *count > os_display->supported_modes)
736
            *count = os_display->supported_modes;
737
 
738
        list_for_each_entry(drmmode, &os_display->connector->modes, head)
739
        {
740
            if( i < *count)
741
            {
5060 serge 742
                mode->width  = drmmode->hdisplay;
743
                mode->height = drmmode->vdisplay;
2338 Serge 744
                mode->bpp    = 32;
745
                mode->freq   = drm_mode_vrefresh(drmmode);
746
                i++;
747
                mode++;
748
            }
749
            else break;
750
        };
751
        *count = i;
752
        err = 0;
753
    };
754
    return err;
755
};
756
 
757
int set_user_mode(videomode_t *mode)
758
{
759
 
3031 serge 760
//    dbgprintf("width %d height %d vrefresh %d\n",
761
//               mode->width, mode->height, mode->freq);
2338 Serge 762
 
763
    if( (mode->width  != 0)  &&
764
        (mode->height != 0)  &&
765
        (mode->freq   != 0 ) &&
766
        ( (mode->width   != os_display->width)  ||
767
          (mode->height  != os_display->height) ||
768
          (mode->freq    != os_display->vrefresh) ) )
769
    {
5060 serge 770
        return set_mode(os_display->ddev, os_display->connector, os_display->crtc, mode, true);
2338 Serge 771
    };
772
 
5060 serge 773
    return -1;
2338 Serge 774
};
775
 
4126 Serge 776
void i915_dpms(struct drm_device *dev, int mode)
777
{
4371 Serge 778
    const struct drm_connector_funcs *f = os_display->connector->funcs;
4126 Serge 779
 
780
    f->dpms(os_display->connector, mode);
781
};
782
 
6283 serge 783
 
784
int i915_fbinfo(struct drm_i915_fb_info *fb)
2338 Serge 785
{
6283 serge 786
    u32 ifl;
2342 Serge 787
 
6283 serge 788
    ifl = safe_cli();
789
    {
790
        struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
791
        struct intel_crtc *crtc = to_intel_crtc(os_display->crtc);
792
        struct kos_framebuffer *kfb = os_display->current_lfb;
793
        struct intel_framebuffer *intel_fb = (struct intel_framebuffer*)kfb->private;
794
        struct drm_i915_gem_object *obj = intel_fb->obj;
3037 serge 795
 
6283 serge 796
        fb->name   = obj->base.name;
797
        fb->width  = os_display->width;
798
        fb->height = os_display->height;
6320 serge 799
        fb->pitch  = os_display->lfb_pitch;
6283 serge 800
        fb->tiling = obj->tiling_mode;
801
        fb->crtc   = crtc->base.base.id;
802
        fb->pipe   = crtc->pipe;
803
    }
804
    safe_sti(ifl);
6296 serge 805
 
6283 serge 806
    return 0;
807
}
3037 serge 808
 
6296 serge 809
 
3277 Serge 810
typedef struct
811
{
812
    int left;
813
    int top;
814
    int right;
815
    int bottom;
816
}rect_t;
3263 Serge 817
 
3277 Serge 818
 
819
#define CURRENT_TASK             (0x80003000)
820
 
821
void  FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect");
822
 
823
int i915_mask_update(struct drm_device *dev, void *data,
824
            struct drm_file *file)
825
{
826
    struct drm_i915_mask *mask = data;
827
    struct drm_gem_object *obj;
828
    static unsigned int mask_seqno[256];
829
    rect_t winrc;
830
    u32    slot;
4371 Serge 831
    int    ret=0;
3277 Serge 832
 
833
    obj = drm_gem_object_lookup(dev, file, mask->handle);
834
    if (obj == NULL)
835
        return -ENOENT;
836
 
837
    if (!obj->filp) {
838
        drm_gem_object_unreference_unlocked(obj);
839
        return -EINVAL;
840
    }
841
 
842
    GetWindowRect(&winrc);
843
    {
3298 Serge 844
//        static warn_count;
3277 Serge 845
 
3290 Serge 846
        mask->width    = winrc.right - winrc.left + 1;
847
        mask->height   = winrc.bottom - winrc.top + 1;
848
        mask->bo_pitch = (mask->width+15) & ~15;
849
 
3298 Serge 850
#if 0
3277 Serge 851
        if(warn_count < 1)
852
        {
853
            printf("left %d top %d right %d bottom %d\n",
854
                    winrc.left, winrc.top, winrc.right, winrc.bottom);
5060 serge 855
            printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_map);
3277 Serge 856
            warn_count++;
857
        };
3298 Serge 858
#endif
859
 
4104 Serge 860
     };
3277 Serge 861
 
3290 Serge 862
 
3277 Serge 863
    slot = *((u8*)CURRENT_TASK);
864
 
865
    if( mask_seqno[slot] != os_display->mask_seqno)
866
    {
867
        u8* src_offset;
868
        u8* dst_offset;
869
        u32 ifl;
870
 
871
        ret = i915_mutex_lock_interruptible(dev);
872
        if (ret)
4371 Serge 873
            goto err1;
3277 Serge 874
 
875
        ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
4398 Serge 876
        if(ret != 0 )
3277 Serge 877
        {
4371 Serge 878
            dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__);
879
            goto err2;
3277 Serge 880
        };
881
 
882
//        printf("width %d height %d\n", winrc.right, winrc.bottom);
883
 
884
//        slot = 0x01;
885
 
5354 serge 886
        src_offset = os_display->win_map;
887
        src_offset+= winrc.top*os_display->width + winrc.left;
3277 Serge 888
 
889
        dst_offset = (u8*)mask->bo_map;
890
 
5354 serge 891
        u32 tmp_h = mask->height;
3277 Serge 892
 
893
        ifl = safe_cli();
894
        {
895
            mask_seqno[slot] = os_display->mask_seqno;
896
 
897
            slot|= (slot<<8)|(slot<<16)|(slot<<24);
898
 
899
            __asm__ __volatile__ (
4560 Serge 900
            "movd       %[slot],   %%xmm6         \n"
3277 Serge 901
            "punpckldq  %%xmm6, %%xmm6            \n"
902
            "punpcklqdq %%xmm6, %%xmm6            \n"
903
            :: [slot]  "m" (slot)
904
            :"xmm6");
905
 
906
            while( tmp_h--)
907
            {
4398 Serge 908
                int tmp_w = mask->width;
3277 Serge 909
 
910
                u8* tmp_src = src_offset;
911
                u8* tmp_dst = dst_offset;
912
 
913
                src_offset+= os_display->width;
914
                dst_offset+= mask->bo_pitch;
915
 
916
                while(tmp_w >= 64)
917
                {
918
                    __asm__ __volatile__ (
919
                    "movdqu     (%0),   %%xmm0            \n"
920
                    "movdqu   16(%0),   %%xmm1            \n"
921
                    "movdqu   32(%0),   %%xmm2            \n"
922
                    "movdqu   48(%0),   %%xmm3            \n"
923
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
924
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
925
                    "pcmpeqb    %%xmm6, %%xmm2            \n"
926
                    "pcmpeqb    %%xmm6, %%xmm3            \n"
927
                    "movdqa     %%xmm0,   (%%edi)         \n"
928
                    "movdqa     %%xmm1, 16(%%edi)         \n"
929
                    "movdqa     %%xmm2, 32(%%edi)         \n"
930
                    "movdqa     %%xmm3, 48(%%edi)         \n"
931
 
932
                    :: "r" (tmp_src), "D" (tmp_dst)
933
                    :"xmm0","xmm1","xmm2","xmm3");
934
                    tmp_w -= 64;
935
                    tmp_src += 64;
936
                    tmp_dst += 64;
937
                }
938
 
939
                if( tmp_w >= 32 )
940
                {
941
                    __asm__ __volatile__ (
942
                    "movdqu     (%0),   %%xmm0            \n"
943
                    "movdqu   16(%0),   %%xmm1            \n"
944
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
945
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
946
                    "movdqa     %%xmm0,   (%%edi)         \n"
947
                    "movdqa     %%xmm1, 16(%%edi)         \n"
948
 
949
                    :: "r" (tmp_src), "D" (tmp_dst)
950
                    :"xmm0","xmm1");
951
                    tmp_w -= 32;
952
                    tmp_src += 32;
953
                    tmp_dst += 32;
954
                }
955
 
4398 Serge 956
                if( tmp_w >= 16 )
3277 Serge 957
                {
958
                    __asm__ __volatile__ (
959
                    "movdqu     (%0),   %%xmm0            \n"
960
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
961
                    "movdqa     %%xmm0,   (%%edi)         \n"
962
                    :: "r" (tmp_src), "D" (tmp_dst)
963
                    :"xmm0");
964
                    tmp_w -= 16;
965
                    tmp_src += 16;
966
                    tmp_dst += 16;
967
                }
4398 Serge 968
 
969
                if( tmp_w >= 8 )
970
                {
971
                    __asm__ __volatile__ (
972
                    "movq       (%0),   %%xmm0            \n"
973
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
974
                    "movq       %%xmm0,   (%%edi)         \n"
975
                    :: "r" (tmp_src), "D" (tmp_dst)
976
                    :"xmm0");
977
                    tmp_w -= 8;
978
                    tmp_src += 8;
979
                    tmp_dst += 8;
980
                }
981
                if( tmp_w >= 4 )
982
                {
983
                    __asm__ __volatile__ (
984
                    "movd       (%0),   %%xmm0            \n"
985
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
986
                    "movd       %%xmm0,   (%%edi)         \n"
987
                    :: "r" (tmp_src), "D" (tmp_dst)
988
                    :"xmm0");
989
                    tmp_w -= 4;
990
                    tmp_src += 4;
991
                    tmp_dst += 4;
992
                }
993
                while(tmp_w--)
994
                    *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
3277 Serge 995
            };
996
        };
997
        safe_sti(ifl);
4371 Serge 998
 
999
        ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
4539 Serge 1000
    }
1001
 
1002
err2:
1003
    mutex_unlock(&dev->struct_mutex);
1004
err1:
1005
    drm_gem_object_unreference(obj);
1006
 
1007
    return ret;
1008
}
1009
 
1010
int i915_mask_update_ex(struct drm_device *dev, void *data,
1011
            struct drm_file *file)
1012
{
1013
    struct drm_i915_mask_update *mask = data;
1014
    struct drm_gem_object *obj;
1015
    static unsigned int mask_seqno[256];
6660 serge 1016
    static int warn_count;
4539 Serge 1017
 
1018
    rect_t win;
1019
    u32    winw,winh;
1020
    u32    ml,mt,mr,mb;
1021
    u32    slot;
1022
    int    ret = 0;
1023
    slot = *((u8*)CURRENT_TASK);
1024
 
6084 serge 1025
    if( mask->forced == 0 && mask_seqno[slot] == os_display->mask_seqno)
4539 Serge 1026
        return 0;
1027
 
6084 serge 1028
    if(mask->forced)
1029
        memset((void*)mask->bo_map,0,mask->width * mask->height);
5367 serge 1030
 
4539 Serge 1031
    GetWindowRect(&win);
1032
    win.right+= 1;
1033
    win.bottom+=  1;
1034
 
1035
    winw = win.right - win.left;
1036
    winh = win.bottom - win.top;
1037
 
1038
    if(mask->dx >= winw ||
1039
       mask->dy >= winh)
1040
       return 1;
1041
 
1042
    ml = win.left + mask->dx;
1043
    mt = win.top  + mask->dy;
1044
    mr = ml + mask->width;
1045
    mb = mt + mask->height;
1046
 
1047
    if( ml >= win.right || mt >= win.bottom ||
1048
        mr < win.left   || mb < win.top )
1049
        return 1;
1050
 
1051
    if( mr > win.right )
1052
        mr = win.right;
1053
 
1054
    if( mb > win.bottom )
1055
        mb = win.bottom;
1056
 
1057
    mask->width  = mr - ml;
1058
    mask->height = mb - mt;
1059
 
1060
    if( mask->width == 0 ||
1061
        mask->height== 0 )
1062
        return 1;
1063
 
6131 serge 1064
    ret = i915_mutex_lock_interruptible(dev);
1065
    if (ret)
1066
        return ret;
1067
 
4539 Serge 1068
    obj = drm_gem_object_lookup(dev, file, mask->handle);
1069
    if (obj == NULL)
6131 serge 1070
    {
1071
        ret = -ENOENT;
1072
        goto unlock;
1073
    }
4539 Serge 1074
 
6131 serge 1075
    if (!obj->filp)
1076
    {
1077
        ret = -ENOENT;
1078
        goto out;
4539 Serge 1079
    }
1080
 
6084 serge 1081
#if 0
1082
    if(warn_count < 100)
4539 Serge 1083
    {
1084
        printf("left %d top %d right %d bottom %d\n",
1085
                ml, mt, mr, mb);
1086
        warn_count++;
1087
    };
1088
#endif
1089
 
1090
 
1091
#if 1
1092
 
1093
    {
1094
        u8* src_offset;
1095
        u8* dst_offset;
1096
        u32 ifl;
1097
 
1098
        i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true);
1099
 
5354 serge 1100
        src_offset = os_display->win_map;
1101
        src_offset+= mt*os_display->width + ml;
4539 Serge 1102
        dst_offset = (u8*)mask->bo_map;
1103
 
5354 serge 1104
        u32 tmp_h = mask->height;
4539 Serge 1105
 
1106
        ifl = safe_cli();
4371 Serge 1107
        {
4539 Serge 1108
            mask_seqno[slot] = os_display->mask_seqno;
1109
 
1110
            slot|= (slot<<8)|(slot<<16)|(slot<<24);
1111
 
1112
            __asm__ __volatile__ (
1113
            "movd       %[slot],   %%xmm6         \n"
1114
            "punpckldq  %%xmm6, %%xmm6            \n"
1115
            "punpcklqdq %%xmm6, %%xmm6            \n"
1116
            :: [slot]  "m" (slot)
1117
            :"xmm6");
1118
 
1119
            while( tmp_h--)
1120
            {
1121
                int tmp_w = mask->width;
1122
 
1123
                u8* tmp_src = src_offset;
1124
                u8* tmp_dst = dst_offset;
1125
 
1126
                src_offset+= os_display->width;
1127
                dst_offset+= mask->bo_pitch;
1128
 
1129
                while(tmp_w >= 64)
1130
                {
1131
                    __asm__ __volatile__ (
1132
                    "movdqu     (%0),   %%xmm0            \n"
1133
                    "movdqu   16(%0),   %%xmm1            \n"
1134
                    "movdqu   32(%0),   %%xmm2            \n"
1135
                    "movdqu   48(%0),   %%xmm3            \n"
1136
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1137
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
1138
                    "pcmpeqb    %%xmm6, %%xmm2            \n"
1139
                    "pcmpeqb    %%xmm6, %%xmm3            \n"
1140
                    "movdqa     %%xmm0,   (%%edi)         \n"
1141
                    "movdqa     %%xmm1, 16(%%edi)         \n"
1142
                    "movdqa     %%xmm2, 32(%%edi)         \n"
1143
                    "movdqa     %%xmm3, 48(%%edi)         \n"
1144
 
1145
                    :: "r" (tmp_src), "D" (tmp_dst)
1146
                    :"xmm0","xmm1","xmm2","xmm3");
1147
                    tmp_w -= 64;
1148
                    tmp_src += 64;
1149
                    tmp_dst += 64;
1150
                }
1151
 
1152
                if( tmp_w >= 32 )
1153
                {
1154
                    __asm__ __volatile__ (
1155
                    "movdqu     (%0),   %%xmm0            \n"
1156
                    "movdqu   16(%0),   %%xmm1            \n"
1157
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1158
                    "pcmpeqb    %%xmm6, %%xmm1            \n"
1159
                    "movdqa     %%xmm0,   (%%edi)         \n"
1160
                    "movdqa     %%xmm1, 16(%%edi)         \n"
1161
 
1162
                    :: "r" (tmp_src), "D" (tmp_dst)
1163
                    :"xmm0","xmm1");
1164
                    tmp_w -= 32;
1165
                    tmp_src += 32;
1166
                    tmp_dst += 32;
1167
                }
1168
 
1169
                if( tmp_w >= 16 )
1170
                {
1171
                    __asm__ __volatile__ (
1172
                    "movdqu     (%0),   %%xmm0            \n"
1173
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1174
                    "movdqa     %%xmm0,   (%%edi)         \n"
1175
                    :: "r" (tmp_src), "D" (tmp_dst)
1176
                    :"xmm0");
1177
                    tmp_w -= 16;
1178
                    tmp_src += 16;
1179
                    tmp_dst += 16;
1180
                }
1181
 
1182
                if( tmp_w >= 8 )
1183
                {
1184
                    __asm__ __volatile__ (
1185
                    "movq       (%0),   %%xmm0            \n"
1186
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1187
                    "movq       %%xmm0,   (%%edi)         \n"
1188
                    :: "r" (tmp_src), "D" (tmp_dst)
1189
                    :"xmm0");
1190
                    tmp_w -= 8;
1191
                    tmp_src += 8;
1192
                    tmp_dst += 8;
1193
                }
1194
                if( tmp_w >= 4 )
4560 Serge 1195
                {
4539 Serge 1196
                    __asm__ __volatile__ (
1197
                    "movd       (%0),   %%xmm0            \n"
1198
                    "pcmpeqb    %%xmm6, %%xmm0            \n"
1199
                    "movd       %%xmm0,   (%%edi)         \n"
1200
                    :: "r" (tmp_src), "D" (tmp_dst)
1201
                    :"xmm0");
1202
                    tmp_w -= 4;
1203
                    tmp_src += 4;
1204
                    tmp_dst += 4;
1205
                }
1206
                while(tmp_w--)
1207
                    *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00;
1208
            };
4371 Serge 1209
        };
4539 Serge 1210
        safe_sti(ifl);
1211
 
1212
        i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false);
3277 Serge 1213
    }
4539 Serge 1214
#endif
3277 Serge 1215
 
6131 serge 1216
out:
3277 Serge 1217
    drm_gem_object_unreference(obj);
1218
 
6131 serge 1219
unlock:
1220
    mutex_unlock(&dev->struct_mutex);
1221
 
4371 Serge 1222
    return ret;
3277 Serge 1223
}
1224
 
1225
 
1226
 
2360 Serge 1227
 
3031 serge 1228
#define NSEC_PER_SEC    1000000000L
2360 Serge 1229
 
3031 serge 1230
void getrawmonotonic(struct timespec *ts)
1231
{
1232
    u32 tmp = GetTimerTicks();
2360 Serge 1233
 
3031 serge 1234
    ts->tv_sec  = tmp/100;
1235
    ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000;
1236
}
2360 Serge 1237
 
6084 serge 1238
void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
3031 serge 1239
{
3480 Serge 1240
    unsigned long flags;
3031 serge 1241
 
3480 Serge 1242
//    wait->flags &= ~WQ_FLAG_EXCLUSIVE;
1243
    spin_lock_irqsave(&q->lock, flags);
1244
    if (list_empty(&wait->task_list))
1245
            __add_wait_queue(q, wait);
1246
    spin_unlock_irqrestore(&q->lock, flags);
1247
}
1248
 
1249
/**
1250
 * finish_wait - clean up after waiting in a queue
1251
 * @q: waitqueue waited on
1252
 * @wait: wait descriptor
1253
 *
1254
 * Sets current thread back to running state and removes
1255
 * the wait descriptor from the given waitqueue if still
1256
 * queued.
1257
 */
1258
void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
1259
{
1260
    unsigned long flags;
1261
 
1262
//    __set_current_state(TASK_RUNNING);
1263
    /*
1264
     * We can check for list emptiness outside the lock
1265
     * IFF:
1266
     *  - we use the "careful" check that verifies both
1267
     *    the next and prev pointers, so that there cannot
1268
     *    be any half-pending updates in progress on other
1269
     *    CPU's that we haven't seen yet (and that might
1270
     *    still change the stack area.
1271
     * and
1272
     *  - all other users take the lock (ie we can only
1273
     *    have _one_ other CPU that looks at or modifies
1274
     *    the list).
1275
     */
1276
    if (!list_empty_careful(&wait->task_list)) {
1277
            spin_lock_irqsave(&q->lock, flags);
1278
            list_del_init(&wait->task_list);
1279
            spin_unlock_irqrestore(&q->lock, flags);
1280
    }
1281
 
1282
    DestroyEvent(wait->evnt);
1283
}
1284
 
1285
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
1286
{
1287
    list_del_init(&wait->task_list);
1288
    return 1;
1289
}