diff options
Diffstat (limited to 'linux-core')
| -rw-r--r-- | linux-core/intel_fb.c | 39 | ||||
| -rw-r--r-- | linux-core/intel_i2c.c | 3 | ||||
| -rw-r--r-- | linux-core/intel_sdvo.c | 11 | 
3 files changed, 44 insertions, 9 deletions
| diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c index 048295ab..04fd0fdd 100644 --- a/linux-core/intel_fb.c +++ b/linux-core/intel_fb.c @@ -49,6 +49,17 @@ struct intelfb_par {  	struct drm_crtc *crtc;  }; +static int +var_to_refresh(const struct fb_var_screeninfo *var) +{ +	int xtot = var->xres + var->left_margin + var->right_margin + +		   var->hsync_len; +	int ytot = var->yres + var->upper_margin + var->lower_margin + +		   var->vsync_len; + +	return (1000000000 / var->pixclock * 1000 + 500) / xtot / ytot; +} +  static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,  			   unsigned blue, unsigned transp,  			   struct fb_info *info) @@ -98,7 +109,7 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,  	struct drm_framebuffer *fb = par->crtc->fb;          struct drm_display_mode *drm_mode;          struct drm_output *output; -        int depth; +        int depth, found = 0;          if (!var->pixclock)                  return -EINVAL; @@ -191,11 +202,14 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,          list_for_each_entry(drm_mode, &output->modes, head) {                  if (drm_mode->hdisplay == var->xres &&                      drm_mode->vdisplay == var->yres && -                    drm_mode->clock != 0) +                    (((PICOS2KHZ(var->pixclock))/1000) >= ((drm_mode->clock/1000)-1)) && +                    (((PICOS2KHZ(var->pixclock))/1000) <= ((drm_mode->clock/1000)+1))) { +			found = 1;  			break; +		}  	} -        if (!drm_mode) +        if (!found)                  return -EINVAL;  #endif @@ -210,7 +224,9 @@ static int intelfb_set_par(struct fb_info *info)  	struct drm_framebuffer *fb = par->crtc->fb;  	struct drm_device *dev = par->dev;          struct drm_display_mode *drm_mode; +        struct drm_output *output;          struct fb_var_screeninfo *var = &info->var; +	int found = 0;          switch (var->bits_per_pixel) {          case 16: @@ -246,9 +262,18 @@ static int intelfb_set_par(struct fb_info *info)          list_for_each_entry(drm_mode, &output->modes, head) {                  if (drm_mode->hdisplay == var->xres &&                      drm_mode->vdisplay == var->yres && -                    drm_mode->clock != 0) +                    (((PICOS2KHZ(var->pixclock))/1000) >= ((drm_mode->clock/1000)-1)) && +                    (((PICOS2KHZ(var->pixclock))/1000) <= ((drm_mode->clock/1000)+1))) { +			found = 1;  			break; +		}          } + +	if (!found) { +		DRM_ERROR("Couldn't find a mode for requested %dx%d-%d\n", +			var->xres,var->yres,var_to_refresh(var)); +		return -EINVAL; +	}  #else          drm_mode = drm_mode_create(dev);          drm_mode->hdisplay = var->xres; @@ -265,13 +290,15 @@ static int intelfb_set_par(struct fb_info *info)  	drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);  #endif +	drm_mode_debug_printmodeline(dev, drm_mode); +          if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0))                  return -EINVAL;          /* Have to destroy our created mode if we're not searching the mode           * list for it.           */ -#if 1  +#if 1          drm_mode_destroy(dev, drm_mode);  #endif @@ -472,6 +499,7 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)  				       drm_bo_type_kernel,  				       DRM_BO_FLAG_READ |  				       DRM_BO_FLAG_WRITE | +				       DRM_BO_FLAG_MEM_TT |  				       DRM_BO_FLAG_MEM_VRAM,  				       0, 0, 0,  				       &fbo); @@ -629,6 +657,7 @@ int intelfb_remove(struct drm_device *dev, struct drm_crtc *crtc)  		unregister_framebuffer(info);  		framebuffer_release(info);  		drm_mem_reg_iounmap(dev, &fb->bo->mem, fb->virtual_base); +		drm_framebuffer_destroy(fb);  	}  	return 0;  } diff --git a/linux-core/intel_i2c.c b/linux-core/intel_i2c.c index b512e592..efcbf656 100644 --- a/linux-core/intel_i2c.c +++ b/linux-core/intel_i2c.c @@ -140,6 +140,9 @@ struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,  	chan->reg = reg;  	snprintf(chan->adapter.name, I2C_NAME_SIZE, "intel drm %s", name);  	chan->adapter.owner = THIS_MODULE; +#ifndef I2C_HW_B_INTELFB +#define I2C_HW_B_INTELFB I2C_HW_B_I810 +#endif  	chan->adapter.id = I2C_HW_B_INTELFB;  	chan->adapter.algo_data	= &chan->algo;  	chan->adapter.dev.parent = &dev->pdev->dev; diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c index 19df1d4d..51fe43cb 100644 --- a/linux-core/intel_sdvo.c +++ b/linux-core/intel_sdvo.c @@ -730,9 +730,12 @@ static void intel_sdvo_dpms(struct drm_output *output, int mode)  						       &input2); -		/* Warn if the device reported failure to sync. */ +		/* Warn if the device reported failure to sync.  +		 * A lot of SDVO devices fail to notify of sync, but it's +		 * a given it the status is a success, we succeeded. +		 */  		if (status == SDVO_CMD_STATUS_SUCCESS && !input1) { -			DRM_ERROR("First %s output reported failure to sync\n", +			DRM_DEBUG("First %s output reported failure to sync\n",  				   SDVO_NAME(sdvo_priv));  		} @@ -839,10 +842,10 @@ static int intel_sdvo_mode_valid(struct drm_output *output,  		return MODE_NO_DBLESCAN;  	if (sdvo_priv->pixel_clock_min > mode->clock) -		return MODE_CLOCK_HIGH; +		return MODE_CLOCK_LOW;  	if (sdvo_priv->pixel_clock_max < mode->clock) -		return MODE_CLOCK_LOW; +		return MODE_CLOCK_HIGH;  	return MODE_OK;  } | 
