Subversion Repositories Kolibri OS

Rev

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