Commit d4f452f8 authored by Linus Torvalds's avatar Linus Torvalds

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.
parents 0d43f512 77de0846
...@@ -626,6 +626,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, ...@@ -626,6 +626,12 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
return NULL; return NULL;
} }
/* it is incorrect if hsync/vsync width is zero */
if (!hsync_pulse_width || !vsync_pulse_width) {
DRM_DEBUG_KMS("Incorrect Detailed timing. "
"Wrong Hsync/Vsync pulse width\n");
return NULL;
}
mode = drm_mode_create(dev); mode = drm_mode_create(dev);
if (!mode) if (!mode)
return NULL; return NULL;
...@@ -647,6 +653,15 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev, ...@@ -647,6 +653,15 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
mode->vsync_end = mode->vsync_start + vsync_pulse_width; mode->vsync_end = mode->vsync_start + vsync_pulse_width;
mode->vtotal = mode->vdisplay + vblank; mode->vtotal = mode->vdisplay + vblank;
/* perform the basic check for the detailed timing */
if (mode->hsync_end > mode->htotal ||
mode->vsync_end > mode->vtotal) {
drm_mode_destroy(dev, mode);
DRM_DEBUG_KMS("Incorrect detailed timing. "
"Sync is beyond the blank.\n");
return NULL;
}
drm_mode_set_name(mode); drm_mode_set_name(mode);
if (pt->misc & DRM_EDID_PT_INTERLACED) if (pt->misc & DRM_EDID_PT_INTERLACED)
......
...@@ -454,22 +454,39 @@ out_free: ...@@ -454,22 +454,39 @@ out_free:
} }
EXPORT_SYMBOL(drm_fb_helper_init_crtc_count); EXPORT_SYMBOL(drm_fb_helper_init_crtc_count);
static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green, static int setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
u16 blue, u16 regno, struct fb_info *info) u16 blue, u16 regno, struct fb_info *info)
{ {
struct drm_fb_helper *fb_helper = info->par; struct drm_fb_helper *fb_helper = info->par;
struct drm_framebuffer *fb = fb_helper->fb; struct drm_framebuffer *fb = fb_helper->fb;
int pindex; int pindex;
if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
u32 *palette;
u32 value;
/* place color in psuedopalette */
if (regno > 16)
return -EINVAL;
palette = (u32 *)info->pseudo_palette;
red >>= (16 - info->var.red.length);
green >>= (16 - info->var.green.length);
blue >>= (16 - info->var.blue.length);
value = (red << info->var.red.offset) |
(green << info->var.green.offset) |
(blue << info->var.blue.offset);
palette[regno] = value;
return 0;
}
pindex = regno; pindex = regno;
if (fb->bits_per_pixel == 16) { if (fb->bits_per_pixel == 16) {
pindex = regno << 3; pindex = regno << 3;
if (fb->depth == 16 && regno > 63) if (fb->depth == 16 && regno > 63)
return; return -EINVAL;
if (fb->depth == 15 && regno > 31) if (fb->depth == 15 && regno > 31)
return; return -EINVAL;
if (fb->depth == 16) { if (fb->depth == 16) {
u16 r, g, b; u16 r, g, b;
...@@ -493,13 +510,7 @@ static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green, ...@@ -493,13 +510,7 @@ static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
if (fb->depth != 16) if (fb->depth != 16)
fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex); fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
return 0;
if (regno < 16 && info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
((u32 *) fb->pseudo_palette)[regno] =
(regno << info->var.red.offset) |
(regno << info->var.green.offset) |
(regno << info->var.blue.offset);
}
} }
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) 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,7 +547,9 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
if (transp) if (transp)
htransp = *transp++; htransp = *transp++;
setcolreg(crtc, hred, hgreen, hblue, start++, info); rc = setcolreg(crtc, hred, hgreen, hblue, start++, info);
if (rc)
return rc;
} }
crtc_funcs->load_lut(crtc); crtc_funcs->load_lut(crtc);
} }
...@@ -555,6 +568,7 @@ int drm_fb_helper_setcolreg(unsigned regno, ...@@ -555,6 +568,7 @@ int drm_fb_helper_setcolreg(unsigned regno,
struct drm_device *dev = fb_helper->dev; struct drm_device *dev = fb_helper->dev;
struct drm_crtc *crtc; struct drm_crtc *crtc;
int i; int i;
int ret;
if (regno > 255) if (regno > 255)
return 1; return 1;
...@@ -568,8 +582,10 @@ int drm_fb_helper_setcolreg(unsigned regno, ...@@ -568,8 +582,10 @@ int drm_fb_helper_setcolreg(unsigned regno,
if (i == fb_helper->crtc_count) if (i == fb_helper->crtc_count)
continue; continue;
ret = setcolreg(crtc, red, green, blue, regno, info);
if (ret)
return ret;
setcolreg(crtc, red, green, blue, regno, info);
crtc_funcs->load_lut(crtc); crtc_funcs->load_lut(crtc);
} }
return 0; return 0;
...@@ -928,7 +944,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch, ...@@ -928,7 +944,7 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,
{ {
info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.type = FB_TYPE_PACKED_PIXELS;
info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR : info->fix.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
FB_VISUAL_DIRECTCOLOR; FB_VISUAL_TRUECOLOR;
info->fix.type_aux = 0; info->fix.type_aux = 0;
info->fix.xpanstep = 1; /* doing it in hw */ info->fix.xpanstep = 1; /* doing it in hw */
info->fix.ypanstep = 1; /* doing it in hw */ info->fix.ypanstep = 1; /* doing it in hw */
......
...@@ -582,10 +582,9 @@ int radeon_device_init(struct radeon_device *rdev, ...@@ -582,10 +582,9 @@ int radeon_device_init(struct radeon_device *rdev,
DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
/* if we have > 1 VGA cards, then disable the radeon VGA resources */ /* if we have > 1 VGA cards, then disable the radeon VGA resources */
r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode); /* this will fail for cards that aren't VGA class devices, just
if (r) { * ignore it */
return -EINVAL; vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
}
r = radeon_init(rdev); r = radeon_init(rdev);
if (r) if (r)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment