Subversion Repositories Kolibri OS

Rev

Rev 2004 | Rev 3120 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1246 serge 1
 
2
#include 
3
#include 
4
#include "radeon_drm.h"
5
#include "radeon.h"
6
#include "radeon_object.h"
7
#include "display.h"
8
#include "drm_fb_helper.h"
1986 serge 9
1246 serge 10
 
1986 serge 11
    struct drm_fb_helper        helper;
12
    struct radeon_framebuffer   rfb;
13
    struct list_head fbdev_list;
14
    struct radeon_device        *rdev;
15
};
16
1246 serge 17
 
1986 serge 18
19
 
20
 
1246 serge 21
static void       __stdcall move_cursor_kms(cursor_t *cursor, int x, int y);
22
23
 
24
25
 
1313 serge 26
27
 
1246 serge 28
{
29
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
30
    struct radeon_device *rdev = crtc->dev->dev_private;
31
32
 
2004 serge 33
        WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset);
34
        WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN |
35
               EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT));
36
    } else if (ASIC_IS_AVIVO(rdev)) {
37
        WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset);
1246 serge 38
        WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN |
39
                 (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT));
40
    } else {
41
        switch (radeon_crtc->crtc_id) {
42
        case 0:
43
            WREG32(RADEON_MM_INDEX, RADEON_CRTC_GEN_CNTL);
44
            break;
45
        case 1:
46
            WREG32(RADEON_MM_INDEX, RADEON_CRTC2_GEN_CNTL);
47
            break;
48
        default:
49
            return;
50
        }
51
52
 
53
                      (RADEON_CRTC_CUR_MODE_24BPP << RADEON_CRTC_CUR_MODE_SHIFT)),
54
             ~(RADEON_CRTC_CUR_EN | RADEON_CRTC_CUR_MODE_MASK));
55
    }
56
}
57
58
 
59
{
60
    struct radeon_device *rdev = crtc->dev->dev_private;
61
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
62
    uint32_t cur_lock;
63
64
 
2004 serge 65
        cur_lock = RREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset);
66
        if (lock)
67
            cur_lock |= EVERGREEN_CURSOR_UPDATE_LOCK;
68
        else
69
            cur_lock &= ~EVERGREEN_CURSOR_UPDATE_LOCK;
70
        WREG32(EVERGREEN_CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
71
    } else if (ASIC_IS_AVIVO(rdev)) {
72
        cur_lock = RREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset);
1246 serge 73
        if (lock)
74
            cur_lock |= AVIVO_D1CURSOR_UPDATE_LOCK;
75
        else
76
            cur_lock &= ~AVIVO_D1CURSOR_UPDATE_LOCK;
77
        WREG32(AVIVO_D1CUR_UPDATE + radeon_crtc->crtc_offset, cur_lock);
78
    } else {
79
        cur_lock = RREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset);
80
        if (lock)
81
            cur_lock |= RADEON_CUR_LOCK;
82
        else
83
            cur_lock &= ~RADEON_CUR_LOCK;
84
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, cur_lock);
85
    }
86
}
87
88
 
89
{
90
    struct radeon_device *rdev;
91
    struct radeon_crtc   *radeon_crtc;
92
    cursor_t *old;
93
    uint32_t  gpu_addr;
94
95
 
96
    radeon_crtc = to_radeon_crtc(rdisplay->crtc);
97
98
 
99
100
 
101
    gpu_addr = radeon_bo_gpu_offset(cursor->robj);
1404 serge 102
1246 serge 103
 
2004 serge 104
        WREG32(EVERGREEN_CUR_SURFACE_ADDRESS_HIGH + radeon_crtc->crtc_offset,
105
               0);
106
        WREG32(EVERGREEN_CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset,
107
               gpu_addr);
108
    } else if (ASIC_IS_AVIVO(rdev)) {
109
        if (rdev->family >= CHIP_RV770)
110
            WREG32(R700_D1CUR_SURFACE_ADDRESS_HIGH, 0);
111
        WREG32(AVIVO_D1CUR_SURFACE_ADDRESS + radeon_crtc->crtc_offset, gpu_addr);
1246 serge 112
    }
