Subversion Repositories Kolibri OS

Rev

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

Rev 1404 Rev 1430
1
#include 
1
#include 
2
#include 
2
#include 
3
#include 
3
#include 
4
#include "radeon_drm.h"
4
#include "radeon_drm.h"
5
#include "radeon.h"
5
#include "radeon.h"
6
#include "radeon_object.h"
6
#include "radeon_object.h"
7
#include "display.h"
7
#include "display.h"
8
 
8
 
9
 
9
 
10
static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
10
static cursor_t*  __stdcall select_cursor_kms(cursor_t *cursor);
11
static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
11
static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
12
 
12
 
13
int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled);
13
int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled);
14
 
14
 
15
void disable_mouse(void);
15
void disable_mouse(void);
16
 
16
 
17
static void radeon_show_cursor_kms(struct drm_crtc *crtc)
17
static void radeon_show_cursor_kms(struct drm_crtc *crtc)
18
{
18
{
19
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
19
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
20
    struct radeon_device *rdev = crtc->dev->dev_private;
20
    struct radeon_device *rdev = crtc->dev->dev_private;
21
 
21
 
22
    if (ASIC_IS_AVIVO(rdev)) {
22
    if (ASIC_IS_AVIVO(rdev)) {
23
        WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
23
        WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
24
        WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
24
        WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
25
                 (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
25
                 (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
26
    } else {
26
    } else {
27
        switch (radeon_crtc->crtc_id) {
27
        switch (radeon_crtc->crtc_id) {
28
        case 0:
28
        case 0:
29
            WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
29
            WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
30
            break;
30
            break;
31
        case 1:
31
        case 1:
32
            WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
32
            WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
33
            break;
33
            break;
34
        default:
34
        default:
35
            return;
35
            return;
36
        }
36
        }
37
 
37
 
38
        WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN |
38
        WREG32_P(RADEON_MM_DATA, (RADEON_CRTC_CUR_EN |
39
                      (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)),
39
                      (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)),
40
             ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
40
             ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
41
    }
41
    }
42
}
42
}
43
 
43
 
44
static void radeon_lock_cursor_kms(struct drm_crtc *crtc, bool lock)
44
static void radeon_lock_cursor_kms(struct drm_crtc *crtc, bool lock)
45
{
45
{
46
    struct radeon_device *rdev = crtc->dev->dev_private;
46
    struct radeon_device *rdev = crtc->dev->dev_private;
47
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
47
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
48
    uint32_t cur_lock;
48
    uint32_t cur_lock;
49
 
49
 
50
    if (ASIC_IS_AVIVO(rdev)) {
50
    if (ASIC_IS_AVIVO(rdev)) {
51
        cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
51
        cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
52
        if (lock)
52
        if (lock)
53
            cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
53
            cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
54
        else
54
        else
55
            cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
55
            cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
56
        WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
56
        WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
57
    } else {
57
    } else {
58
        cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset);
58
        cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset);
59
        if (lock)
59
        if (lock)
60
            cur_lock |= RADEON_CUR_LOCK;
60
            cur_lock |= RADEON_CUR_LOCK;
61
        else
61
        else
62
            cur_lock &= ~RADEON_CUR_LOCK;
62
            cur_lock &= ~RADEON_CUR_LOCK;
63
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock);
63
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock);
64
    }
64
    }
65
}
65
}
66
 
66
 
