summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/drm_edid.c15
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c42
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c7
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,
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);
if (!mode)
return NULL;
@@ -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->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);
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:
}
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)
{
struct drm_fb_helper *fb_helper = info->par;
struct drm_framebuffer *fb = fb_helper->fb;
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;
if (fb->bits_per_pixel == 16) {
pindex = regno << 3;
if (fb->depth == 16 && regno > 63)
- return;
+ return -EINVAL;
if (fb->depth == 15 && regno > 31)
- return;
+ return -EINVAL;
if (fb->depth == 16) {
u16 r, g, b;
@@ -493,13 +510,7 @@ static void setcolreg(struct drm_crtc *crtc, u16 red, u16 green,
if (fb->depth != 16)
fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
-
- 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);
- }
+ return 0;
}
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)
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);
}
@@ -555,6 +568,7 @@ int drm_fb_helper_setcolreg(unsigned regno,
struct drm_device *dev = fb_helper->dev;
struct drm_crtc *crtc;
int i;
+ int ret;
if (regno > 255)
return 1;
@@ -568,8 +582,10 @@ int drm_fb_helper_setcolreg(unsigned regno,
if (i == fb_helper->crtc_count)
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);
}
return 0;
@@ -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.visual = depth == 8 ? FB_VISUAL_PSEUDOCOLOR :
- FB_VISUAL_DIRECTCOLOR;
+ FB_VISUAL_TRUECOLOR;
info->fix.type_aux = 0;
info->fix.xpanstep = 1; /* doing it in hw */
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,
DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size);
/* if we have > 1 VGA cards, then disable the radeon VGA resources */
- r = vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
- if (r) {
- return -EINVAL;
- }
+ /* this will fail for cards that aren't VGA class devices, just
+ * ignore it */
+ vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
r = radeon_init(rdev);
if (r)