aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2009-10-04 19:58:02 -0400
committerDave Airlie <airlied@redhat.com>2009-10-04 20:00:59 -0400
commit068143d38804825d59d951a192cfadd2e22f457d (patch)
tree87acefe03fe5a97577e90f89c79909aad5ba2a5e
parentdfee5614e4d83a32cef9193a8b19bc1d8900f93d (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.c55
-rw-r--r--drivers/gpu/drm/i915/intel_display.c1
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c3
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c1
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c3
-rw-r--r--drivers/gpu/drm/radeon/radeon_legacy_crtc.c1
-rw-r--r--include/drm/drm_crtc_helper.h3
-rw-r--r--include/drm/drm_fb_helper.h4
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}
455EXPORT_SYMBOL(drm_fb_helper_init_crtc_count); 455EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
456 456
457int 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}
497EXPORT_SYMBOL(drm_fb_helper_setcmap);
498
457int drm_fb_helper_setcolreg(unsigned regno, 499int 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}
852EXPORT_SYMBOL(drm_fb_helper_free); 895EXPORT_SYMBOL(drm_fb_helper_free);
853 896
854void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch) 897void 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
3518static const struct drm_crtc_funcs intel_crtc_funcs = { 3519static 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
65static struct drm_fb_helper_funcs intel_fb_helper_funcs = { 66static 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
738void radeon_atombios_init_crtc(struct drm_device *dev, 739void 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
66struct drm_encoder_helper_funcs { 69struct 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,
98void drm_fb_helper_restore(void); 98void drm_fb_helper_restore(void);
99void drm_fb_helper_fill_var(struct fb_info *info, struct drm_framebuffer *fb, 99void 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);
101void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch); 101void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
102 uint32_t depth);
102 103
103int drm_fb_helper_add_connector(struct drm_connector *connector); 104int drm_fb_helper_add_connector(struct drm_connector *connector);
104int drm_fb_helper_parse_command_line(struct drm_device *dev); 105int drm_fb_helper_parse_command_line(struct drm_device *dev);
106int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);
105 107
106#endif 108#endif