67
cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
67
cursor_t* __stdcall select_cursor_kms(cursor_t *cursor)
68
{
68
{
69
    struct radeon_device *rdev;
69
    struct radeon_device *rdev;
70
    struct radeon_crtc   *radeon_crtc;
70
    struct radeon_crtc   *radeon_crtc;
71
    cursor_t *old;
71
    cursor_t *old;
72
    uint32_t  gpu_addr;
72
    uint32_t  gpu_addr;
73
 
73
 
74
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
74
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
75
    radeon_crtc = to_radeon_crtc(rdisplay->crtc);
75
    radeon_crtc = to_radeon_crtc(rdisplay->crtc);
76
 
76
 
77
    old = rdisplay->cursor;
77
    old = rdisplay->cursor;
78
 
78
 
79
    rdisplay->cursor = cursor;
79
    rdisplay->cursor = cursor;
80
    gpu_addr = radeon_bo_gpu_offset(cursor->robj);
80
    gpu_addr = radeon_bo_gpu_offset(cursor->robj);
81
 
81
 
82
    if (ASIC_IS_AVIVO(rdev))
82
    if (ASIC_IS_AVIVO(rdev))
83
        WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
83
        WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
84
    else {
84
    else {
85
        radeon_crtc->legacy_cursor_offset = gpu_addr - rdev->mc.vram_location;
85
        radeon_crtc->legacy_cursor_offset = gpu_addr - rdev->mc.vram_start;
86
        /* offset is from DISP(2)_BASE_ADDRESS */
86
        /* offset is from DISP(2)_BASE_ADDRESS */
87
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
87
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
88
    }
88
    }
89
 
89
 
90
    return old;
90
    return old;
91
};
91
};
92
 
92
 
93
void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
93
void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y)
94
{
94
{
95
    struct radeon_device *rdev;
95
    struct radeon_device *rdev;
96
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
96
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
97
    struct drm_crtc *crtc = rdisplay->crtc;
97
    struct drm_crtc *crtc = rdisplay->crtc;
98
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
98
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
99
 
99
 
100
    int hot_x = cursor->hot_x;
100
    int hot_x = cursor->hot_x;
101
    int hot_y = cursor->hot_y;
101
    int hot_y = cursor->hot_y;
102
 
102
 
103
    radeon_lock_cursor_kms(crtc, true);
103
    radeon_lock_cursor_kms(crtc, true);
104
    if (ASIC_IS_AVIVO(rdev))
104
    if (ASIC_IS_AVIVO(rdev))
105
    {
105
    {
106
        int w = 32;
106
        int w = 32;
107
        int i = 0;
107
        int i = 0;
108
        struct drm_crtc *crtc_p;
108
        struct drm_crtc *crtc_p;
109
 
109
 
110
        /* avivo cursor are offset into the total surface */
110
        /* avivo cursor are offset into the total surface */
111
//        x += crtc->x;
111
//        x += crtc->x;
112
//        y += crtc->y;
112
//        y += crtc->y;
113
 
113
 
114
//        DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
114
//        DRM_DEBUG("x %d y %d c->x %d c->y %d\n", x, y, crtc->x, crtc->y);
115
#if 0
115
#if 0
116
        /* avivo cursor image can't end on 128 pixel boundry or
116
        /* avivo cursor image can't end on 128 pixel boundry or
117
         * go past the end of the frame if both crtcs are enabled
117
         * go past the end of the frame if both crtcs are enabled
118
         */
118
         */
119
        list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) {
119
        list_for_each_entry(crtc_p, &crtc->dev->mode_config.crtc_list, head) {
120
            if (crtc_p->enabled)
120
            if (crtc_p->enabled)
121
                i++;
121
                i++;
122
        }
122
        }
123
        if (i > 1) {
123
        if (i > 1) {
124
            int cursor_end, frame_end;
124
            int cursor_end, frame_end;
125
 
125
 
126
            cursor_end = x + w;
126
            cursor_end = x + w;
127
            frame_end = crtc->x + crtc->mode.crtc_hdisplay;
127
            frame_end = crtc->x + crtc->mode.crtc_hdisplay;
128
            if (cursor_end >= frame_end) {
128
            if (cursor_end >= frame_end) {
129
                w = w - (cursor_end - frame_end);
129
                w = w - (cursor_end - frame_end);
130
                if (!(frame_end & 0x7f))
130
                if (!(frame_end & 0x7f))
131
                    w--;
131
                    w--;
132
            } else {
132
            } else {
133
                if (!(cursor_end & 0x7f))
133
                if (!(cursor_end & 0x7f))
134
                    w--;
134
                    w--;
135
            }
135
            }
136
            if (w <= 0)
136
            if (w <= 0)
137
                w = 1;
137
                w = 1;
138
        }
138
        }
139
#endif
139
#endif
140
        WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset,
140
        WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset,
141
               (x << 16) | y);
141
               (x << 16) | y);
142
        WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset,
142
        WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset,
143
               (hot_x << 16) | hot_y);
