~ubuntu-branches/ubuntu/karmic/xserver-xorg-video-nouveau/karmic

« back to all changes in this revision

Viewing changes to src/drmmode_display.c

  • Committer: Bazaar Package Importer
  • Author(s): Chris Lamb
  • Date: 2008-07-06 20:26:53 UTC
  • Revision ID: james.westby@ubuntu.com-20080706202653-e99oiii765j3a0qn
Tags: upstream-0.0.10~git+20080706+b1f3169
Import upstream version 0.0.10~git+20080706+b1f3169

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright � 2007 Red Hat, Inc.
 
3
 * Copyright � 2008 Maarten Maathuis
 
4
 *
 
5
 * Permission is hereby granted, free of charge, to any person obtaining a
 
6
 * copy of this software and associated documentation files (the "Software"),
 
7
 * to deal in the Software without restriction, including without limitation
 
8
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
9
 * and/or sell copies of the Software, and to permit persons to whom the
 
10
 * Software is furnished to do so, subject to the following conditions:
 
11
 *
 
12
 * The above copyright notice and this permission notice (including the next
 
13
 * paragraph) shall be included in all copies or substantial portions of the
 
14
 * Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 
22
 * SOFTWARE.
 
23
 *
 
24
 * Authors:
 
25
 *    Dave Airlie <airlied@redhat.com>
 
26
 *
 
27
 */
 
28
 
 
29
#ifdef HAVE_CONFIG_H
 
30
#include "config.h"
 
31
#endif
 
32
 
 
33
#ifdef XF86DRM_MODE
 
34
 
 
35
#include "drmmode_display.h"
 
36
#include "sarea.h"
 
37
 
 
38
/* not using for the moment */
 
39
uint32_t drmmode_create_new_fb(ScrnInfoPtr pScrn, int width, int height, int *pitch)
 
40
{
 
41
#if NOUVEAU_EXA_PIXMAPS
 
42
        NVPtr pNv = NVPTR(pScrn);
 
43
        int ret = 0;
 
44
 
 
45
        /* temporary hack, allow old framebuffers to continue to exist and idle. */
 
46
        if (pNv->FB_old) {
 
47
                nouveau_bo_del(pNv->FB_old);
 
48
                pNv->FB_old = NULL;
 
49
        }
 
50
 
 
51
        pNv->FB_old = pNv->FB;
 
52
        pNv->FB = NULL;
 
53
 
 
54
        *pitch = NOUVEAU_ALIGN(*pitch, 64) * (pScrn->bitsPerPixel >> 3);
 
55
 
 
56
        ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
 
57
                        0, *pitch * NOUVEAU_ALIGN(height, 64), &pNv->FB)
 
58
 
 
59
        if (ret)
 
60
                return 0;
 
61
 
 
62
        ret = nouveau_bo_map(pNv->FB, NOUVEAU_BO_RDWR);
 
63
 
 
64
        if (ret)
 
65
                return 0;
 
66
 
 
67
        return pNv->FB.handle;
 
68
#else
 
69
        return 0; /* we have a fixed FB */
 
70
#endif /* NOUVEAU_EXA_PIXMAPS */
 
71
}
 
72
 
 
73
#if 0
 
74
static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height);
 
75
#endif
 
76
 
 
77
static Bool
 
78
drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
 
79
{
 
80
        //xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
 
81
        //drmmode_crtc_private_ptr drmmode_crtc = xf86_config->crtc[0]->driver_private;
 
82
        //drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
83
        //Bool ret;
 
84
 
 
85
        ErrorF("resize called %d %d\n", width, height);
 
86
        //ret = drmmode_resize_fb(scrn, drmmode, width, height);
 
87
        scrn->virtualX = width;
 
88
        scrn->virtualY = height;
 
89
 
 
90
        return TRUE; //ret;
 
91
}
 
92
 
 
93
static void
 
