Subversion Repositories Kolibri OS

Rev

Rev 3480 | Rev 4104 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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