143
               (hot_x << 16) | hot_y);
144
        WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
144
        WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
145
               ((w - 1) << 16) | 31);
145
               ((w - 1) << 16) | 31);
146
    } else {
146
    } else {
147
        if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
147
        if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
148
            y *= 2;
148
            y *= 2;
149
 
149
 
150
        uint32_t  gpu_addr;
150
        uint32_t  gpu_addr;
151
        int       xorg =0, yorg=0;
151
        int       xorg =0, yorg=0;
152
 
152
 
153
        x = x - hot_x;
153
        x = x - hot_x;
154
        y = y - hot_y;
154
        y = y - hot_y;
155
 
155
 
156
        if( x < 0 )
156
        if( x < 0 )
157
        {
157
        {
158
            xorg = -x + 1;
158
            xorg = -x + 1;
159
            x = 0;
159
            x = 0;
160
        }
160
        }
161
 
161
 
162
        if( y < 0 )
162
        if( y < 0 )
163
        {
163
        {
164
            yorg = -hot_y + 1;
164
            yorg = -hot_y + 1;
165
            y = 0;
165
            y = 0;
166
        };
166
        };
167
 
167
 
168
        WREG32(RADEON_CUR_HORZ_VERT_OFF,
168
        WREG32(RADEON_CUR_HORZ_VERT_OFF,
169
               (RADEON_CUR_LOCK | (xorg << 16) | yorg ));
169
               (RADEON_CUR_LOCK | (xorg << 16) | yorg ));
170
        WREG32(RADEON_CUR_HORZ_VERT_POSN,
170
        WREG32(RADEON_CUR_HORZ_VERT_POSN,
171
               (RADEON_CUR_LOCK | (x << 16) | y));
171
               (RADEON_CUR_LOCK | (x << 16) | y));
172
 
172
 
173
        gpu_addr = radeon_bo_gpu_offset(cursor->robj);
173
        gpu_addr = radeon_bo_gpu_offset(cursor->robj);
174
 
174
 
175
        /* offset is from DISP(2)_BASE_ADDRESS */
175
        /* offset is from DISP(2)_BASE_ADDRESS */
176
        WREG32(RADEON_CUR_OFFSET,
176
        WREG32(RADEON_CUR_OFFSET,
177
         (gpu_addr - rdev->mc.vram_location + (yorg * 256)));
177
         (gpu_addr - rdev->mc.vram_start + (yorg * 256)));
178
    }
178
    }
179
    radeon_lock_cursor_kms(crtc, false);
179
    radeon_lock_cursor_kms(crtc, false);
180
}
180
}
181
 
181
 
182
static char *manufacturer_name(unsigned char *x)
182
static char *manufacturer_name(unsigned char *x)
183
{
183
{
184
    static char name[4];
184
    static char name[4];
185
 
185
 
186
    name[0] = ((x[0] & 0x7C) >> 2) + '@';
186
    name[0] = ((x[0] & 0x7C) >> 2) + '@';
187
    name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
187
    name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
188
    name[2] = (x[1] & 0x1F) + '@';
188
    name[2] = (x[1] & 0x1F) + '@';
189
    name[3] = 0;
189
    name[3] = 0;
190
 
190
 
191
    return name;
191
    return name;
192
}
192
}
193
 
193
 
194
bool set_mode(struct drm_device *dev, struct drm_connector *connector,
194
bool set_mode(struct drm_device *dev, struct drm_connector *connector,
195
              videomode_t *reqmode, bool strict)
195
              videomode_t *reqmode, bool strict)