2004 serge 113
    else {
1246 serge 114
        radeon_crtc->legacy_cursor_offset = gpu_addr - rdev->mc.vram_start;
1430 serge 115
        /* offset is from DISP(2)_BASE_ADDRESS */
1246 serge 116
        WREG32(RADEON_CUR_OFFSET + radeon_crtc->crtc_offset, radeon_crtc->legacy_cursor_offset);
117
    }
118
119
 
120
};
121
122
 
123
{
124
    struct radeon_device *rdev;
125
    rdev = (struct radeon_device *)rdisplay->ddev->dev_private;
126
    struct drm_crtc *crtc = rdisplay->crtc;
127
    struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
128
129
 
130
    int hot_y = cursor->hot_y;
131
    int w = 32;
2004 serge 132
1246 serge 133
 
134
135
 
2004 serge 136
        WREG32(EVERGREEN_CUR_POSITION + radeon_crtc->crtc_offset,
137
               (x << 16) | y);
138
        WREG32(EVERGREEN_CUR_HOT_SPOT + radeon_crtc->crtc_offset,
139
               (hot_x << 16) | hot_y);
140
        WREG32(EVERGREEN_CUR_SIZE + radeon_crtc->crtc_offset,
141
               ((w - 1) << 16) | 31);
142
    } else if (ASIC_IS_AVIVO(rdev)) {
143
        WREG32(AVIVO_D1CUR_POSITION + radeon_crtc->crtc_offset,
1246 serge 144
               (x << 16) | y);
145
        WREG32(AVIVO_D1CUR_HOT_SPOT + radeon_crtc->crtc_offset,
146
               (hot_x << 16) | hot_y);
147
        WREG32(AVIVO_D1CUR_SIZE + radeon_crtc->crtc_offset,
148
               ((w - 1) << 16) | 31);
149
    } else {
150
        if (crtc->mode.flags & DRM_MODE_FLAG_DBLSCAN)
151
            y *= 2;
152
153
 
1404 serge 154
        int       xorg =0, yorg=0;
155
156
 
157
        y = y - hot_y;
158
159
 
160
        {
161
            xorg = -x + 1;
162
            x = 0;
163
        }
164
165
 
166
        {
167
            yorg = -hot_y + 1;
168
            y = 0;
169
        };
170
171
 
172
               (RADEON_CUR_LOCK | (xorg << 16) | yorg ));
173
        WREG32(RADEON_CUR_HORZ_VERT_POSN,
174
               (RADEON_CUR_LOCK | (x << 16) | y));
1246 serge 175
176
 
1404 serge 177
178
 
1246 serge 179
        WREG32(RADEON_CUR_OFFSET,
1404 serge 180
         (gpu_addr - rdev->mc.vram_start + (yorg * 256)));
1430 serge 181
    }
1246 serge 182
    radeon_lock_cursor_kms(crtc, false);
183
}
184
185
 
186
{
187
    static char name[4];
188
189
 
190
    name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@';
191
    name[2] = (x[1] & 0x1F) + '@';
192
    name[3] = 0;
193
194
 
195
}
196
197
 
198
              videomode_t *reqmode, bool strict)
1403 serge 199
{
1246 serge 200
    struct drm_display_mode  *mode = NULL, *tmpmode;
201
202
 
1986 serge 203
204
 
205
206
 
207
 
1246 serge 208
209
 
210
211
 
212
               reqmode->width, reqmode->height, reqmode->freq);
213
214
 
215
    {
216
        if( (drm_mode_width(tmpmode)    == reqmode->width)  &&
217
            (drm_mode_height(tmpmode)   == reqmode->height) &&
218
            (drm_mode_vrefresh(tmpmode) == reqmode->freq) )
219
        {
220
            mode = tmpmode;
221
            goto do_set;
222
        }
223
    };
224
225
 
226
    {
227
        list_for_each_entry(tmpmode, &connector->modes, head)
228
        {
229
            if( (drm_mode_width(tmpmode)  == reqmode->width)  &&
230
                (drm_mode_height(tmpmode) == reqmode->height) )
231
            {
232
                mode = tmpmode;
233
                goto do_set;
234
            }
235
        };
236
    };
