diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_fb.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 9e8f191eb64a..ec383edf5f38 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,11 +566,16 @@ 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; |
545 | } | 575 | } |
546 | 576 | ||
577 | memset_io(fbptr, 0, aligned_size); | ||
578 | |||
547 | strcpy(info->fix.id, "radeondrmfb"); | 579 | strcpy(info->fix.id, "radeondrmfb"); |
548 | info->fix.type = FB_TYPE_PACKED_PIXELS; | 580 | info->fix.type = FB_TYPE_PACKED_PIXELS; |
549 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 581 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
@@ -572,6 +604,11 @@ int radeonfb_create(struct radeon_device *rdev, | |||
572 | info->var.width = -1; | 604 | info->var.width = -1; |
573 | info->var.xres = fb_width; | 605 | info->var.xres = fb_width; |
574 | info->var.yres = fb_height; | 606 | info->var.yres = fb_height; |
607 | |||
608 | /* setup aperture base/size for vesafb takeover */ | ||
609 | info->aperture_base = rdev->ddev->mode_config.fb_base; | ||
610 | info->aperture_size = rdev->mc.real_vram_size; | ||
611 | |||
575 | info->fix.mmio_start = 0; | 612 | info->fix.mmio_start = 0; |
576 | info->fix.mmio_len = 0; | 613 | info->fix.mmio_len = 0; |
577 | info->pixmap.size = 64*1024; | 614 | info->pixmap.size = 64*1024; |
@@ -600,6 +637,7 @@ int radeonfb_create(struct radeon_device *rdev, | |||
600 | info->var.transp.offset = 0; | 637 | info->var.transp.offset = 0; |
601 | info->var.transp.length = 0; | 638 | info->var.transp.length = 0; |
602 | break; | 639 | break; |
640 | #ifdef __LITTLE_ENDIAN | ||
603 | case 15: | 641 | case 15: |
604 | info->var.red.offset = 10; | 642 | info->var.red.offset = 10; |
605 | info->var.green.offset = 5; | 643 | info->var.green.offset = 5; |
@@ -639,7 +677,29 @@ int radeonfb_create(struct radeon_device *rdev, | |||
639 | info->var.transp.offset = 24; | 677 | info->var.transp.offset = 24; |
640 | info->var.transp.length = 8; | 678 | info->var.transp.length = 8; |
641 | break; | 679 | break; |
680 | #else | ||
681 | case 24: | ||
682 | info->var.red.offset = 8; | ||
683 | info->var.green.offset = 16; | ||
684 | info->var.blue.offset = 24; | ||
685 | info->var.red.length = 8; | ||
686 | info->var.green.length = 8; | ||
687 | info->var.blue.length = 8; | ||
688 | info->var.transp.offset = 0; | ||
689 | info->var.transp.length = 0; | ||
690 | break; | ||
691 | case 32: | ||
692 | info->var.red.offset = 8; | ||
693 | info->var.green.offset = 16; | ||
694 | info->var.blue.offset = 24; | ||
695 | info->var.red.length = 8; | ||
696 | info->var.green.length = 8; | ||
697 | info->var.blue.length = 8; | ||
698 | info->var.transp.offset = 0; | ||
699 | info->var.transp.length = 8; | ||
700 | break; | ||
642 | default: | 701 | default: |
702 | #endif | ||
643 | break; | 703 | break; |
644 | } | 704 | } |
645 | 705 | ||