Subversion Repositories Kolibri OS

Rev

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

Rev 1221 Rev 1230
1
#include 
1
#include 
2
#include 
2
#include 
3
#include 
3
#include 
4
#include 
4
#include 
5
#include "radeon_drm.h"
5
#include "radeon_drm.h"
6
#include "radeon.h"
6
#include "radeon.h"
7
#include "radeon_object.h"
7
#include "radeon_object.h"
8
 
8
 
9
#define CURSOR_WIDTH 64
9
#define CURSOR_WIDTH 64
10
#define CURSOR_HEIGHT 64
10
#define CURSOR_HEIGHT 64
11
 
11
 
12
typedef struct tag_object  kobj_t;
12
typedef struct tag_object  kobj_t;
13
typedef struct tag_display display_t;
13
typedef struct tag_display display_t;
14
 
14
 
15
struct tag_object
15
struct tag_object
16
{
16
{
17
    uint32_t   magic;
17
    uint32_t   magic;
18
    void      *destroy;
18
    void      *destroy;
19
    kobj_t    *fd;
19
    kobj_t    *fd;
20
    kobj_t    *bk;
20
    kobj_t    *bk;
21
    uint32_t   pid;
21
    uint32_t   pid;
22
};
22
};
23
 
23
 
24
typedef struct
24
typedef struct
25
{
25
{
26
    kobj_t     header;
26
    kobj_t     header;
27
 
27
 
28
    uint32_t  *data;
28
    uint32_t  *data;
29
    uint32_t   hot_x;
29
    uint32_t   hot_x;
30
    uint32_t   hot_y;
30
    uint32_t   hot_y;
31
 
31
 
32
    struct list_head      list;
32
    struct list_head      list;
33
    struct radeon_object *robj;
33
    struct radeon_object *robj;
34
}cursor_t;
34
}cursor_t;
35
 
35
 
-
 
36
int        init_cursor(cursor_t *cursor);
-
 
37
cursor_t*  __stdcall select_cursor(cursor_t *cursor);
-
 
38
void       __stdcall move_cursor(cursor_t *cursor, int x, int y);
-
 
39
void       __stdcall restore_cursor(int x, int y);
-
 
40
 
36
struct tag_display
41
struct tag_display
37
{
42
{
38
    int  x;
43
    int  x;
39
    int  y;
44
    int  y;
40
    int  width;
45
    int  width;
41
    int  height;
46
    int  height;
42
    int  bpp;
47
    int  bpp;
43
    int  vrefresh;
48
    int  vrefresh;
44
    int  pitch;
49
    int  pitch;
45
    int  lfb;
50
    int  lfb;
46
 
51
 
47
    struct drm_device *ddev;
52
    struct drm_device *ddev;
48
    struct drm_crtc   *crtc;
53
    struct drm_crtc   *crtc;
49
 
54
 
50
    struct list_head   cursors;
55
    struct list_head   cursors;
51
 
56
 
52
    cursor_t   *cursor;
57
    cursor_t   *cursor;
53
    int       (*init_cursor)(cursor_t*);
58
    int       (*init_cursor)(cursor_t*);
54
    cursor_t* (*select_cursor)(display_t*, cursor_t*);
59
    cursor_t* (__stdcall *select_cursor)(cursor_t*);
55
    void      (*show_cursor)(int show);
60
    void      (*show_cursor)(int show);
56
    void      (*move_cursor)(int x, int y);
61
    void      (__stdcall *move_cursor)(cursor_t *cursor, int x, int y);
-
 
62
    void      (__stdcall *restore_cursor)(int x, int y);
57
};
63
 
-
 
64
};
58
 
65
 
59
 
66
 
60
display_t *rdisplay;
67
static display_t *rdisplay;
-
 
68
 
-
 
69
 
-
 
70
void set_crtc(struct drm_crtc *crtc)
-
 
71
{
-
 
72
    ENTER();
-
 
73
    rdisplay->crtc = crtc;
-
 
74
    LEAVE();
-
 
75
}
61
 
76
 