94
drmmode_ConvertFromKMode(ScrnInfoPtr    scrn,
 
95
                        struct drm_mode_modeinfo *kmode,
 
96
                        DisplayModePtr  mode)
 
97
{
 
98
        memset(mode, 0, sizeof(DisplayModeRec));
 
99
        mode->status = MODE_OK;
 
100
 
 
101
        mode->Clock = kmode->clock;
 
102
 
 
103
        mode->HDisplay = kmode->hdisplay;
 
104
        mode->HSyncStart = kmode->hsync_start;
 
105
        mode->HSyncEnd = kmode->hsync_end;
 
106
        mode->HTotal = kmode->htotal;
 
107
        mode->HSkew = kmode->hskew;
 
108
 
 
109
        mode->VDisplay = kmode->vdisplay;
 
110
        mode->VSyncStart = kmode->vsync_start;
 
111
        mode->VSyncEnd = kmode->vsync_end;
 
112
        mode->VTotal = kmode->vtotal;
 
113
        mode->VScan = kmode->vscan;
 
114
 
 
115
        mode->Flags = kmode->flags; //& FLAG_BITS;
 
116
        mode->name = strdup(kmode->name);
 
117
 
 
118
        if (kmode->type & DRM_MODE_TYPE_DRIVER)
 
119
                mode->type = M_T_DRIVER;
 
120
        if (kmode->type & DRM_MODE_TYPE_PREFERRED)
 
121
                mode->type |= M_T_PREFERRED;
 
122
        xf86SetModeCrtc (mode, scrn->adjustFlags);
 
123
}
 
124
 
 
125
static void
 
126
drmmode_ConvertToKMode(ScrnInfoPtr      scrn,
 
127
                struct drm_mode_modeinfo *kmode,
 
128
                DisplayModePtr  mode)
 
129
{
 
130
        memset(kmode, 0, sizeof(*kmode));
 
131
 
 
132
        kmode->clock = mode->Clock;
 
133
        kmode->hdisplay = mode->HDisplay;
 
134
        kmode->hsync_start = mode->HSyncStart;
 
135
        kmode->hsync_end = mode->HSyncEnd;
 
136
        kmode->htotal = mode->HTotal;
 
137
        kmode->hskew = mode->HSkew;
 
138
 
 
139
        kmode->vdisplay = mode->VDisplay;
 
140
        kmode->vsync_start = mode->VSyncStart;
 
141
        kmode->vsync_end = mode->VSyncEnd;
 
142
        kmode->vtotal = mode->VTotal;
 
143
        kmode->vscan = mode->VScan;
 
144
 
 
145
        kmode->flags = mode->Flags; //& FLAG_BITS;
 
146
        if (mode->name)
 
147
                strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
 
148
        kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
 
149
 
 
150
}
 
151
 
 
152
static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
 
153
        drmmode_xf86crtc_resize
 
154
};
 
155
 
 
156
static void
 
157
drmmode_crtc_dpms(xf86CrtcPtr crtc, int mode)
 
158
{
 
159
        return;
 
160
}
 
161
 
 
162
static Bool
 
163
drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
 
164
                        Rotation rotation, int x, int y)
 
