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 |