237
238
 
239
240
 
241
    {
242
        struct drm_framebuffer   *fb;
243
        struct drm_encoder       *encoder;
244
        struct drm_crtc          *crtc;
245
246
 
247
        char *con_name;
248
        char *enc_name;
249
250
 
251
        crtc = encoder->crtc;
252
253
 
1963 serge 254
//                              struct drm_framebuffer, filp_head);
255
1246 serge 256
 
257
258
 
259
//        manufacturer_name(con_edid + 0x08),
260
//        (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)),
261
//        (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8)
262
//            + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24)));
263
264
 
265
        enc_name = drm_get_encoder_name(encoder);
266
267
 
268
                   reqmode->width, reqmode->height, con_name, enc_name);
269
270
 
1986 serge 271
272
 
1246 serge 273
        fb->height = reqmode->height;
274
2997 Serge 275
 
276
                         fb->pitches[3] = radeon_align_pitch(dev->dev_private, reqmode->width, 32, false) * ((32 + 1) / 8);
277
        fb->bits_per_pixel = 32;
1986 serge 278
        fb->depth = 24;
2997 Serge 279
1246 serge 280
 
281
        crtc->enabled = true;
282
        rdisplay->crtc = crtc;
283
284
 
285
286
 
287
        radeon_show_cursor_kms(crtc);
288
289
 
290
        {
291
            rdisplay->width    = fb->width;
292
            rdisplay->height   = fb->height;
293
            rdisplay->pitch    = fb->pitches[0];
2997 Serge 294
            rdisplay->vrefresh = drm_mode_vrefresh(mode);
1246 serge 295
296
 
2997 Serge 297
1246 serge 298
 
299
                       fb->width, fb->height, fb->pitches[0]);
2997 Serge 300
        }
1246 serge 301
        else
302
            DRM_ERROR("failed to set mode %d_%d on crtc %p\n",
303
                       fb->width, fb->height, crtc);
304
    }
305
306
 
307
    return ret;
308
};
309
310
 
311
{
312
    struct drm_display_mode  *mode;
313
    int count = 0;
314
315
 
316
    {
317
        count++;
318
    };
319
    return count;
320
};
321
322
 
323
{
324
    struct drm_connector  *connector;
325
    struct drm_connector_helper_funcs *connector_funcs;
1963 serge 326
327
 
1246 serge 328
329
 
330
    {
331
        struct drm_encoder  *encoder;
332
        struct drm_crtc     *crtc;
333
334
 
335
            continue;
336
337
 
1963 serge 338
        encoder = connector_funcs->best_encoder(connector);
339
        if( encoder == NULL)
1246 serge 340
            continue;
341
342
 
1963 serge 343
344
 
1246 serge 345
1963 serge 346
 
1986 serge 347
                   connector, connector->base.id,
348
                   connector->status, connector->encoder,
349
                   crtc);
350
1246 serge 351
 
1986 serge 352
//            continue;
353
354
 
1246 serge 355
1986 serge 356
 
1246 serge 357
    };
358
359
 
360
};
361
362
 
1986 serge 363
 
364
 
1403 serge 365
{
1246 serge 366
    struct drm_device   *dev;
367
368
 
2997 Serge 369
    struct drm_connector_helper_funcs *connector_funcs;
370
    struct drm_encoder      *encoder;
371
    struct drm_crtc         *crtc = NULL;
372
    struct drm_framebuffer  *fb;
373
    struct drm_display_mode *native;
374
375
 
376
 
1246 serge 377
    bool                 retval = false;
378
    u32_t                ifl;
379
380
 
1986 serge 381
    struct drm_fb_helper *fb_helper;
382
383
 
384
385
 
1246 serge 386
387
 
2997 Serge 388
1246 serge 389
 
2997 Serge 390
    {
391
        if( connector->status != connector_status_connected)
392
            continue;
393
1246 serge 394
 
2997 Serge 395
        encoder = connector_funcs->best_encoder(connector);
396
        if( encoder == NULL)
397
        {
398
            dbgprintf("CONNECTOR %x ID: %d no active encoders\n",
399
                      connector, connector->base.id);
400
            continue;
401
        }
402
        connector->encoder = encoder;
403
404
 
405
               connector, connector->base.id,
406
               connector->status, connector->encoder,
407
               encoder->crtc);
408
409
 
410
        break;
411
    };