165
{
 
166
        xf86CrtcConfigPtr   xf86_config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
 
167
        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
168
        drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
169
        int saved_x, saved_y;
 
170
        Rotation saved_rotation;
 
171
        DisplayModeRec saved_mode;
 
172
        uint32_t *output_ids;
 
173
        int output_count = 0;
 
174
        int ret = TRUE;
 
175
        int i;
 
176
        int fb_id;
 
177
        struct drm_mode_modeinfo kmode;
 
178
 
 
179
        ErrorF("drmmode_set_mode_major called\n");
 
180
 
 
181
        saved_mode = crtc->mode;
 
182
        saved_x = crtc->x;
 
183
        saved_y = crtc->y;
 
184
        saved_rotation = crtc->rotation;
 
185
 
 
186
        crtc->mode = *mode;
 
187
        crtc->x = x;
 
188
        crtc->y = y;
 
189
        crtc->rotation = rotation;
 
190
 
 
191
        output_ids = xcalloc(sizeof(uint32_t), xf86_config->num_output);
 
192
        if (!output_ids) {
 
193
                ret = FALSE;
 
194
                goto done;
 
195
        }
 
196
 
 
197
        for (i = 0; i < xf86_config->num_output; i++) {
 
198
                xf86OutputPtr output = xf86_config->output[i];
 
199
                drmmode_output_private_ptr drmmode_output;
 
200
 
 
201
                if (output->crtc != crtc)
 
202
                        continue;
 
203
 
 
204
                drmmode_output = output->driver_private;
 
205
                output_ids[output_count] = drmmode_output->mode_output->connector_id;
 
206
                output_count++;
 
207
        }
 
208
 
 
209
        if (!xf86CrtcRotate(crtc, mode, rotation)) {
 
210
                goto done;
 
211
        }
 
212
 
 
213
        drmmode_ConvertToKMode(crtc->scrn, &kmode, mode);
 
214
 
 
215
        if (drmmode_crtc->shadow_id && crtc->rotatedData)
 
216
                fb_id = drmmode_crtc->shadow_id;
 
217
        else
 
218
                fb_id = drmmode->fb_id;
 
219
        ErrorF("fb id is %d\n", fb_id);
 
220
        drmModeSetCrtc(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id,
 
221
                        fb_id, x, y, output_ids, output_count, &kmode);
 
222
 
 
223
done:
 
224
        if (!ret) {
 
225
                crtc->x = saved_x;
 
226
                crtc->y = saved_y;
 
227
                crtc->rotation = saved_rotation;
 
228
                crtc->mode = saved_mode;
 
229
        }
 
230
 
 
231
        if (output_ids)
 
232
                xfree(output_ids);
 
233
        return ret;
 
234
}
 
235
 
 
236
static void
 
237
drmmode_set_cursor_colors (xf86CrtcPtr crtc, int bg, int fg)
 
238
{
 
239
  
 
240
}
 
241
 
 
242
static void
 
243
drmmode_set_cursor_position (xf86CrtcPtr crtc, int x, int y)
 
244
{
 
245
        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
246
        drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
247
 
 
248
        drmModeMoveCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, x, y);
 
249
}
 
250
 
 
251
static void
 
252
drmmode_load_cursor_argb (xf86CrtcPtr crtc, CARD32 *image)
 
253
{
 
254
        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
255
 
 
256
        NVPtr pNv = NVPTR(crtc->scrn);
 
257
        uint32_t *dst = NULL;
 
258
 
 
259
        if (drmmode_crtc->index == 1)
 
260
                dst = (uint32_t *) pNv->Cursor2->map;
 
261
        else
 
262
                dst = (uint32_t *) pNv->Cursor->map;
 
263
 
 
264
        /* Assume cursor is 64x64 */
 
265
        memcpy(dst, (uint32_t *)image, 64 * 64 * 4);
 
266
}
 
267
 
 
268
 
 
269
static void
 
270
drmmode_hide_cursor (xf86CrtcPtr crtc)
 
271
{
 
272
        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
273
        drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
274
 
 
275
        drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, 0, 64, 64);
 
276
 
 
277
}
 
278
 
 
279
static void
 
280
drmmode_show_cursor (xf86CrtcPtr crtc)
 
281
{
 
282
        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
283
        drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
284
        NVPtr pNv = NVPTR(crtc->scrn);
 
285
 
 
286
        drm_handle_t handle = 0;
 
287
 
 
288
        if (drmmode_crtc->index == 1)
 
289
                handle = pNv->Cursor2->map_handle;
 
290
        else
 
291
                handle = pNv->Cursor->map_handle;
 
292
 
 
293
        drmModeSetCursor(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, handle, 64, 64);
 
294
}
 
295
 
 
296
/* This stuff isn't ready for NOUVEAU_EXA_PIXMAPS, but can be easily ported. */
 
