diff options
author | Dave Airlie <airlied@redhat.com> | 2009-10-23 04:49:03 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-10-25 23:27:52 -0400 |
commit | c850cb782626fda78e5e9e5baf18a5bd806a225c (patch) | |
tree | e64e5cee964f54a2186de68c15c40ce84f743ce4 | |
parent | d0c403e950d449c8c413a1fbf05dfec45ce03e55 (diff) |
drm/kms: fix kms/fbdev colormap support properly.
This sets the fbcon to use TRUECOLOR by default, it then
only modifies the pseudo palette for fbcon, and only touches
the real palette when in 8-bit pseudo color mode.
Signed-off-by: Dave Airlie <airlied@redhat.com>
-rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 42 |
1 files changed, 29 insertions, 13 deletions
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index 23dc9c115fd9..9c924614c418 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -454,22 +454,39 @@ 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 | static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green, | 457 | static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green, |
458 | u16 blue, u16 regno, struct fb_info *info) | 458 | u16 blue, u16 regno, struct fb_info *info) |
459 | { | 459 | { |
460 | struct drm_fb_helper *fb_helper = info->par; | 460 | struct drm_fb_helper *fb_helper = info->par; |
461 | struct drm_framebuffer *fb = fb_helper->fb; | 461 | struct drm_framebuffer *fb = fb_helper->fb; |
462 | int pindex; | 462 | int pindex; |
463 | 463 | ||
464 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { | ||
465 | u32 *palette; | ||
466 | u32 value; | ||
467 | /* place color in psuedopalette */ | ||
468 | if (regno > 16) | ||
469 | return -EINVAL; | ||
470 | palette = (u32 *)info->pseudo_palette; | ||
471 | red >>= (16 - info->var.red.length); | ||
472 | green >>= (16 - info->var.green.length); | ||
473 | blue >>= (16 - info->var.blue.length); | ||
474 | value = (red << info->var.red.offset) | | ||
475 | (green << info->var.green.offset) | | ||
476 | (blue << info->var.blue.offset); | ||
477 | palette[regno] = value; | ||
478 | return 0; | ||
479 | } | ||
480 | |||
464 | pindex = regno; | 481 | pindex = regno; |
465 | 482 | ||
466 | if (fb->bits_per_pixel == 16) { | 483 | if (fb->bits_per_pixel == 16) { |
467 | pindex = regno << 3; | 484 | pindex = regno << 3; |
468 | 485 | ||
469 | if (fb->depth == 16 && regno > 63) | 486 | if (fb->depth == 16 && regno > 63) |
470 | return; | 487 | return -EINVAL; |
471 | if (fb->depth == 15 && regno > 31) | 488 | if (fb->depth == 15 && regno > 31) |
472 | return; | 489 | return -EINVAL; |
473 | 490 | ||
474 | if (fb->depth == 16) { | 491 | if (fb->depth == 16) { |
475 | u16 r, g, b; | 492 | u16 r, g, b; |
@@ -493,13 +510,7 @@ static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green, | |||
493 | 510 | ||
494 | if (fb->depth != 16) | 511 | if (fb->depth != 16) |
495 | fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex); | 512 | fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex); |
496 | 513 | return 0; | |
497 | if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
498 | ((u32 *) fb->pseudo_palette)[regno] = | ||
499 | (regno << info->var.red.offset) | | ||
500 | (regno << info->var.green.offset) | | ||
501 | (regno << info->var.blue.offset); | ||
502 | } | ||
503 | } | 514 | } |
504 | 515 | ||
505 | int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) | 516 | int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) |
@@ -536,7 +547,9 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) | |||
536 | if (transp) | 547 | if (transp) |
537 | htransp = *transp++; | 548 | htransp = *transp++; |
538 | 549 | ||
539 | setcolreg(crtc, hred, hgreen, hblue, start++, info); | 550 | rc = setcolreg(crtc, hred, hgreen, hblue, start++, info); |
551 | if (rc) | ||
552 | return rc; | ||
540 | } | 553 | } |
541 | crtc_funcs->load_lut(crtc); | 554 | crtc_funcs->load_lut(crtc); |
542 | } | 555 | } |
@@ -555,6 +568,7 @@ int drm_fb_helper_setcolreg(unsigned regno, | |||
555 | struct drm_device *dev = fb_helper->dev; | 568 | struct drm_device *dev = fb_helper->dev; |
556 | struct drm_crtc *crtc; | 569 | struct drm_crtc *crtc; |
557 | int i; | 570 | int i; |
571 | int ret; | ||
558 | 572 | ||
559 | if (regno > 255) | 573 | if (regno > 255) |
560 | return 1; | 574 | return 1; |
@@ -568,8 +582,10 @@ int drm_fb_helper_setcolreg(unsigned regno, | |||
568 | if (i == fb_helper->crtc_count) | 582 | if (i == fb_helper->crtc_count) |
569 | continue; | 583 | continue; |
570 | 584 | ||
585 | ret = setcolreg(crtc, red, green, blue, regno, info); | ||
586 | if (ret) | ||
587 | return ret; | ||
571 | 588 | ||
572 | setcolreg(crtc, red, green, blue, regno, info); | ||
573 | crtc_funcs->load_lut(crtc); | 589 | crtc_funcs->load_lut(crtc); |
574 | } | 590 | } |
575 | return 0; | 591 | return 0; |
@@ -928,7 +944,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, | |||
928 | { | 944 | { |
929 | info->fix.type = FB_TYPE_PACKED_PIXELS; | 945 | info->fix.type = FB_TYPE_PACKED_PIXELS; |
930 | info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR : | 946 | info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR : |
931 | FB_VISUAL_DIRECTCOLOR; | 947 | FB_VISUAL_TRUECOLOR; |
932 | info->fix.type_aux = 0; | 948 | info->fix.type_aux = 0; |
933 | info->fix.xpanstep = 1; /* doing it in hw */ | 949 | info->fix.xpanstep = 1; /* doing it in hw */ |
934 | info->fix.ypanstep = 1; /* doing it in hw */ | 950 | info->fix.ypanstep = 1; /* doing it in hw */ |