diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-29 12:15:02 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-10-29 12:15:02 -0400 |
| commit | d4f452f8259086028aa17d495deb735e056188f4 (patch) | |
| tree | be32c2528446cb0493bbcab583a4c12f95404e3c | |
| parent | 0d43f5123d1456669b3bbc69854faf6fd5b14caa (diff) | |
| parent | 77de0846aed9d7a1b0ea65090620900d66fb5cfb (diff) | |
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6
* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
drm/kms: fix kms/fbdev colormap support properly.
drm: Add the basic check for the detailed timing in EDID
drm/radeon/kms: ignore vga arbiter return.
| -rw-r--r-- | drivers/gpu/drm/drm_edid.c | 15 | ||||
| -rw-r--r-- | drivers/gpu/drm/drm_fb_helper.c | 42 | ||||
| -rw-r--r-- | drivers/gpu/drm/radeon/radeon_device.c | 7 |
3 files changed, 47 insertions, 17 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 3c0d2b3aed76..cea665d86dd3 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
| @@ -626,6 +626,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
| 626 | return NULL; | 626 | return NULL; |
| 627 | } | 627 | } |
| 628 | 628 | ||
| 629 | /* it is incorrect if hsync/vsync width is zero */ | ||
| 630 | if (!hsync_pulse_width || !vsync_pulse_width) { | ||
| 631 | DRM_DEBUG_KMS("Incorrect Detailed timing. " | ||
| 632 | "Wrong Hsync/Vsync pulse width\n"); | ||
| 633 | return NULL; | ||
| 634 | } | ||
| 629 | mode = drm_mode_create(dev); | 635 | mode = drm_mode_create(dev); |
| 630 | if (!mode) | 636 | if (!mode) |
| 631 | return NULL; | 637 | return NULL; |
| @@ -647,6 +653,15 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, | |||
| 647 | mode->vsync_end = mode->vsync_start + vsync_pulse_width; | 653 | mode->vsync_end = mode->vsync_start + vsync_pulse_width; |
| 648 | mode->vtotal = mode->vdisplay + vblank; | 654 | mode->vtotal = mode->vdisplay + vblank; |
| 649 | 655 | ||
| 656 | /* perform the basic check for the detailed timing */ | ||
| 657 | if (mode->hsync_end > mode->htotal || | ||
| 658 | mode->vsync_end > mode->vtotal) { | ||
| 659 | drm_mode_destroy(dev, mode); | ||
| 660 | DRM_DEBUG_KMS("Incorrect detailed timing. " | ||
| 661 | "Sync is beyond the blank.\n"); | ||
| 662 | return NULL; | ||
| 663 | } | ||
| 664 | |||
| 650 | drm_mode_set_name(mode); | 665 | drm_mode_set_name(mode); |
| 651 | 666 | ||
| 652 | if (pt->misc & DRM_EDID_PT_INTERLACED) | 667 | if (pt->misc & DRM_EDID_PT_INTERLACED) |
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 */ |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 3d667031de6e..df988142e6b0 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
| @@ -582,10 +582,9 @@ int radeon_device_init(struct radeon_device *rdev, | |||
| 582 | DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); | 582 | DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); |
| 583 | 583 | ||
| 584 | /* if we have > 1 VGA cards, then disable the radeon VGA resources */ | 584 | /* if we have > 1 VGA cards, then disable the radeon VGA resources */ |
| 585 | r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); | 585 | /* this will fail for cards that aren't VGA class devices, just |
| 586 | if (r) { | 586 | * ignore it */ |
| 587 | return -EINVAL; | 587 | vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); |
| 588 | } | ||
| 589 | 588 | ||
| 590 | r = radeon_init(rdev); | 589 | r = radeon_init(rdev); |
| 591 | if (r) | 590 | if (r) |