297
static void *
 
298
drmmode_shadow_allocate (xf86CrtcPtr crtc, int width, int height)
 
299
{
 
300
        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
301
        drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
302
        ScrnInfoPtr pScrn = crtc->scrn;
 
303
        NVPtr pNv = NVPTR(pScrn);
 
304
        int size, pitch, ret;
 
305
 
 
306
        ErrorF("drmmode_shadow_allocate\n");
 
307
 
 
308
        pitch = width * (pScrn->bitsPerPixel/8);
 
309
        size = pitch * height;
 
310
 
 
311
        if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
 
312
                        64, size, &drmmode_crtc->shadow)) {
 
313
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to allocate memory for shadow buffer!\n");
 
314
                return NULL;
 
315
        }
 
316
 
 
317
        if (drmmode_crtc->shadow && nouveau_bo_map(drmmode_crtc->shadow, NOUVEAU_BO_RDWR)) {
 
318
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
319
                                "Failed to map shadow buffer.\n");
 
320
                return NULL;
 
321
        }
 
322
 
 
323
        ret = drmModeAddFB(drmmode->fd, width, height, pScrn->depth, pScrn->bitsPerPixel, pitch, drmmode_crtc->shadow->map_handle, &drmmode_crtc->shadow_id);
 
324
        if (ret)
 
325
                return NULL;
 
326
 
 
327
        /* for easy acces by exa */
 
328
        pNv->shadow[drmmode_crtc->index] = drmmode_crtc->shadow;
 
329
 
 
330
        return drmmode_crtc->shadow->map;
 
331
}
 
332
 
 
333
static PixmapPtr
 
334
drmmode_shadow_create(xf86CrtcPtr crtc, void *data, int width, int height)
 
335
{
 
336
        ScrnInfoPtr pScrn = crtc->scrn;
 
337
        uint32_t pitch;
 
338
        PixmapPtr rotate_pixmap;
 
339
 
 
340
        ErrorF("drmmode_shadow_create\n");
 
341
 
 
342
        if (!data)
 
343
                data = crtc->funcs->shadow_allocate (crtc, width, height);
 
344
 
 
345
        pitch = width * (pScrn->bitsPerPixel/8);
 
346
 
 
347
        rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen,
 
348
                                                width, height,
 
349
                                                pScrn->depth,
 
350
                                                pScrn->bitsPerPixel,
 
351
                                                pitch,
 
352
                                                data);
 
353
 
 
354
        if (rotate_pixmap == NULL) {
 
355
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
356
                        "Couldn't allocate shadow pixmap for rotated CRTC\n");
 
357
        }
 
358
 
 
359
        return rotate_pixmap;
 
360
}
 
361
 
 
362
static void
 
363
drmmode_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rotate_pixmap, void *data)
 
364
{
 
365
        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
366
        drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
367
        ScrnInfoPtr pScrn = crtc->scrn;
 
368
        NVPtr pNv = NVPTR(pScrn);
 
369
        ScreenPtr pScreen = pScrn->pScreen;
 
370
 
 
371
        ErrorF("drmmode_shadow_destroy\n");
 
372
 
 
373
        if (rotate_pixmap)
 
374
                pScreen->DestroyPixmap(rotate_pixmap);
 
375
 
 
376
        if (drmmode_crtc->shadow_id) {
 
377
                drmModeRmFB(drmmode->fd, drmmode_crtc->shadow_id);
 
378
                drmmode_crtc->shadow_id = 0;
 
379
        }
 
380
 
 
381
        if (drmmode_crtc->shadow)
 
382
                nouveau_bo_del(&drmmode_crtc->shadow);
 
383
 
 
384
        drmmode_crtc->shadow = NULL;
 
385
 
 
386
        /* for easy acces by exa */
 
387
        pNv->shadow[drmmode_crtc->index] = NULL;
 
388
}
 
389
 
 
390
static void
 