412
413
 
414
    {
1246 serge 415
        dbgprintf("No active connectors!\n");
2997 Serge 416
        return -1;
417
    };
418
419
 
420
        struct drm_display_mode *tmp;
421
422
 
423
            if (drm_mode_width(tmp) > 16384 ||
424
                drm_mode_height(tmp) > 16384)
425
                continue;
426
            if (tmp->type & DRM_MODE_TYPE_PREFERRED)
427
            {
428
                native = tmp;
429
                break;
430
            };
431
        }
432
    }
433
434
 
435
    {
436
        dbgprintf("native w %d h %d\n", native->hdisplay, native->vdisplay);
437
        struct radeon_encoder *radeon_encoder = to_radeon_encoder(connector->encoder);
438
        radeon_encoder->rmx_type = RMX_FULL;
439
        radeon_encoder->native_mode = *native;
440
    };
441
442
 
443
 
444
    {
445
        struct drm_crtc *tmp_crtc;
446
        int crtc_mask = 1;
447
448
 
449
        {
1246 serge 450
            if (encoder->possible_crtcs & crtc_mask)
2997 Serge 451
            {
452
                crtc = tmp_crtc;
453
                encoder->crtc = crtc;
454
                break;
455
            };
456
            crtc_mask <<= 1;
457
        };
1246 serge 458
    };
459
460
 
2997 Serge 461
    {
462
        dbgprintf("No CRTC for encoder %d\n", encoder->base.id);
463
        return -1;
464
    };
465
1986 serge 466
 
467
 
2997 Serge 468
1986 serge 469
 
470
 
2997 Serge 471
1986 serge 472
 
2997 Serge 473
    rdisplay->ddev = dev;
474
    rdisplay->connector = connector;
475
    rdisplay->crtc = crtc;
476
1986 serge 477
 
2997 Serge 478
1986 serge 479
 
480
 
481
 
2997 Serge 482
    {
483
        list_for_each_entry(cursor, &rdisplay->cursors, list)
484
        {
485
            init_cursor(cursor);
486
        };
487
1986 serge 488
 
1246 serge 489
    safe_sti(ifl);
2997 Serge 490
1246 serge 491
 
1986 serge 492
 
1268 serge 493
              rdisplay->width, rdisplay->height, rdisplay->vrefresh);
494
    dbgprintf("user mode mode %d x %d x %d\n",
495
              usermode->width, usermode->height, usermode->freq);
496
497
 
2997 Serge 498
 
1246 serge 499
        (usermode->height != 0) &&
500
        ( (usermode->width  != rdisplay->width)  ||
501
          (usermode->height != rdisplay->height) ||
502
          (usermode->freq   != rdisplay->vrefresh) ) )
503
    {
504
505
 
506
    }
507
    else
2997 Serge 508
    {
509
        usermode->width  = rdisplay->width;
510
        usermode->height = rdisplay->height;
511
        usermode->freq   = 60;
512
        retval = set_mode(dev, rdisplay->connector, usermode, false);
513
    };
514
1246 serge 515
 
516
    {
517
        rdisplay->restore_cursor(0,0);
518
        rdisplay->init_cursor    = init_cursor;
519
        rdisplay->select_cursor  = select_cursor_kms;
520
        rdisplay->show_cursor    = NULL;
521
        rdisplay->move_cursor    = move_cursor_kms;
522
        rdisplay->restore_cursor = restore_cursor;
523
        rdisplay->disable_mouse  = disable_mouse;
1313 serge 524
1268 serge 525
 
526
        radeon_show_cursor_kms(rdisplay->crtc);
1246 serge 527
    };
528
    safe_sti(ifl);
529
530
 
531
532
 
533
};
534
535
 
