diff options
| author | Dave Airlie <airlied@redhat.com> | 2009-10-04 19:58:02 -0400 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2009-10-04 20:00:59 -0400 |
| commit | 068143d38804825d59d951a192cfadd2e22f457d (patch) | |
| tree | 87acefe03fe5a97577e90f89c79909aad5ba2a5e | |
| parent | dfee5614e4d83a32cef9193a8b19bc1d8900f93d (diff) | |
drm/fb: add setcmap and fix 8-bit support.
This adds support for the setcmap api and fixes the 8bpp
support at least on radeon hardware. It adds a new load_lut
hook which can be called once the color map is setup.
Signed-off-by: Dave Airlie <airlied@redhat.com>
| -rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 55 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/atombios_crtc.c | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_fb.c | 3 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_legacy_crtc.c | 1 | ||||
| -rw-r--r-- | include/drm/drm_crtc_helper.h | 3 | ||||
| -rw-r--r-- | include/drm/drm_fb_helper.h | 4 |
8 files changed, 63 insertions, 8 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 819ddcbfcce5..3746bd2f0f08 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
| @@ -454,6 +454,48 @@ out_free: | |||
| 454 | } | 454 | } |
| 455 | EXPORT_SYMBOL(drm_fb_helper_init_crtc_count); | 455 | EXPORT_SYMBOL(drm_fb_helper_init_crtc_count); |
| 456 | 456 | ||
| 457 | int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) | ||
| 458 | { | ||
| 459 | struct drm_fb_helper *fb_helper = info->par; | ||
| 460 | struct drm_device *dev = fb_helper->dev; | ||
| 461 | u16 *red, *green, *blue, *transp; | ||
| 462 | struct drm_crtc *crtc; | ||
| 463 | int i, rc = 0; | ||
| 464 | int start; | ||
| 465 | |||
| 466 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | ||
| 467 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; | ||
| 468 | for (i = 0; i < fb_helper->crtc_count; i++) { | ||
| 469 | if (crtc->base.id == fb_helper->crtc_info[i].crtc_id) | ||
| 470 | break; | ||
| 471 | } | ||
| 472 | if (i == fb_helper->crtc_count) | ||
| 473 | continue; | ||
| 474 | |||
| 475 | red = cmap->red; | ||
| 476 | green = cmap->green; | ||
| 477 | blue = cmap->blue; | ||
| 478 | transp = cmap->transp; | ||
| 479 | start = cmap->start; | ||
| 480 | |||
| 481 | for (i = 0; i < cmap->len; i++) { | ||
| 482 | u16 hred, hgreen, hblue, htransp = 0xffff; | ||
| 483 | |||
| 484 | hred = *red++; | ||
| 485 | hgreen = *green++; | ||
| 486 | hblue = *blue++; | ||
| 487 | |||
| 488 | if (transp) | ||
| 489 | htransp = *transp++; | ||
| 490 | |||
| 491 | fb_helper->funcs->gamma_set(crtc, hred, hgreen, hblue, start++); | ||
| 492 | } | ||
| 493 | crtc_funcs->load_lut(crtc); | ||
| 494 | } | ||
| 495 | return rc; | ||
| 496 | } | ||
| 497 | EXPORT_SYMBOL(drm_fb_helper_setcmap); | ||
| 498 | |||
| 457 | int drm_fb_helper_setcolreg(unsigned regno, | 499 | int drm_fb_helper_setcolreg(unsigned regno, |
| 458 | unsigned red, | 500 | unsigned red, |
| 459 | unsigned green, | 501 | unsigned green, |
| @@ -485,20 +527,21 @@ int drm_fb_helper_setcolreg(unsigned regno, | |||
| 485 | } | 527 | } |
| 486 | 528 | ||
| 487 | if (regno < 16) { | 529 | if (regno < 16) { |
| 530 | u32 *pal = fb->pseudo_palette; | ||
| 488 | switch (fb->depth) { | 531 | switch (fb->depth) { |
| 489 | case 15: | 532 | case 15: |
| 490 | fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | | 533 | pal[regno] = ((red & 0xf800) >> 1) | |
| 491 | ((green & 0xf800) >> 6) | | 534 | ((green & 0xf800) >> 6) | |
| 492 | ((blue & 0xf800) >> 11); | 535 | ((blue & 0xf800) >> 11); |
| 493 | break; | 536 | break; |
| 494 | case 16: | 537 | case 16: |
| 495 | fb->pseudo_palette[regno] = (red & 0xf800) | | 538 | pal[regno] = (red & 0xf800) | |
| 496 | ((green & 0xfc00) >> 5) | | 539 | ((green & 0xfc00) >> 5) | |
| 497 | ((blue & 0xf800) >> 11); | 540 | ((blue & 0xf800) >> 11); |
| 498 | break; | 541 | break; |
| 499 | case 24: | 542 | case 24: |
| 500 | case 32: | 543 | case 32: |
| 501 | fb->pseudo_palette[regno] = | 544 | pal[regno] = |
| 502 | (((red >> 8) & 0xff) << info->var.red.offset) | | 545 | (((red >> 8) & 0xff) << info->var.red.offset) | |
| 503 | (((green >> 8) & 0xff) << info->var.green.offset) | | 546 | (((green >> 8) & 0xff) << info->var.green.offset) | |
| 504 | (((blue >> 8) & 0xff) << info->var.blue.offset); | 547 | (((blue >> 8) & 0xff) << info->var.blue.offset); |
| @@ -851,10 +894,12 @@ void drm_fb_helper_free(struct drm_fb_helper *helper) | |||
| 851 | } | 894 | } |
| 852 | EXPORT_SYMBOL(drm_fb_helper_free); | 895 | EXPORT_SYMBOL(drm_fb_helper_free); |
| 853 | 896 | ||
| 854 | void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch) | 897 | void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, |
| 898 | uint32_t depth) | ||
| 855 | { | 899 | { |
| 856 | info->fix.type = FB_TYPE_PACKED_PIXELS; | 900 | info->fix.type = FB_TYPE_PACKED_PIXELS; |
| 857 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 901 | info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR : |
| 902 | FB_VISUAL_TRUECOLOR; | ||
| 858 | info->fix.type_aux = 0; | 903 | info->fix.type_aux = 0; |
| 859 | info->fix.xpanstep = 1; /* doing it in hw */ | 904 | info->fix.xpanstep = 1; /* doing it in hw */ |
| 860 | info->fix.ypanstep = 1; /* doing it in hw */ | 905 | info->fix.ypanstep = 1; /* doing it in hw */ |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 155719ff99d1..a840cb1bd36a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
| @@ -3513,6 +3513,7 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = { | |||
| 3513 | .mode_set_base = intel_pipe_set_base, | 3513 | .mode_set_base = intel_pipe_set_base, |
| 3514 | .prepare = intel_crtc_prepare, | 3514 | .prepare = intel_crtc_prepare, |
| 3515 | .commit = intel_crtc_commit, | 3515 | .commit = intel_crtc_commit, |
| 3516 | .load_lut = intel_crtc_load_lut, | ||
| 3516 | }; | 3517 | }; |
| 3517 | 3518 | ||
| 3518 | static const struct drm_crtc_funcs intel_crtc_funcs = { | 3519 | static const struct drm_crtc_funcs intel_crtc_funcs = { |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index e85d7e9eed7d..3ee8db1fbcd0 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
| @@ -60,6 +60,7 @@ static struct fb_ops intelfb_ops = { | |||
| 60 | .fb_imageblit = cfb_imageblit, | 60 | .fb_imageblit = cfb_imageblit, |
| 61 | .fb_pan_display = drm_fb_helper_pan_display, | 61 | .fb_pan_display = drm_fb_helper_pan_display, |
| 62 | .fb_blank = drm_fb_helper_blank, | 62 | .fb_blank = drm_fb_helper_blank, |
| 63 | .fb_setcmap = drm_fb_helper_setcmap, | ||
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| 65 | static struct drm_fb_helper_funcs intel_fb_helper_funcs = { | 66 | static struct drm_fb_helper_funcs intel_fb_helper_funcs = { |
| @@ -206,7 +207,7 @@ static int intelfb_create(struct drm_device *dev, uint32_t fb_width, | |||
| 206 | 207 | ||
| 207 | // memset(info->screen_base, 0, size); | 208 | // memset(info->screen_base, 0, size); |
| 208 | 209 | ||
| 209 | drm_fb_helper_fill_fix(info, fb->pitch); | 210 | drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); |
| 210 | drm_fb_helper_fill_var(info, fb, fb_width, fb_height); | 211 | drm_fb_helper_fill_var(info, fb, fb_width, fb_height); |
| 211 | 212 | ||
| 212 | /* FIXME: we really shouldn't expose mmio space at all */ | 213 | /* FIXME: we really shouldn't expose mmio space at all */ |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 6a015929deee..14fa9701aeb3 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
| @@ -733,6 +733,7 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { | |||
| 733 | .mode_set_base = atombios_crtc_set_base, | 733 | .mode_set_base = atombios_crtc_set_base, |
| 734 | .prepare = atombios_crtc_prepare, | 734 | .prepare = atombios_crtc_prepare, |
| 735 | .commit = atombios_crtc_commit, | 735 | .commit = atombios_crtc_commit, |
| 736 | .load_lut = radeon_crtc_load_lut, | ||
| 736 | }; | 737 | }; |
| 737 | 738 | ||
| 738 | void radeon_atombios_init_crtc(struct drm_device *dev, | 739 | void radeon_atombios_init_crtc(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index 325e40b5e0b6..c32f44096fec 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
| @@ -55,6 +55,7 @@ static struct fb_ops radeonfb_ops = { | |||
| 55 | .fb_imageblit = cfb_imageblit, | 55 | .fb_imageblit = cfb_imageblit, |
| 56 | .fb_pan_display = drm_fb_helper_pan_display, | 56 | .fb_pan_display = drm_fb_helper_pan_display, |
| 57 | .fb_blank = drm_fb_helper_blank, | 57 | .fb_blank = drm_fb_helper_blank, |
| 58 | .fb_setcmap = drm_fb_helper_setcmap, | ||
| 58 | }; | 59 | }; |
| 59 | 60 | ||
| 60 | /** | 61 | /** |
| @@ -239,7 +240,7 @@ int radeonfb_create(struct drm_device *dev, | |||
| 239 | 240 | ||
| 240 | strcpy(info->fix.id, "radeondrmfb"); | 241 | strcpy(info->fix.id, "radeondrmfb"); |
| 241 | 242 | ||
| 242 | drm_fb_helper_fill_fix(info, fb->pitch); | 243 | drm_fb_helper_fill_fix(info, fb->pitch, fb->depth); |
| 243 | 244 | ||
| 244 | info->flags = FBINFO_DEFAULT; | 245 | info->flags = FBINFO_DEFAULT; |
| 245 | info->fbops = &radeonfb_ops; | 246 | info->fbops = &radeonfb_ops; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index 2b997a15fb1f..36410f85d705 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
| @@ -1053,6 +1053,7 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | |||
| 1053 | .mode_set_base = radeon_crtc_set_base, | 1053 | .mode_set_base = radeon_crtc_set_base, |
| 1054 | .prepare = radeon_crtc_prepare, | 1054 | .prepare = radeon_crtc_prepare, |
| 1055 | .commit = radeon_crtc_commit, | 1055 | .commit = radeon_crtc_commit, |
| 1056 | .load_lut = radeon_crtc_load_lut, | ||
| 1056 | }; | 1057 | }; |
| 1057 | 1058 | ||
| 1058 | 1059 | ||
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h index ef47dfd8e5e9..b29e20168b5f 100644 --- a/include/drm/drm_crtc_helper.h +++ b/include/drm/drm_crtc_helper.h | |||
| @@ -61,6 +61,9 @@ struct drm_crtc_helper_funcs { | |||
| 61 | /* Move the crtc on the current fb to the given position *optional* */ | 61 | /* Move the crtc on the current fb to the given position *optional* */ |
| 62 | int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, | 62 | int (*mode_set_base)(struct drm_crtc *crtc, int x, int y, |
| 63 | struct drm_framebuffer *old_fb); | 63 | struct drm_framebuffer *old_fb); |
| 64 | |||
| 65 | /* reload the current crtc LUT */ | ||
| 66 | void (*load_lut)(struct drm_crtc *crtc); | ||
| 64 | }; | 67 | }; |
| 65 | 68 | ||
| 66 | struct drm_encoder_helper_funcs { | 69 | struct drm_encoder_helper_funcs { |
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h index 4aa5740ce59f..f1ed08559fc7 100644 --- a/include/drm/drm_fb_helper.h +++ b/include/drm/drm_fb_helper.h | |||
| @@ -98,9 +98,11 @@ int drm_fb_helper_setcolreg(unsigned regno, | |||
| 98 | void drm_fb_helper_restore(void); | 98 | void drm_fb_helper_restore(void); |
| 99 | void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb, | 99 | void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb, |
| 100 | uint32_t fb_width, uint32_t fb_height); | 100 | uint32_t fb_width, uint32_t fb_height); |
| 101 | void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch); | 101 | void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, |
| 102 | uint32_t depth); | ||
| 102 | 103 | ||
| 103 | int drm_fb_helper_add_connector(struct drm_connector *connector); | 104 | int drm_fb_helper_add_connector(struct drm_connector *connector); |
| 104 | int drm_fb_helper_parse_command_line(struct drm_device *dev); | 105 | int drm_fb_helper_parse_command_line(struct drm_device *dev); |
| 106 | int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info); | ||
| 105 | 107 | ||
| 106 | #endif | 108 | #endif |