391
drmmode_gamma_set(xf86CrtcPtr crtc, CARD16 *red, CARD16 *green, CARD16 *blue, int size)
 
392
{
 
393
        ScrnInfoPtr pScrn = crtc->scrn;
 
394
        drmmode_crtc_private_ptr drmmode_crtc = crtc->driver_private;
 
395
        drmmode_ptr drmmode = drmmode_crtc->drmmode;
 
396
        int ret;
 
397
 
 
398
        ErrorF("drmmode_gamma_set\n");
 
399
 
 
400
        ret = drmModeCrtcSetGamma(drmmode->fd, drmmode_crtc->mode_crtc->crtc_id, size, (uint16_t *)red, (uint16_t *)green, (uint16_t *)blue);
 
401
        if (ret)
 
402
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "drmModeCrtcSetGamma failed\n");
 
403
}
 
404
 
 
405
static const xf86CrtcFuncsRec drmmode_crtc_funcs = {
 
406
        .dpms = drmmode_crtc_dpms,
 
407
        .set_mode_major = drmmode_set_mode_major,
 
408
        .set_cursor_colors = drmmode_set_cursor_colors,
 
409
        .set_cursor_position = drmmode_set_cursor_position,
 
410
        .show_cursor = drmmode_show_cursor,
 
411
        .hide_cursor = drmmode_hide_cursor,
 
412
        .load_cursor_argb = drmmode_load_cursor_argb,
 
413
        .shadow_create = drmmode_shadow_create,
 
414
        .shadow_allocate = drmmode_shadow_allocate,
 
415
        .shadow_destroy = drmmode_shadow_destroy,
 
416
        .gamma_set = drmmode_gamma_set,
 
417
        .destroy = NULL, /* XXX */
 
418
};
 
419
 
 
420
 
 
421
static void
 
422
drmmode_crtc_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 
423
{
 
424
        xf86CrtcPtr crtc;
 
425
        drmmode_crtc_private_ptr drmmode_crtc;
 
426
 
 
427
        crtc = xf86CrtcCreate(pScrn, &drmmode_crtc_funcs);
 
428
        if (crtc == NULL)
 
429
                return;
 
430
 
 
431
        drmmode_crtc = xnfcalloc(sizeof(drmmode_crtc_private_rec), 1);
 
432
        drmmode_crtc->mode_crtc = drmModeGetCrtc(drmmode->fd, drmmode->mode_res->crtcs[num]);
 
433
        drmmode_crtc->drmmode = drmmode;
 
434
        drmmode_crtc->index = num;
 
435
        crtc->driver_private = drmmode_crtc;
 
436
 
 
437
        return;
 
438
}
 
439
 
 
440
static xf86OutputStatus
 
441
drmmode_output_detect(xf86OutputPtr output)
 
442
{
 
443
        /* go to the hw and retrieve a new output struct */
 
444
        drmmode_output_private_ptr drmmode_output = output->driver_private;
 
445
        drmmode_ptr drmmode = drmmode_output->drmmode;
 
446
        xf86OutputStatus status;
 
447
        drmModeFreeConnector(drmmode_output->mode_output);
 
448
 
 
449
        ErrorF("drmmode_output_detect called\n");
 
450
 
 
451
        drmmode_output->mode_output = drmModeGetConnector(drmmode->fd, drmmode_output->output_id);
 
452
 
 
453
        switch (drmmode_output->mode_output->connection) {
 
454
        case DRM_MODE_CONNECTED:
 
455
                status = XF86OutputStatusConnected;
 
456
                break;
 
457
        case DRM_MODE_DISCONNECTED:
 
458
                status = XF86OutputStatusDisconnected;
 
459
                break;
 
460
        default:
 
461
        case DRM_MODE_UNKNOWNCONNECTION:
 
462
                status = XF86OutputStatusUnknown;
 
463
                break;
 
464
        }
 
465
        return status;
 
466
}
 
467
 
 
468
static Bool
 