62
int init_cursor(cursor_t *cursor)
77
int init_cursor(cursor_t *cursor)
63
{
78
{
64
    struct radeon_device *rdev;
79
    struct radeon_device *rdev;
65
 
80
 
66
    uint32_t *bits;
81
    uint32_t *bits;
67
    uint32_t *src;
82
    uint32_t *src;
68
 
83
 
69
    int       i,j;
84
    int       i,j;
70
    int       r;
85
    int       r;
71
 
86
 
72
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
87
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
73
 
88
 
74
    r = radeon_object_create(rdev, NULL, CURSOR_WIDTH*CURSOR_HEIGHT*4,
89
    r = radeon_object_create(rdev, NULL, CURSOR_WIDTH*CURSOR_HEIGHT*4,
75
                     false,
90
                     false,
76
                     RADEON_GEM_DOMAIN_VRAM,
91
                     RADEON_GEM_DOMAIN_VRAM,
77
                     false, &cursor->robj);
92
                     false, &cursor->robj);
78
 
93
 
79
    if (unlikely(r != 0))
94
    if (unlikely(r != 0))
80
        return r;
95
        return r;
81
 
96
 
82
    radeon_object_pin(cursor->robj, RADEON_GEM_DOMAIN_VRAM, NULL);
97
    radeon_object_pin(cursor->robj, RADEON_GEM_DOMAIN_VRAM, NULL);
83
 
98
 
84
    r = radeon_object_kmap(cursor->robj, &bits);
99
    r = radeon_object_kmap(cursor->robj, &bits);
85
    if (r) {
100
    if (r) {
86
         DRM_ERROR("radeon: failed to map cursor (%d).\n", r);
101
         DRM_ERROR("radeon: failed to map cursor (%d).\n", r);
87
         return r;
102
         return r;
88
    };
103
    };
89
 
104
 
90
    src = cursor->data;
105
    src = cursor->data;
91
 
106
 
92
    for(i = 0; i < 32; i++)
107
    for(i = 0; i < 32; i++)
93
    {
108
    {
94
        for(j = 0; j < 32; j++)
109
        for(j = 0; j < 32; j++)
95
            *bits++ = *src++;
110
            *bits++ = *src++;
96
        for(j = 0; j < CURSOR_WIDTH-32; j++)
111
        for(j = 32; j < CURSOR_WIDTH; j++)
97
            *bits++ = 0;
112
            *bits++ = 0;
98
    }
113
    }
99
    for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
114
    for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++)
100
        *bits++ = 0;
115
        *bits++ = 0;
101
 
116
 
102
    radeon_object_kunmap(cursor->robj);
117
    radeon_object_kunmap(cursor->robj);
103
 
118
 
104
    return 0;
119
    return 0;
105
};
120
};
106
 
121
 
-
 
122
static void radeon_show_cursor(struct drm_crtc *crtc)
-
 
123
{
-
 
124
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
-
 
125
    struct radeon_device *rdev = crtc->dev->dev_private;
-
 
126
 
-
 
127
    if (ASIC_IS_AVIVO(rdev)) {
-
 
128
        WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
-
 
129
        WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
-
 
130
                 (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
-
 
131
    } else {
-
 
132
        switch (radeon_crtc->crtc_id) {
-
 
133
        case 0:
-
 
134
            WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
-
 
135
            break;
-
 
136
        case 1:
-
 
137
            WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
-
 
138
            break;
-
 
139
        default:
-
 
140
            return;
-
 
141
        }
-
 
142
 
-
 
143
        WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN |
-
 
144
                      (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)),
-
 
145
             ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
-
 
146
    }
-
 
147
}
-
 
148
 
107
int init_display(struct radeon_device *rdev)
149
int pre_init_display(struct radeon_device *rdev)
108
{
150
{
109
    cursor_t  *cursor;
151
    cursor_t  *cursor;
110
 
152
 
-
 
153
    ENTER();
-
 
154
 
111
//    rdisplay = get_display();
155
    rdisplay = GetDisplay();
112
 
156
 
113
    rdisplay->ddev = rdev->ddev;
157
    rdisplay->ddev = rdev->ddev;
114
 
158
 
115
    list_for_each_entry(cursor, &rdisplay->cursors, list)
159
    list_for_each_entry(cursor, &rdisplay->cursors, list)
116
    {
160
    {
117
        init_cursor(cursor);
161
        init_cursor(cursor);
118
    };
162
    };
119
    return 1;
163
 
-
 
164
    LEAVE();
-
 
165
 
-
 
166
    return 1;
-
 
167
};
-
 
168
 
-
 
169
int post_init_display(struct radeon_device *rdev)
-
 
170
{
-
 
171
    cursor_t  *cursor;
-
 
172
 
-
 
173
    ENTER();
-
 
174
 
-
 
175
    select_cursor(rdisplay->cursor);
-
 
176
 
-
 
177
    radeon_show_cursor(rdisplay->crtc);
-
 
178
 
-
 
179
    rdisplay->init_cursor   = init_cursor;
-
 
180
    rdisplay->select_cursor = select_cursor;
-
 
181
    rdisplay->show_cursor   = NULL;
-
 
182
    rdisplay->move_cursor   = move_cursor;
-
 
183
    rdisplay->restore_cursor = restore_cursor;
-
 
184
 
-
 
185
    LEAVE();
-
 
186
 
-
 
187
    return 1;
120
};
188
};
121
 
