Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6283 serge 1
#include 
2
#include "i915_drv.h"
3
#include "intel_drv.h"
4
#include 
5
#include 
6
 
7
static struct mutex cursor_lock;
8
 
9
static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
10
{
11
    struct drm_crtc *crtc = os_display->crtc;
12
    struct drm_plane_state *cursor_state = crtc->cursor->state;
13
 
14
    x-= cursor->hot_x;
15
    y-= cursor->hot_y;
16
 
17
    crtc->cursor_x = x;
18
    crtc->cursor_y = y;
19
 
20
    cursor_state->crtc_x = x;
21
    cursor_state->crtc_y = y;
22
 
7144 serge 23
    intel_crtc_update_cursor(crtc, cursor_state);
6283 serge 24
};
25
 
26
static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
27
{
28
    struct drm_i915_private *dev_priv = os_display->ddev->dev_private;
29
    struct drm_crtc   *crtc = os_display->crtc;
30
    struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
7144 serge 31
    struct drm_plane  *cursor_plane = crtc->cursor;
32
    struct intel_plane_state *cursor_state = to_intel_plane_state(cursor_plane->state);
6283 serge 33
 
34
    cursor_t *old;
35
 
36
    old = os_display->cursor;
37
 
38
    mutex_lock(&cursor_lock);
39
 
40
    os_display->cursor = cursor;
41
 
42
    if (!dev_priv->info.cursor_needs_physical)
43
       intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj);
44
    else
45
        intel_crtc->cursor_addr = (addr_t)cursor->cobj;
46
 
7144 serge 47
    cursor_state->visible = 1;
48
 
49
    cursor_plane->state->crtc_w   = 64;
50
    cursor_plane->state->crtc_h   = 64;
51
    cursor_plane->state->rotation = 0;
52
 
6283 serge 53
    mutex_unlock(&cursor_lock);
54
 
55
    move_cursor_kms(cursor, crtc->cursor_x, crtc->cursor_y);
56
    return old;
57
};
58
 
59
static void __stdcall restore_cursor(int x, int y){};
60
static void disable_mouse(void){};
61
 
62
static void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor)
63
{
7173 serge 64
    struct drm_i915_private *dev_priv = main_device->dev_private;
6283 serge 65
    struct drm_i915_gem_object *obj = cursor->cobj;
7173 serge 66
    u32      ifl;
67
 
68
    ifl = safe_cli();
6283 serge 69
    list_del(&cursor->list);
7173 serge 70
    safe_sti(ifl);
6283 serge 71
 
7173 serge 72
    if (!dev_priv->info.cursor_needs_physical)
73
    {
6283 serge 74
    i915_gem_object_ggtt_unpin(cursor->cobj);
75
 
76
    mutex_lock(&main_device->struct_mutex);
77
    drm_gem_object_unreference(&obj->base);
78
    mutex_unlock(&main_device->struct_mutex);
7173 serge 79
    }
80
    else
81
    {
82
        addr_t page = (addr_t)obj;
83
        for(addr_t i = 0; i < (KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8)/4096; i+=4096)
84
            FreePage(page+i);
85
    }
6283 serge 86
 
87
    __DestroyObject(cursor);
88
};
89
 
90
static int init_cursor(cursor_t *cursor)
91
{
92
    display_t *display = GetDisplay();
6296 serge 93
    struct drm_device *dev = display->ddev;
94
    struct drm_i915_private *dev_priv = dev->dev_private;
6283 serge 95
    struct drm_i915_gem_object *obj;
96
    uint32_t *bits;
97
    uint32_t *src;
98
    void     *mapped;
99
 
100
    int       i,j;
101
    int       ret;
102
 
6296 serge 103
    mutex_lock(&dev->struct_mutex);
104
 
6283 serge 105
    if (dev_priv->info.cursor_needs_physical)
106
    {
7173 serge 107
        mapped = bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8);
6283 serge 108
        if (unlikely(bits == NULL))
6296 serge 109
        {
110
            ret = -ENOMEM;
111
            goto unlock;
112
        };
6283 serge 113
        cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
114
    }
115
    else
116
    {
117
        obj = i915_gem_alloc_object(display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4);
118
        if (unlikely(obj == NULL))
6296 serge 119
        {
120
            ret = -ENOMEM;
121
            goto unlock;
122
        };
6283 serge 123
 
124
        ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL);
6296 serge 125
        if (ret)
126
            goto unref;
6283 serge 127
 
128
        ret = i915_gem_object_set_to_gtt_domain(obj, true);
129
        if (ret)
6296 serge 130
            goto unpin;
131
 
6283 serge 132
/* You don't need to worry about fragmentation issues.
133
 * GTT space is continuous. I guarantee it.                           */
134
 
135
        mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
136
                    KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW);
137
 
138
        if (unlikely(bits == NULL))
139
        {
6296 serge 140
            ret = -ENOMEM;
141
            goto unpin;
6283 serge 142
        };
143
        cursor->cobj = obj;
144
    };
145
 
6296 serge 146
    mutex_unlock(&dev->struct_mutex);
147
 
6283 serge 148
    src = cursor->data;
149
 
150
    for(i = 0; i < 32; i++)
151
    {
152
        for(j = 0; j < 32; j++)
153
            *bits++ = *src++;
154
        for(j = 32; j < KMS_CURSOR_WIDTH; j++)
155
            *bits++ = 0;
156
    }
157
    for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++)
158
        *bits++ = 0;
159
 
160
    FreeKernelSpace(mapped);
161
    KernelFree(cursor->data);
162
    cursor->data = bits;
163
    cursor->header.destroy = destroy_cursor;
164
 
165
    return 0;
6296 serge 166
 
167
unpin:
168
    i915_gem_object_ggtt_unpin(obj);
169
unref:
170
    drm_gem_object_unreference(&obj->base);
171
unlock:
172
    mutex_unlock(&dev->struct_mutex);
173
    return ret;
6283 serge 174
}
175
 
176
void init_system_cursors(struct drm_device *dev)
177
{
178
    cursor_t  *cursor;
179
    display_t *display;
180
    u32      ifl;
181
 
182
    display = GetDisplay();
183
 
184
    mutex_init(&cursor_lock);
185
 
186
    ifl = safe_cli();
187
    {
188
        list_for_each_entry(cursor, &display->cursors, list)
189
        {
190
            init_cursor(cursor);
191
        };
192
 
193
        display->restore_cursor(0,0);
194
        display->init_cursor    = init_cursor;
195
        display->select_cursor  = select_cursor_kms;
196
        display->show_cursor    = NULL;
197
        display->move_cursor    = move_cursor_kms;
198
        display->restore_cursor = restore_cursor;
199
        display->disable_mouse  = disable_mouse;
200
        display->crtc->cursor_x = display->width/2;
201
        display->crtc->cursor_y = display->height/2;
202
 
203
        select_cursor_kms(display->cursor);
204
    };
205
    safe_sti(ifl);
206
}