469
drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
 
470
{
 
471
        return MODE_OK;
 
472
}
 
473
 
 
474
static DisplayModePtr
 
475
drmmode_output_get_modes(xf86OutputPtr output)
 
476
{
 
477
        drmmode_output_private_ptr drmmode_output = output->driver_private;
 
478
        drmModeConnectorPtr koutput = drmmode_output->mode_output;
 
479
        drmmode_ptr drmmode = drmmode_output->drmmode;
 
480
        int i;
 
481
        DisplayModePtr Modes = NULL, Mode;
 
482
        drmModePropertyPtr props;
 
483
 
 
484
        ErrorF("drmmode_output_get_modes called\n");
 
485
 
 
486
        /* look for an EDID property */
 
487
        for (i = 0; i < koutput->count_props; i++) {
 
488
                props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
 
489
                if (props && (props->flags & DRM_MODE_PROP_BLOB)) {
 
490
                        if (!strcmp(props->name, "EDID")) {
 
491
                                ErrorF("EDID property found\n");
 
492
                                if (drmmode_output->edid_blob)
 
493
                                        drmModeFreePropertyBlob(drmmode_output->edid_blob);
 
494
                                drmmode_output->edid_blob = drmModeGetPropertyBlob(drmmode->fd, koutput->prop_values[i]);
 
495
 
 
496
                                if (!drmmode_output->edid_blob)
 
497
                                        ErrorF("No EDID blob\n");
 
498
                        }
 
499
                        drmModeFreeProperty(props);
 
500
                }
 
501
        }
 
502
 
 
503
        if (drmmode_output->edid_blob)
 
504
                xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, drmmode_output->edid_blob->data));
 
505
        else
 
506
                xf86OutputSetEDID(output, xf86InterpretEDID(output->scrn->scrnIndex, NULL));
 
507
 
 
508
        /* modes should already be available */
 
509
        for (i = 0; i < koutput->count_modes; i++) {
 
510
                Mode = xnfalloc(sizeof(DisplayModeRec));
 
511
 
 
512
                drmmode_ConvertFromKMode(output->scrn, &koutput->modes[i], Mode);
 
513
                Modes = xf86ModesAdd(Modes, Mode);
 
514
 
 
515
        }
 
516
        return Modes;
 
517
}
 
518
 
 
519
static void
 
520
drmmode_output_destroy(xf86OutputPtr output)
 
521
{
 
522
        drmmode_output_private_ptr drmmode_output = output->driver_private;
 
523
 
 
524
        if (drmmode_output->edid_blob)
 
525
                drmModeFreePropertyBlob(drmmode_output->edid_blob);
 
526
        drmModeFreeConnector(drmmode_output->mode_output);
 
527
        xfree(drmmode_output);
 
528
        output->driver_private = NULL;
 
529
}
 
530
 
 
531
static void
 
532
drmmode_output_dpms(xf86OutputPtr output, int mode)
 
533
{
 
534
        drmmode_output_private_ptr drmmode_output = output->driver_private;
 
535
        drmModeConnectorPtr koutput = drmmode_output->mode_output;
 
536
        drmmode_ptr drmmode = drmmode_output->drmmode;
 
537
        drmModePropertyPtr props;
 
538
        int i;
 
539
 
 
540
        ErrorF("drmmode_output_dpms called with mode %d\n", mode);
 
541
 
 
542
        for (i = 0; i < koutput->count_props; i++) {
 
543
                props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
 
544
                if (props && (props->flags & DRM_MODE_PROP_ENUM)) {
 
545
                        if (!strcmp(props->name, "DPMS")) {
 
546
                                ErrorF("DPMS property found\n");
 
547
                                drmModeConnectorSetProperty(drmmode->fd, drmmode_output->output_id, props->prop_id, mode); 
 
548
                        }
 
549
                        drmModeFreeProperty(props);
 
550
                }
 
551
        }
 
552
}
 