196
{
196
{
197
    struct drm_display_mode  *mode = NULL, *tmpmode;
197
    struct drm_display_mode  *mode = NULL, *tmpmode;
198
 
198
 
199
    bool ret = false;
199
    bool ret = false;
200
 
200
 
201
    ENTER();
201
    ENTER();
202
 
202
 
203
    dbgprintf("width %d height %d vrefresh %d\n",
203
    dbgprintf("width %d height %d vrefresh %d\n",
204
               reqmode->width, reqmode->height, reqmode->freq);
204
               reqmode->width, reqmode->height, reqmode->freq);
205
 
205
 
206
    list_for_each_entry(tmpmode, &connector->modes, head)
206
    list_for_each_entry(tmpmode, &connector->modes, head)
207
    {
207
    {
208
        if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
208
        if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
209
            (drm_mode_height(tmpmode)   == reqmode->height) &&
209
            (drm_mode_height(tmpmode)   == reqmode->height) &&
210
            (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
210
            (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
211
        {
211
        {
212
            mode = tmpmode;
212
            mode = tmpmode;
213
            goto do_set;
213
            goto do_set;
214
        }
214
        }
215
    };
215
    };
216
 
216
 
217
    if( (mode == NULL) && (strict == false) )
217
    if( (mode == NULL) && (strict == false) )
218
    {
218
    {
219
        list_for_each_entry(tmpmode, &connector->modes, head)
219
        list_for_each_entry(tmpmode, &connector->modes, head)
220
        {
220
        {
221
            if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
221
            if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
222
                (drm_mode_height(tmpmode) == reqmode->height) )
222
                (drm_mode_height(tmpmode) == reqmode->height) )
223
            {
223
            {
224
                mode = tmpmode;
224
                mode = tmpmode;
225
                goto do_set;
225
                goto do_set;
226
            }
226
            }
227
        };
227
        };
228
    };
228
    };
229
 
229
 
230
do_set:
230
do_set:
231
 
231
 
232
    if( mode != NULL )
232
    if( mode != NULL )
233
    {
233
    {
234
        struct drm_framebuffer   *fb;
234
        struct drm_framebuffer   *fb;
235
        struct drm_encoder       *encoder;
235
        struct drm_encoder       *encoder;
236
        struct drm_crtc          *crtc;
236
        struct drm_crtc          *crtc;
237
 
237
 
238
//        char  con_edid[128];
238
//        char  con_edid[128];
239
        char *con_name;
239
        char *con_name;
240
        char *enc_name;
240
        char *enc_name;
241
 
241
 
242
        encoder = connector->encoder;
242
        encoder = connector->encoder;
243
        crtc = encoder->crtc;
243
        crtc = encoder->crtc;
244
 
244
 
245
        fb = list_first_entry(&dev->mode_config.fb_kernel_list,
245
        fb = list_first_entry(&dev->mode_config.fb_kernel_list,
246
                              struct drm_framebuffer, filp_head);
246
                              struct drm_framebuffer, filp_head);
247
 
247
 
248
//        memcpy(con_edid, connector->edid_blob_ptr->data, 128);
248
//        memcpy(con_edid, connector->edid_blob_ptr->data, 128);
249
 
249
 
250
//        dbgprintf("Manufacturer: %s Model %x Serial Number %u\n",
250
//        dbgprintf("Manufacturer: %s Model %x Serial Number %u\n",
251
//        manufacturer_name(con_edid + 0x08),
251
//        manufacturer_name(con_edid + 0x08),
252
//        (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
252
//        (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
253
//        (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
253
//        (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
254
//            + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
254
//            + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
255
 
255
 
256
        con_name = drm_get_connector_name(connector);
256
        con_name = drm_get_connector_name(connector);
257
        enc_name = drm_get_encoder_name(encoder);
257
        enc_name = drm_get_encoder_name(encoder);
258
 
258
 
259
        dbgprintf("set mode %d %d connector %s encoder %s\n",
259
        dbgprintf("set mode %d %d connector %s encoder %s\n",
260
                   reqmode->width, reqmode->height, con_name, enc_name);
260
                   reqmode->width, reqmode->height, con_name, enc_name);
261
 
261
 
262
        fb->width  = reqmode->width;
262
        fb->width  = reqmode->width;
263
        fb->height = reqmode->height;
263
        fb->height = reqmode->height;
264
        fb->pitch  = radeon_align_pitch(dev->dev_private, reqmode->width, 32, false) * ((32 + 1) / 8);
264
        fb->pitch  = radeon_align_pitch(dev->dev_private, reqmode->width, 32, false) * ((32 + 1) / 8);
265
 
265
 
266
        crtc->fb = fb;
266
        crtc->fb = fb;
267
        crtc->enabled = true;
267
        crtc->enabled = true;
268
        rdisplay->crtc = crtc;
268
        rdisplay->crtc = crtc;
269
 
269
 
270
        ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb);
270
        ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb);
271
 
271
 
272
        select_cursor_kms(rdisplay->cursor);
272
        select_cursor_kms(rdisplay->cursor);
273
        radeon_show_cursor_kms(crtc);
273
        radeon_show_cursor_kms(crtc);
274
 
274
 
275
        if (ret == true)
275
        if (ret == true)
276
        {
276
        {
277
            rdisplay->width    = fb->width;
277
            rdisplay->width    = fb->width;
278
            rdisplay->height   = fb->height;
278
            rdisplay->height   = fb->height;
279
            rdisplay->pitch    = fb->pitch;
279
            rdisplay->pitch    = fb->pitch;
280
            rdisplay->vrefresh = drm_mode_vrefresh(mode);
280
            rdisplay->vrefresh = drm_mode_vrefresh(mode);
281
 
281
 
282
            sysSetScreen(fb->width, fb->height, fb->pitch);
282
            sysSetScreen(fb->width, fb->height, fb->pitch);
283
 
283
 
284
            dbgprintf("new mode %d x %d pitch %d\n",
284
            dbgprintf("new mode %d x %d pitch %d\n",
285
                       fb->width, fb->height, fb->pitch);
285
                       fb->width, fb->height, fb->pitch);
286
        }
286
        }
287
        else
287
        else
288
            DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
288
            DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
289
                       fb->width, fb->height, crtc);
289
                       fb->width, fb->height, crtc);