1403 serge 536
{
1246 serge 537
    int err = -1;
538
539
 
2997 Serge 540
1246 serge 541
 
542
543
 
544
    {
545
        *count = rdisplay->supported_modes;
546
        err = 0;
547
    }
548
    else if( mode != NULL )
549
    {
550
        struct drm_display_mode  *drmmode;
551
        int i = 0;
552
553
 
554
            *count = rdisplay->supported_modes;
555
556
 
557
        {
558
            if( i < *count)
559
            {
560
                mode->width  = drm_mode_width(drmmode);
561
                mode->height = drm_mode_height(drmmode);
562
                mode->bpp    = 32;
563
                mode->freq   = drm_mode_vrefresh(drmmode);
564
                i++;
565
                mode++;
566
            }
567
            else break;
568
        };
569
        *count = i;
570
        err = 0;
571
    };
572
//    LEAVE();
2997 Serge 573
    return err;
1246 serge 574
}
575
576
 
1403 serge 577
{
1246 serge 578
    int err = -1;
579
580
 
2997 Serge 581
1246 serge 582
 
583
               mode->width, mode->height, mode->freq);
584
585
 
586
        (mode->height != 0)  &&
587
        (mode->freq   != 0 ) &&
588
        ( (mode->width   != rdisplay->width)  ||
589
          (mode->height  != rdisplay->height) ||
590
          (mode->freq    != rdisplay->vrefresh) ) )
591
    {
592
        if( set_mode(rdisplay->ddev, rdisplay->connector, mode, true) )
593
            err = 0;
594
    };
595
596
 
2997 Serge 597
    return err;
1246 serge 598
};
599
600
 
1986 serge 601
 
2997 Serge 602
                     struct drm_mode_fb_cmd2 *mode_cmd,
603
                     struct drm_gem_object **gobj_p)
1986 serge 604
{
1404 serge 605
    struct radeon_device *rdev = rfbdev->rdev;
1986 serge 606
    struct drm_gem_object *gobj = NULL;
607
    struct radeon_bo *rbo = NULL;
608
    bool fb_tiled = false; /* useful for testing */
609
    u32 tiling_flags = 0;
610
    int ret;
611
    int aligned_size, size;
612
    int height = mode_cmd->height;
613
    u32 bpp, depth;
2997 Serge 614
1404 serge 615
 
1986 serge 616
    static struct drm_mm_node  vm_node;
617
618
 
2997 Serge 619
 
620
621
 
1986 serge 622
    mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, bpp,
2997 Serge 623
                          fb_tiled) * ((bpp + 1) / 8);
624
1986 serge 625
 
626
        height = ALIGN(mode_cmd->height, 8);
627
    size = mode_cmd->pitches[0] * height;
2997 Serge 628
    aligned_size = ALIGN(size, PAGE_SIZE);
1986 serge 629
630
 
2997 Serge 631
 
1986 serge 632
    if (unlikely(ret)) {
633
        printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
2997 Serge 634
               aligned_size);
635
        return -ENOMEM;
636
    }
1404 serge 637
638
 
1986 serge 639
    kos_bo.gem_base.driver_private = NULL;
640
    kos_bo.surface_reg = -1;
641
    kos_bo.domain = RADEON_GEM_DOMAIN_VRAM;
642
643
 
644
645
 
646
    rbo = gem_to_radeon_bo(gobj);
647
648
 
649
        tiling_flags = RADEON_TILING_MACRO;
650
651
 
2997 Serge 652
//        ret = radeon_bo_set_tiling_flags(rbo,
653
//                         tiling_flags | RADEON_TILING_SURFACE,
654
//                         mode_cmd->pitches[0]);
655
//        if (ret)
656
//            dev_err(rdev->dev, "FB failed to set tiling flags\n");
657
//    }
658
1404 serge 659
 
1986 serge 660
    vm_node.start = 0;
661
    vm_node.mm = NULL;
662
663
 
664
    rbo->tbo.offset  = rbo->tbo.vm_node->start << PAGE_SHIFT;
665
    rbo->tbo.offset += (u64)rbo->rdev->mc.vram_start;
666
    rbo->kptr        = (void*)0xFE000000;
667
    rbo->pin_count   = 1;
668
669
 
670
 
671
    return 0;
672
}
1404 serge 673