553
 
 
554
static const xf86OutputFuncsRec drmmode_output_funcs = {
 
555
        .dpms = drmmode_output_dpms,
 
556
        .detect = drmmode_output_detect,
 
557
        .mode_valid = drmmode_output_mode_valid,
 
558
        .get_modes = drmmode_output_get_modes,
 
559
        .destroy = drmmode_output_destroy
 
560
};
 
561
 
 
562
static int subpixel_conv_table[7] = { 0, SubPixelUnknown,
 
563
                                      SubPixelHorizontalRGB,
 
564
                                      SubPixelHorizontalBGR,
 
565
                                      SubPixelVerticalRGB,
 
566
                                      SubPixelVerticalBGR,
 
567
                                      SubPixelNone };
 
568
 
 
569
struct output_name {
 
570
        const char *name;
 
571
        int count;
 
572
};
 
573
 
 
574
struct output_name output_names[] = {
 
575
        { "None", 0 },
 
576
        { "VGA", 0 },
 
577
        { "DVI-I", 0 },
 
578
        { "DVI-D", 0 },
 
579
};
 
580
 
 
581
static void
 
582
drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
 
583
{
 
584
        xf86OutputPtr output;
 
585
        drmModeConnectorPtr koutput;
 
586
        drmModeEncoderPtr kencoder;
 
587
        drmmode_output_private_ptr drmmode_output;
 
588
        char name[32];
 
589
 
 
590
        ErrorF("drmmode_output_init\n");
 
591
 
 
592
        koutput = drmModeGetConnector(drmmode->fd, drmmode->mode_res->connectors[num]);
 
593
        if (!koutput) {
 
594
                ErrorF("No connector\n");
 
595
                return;
 
596
        }
 
597
 
 
598
        kencoder = drmModeGetEncoder(drmmode->fd, koutput->encoders[0]);
 
599
        if (!kencoder) {
 
600
                ErrorF("No encoder\n");
 
601
                drmModeFreeConnector(koutput);
 
602
                return;
 
603
        }
 
604
 
 
605
        snprintf(name, 32, "%s-%d", output_names[koutput->connector_type].name, output_names[koutput->connector_type].count++);
 
606
 
 
607
        output = xf86OutputCreate (pScrn, &drmmode_output_funcs, name);
 
608
        if (!output) {
 
609
                drmModeFreeEncoder(kencoder);
 
610
                drmModeFreeConnector(koutput);
 
611
                return;
 
612
        }
 
613
 
 
614
        drmmode_output = xcalloc(sizeof(drmmode_output_private_rec), 1);
 
615
        if (!drmmode_output) {
 
616
                xf86OutputDestroy(output);
 
617
                drmModeFreeConnector(koutput);
 
618
                drmModeFreeEncoder(kencoder);
 
619
                return;
 
620
        }
 
621
 
 
622
        drmmode_output->output_id = drmmode->mode_res->connectors[num];
 
623
        drmmode_output->mode_output = koutput;
 
624
        drmmode_output->mode_encoder = kencoder;
 
625
        drmmode_output->drmmode = drmmode;
 
626
        output->mm_width = koutput->mmWidth;
 
627
        output->mm_height = koutput->mmHeight;
 
628
 
 
629
        output->subpixel_order = subpixel_conv_table[koutput->subpixel];
 
630
        output->driver_private = drmmode_output;
 
631
 
 
632
        output->possible_crtcs = kencoder->possible_crtcs;
 
633
        output->possible_clones = kencoder->possible_clones;
 
634
        return;
 
635
}
 
636
 
 
637
void drmmode_set_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height, int pitch, struct nouveau_bo *bo)
 