290
    }
290
    }
291
 
291
 
292
    LEAVE();
292
    LEAVE();
293
    return ret;
293
    return ret;
294
};
294
};
295
 
295
 
296
static int count_connector_modes(struct drm_connector* connector)
296
static int count_connector_modes(struct drm_connector* connector)
297
{
297
{
298
    struct drm_display_mode  *mode;
298
    struct drm_display_mode  *mode;
299
    int count = 0;
299
    int count = 0;
300
 
300
 
301
    list_for_each_entry(mode, &connector->modes, head)
301
    list_for_each_entry(mode, &connector->modes, head)
302
    {
302
    {
303
        count++;
303
        count++;
304
    };
304
    };
305
    return count;
305
    return count;
306
};
306
};
307
 
307
 
308
static struct drm_connector* get_def_connector(struct drm_device *dev)
308
static struct drm_connector* get_def_connector(struct drm_device *dev)
309
{
309
{
310
    struct drm_connector  *connector;
310
    struct drm_connector  *connector;
311
    struct drm_connector  *def_connector = NULL;
311
    struct drm_connector  *def_connector = NULL;
312
 
312
 
313
    list_for_each_entry(connector, &dev->mode_config.connector_list, head)
313
    list_for_each_entry(connector, &dev->mode_config.connector_list, head)
314
    {
314
    {
315
        struct drm_encoder  *encoder;
315
        struct drm_encoder  *encoder;
316
        struct drm_crtc     *crtc;
316
        struct drm_crtc     *crtc;
317
 
317
 
318
        if( connector->status != connector_status_connected)
318
        if( connector->status != connector_status_connected)
319
            continue;
319
            continue;
320
 
320
 
321
        encoder = connector->encoder;
321
        encoder = connector->encoder;
322
        if( encoder == NULL)
322
        if( encoder == NULL)
323
            continue;
323
            continue;
324
 
324
 
325
        crtc = encoder->crtc;
325
        crtc = encoder->crtc;
326
        if(crtc == NULL)
326
        if(crtc == NULL)
327
            continue;
327
            continue;
328
 
328
 
329
        def_connector = connector;
329
        def_connector = connector;
330
        break;
330
        break;
331
    };
331
    };
332
 
332
 
333
    return def_connector;
333
    return def_connector;
334
};
334
};
335
 