189
 
122
static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock)
190
static void radeon_lock_cursor(struct drm_crtc *crtc, bool lock)
123
{
191
{
124
    struct radeon_device *rdev = crtc->dev->dev_private;
192
    struct radeon_device *rdev = crtc->dev->dev_private;
125
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
193
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
126
    uint32_t cur_lock;
194
    uint32_t cur_lock;
127
 
195
 
128
    if (ASIC_IS_AVIVO(rdev)) {
196
    if (ASIC_IS_AVIVO(rdev)) {
129
        cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
197
        cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
130
        if (lock)
198
        if (lock)
131
            cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
199
            cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
132
        else
200
        else
133
            cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
201
            cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
134
        WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
202
        WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
135
    } else {
203
    } else {
136
        cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset);
204
        cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset);
137
        if (lock)
205
        if (lock)
138
            cur_lock |= RADEON_CUR_LOCK;
206
            cur_lock |= RADEON_CUR_LOCK;
139
        else
207
        else
140
            cur_lock &= ~RADEON_CUR_LOCK;
208
            cur_lock &= ~RADEON_CUR_LOCK;
141
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock);
209
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock);
142
    }
210
    }
143
}
211
}
144
 
212
 
145
cursor_t* select_cursor(display_t *display, cursor_t *cursor)
213
cursor_t* __stdcall select_cursor(cursor_t *cursor)
146
{
214
{
147
    struct radeon_device *rdev;
215
    struct radeon_device *rdev;
148
    struct radeon_crtc   *radeon_crtc;
216
    struct radeon_crtc   *radeon_crtc;
149
    cursor_t *old;
217
    cursor_t *old;
150
    uint32_t  gpu_addr;
218
    uint32_t  gpu_addr;
151
 
219
 
152
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
220
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
153
    radeon_crtc = to_radeon_crtc(rdisplay->crtc);
221
    radeon_crtc = to_radeon_crtc(rdisplay->crtc);
154
 
222
 
155
    old = display->cursor;
223
    old = rdisplay->cursor;
156
 
224
 
157
    display->cursor = cursor;
225
    rdisplay->cursor = cursor;
158
    gpu_addr = cursor->robj->gpu_addr;
226
    gpu_addr = cursor->robj->gpu_addr;
159
 
227
 
160
    if (ASIC_IS_AVIVO(rdev))
228
    if (ASIC_IS_AVIVO(rdev))
161
        WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
229
        WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
162
    else {
230
    else {
163
        radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr;
231
        radeon_crtc->legacy_cursor_offset = gpu_addr - radeon_crtc->legacy_display_base_addr;
164
        /* offset is from DISP(2)_BASE_ADDRESS */
232
        /* offset is from DISP(2)_BASE_ADDRESS */
165
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
233
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
166
    }
234
    }
167
    return old;
235
 
-
 
236
    return old;
168
};
237
};
169
 
238
 
170
 
239
 
