Subversion Repositories Kolibri OS

Rev

Rev 6937 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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