335
 
336
bool init_display_kms(struct radeon_device *rdev, videomode_t *usermode)
336
bool init_display_kms(struct radeon_device *rdev, videomode_t *usermode)
337
{
337
{
338
    struct drm_device   *dev;
338
    struct drm_device   *dev;
339
 
339
 
340
    cursor_t            *cursor;
340
    cursor_t            *cursor;
341
    bool                 retval = false;
341
    bool                 retval = false;
342
    u32_t                ifl;
342
    u32_t                ifl;
343
 
343
 
344
    ENTER();
344
    ENTER();
345
 
345
 
346
    rdisplay = GetDisplay();
346
    rdisplay = GetDisplay();
347
 
347
 
348
    dev = rdisplay->ddev = rdev->ddev;
348
    dev = rdisplay->ddev = rdev->ddev;
349
 
349
 
350
    ifl = safe_cli();
350
    ifl = safe_cli();
351
    {
351
    {
352
        list_for_each_entry(cursor, &rdisplay->cursors, list)
352
        list_for_each_entry(cursor, &rdisplay->cursors, list)
353
        {
353
        {
354
            init_cursor(cursor);
354
            init_cursor(cursor);
355
        };
355
        };
356
    };
356
    };
357
    safe_sti(ifl);
357
    safe_sti(ifl);
358
 
358
 
359
    rdisplay->connector = get_def_connector(dev);
359
    rdisplay->connector = get_def_connector(dev);
360
    if( rdisplay->connector == 0 )
360
    if( rdisplay->connector == 0 )
361
    {
361
    {
362
        dbgprintf("no active connectors\n");
362
        dbgprintf("no active connectors\n");
363
        return false;
363
        return false;
364
    };
364
    };
365
 
365
 
366
    rdisplay->crtc = rdisplay->connector->encoder->crtc;
366
    rdisplay->crtc = rdisplay->connector->encoder->crtc;
367
    rdisplay->supported_modes = count_connector_modes(rdisplay->connector);
367
    rdisplay->supported_modes = count_connector_modes(rdisplay->connector);
368
 
368
 
369
    dbgprintf("current mode %d x %d x %d\n",
369
    dbgprintf("current mode %d x %d x %d\n",
370
              rdisplay->width, rdisplay->height, rdisplay->vrefresh);
370
              rdisplay->width, rdisplay->height, rdisplay->vrefresh);
371
    dbgprintf("user mode mode %d x %d x %d\n",
371
    dbgprintf("user mode mode %d x %d x %d\n",
372
              usermode->width, usermode->height, usermode->freq);
372
              usermode->width, usermode->height, usermode->freq);
373
 
373
 
374
    if( (usermode->width  != 0) &&
374
    if( (usermode->width  != 0) &&
375
        (usermode->height != 0) &&
375
        (usermode->height != 0) &&
376
        ( (usermode->width  != rdisplay->width)  ||
376
        ( (usermode->width  != rdisplay->width)  ||
377
          (usermode->height != rdisplay->height) ||
377
          (usermode->height != rdisplay->height) ||
378
          (usermode->freq   != rdisplay->vrefresh) ) )
378
          (usermode->freq   != rdisplay->vrefresh) ) )
379
    {
379
    {
380
 
380
 
381
        retval = set_mode(dev, rdisplay->connector, usermode, false);
381
        retval = set_mode(dev, rdisplay->connector, usermode, false);
382
    }
382
    }
383
 
383
 
384
    ifl = safe_cli();
384
    ifl = safe_cli();
385
    {
385
    {
386
        rdisplay->restore_cursor(0,0);
386
        rdisplay->restore_cursor(0,0);
387
        rdisplay->init_cursor    = init_cursor;
387
        rdisplay->init_cursor    = init_cursor;
388
        rdisplay->select_cursor  = select_cursor_kms;
388
        rdisplay->select_cursor  = select_cursor_kms;
389
        rdisplay->show_cursor    = NULL;
389
        rdisplay->show_cursor    = NULL;
390
        rdisplay->move_cursor    = move_cursor_kms;
390
        rdisplay->move_cursor    = move_cursor_kms;
391
        rdisplay->restore_cursor = restore_cursor;
391
        rdisplay->restore_cursor = restore_cursor;
392
        rdisplay->disable_mouse  = disable_mouse;
392
        rdisplay->disable_mouse  = disable_mouse;
393
 
393
 
394
        select_cursor_kms(rdisplay->cursor);
394
        select_cursor_kms(rdisplay->cursor);
395
        radeon_show_cursor_kms(rdisplay->crtc);
395
        radeon_show_cursor_kms(rdisplay->crtc);
396
    };
396
    };
397
    safe_sti(ifl);
397
    safe_sti(ifl);
398
 
398
 
399
    LEAVE();
399
    LEAVE();
400
 
400
 
401
    return retval;
401
    return retval;
402
};
402
};
403
 
