Subversion Repositories Kolibri OS

Rev

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

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