diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_fb.c')
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 70 |
1 files changed, 64 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 9e8f191eb64a..3206c0ad7b6c 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
| @@ -101,9 +101,10 @@ static int radeonfb_setcolreg(unsigned regno, | |||
| 101 | break; | 101 | break; |
| 102 | case 24: | 102 | case 24: |
| 103 | case 32: | 103 | case 32: |
| 104 | fb->pseudo_palette[regno] = ((red & 0xff00) << 8) | | 104 | fb->pseudo_palette[regno] = |
| 105 | (green & 0xff00) | | 105 | (((red >> 8) & 0xff) << info->var.red.offset) | |
| 106 | ((blue & 0xff00) >> 8); | 106 | (((green >> 8) & 0xff) << info->var.green.offset) | |
| 107 | (((blue >> 8) & 0xff) << info->var.blue.offset); | ||
| 107 | break; | 108 | break; |
| 108 | } | 109 | } |
| 109 | } | 110 | } |
| @@ -154,6 +155,7 @@ static int radeonfb_check_var(struct fb_var_screeninfo *var, | |||
| 154 | var->transp.length = 0; | 155 | var->transp.length = 0; |
| 155 | var->transp.offset = 0; | 156 | var->transp.offset = 0; |
| 156 | break; | 157 | break; |
| 158 | #ifdef __LITTLE_ENDIAN | ||
| 157 | case 15: | 159 | case 15: |
| 158 | var->red.offset = 10; | 160 | var->red.offset = 10; |
| 159 | var->green.offset = 5; | 161 | var->green.offset = 5; |
| @@ -194,6 +196,28 @@ static int radeonfb_check_var(struct fb_var_screeninfo *var, | |||
| 194 | var->transp.length = 8; | 196 | var->transp.length = 8; |
| 195 | var->transp.offset = 24; | 197 | var->transp.offset = 24; |
| 196 | break; | 198 | break; |
| 199 | #else | ||
| 200 | case 24: | ||
| 201 | var->red.offset = 8; | ||
| 202 | var->green.offset = 16; | ||
| 203 | var->blue.offset = 24; | ||
| 204 | var->red.length = 8; | ||
| 205 | var->green.length = 8; | ||
| 206 | var->blue.length = 8; | ||
| 207 | var->transp.length = 0; | ||
| 208 | var->transp.offset = 0; | ||
| 209 | break; | ||
| 210 | case 32: | ||
| 211 | var->red.offset = 8; | ||
| 212 | var->green.offset = 16; | ||
| 213 | var->blue.offset = 24; | ||
| 214 | var->red.length = 8; | ||
| 215 | var->green.length = 8; | ||
| 216 | var->blue.length = 8; | ||
| 217 | var->transp.length = 8; | ||
| 218 | var->transp.offset = 0; | ||
| 219 | break; | ||
| 220 | #endif | ||
| 197 | default: | 221 | default: |
| 198 | return -EINVAL; | 222 | return -EINVAL; |
| 199 | } | 223 | } |
| @@ -447,10 +471,10 @@ static struct notifier_block paniced = { | |||
| 447 | .notifier_call = radeonfb_panic, | 471 | .notifier_call = radeonfb_panic, |
| 448 | }; | 472 | }; |
| 449 | 473 | ||
| 450 | static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp) | 474 | static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) |
| 451 | { | 475 | { |
| 452 | int aligned = width; | 476 | int aligned = width; |
| 453 | int align_large = (ASIC_IS_AVIVO(rdev)); | 477 | int align_large = (ASIC_IS_AVIVO(rdev)) || tiled; |
| 454 | int pitch_mask = 0; | 478 | int pitch_mask = 0; |
| 455 | 479 | ||
| 456 | switch (bpp / 8) { | 480 | switch (bpp / 8) { |
| @@ -488,12 +512,13 @@ int radeonfb_create(struct radeon_device *rdev, | |||
| 488 | u64 fb_gpuaddr; | 512 | u64 fb_gpuaddr; |
| 489 | void *fbptr = NULL; | 513 | void *fbptr = NULL; |
| 490 | unsigned long tmp; | 514 | unsigned long tmp; |
| 515 | bool fb_tiled = false; /* useful for testing */ | ||
| 491 | 516 | ||
| 492 | mode_cmd.width = surface_width; | 517 | mode_cmd.width = surface_width; |
| 493 | mode_cmd.height = surface_height; | 518 | mode_cmd.height = surface_height; |
| 494 | mode_cmd.bpp = 32; | 519 | mode_cmd.bpp = 32; |
| 495 | /* need to align pitch with crtc limits */ | 520 | /* need to align pitch with crtc limits */ |
| 496 | mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp) * ((mode_cmd.bpp + 1) / 8); | 521 | mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8); |
| 497 | mode_cmd.depth = 24; | 522 | mode_cmd.depth = 24; |
| 498 | 523 | ||
| 499 | size = mode_cmd.pitch * mode_cmd.height; | 524 | size = mode_cmd.pitch * mode_cmd.height; |
| @@ -511,6 +536,8 @@ int radeonfb_create(struct radeon_device *rdev, | |||
| 511 | } | 536 | } |
| 512 | robj = gobj->driver_private; | 537 | robj = gobj->driver_private; |
| 513 | 538 | ||
| 539 | if (fb_tiled) | ||
| 540 | radeon_object_set_tiling_flags(robj, RADEON_TILING_MACRO|RADEON_TILING_SURFACE, mode_cmd.pitch); | ||
| 514 | mutex_lock(&rdev->ddev->struct_mutex); | 541 | mutex_lock(&rdev->ddev->struct_mutex); |
| 515 | fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); | 542 | fb = radeon_framebuffer_create(rdev->ddev, &mode_cmd, gobj); |
| 516 | if (fb == NULL) { | 543 | if (fb == NULL) { |
| @@ -539,6 +566,9 @@ int radeonfb_create(struct radeon_device *rdev, | |||
| 539 | } | 566 | } |
| 540 | rfbdev = info->par; | 567 | rfbdev = info->par; |
| 541 | 568 | ||
| 569 | if (fb_tiled) | ||
| 570 | radeon_object_check_tiling(robj, 0, 0); | ||
| 571 | |||
| 542 | ret = radeon_object_kmap(robj, &fbptr); | 572 | ret = radeon_object_kmap(robj, &fbptr); |
| 543 | if (ret) { | 573 | if (ret) { |
| 544 | goto out_unref; | 574 | goto out_unref; |
| @@ -572,6 +602,11 @@ int radeonfb_create(struct radeon_device *rdev, | |||
| 572 | info->var.width = -1; | 602 | info->var.width = -1; |
| 573 | info->var.xres = fb_width; | 603 | info->var.xres = fb_width; |
| 574 | info->var.yres = fb_height; | 604 | info->var.yres = fb_height; |
| 605 | |||
| 606 | /* setup aperture base/size for vesafb takeover */ | ||
| 607 | info->aperture_base = rdev->ddev->mode_config.fb_base; | ||
| 608 | info->aperture_size = rdev->mc.real_vram_size; | ||
| 609 | |||
| 575 | info->fix.mmio_start = 0; | 610 | info->fix.mmio_start = 0; |
| 576 | info->fix.mmio_len = 0; | 611 | info->fix.mmio_len = 0; |
| 577 | info->pixmap.size = 64*1024; | 612 | info->pixmap.size = 64*1024; |
| @@ -600,6 +635,7 @@ int radeonfb_create(struct radeon_device *rdev, | |||
| 600 | info->var.transp.offset = 0; | 635 | info->var.transp.offset = 0; |
| 601 | info->var.transp.length = 0; | 636 | info->var.transp.length = 0; |
| 602 | break; | 637 | break; |
| 638 | #ifdef __LITTLE_ENDIAN | ||
| 603 | case 15: | 639 | case 15: |
| 604 | info->var.red.offset = 10; | 640 | info->var.red.offset = 10; |
| 605 | info->var.green.offset = 5; | 641 | info->var.green.offset = 5; |
| @@ -639,7 +675,29 @@ int radeonfb_create(struct radeon_device *rdev, | |||
| 639 | info->var.transp.offset = 24; | 675 | info->var.transp.offset = 24; |
| 640 | info->var.transp.length = 8; | 676 | info->var.transp.length = 8; |
| 641 | break; | 677 | break; |
| 678 | #else | ||
| 679 | case 24: | ||
| 680 | info->var.red.offset = 8; | ||
| 681 | info->var.green.offset = 16; | ||
| 682 | info->var.blue.offset = 24; | ||
| 683 | info->var.red.length = 8; | ||
| 684 | info->var.green.length = 8; | ||
| 685 | info->var.blue.length = 8; | ||
| 686 | info->var.transp.offset = 0; | ||
| 687 | info->var.transp.length = 0; | ||
| 688 | break; | ||
| 689 | case 32: | ||
| 690 | info->var.red.offset = 8; | ||
| 691 | info->var.green.offset = 16; | ||
| 692 | info->var.blue.offset = 24; | ||
| 693 | info->var.red.length = 8; | ||
| 694 | info->var.green.length = 8; | ||
| 695 | info->var.blue.length = 8; | ||
| 696 | info->var.transp.offset = 0; | ||
| 697 | info->var.transp.length = 8; | ||
| 698 | break; | ||
| 642 | default: | 699 | default: |
| 700 | #endif | ||
| 643 | break; | 701 | break; |
| 644 | } | 702 | } |
| 645 | 703 | ||