403
 
404
int get_modes(videomode_t *mode, int *count)
404
int get_modes(videomode_t *mode, int *count)
405
{
405
{
406
    int err = -1;
406
    int err = -1;
407
 
407
 
408
    ENTER();
408
    ENTER();
409
 
409
 
410
    dbgprintf("mode %x count %d\n", mode, *count);
410
    dbgprintf("mode %x count %d\n", mode, *count);
411
 
411
 
412
    if( *count == 0 )
412
    if( *count == 0 )
413
    {
413
    {
414
        *count = rdisplay->supported_modes;
414
        *count = rdisplay->supported_modes;
415
        err = 0;
415
        err = 0;
416
    }
416
    }
417
    else if( mode != NULL )
417
    else if( mode != NULL )
418
    {
418
    {
419
        struct drm_display_mode  *drmmode;
419
        struct drm_display_mode  *drmmode;
420
        int i = 0;
420
        int i = 0;
421
 
421
 
422
        if( *count > rdisplay->supported_modes)
422
        if( *count > rdisplay->supported_modes)
423
            *count = rdisplay->supported_modes;
423
            *count = rdisplay->supported_modes;
424
 
424
 
425
        list_for_each_entry(drmmode, &rdisplay->connector->modes, head)
425
        list_for_each_entry(drmmode, &rdisplay->connector->modes, head)
426
        {
426
        {
427
            if( i < *count)
427
            if( i < *count)
428
            {
428
            {
429
                mode->width  = drm_mode_width(drmmode);
429
                mode->width  = drm_mode_width(drmmode);
430
                mode->height = drm_mode_height(drmmode);
430
                mode->height = drm_mode_height(drmmode);
431
                mode->bpp    = 32;
431
                mode->bpp    = 32;
432
                mode->freq   = drm_mode_vrefresh(drmmode);
432
                mode->freq   = drm_mode_vrefresh(drmmode);
433
                i++;
433
                i++;
434
                mode++;
434
                mode++;
435
            }
435
            }
436
            else break;
436
            else break;
437
        };
437
        };
438
        *count = i;
438
        *count = i;
439
        err = 0;
439
        err = 0;
440
    };
440
    };
441
    LEAVE();
441
    LEAVE();
442
    return err;
442
    return err;
443
}
443
}
444
 