171
int radeon_cursor_move(display_t *display, int x, int y)
240
void __stdcall move_cursor(cursor_t *cursor, int x, int y)
172
{
241
{
-
 
242
    struct radeon_device *rdev;
-
 
243
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
173
    struct drm_crtc *crtc = rdisplay->crtc;
244
    struct drm_crtc *crtc = rdisplay->crtc;
174
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
245
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
175
    struct radeon_device *rdev = crtc->dev->dev_private;
-
 
176
 
246
 
177
    int hot_x = rdisplay->cursor->hot_x - 1;
247
    int hot_x = cursor->hot_x;
178
    int hot_y = rdisplay->cursor->hot_y - 1;
248
    int hot_y = cursor->hot_y;
179
 
249
 
180
    radeon_lock_cursor(crtc, true);
250
    radeon_lock_cursor(crtc, true);
181
    if (ASIC_IS_AVIVO(rdev))
251
    if (ASIC_IS_AVIVO(rdev))
182
    {
252
    {
183
        int w = 32;
253
        int w = 32;
184
        int i = 0;
254
        int i = 0;
185
        struct drm_crtc *crtc_p;
255
        struct drm_crtc *crtc_p;
186
 
256
 
187
        /* avivo cursor are offset into the total surface */
257
        /* avivo cursor are offset into the total surface */
188
        x += crtc->x;
258
//        x += crtc->x;
189
        y += crtc->y;
259
//        y += crtc->y;
190
 
260
 
191
//        DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
261
//        DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
192
#if 0
262
#if 0
193
        /* avivo cursor image can't end on 128 pixel boundry or
263
        /* avivo cursor image can't end on 128 pixel boundry or
194
         * go past the end of the frame if both crtcs are enabled
264
         * go past the end of the frame if both crtcs are enabled
195
         */
265
         */
196
        list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) {
266
        list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) {
197
            if (crtc_p->enabled)
267
            if (crtc_p->enabled)
198
                i++;
268
                i++;
199
        }
269
        }
200
        if (i > 1) {
270
        if (i > 1) {
201
            int cursor_end, frame_end;
271
            int cursor_end, frame_end;
202
 
272
 
203
            cursor_end = x + w;
273
            cursor_end = x + w;
204
            frame_end = crtc->x + crtc->mode.crtc_hdisplay;
274
            frame_end = crtc->x + crtc->mode.crtc_hdisplay;
205
            if (cursor_end >= frame_end) {
275
            if (cursor_end >= frame_end) {
206
                w = w - (cursor_end - frame_end);
276
                w = w - (cursor_end - frame_end);
207
                if (!(frame_end & 0x7f))
277
                if (!(frame_end & 0x7f))
208
                    w--;
278
                    w--;
209
            } else {
279
            } else {
210
                if (!(cursor_end & 0x7f))
280
                if (!(cursor_end & 0x7f))
211
                    w--;
281
                    w--;
212
            }
282
            }
213
            if (w <= 0)
283
            if (w <= 0)
214
                w = 1;
284
                w = 1;
215
        }
285
        }
216
#endif
286
#endif
217
 
287
        WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset,
218
        WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset,
-
 
219
               (x << 16) | y);
288
               (x << 16) | y);
220
        WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset,
289
        WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset,
221
               (hot_x << 16) | hot_y-1);
290
               (hot_x << 16) | hot_y);
222
        WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
291
        WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
223
               ((w - 1) << 16) | 31);
292
               ((w - 1) << 16) | 31);
224
    } else {
293
    } else {
225
        if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
294
        if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
226
            y *= 2;
295
            y *= 2;
227
 
296
 
228
        WREG32(RADEON_CUR_HORZ_VERT_OFF + radeon_crtc->crtc_offset,
297
        WREG32(RADEON_CUR_HORZ_VERT_OFF + radeon_crtc->crtc_offset,
229
               (RADEON_CUR_LOCK | (hot_x << 16) | (hot_y << 16)));
298
               (RADEON_CUR_LOCK | (hot_x << 16) | (hot_y << 16)));
230
        WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset,
299
        WREG32(RADEON_CUR_HORZ_VERT_POSN + radeon_crtc->crtc_offset,
231
               (RADEON_CUR_LOCK | (x << 16) | y));
300
               (RADEON_CUR_LOCK | (x << 16) | y));
232
 
301
 
233
        /* offset is from DISP(2)_BASE_ADDRESS */
302
        /* offset is from DISP(2)_BASE_ADDRESS */
234
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset,
303
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset,
235
         (radeon_crtc->legacy_cursor_offset + (hot_y * 256)));
304
         (radeon_crtc->legacy_cursor_offset + (hot_y * 256)));
236
    }
305
    }
237
    radeon_lock_cursor(crtc, false);
306
    radeon_lock_cursor(crtc, false);
238
 
307
}
239
    return 0;
-
 
240
}
-
 
241
308
 
-
 
309
void __stdcall restore_cursor(int x, int y)
-
 
310
{
-
 
311
};