638
{
 
639
        int ret;
 
640
 
 
641
        ErrorF("drmmode_set_fb is called\n");
 
642
 
 
643
        ret = drmModeAddFB(drmmode->fd, width, height, scrn->depth,
 
644
                           scrn->bitsPerPixel, pitch, bo->map_handle, &drmmode->fb_id);
 
645
 
 
646
        if (ret) {
 
647
                ErrorF("Failed to add fb\n");
 
648
        }
 
649
 
 
650
        drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
 
651
        if (!drmmode->mode_fb)
 
652
                return;
 
653
 
 
654
        ErrorF("Add fb id %d %d %d\n", drmmode->fb_id, width, height);
 
655
}
 
656
 
 
657
#if 0
 
658
static Bool drmmode_resize_fb(ScrnInfoPtr scrn, drmmode_ptr drmmode, int width, int height)
 
659
{
 
660
        uint32_t handle;
 
661
        int pitch;
 
662
        int ret;
 
663
 
 
664
        ErrorF("current width %d height %d\n", drmmode->mode_fb->width, drmmode->mode_fb->height);
 
665
 
 
666
        if (drmmode->mode_fb->width == width && drmmode->mode_fb->height == height)
 
667
                return TRUE;
 
668
 
 
669
        if (!drmmode->create_new_fb)
 
670
                return FALSE;
 
671
 
 
672
        handle = drmmode->create_new_fb(scrn, width, height, &pitch);
 
673
        if (handle == 0)
 
674
                return FALSE;
 
675
 
 
676
        ErrorF("pitch is %d\n", pitch);
 
677
        ret = drmModeReplaceFB(drmmode->fd, drmmode->fb_id, 
 
678
                               width, height,
 
679
                               scrn->depth, scrn->depth, pitch,
 
680
                               handle);
 
681
 
 
682
        if (ret)
 
683
                return FALSE;
 
684
 
 
685
        drmModeFreeFB(drmmode->mode_fb);
 
686
        drmmode->mode_fb = drmModeGetFB(drmmode->fd, drmmode->fb_id);
 
687
 
 
688
        if (!drmmode->mode_fb)
 
689
                return FALSE;
 
690
 
 
691
        return TRUE;
 
692
}
 
693
#endif
 
694
 
 
695
Bool drmmode_pre_init(ScrnInfoPtr pScrn, char *busId, drmmode_ptr drmmode, int cpp)
 
696
{
 
697
        xf86CrtcConfigPtr xf86_config = NULL;
 
698
        int i, ret;
 
699
 
 
700
        int drm_page_size;
 
701
        drm_page_size = getpagesize();
 
702
 
 
703
        /* Create a bus Id */
 
704
        /* Low level DRM open */
 
705
        ret = DRIOpenDRMMaster(pScrn, (drm_page_size > SAREA_MAX) ? drm_page_size : SAREA_MAX, busId, "nouveau");
 
706
        if (!ret) {
 
707
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
708
                        "[dri] DRIGetVersion failed to open the DRM\n");
 
709
                return FALSE;
 
710
        }
 
711
 
 
712
        drmmode->fd = DRIMasterFD(pScrn);
 
713
 
 
714
        xf86CrtcConfigInit(pScrn, &drmmode_xf86crtc_config_funcs);
 
715
        xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
 
716
 
 
717
        drmmode->cpp = cpp;
 
718
        drmmode->mode_res = drmModeGetResources(drmmode->fd);
 
719
        if (!drmmode->mode_res)
 
720
                return FALSE;
 
721
 
 
722
        xf86CrtcSetSizeRange(pScrn, 320, 200, drmmode->mode_res->max_width, drmmode->mode_res->max_height);
 
723
        for (i = 0; i < drmmode->mode_res->count_crtcs; i++)
 
724
                drmmode_crtc_init(pScrn, drmmode, i);
 
725
 
 
726
        for (i = 0; i < drmmode->mode_res->count_connectors; i++)
 
727
                drmmode_output_init(pScrn, drmmode, i);
 
728
 
 
729
        if (!xf86InitialConfiguration(pScrn, FALSE))
 
730
                return FALSE;
 
731
 
 
732
        return TRUE;
 
733
}
 
734
 
 
735
#endif /* XF86DRM_MODE */