444
 
445
int set_user_mode(videomode_t *mode)
445
int set_user_mode(videomode_t *mode)
446
{
446
{
447
    int err = -1;
447
    int err = -1;
448
 
448
 
449
    ENTER();
449
    ENTER();
450
 
450
 
451
    dbgprintf("width %d height %d vrefresh %d\n",
451
    dbgprintf("width %d height %d vrefresh %d\n",
452
               mode->width, mode->height, mode->freq);
452
               mode->width, mode->height, mode->freq);
453
 
453
 
454
    if( (mode->width  != 0)  &&
454
    if( (mode->width  != 0)  &&
455
        (mode->height != 0)  &&
455
        (mode->height != 0)  &&
456
        (mode->freq   != 0 ) &&
456
        (mode->freq   != 0 ) &&
457
        ( (mode->width   != rdisplay->width)  ||
457
        ( (mode->width   != rdisplay->width)  ||
458
          (mode->height  != rdisplay->height) ||
458
          (mode->height  != rdisplay->height) ||
459
          (mode->freq    != rdisplay->vrefresh) ) )
459
          (mode->freq    != rdisplay->vrefresh) ) )
460
    {
460
    {
461
        if( set_mode(rdisplay->ddev, rdisplay->connector, mode, true) )
461
        if( set_mode(rdisplay->ddev, rdisplay->connector, mode, true) )
462
            err = 0;
462
            err = 0;
463
    };
463
    };
464
 
464
 
465
    LEAVE();
465
    LEAVE();
466
    return err;
466
    return err;
467
};
467
};
468
 
468
 
469
#if 0
469
#if 0
470
void drm_helper_disable_unused_functions(struct drm_device *dev)
470
void drm_helper_disable_unused_functions(struct drm_device *dev)
471
{
471
{
472
    struct drm_encoder *encoder;
472
    struct drm_encoder *encoder;
473
    struct drm_connector *connector;
473
    struct drm_connector *connector;
474
    struct drm_encoder_helper_funcs *encoder_funcs;
474
    struct drm_encoder_helper_funcs *encoder_funcs;
475
    struct drm_crtc *crtc;
475
    struct drm_crtc *crtc;
476
 
476
 
477
    list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
477
    list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
478
        if (!connector->encoder)
478
        if (!connector->encoder)
479
            continue;
479
            continue;
480
        if (connector->status == connector_status_disconnected)
480
        if (connector->status == connector_status_disconnected)
481
            connector->encoder = NULL;
481
            connector->encoder = NULL;
482
    }
482
    }
483
 
483
 
484
    list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
484
    list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
485
        encoder_funcs = encoder->helper_private;
485
        encoder_funcs = encoder->helper_private;
486
        if (!drm_helper_encoder_in_use(encoder)) {
486
        if (!drm_helper_encoder_in_use(encoder)) {
487
            if (encoder_funcs->disable)
487
            if (encoder_funcs->disable)
488
                (*encoder_funcs->disable)(encoder);
488
                (*encoder_funcs->disable)(encoder);
489
            else
489
            else
490
            (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
490
            (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
491
            /* disconnector encoder from any connector */
491
            /* disconnector encoder from any connector */
492
            encoder->crtc = NULL;
492
            encoder->crtc = NULL;
493
        }
493
        }
494
    }
494
    }
495
 
495
 
496
    list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
496
    list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
497
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
497
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
498
        crtc->enabled = drm_helper_crtc_in_use(crtc);
498
        crtc->enabled = drm_helper_crtc_in_use(crtc);
499
        if (!crtc->enabled) {
499
        if (!crtc->enabled) {
500
            crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
500
            crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
501
            crtc->fb = NULL;
501
            crtc->fb = NULL;
502
        }
502
        }
503
    }
503
    }
504
}
504
}
505
#endif
505
#endif