Subversion Repositories Kolibri OS

Rev

Rev 6296 | Go to most recent revision | 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
{
64
    struct drm_i915_gem_object *obj = cursor->cobj;
65
    list_del(&cursor->list);
66
 
67
    i915_gem_object_ggtt_unpin(cursor->cobj);
68
 
69
    mutex_lock(&main_device->struct_mutex);
70
    drm_gem_object_unreference(&obj->base);
71
    mutex_unlock(&main_device->struct_mutex);
72
 
73
    __DestroyObject(cursor);
74
};
75
 
76
static int init_cursor(cursor_t *cursor)
77
{
78
    display_t *display = GetDisplay();
6296 serge 79
    struct drm_device *dev = display->ddev;
80
    struct drm_i915_private *dev_priv = dev->dev_private;
6283 serge 81
    struct drm_i915_gem_object *obj;
82
    uint32_t *bits;
83
    uint32_t *src;
84
    void     *mapped;
85
 
86
    int       i,j;
87
    int       ret;
88
 
6296 serge 89
    mutex_lock(&dev->struct_mutex);
90
 
6283 serge 91
    if (dev_priv->info.cursor_needs_physical)
92
    {
93
        bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8);
94
        if (unlikely(bits == NULL))
6296 serge 95
        {
96
            ret = -ENOMEM;
97
            goto unlock;
98
        };
6283 serge 99
        cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits);
100
    }
101
    else
102
    {
103
        obj = i915_gem_alloc_object(display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4);
104
        if (unlikely(obj == NULL))
6296 serge 105
        {
106
            ret = -ENOMEM;
107
            goto unlock;
108
        };
6283 serge 109
 
110
        ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL);
6296 serge 111
        if (ret)
112
            goto unref;
6283 serge 113
 
114
        ret = i915_gem_object_set_to_gtt_domain(obj, true);
115
        if (ret)
6296 serge 116
            goto unpin;
117
 
6283 serge 118
/* You don't need to worry about fragmentation issues.
119
 * GTT space is continuous. I guarantee it.                           */
120
 
121
        mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj),
122
                    KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW);
123
 
124
        if (unlikely(bits == NULL))
125
        {
6296 serge 126
            ret = -ENOMEM;
127
            goto unpin;
6283 serge 128
        };
129
        cursor->cobj = obj;
130
    };
131
 
6296 serge 132
    mutex_unlock(&dev->struct_mutex);
133
 
6283 serge 134
    src = cursor->data;
135
 
136
    for(i = 0; i < 32; i++)
137
    {
138
        for(j = 0; j < 32; j++)
139
            *bits++ = *src++;
140
        for(j = 32; j < KMS_CURSOR_WIDTH; j++)
141
            *bits++ = 0;
142
    }
143
    for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++)
144
        *bits++ = 0;
145
 
146
    FreeKernelSpace(mapped);
147
    KernelFree(cursor->data);
148
    cursor->data = bits;
149
    cursor->header.destroy = destroy_cursor;
150
 
151
    return 0;
6296 serge 152
 
153
unpin:
154
    i915_gem_object_ggtt_unpin(obj);
155
unref:
156
    drm_gem_object_unreference(&obj->base);
157
unlock:
158
    mutex_unlock(&dev->struct_mutex);
159
    return ret;
6283 serge 160
}
161
 
162
void init_system_cursors(struct drm_device *dev)
163
{
164
    cursor_t  *cursor;
165
    display_t *display;
166
    u32      ifl;
167
 
168
    display = GetDisplay();
169
 
170
    mutex_init(&cursor_lock);
171
 
172
    ifl = safe_cli();
173
    {
174
        list_for_each_entry(cursor, &display->cursors, list)
175
        {
176
            init_cursor(cursor);
177
        };
178
 
179
        display->restore_cursor(0,0);
180
        display->init_cursor    = init_cursor;
181
        display->select_cursor  = select_cursor_kms;
182
        display->show_cursor    = NULL;
183
        display->move_cursor    = move_cursor_kms;
184
        display->restore_cursor = restore_cursor;
185
        display->disable_mouse  = disable_mouse;
186
        display->crtc->cursor_x = display->width/2;
187
        display->crtc->cursor_y = display->height/2;
188
 
189
        select_cursor_kms(display->cursor);
190
    };
191
    safe_sti(ifl);
192
}