diff options
| author | Jesse Barnes <jbarnes@hobbes.virtuousgeek.org> | 2007-04-11 20:41:54 -0700 | 
|---|---|---|
| committer | Jesse Barnes <jbarnes@hobbes.virtuousgeek.org> | 2007-04-11 20:41:54 -0700 | 
| commit | e8bd9fdf31bf3db91431b69ce1fc8d419148c838 (patch) | |
| tree | 6a71e0a919484e8a5255063d3abc691e05e70665 /linux-core | |
| parent | 0430a80fc7861a3397a3f2649dfeb9eff14359a5 (diff) | |
| parent | b1f0fd6dfbd1495aa08c6358e936582eeca042c8 (diff) | |
Merge branch 'modesetting-101' of git+ssh://git.freedesktop.org/git/mesa/drm into origin/modesetting-101
Diffstat (limited to 'linux-core')
| -rw-r--r-- | linux-core/drm_crtc.c | 87 | ||||
| -rw-r--r-- | linux-core/drm_crtc.h | 2 | ||||
| -rw-r--r-- | linux-core/drm_drv.c | 1 | ||||
| -rw-r--r-- | linux-core/drm_fb.c | 10 | ||||
| -rw-r--r-- | linux-core/intel_display.c | 21 | 
5 files changed, 87 insertions, 34 deletions
| diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c index b349527d..2f140dbd 100644 --- a/linux-core/drm_crtc.c +++ b/linux-core/drm_crtc.c @@ -37,6 +37,7 @@ struct drm_framebuffer *drm_framebuffer_create(drm_device_t *dev)  	spin_lock(&dev->mode_config.config_lock);  	/* Limit to single framebuffer for now */  	if (dev->mode_config.num_fb > 1) { +		spin_unlock(&dev->mode_config.config_lock);  		DRM_ERROR("Attempt to add multiple framebuffers failed\n");  		return NULL;  	} @@ -253,8 +254,7 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,  	/* Now, enable the clocks, plane, pipe, and outputs that we set up. */  	crtc->funcs->commit(crtc);  	list_for_each_entry(output, &dev->mode_config.output_list, head) { -		if (output->crtc == crtc) -		{ +		if (output->crtc == crtc) {  			output->funcs->commit(output);  #if 0 // TODO def RANDR_12_INTERFACE  			if (output->randr_output) @@ -542,6 +542,9 @@ bool drm_initial_config(drm_device_t *dev, struct drm_framebuffer *fb,  	list_for_each_entry(output, &dev->mode_config.output_list, head) {  		struct drm_display_mode *des_mode; +		if (list_empty(&output->modes)) +			continue; +  		/* Get the first preferred moded */  		list_for_each_entry(des_mode, &output->modes, head) {  			if (des_mode->flags & DRM_MODE_TYPE_PREFERRED) @@ -579,7 +582,7 @@ void drm_mode_config_cleanup(drm_device_t *dev)  {  	struct drm_output *output, *ot;  	struct drm_crtc *crtc, *ct; -	 +	struct drm_crtc *fb, *fbt;  	list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) {  		drm_output_destroy(output);  	} @@ -587,10 +590,15 @@ void drm_mode_config_cleanup(drm_device_t *dev)  	list_for_each_entry_safe(crtc, ct, &dev->mode_config.crtc_list, head) {  		drm_crtc_destroy(crtc);  	} + +	list_for_each_entry_safe(fb, fbt, &dev->mode_config.fb_list, head) { +		drmfb_remove(dev, fb); +		drm_framebuffer_destroy(fb); +	}  }  EXPORT_SYMBOL(drm_mode_config_cleanup); -int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_display_mode *new_mode, struct drm_output **output_set) +int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info, struct drm_display_mode *new_mode, struct drm_output **output_set, struct drm_framebuffer *fb)  {  	drm_device_t *dev = crtc->dev;  	struct drm_crtc **save_crtcs, *new_crtc; @@ -603,6 +611,9 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,  	if (!save_crtcs)  		return -ENOMEM; +	if (crtc->fb != fb) +		changed = true; +  	if (crtc_info->x != crtc->x || crtc_info->y != crtc->y)  		changed = true; @@ -617,8 +628,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,  		else  			new_crtc = output->crtc; -		for (ro = 0; ro < crtc_info->count_outputs; ro++) -		{ +		for (ro = 0; ro < crtc_info->count_outputs; ro++) {  			if (output_set[ro] == output)  				new_crtc = crtc;  		} @@ -629,6 +639,7 @@ int drm_crtc_set_config(struct drm_crtc *crtc, struct drm_mode_crtc *crtc_info,  	}  	if (changed) { +		crtc->fb = fb;  		crtc->enabled = (new_mode != NULL);  		if (new_mode != NULL) {  			DRM_DEBUG("attempting to set mode from userspace\n"); @@ -897,6 +908,7 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,  	struct drm_crtc *crtc;  	struct drm_output **output_set = NULL, *output;  	struct drm_display_mode *mode; +	struct drm_framebuffer *fb = NULL;  	int retcode = 0;  	int i; @@ -904,23 +916,28 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,  		return -EFAULT;  	crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req.crtc_id); -	if (!crtc || (crtc->id != crtc_req.crtc_id)) -	{ +	if (!crtc || (crtc->id != crtc_req.crtc_id)) {  		DRM_DEBUG("Unknown CRTC ID %d\n", crtc_req.crtc_id);  		return -EINVAL;  	}  	if (crtc_req.mode) { + +		/* if we have a mode we need a framebuffer */ +		if (crtc_req.fb_id) { +			fb = idr_find(&dev->mode_config.crtc_idr, crtc_req.fb_id); +			if (!fb || (fb->id != crtc_req.fb_id)) { +				DRM_DEBUG("Unknown FB ID%d\n", crtc_req.fb_id); +				return -EINVAL; +			} +		}  		mode = idr_find(&dev->mode_config.crtc_idr, crtc_req.mode); -		if (!mode || (mode->mode_id != crtc_req.mode)) -		{ -			{ -				struct drm_output *output; - -				list_for_each_entry(output, &dev->mode_config.output_list, head) { -					list_for_each_entry(mode, &output->modes, head) { -						drm_mode_debug_printmodeline(dev, mode); -					} +		if (!mode || (mode->mode_id != crtc_req.mode)) { +			struct drm_output *output; +			 +			list_for_each_entry(output, &dev->mode_config.output_list, head) { +				list_for_each_entry(mode, &output->modes, head) { +					drm_mode_debug_printmodeline(dev, mode);  				}  			} @@ -935,8 +952,8 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,  		return -EINVAL;  	} -	if (crtc_req.count_outputs > 0 && !mode) { -		DRM_DEBUG("Count outputs is %d but no mode set\n", crtc_req.count_outputs); +	if (crtc_req.count_outputs > 0 && !mode && !fb) { +		DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req.count_outputs);  		return -EINVAL;  	} @@ -960,7 +977,7 @@ int drm_mode_setcrtc(struct inode *inode, struct file *filp,  		}  	} -	retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set); +	retcode = drm_crtc_set_config(crtc, &crtc_req, mode, output_set, fb);  	return retcode;  } @@ -1058,3 +1075,33 @@ int drm_mode_rmfb(struct inode *inode, struct file *filp,  	return 0;  } +int drm_mode_getfb(struct inode *inode, struct file *filp, +		   unsigned int cmd, unsigned long arg) +{ +	drm_file_t *priv = filp->private_data; +	drm_device_t *dev = priv->head->dev;	 +	struct drm_mode_fb_cmd __user *argp = (void __user *)arg; +	struct drm_mode_fb_cmd r; +	struct drm_framebuffer *fb; + +	if (copy_from_user(&r, argp, sizeof(r))) +		return -EFAULT; + +	fb = idr_find(&dev->mode_config.crtc_idr, r.buffer_id); +	if (!fb || (r.buffer_id != fb->id)) { +		DRM_ERROR("invalid framebuffer id\n"); +		return -EINVAL; +	} + +	r.height = fb->height; +	r.width = fb->width; +	r.depth = fb->depth; +	r.bpp = fb->bits_per_pixel; +	r.handle = fb->bo->base.hash.key; +	r.pitch = fb->pitch; + +	if (copy_to_user(argp, &r, sizeof(r))) +		return -EFAULT; + +	return 0; +} diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h index 54c508c5..c02dcedc 100644 --- a/linux-core/drm_crtc.h +++ b/linux-core/drm_crtc.h @@ -474,5 +474,7 @@ extern int drm_mode_addfb(struct inode *inode, struct file *filp,  			  unsigned int cmd, unsigned long arg);  extern int drm_mode_rmfb(struct inode *inode, struct file *filp,  			 unsigned int cmd, unsigned long arg); +extern int drm_mode_getfb(struct inode *inode, struct file *filp, +			  unsigned int cmd, unsigned long arg);  #endif /* __DRM_CRTC_H__ */ diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c index b43af328..b7a7aded 100644 --- a/linux-core/drm_drv.c +++ b/linux-core/drm_drv.c @@ -129,6 +129,7 @@ static drm_ioctl_desc_t drm_ioctls[] = {  	[DRM_IOCTL_NR(DRM_IOCTL_MODE_SETCRTC)] = {drm_mode_setcrtc, DRM_MASTER|DRM_ROOT_ONLY},  	[DRM_IOCTL_NR(DRM_IOCTL_MODE_ADDFB)] = {drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY},  	[DRM_IOCTL_NR(DRM_IOCTL_MODE_RMFB)] = {drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY}, +	[DRM_IOCTL_NR(DRM_IOCTL_MODE_GETFB)] = {drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY},  };  #define DRM_CORE_IOCTL_COUNT	ARRAY_SIZE( drm_ioctls ) diff --git a/linux-core/drm_fb.c b/linux-core/drm_fb.c index 1a0fb79c..a70e4d52 100644 --- a/linux-core/drm_fb.c +++ b/linux-core/drm_fb.c @@ -77,6 +77,15 @@ static int drmfb_setcolreg(unsigned regno, unsigned red, unsigned green,  	return 0;  } +/* this will let fbcon do the mode init */ +static int drmfb_set_par(struct fb_info *info) +{ +	struct drmfb_par *par = info->par; +	struct drm_device *dev = par->dev; + +	drm_set_desired_modes(dev); +} +  static struct fb_ops drmfb_ops = {  	.owner = THIS_MODULE,  	//	.fb_open = drmfb_open, @@ -84,6 +93,7 @@ static struct fb_ops drmfb_ops = {  	//	.fb_write = drmfb_write,  	//	.fb_release = drmfb_release,  	//	.fb_ioctl = drmfb_ioctl, +	.fb_set_par = drmfb_set_par,  	.fb_setcolreg = drmfb_setcolreg,  	.fb_fillrect = cfb_fillrect,  	.fb_copyarea = cfb_copyarea, diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c index 396f4cfa..aed86231 100644 --- a/linux-core/intel_display.c +++ b/linux-core/intel_display.c @@ -412,8 +412,7 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)  	case DPMSModeSuspend:  		/* Enable the DPLL */  		temp = I915_READ(dpll_reg); -		if ((temp & DPLL_VCO_ENABLE) == 0) -		{ +		if ((temp & DPLL_VCO_ENABLE) == 0) {  			I915_WRITE(dpll_reg, temp);  			I915_READ(dpll_reg);  			/* Wait for the clocks to stabilize. */ @@ -435,8 +434,7 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)  		/* Enable the plane */  		temp = I915_READ(dspcntr_reg); -		if ((temp & DISPLAY_PLANE_ENABLE) == 0) -		{ +		if ((temp & DISPLAY_PLANE_ENABLE) == 0) {  			I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);  			/* Flush the plane changes */  			I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); @@ -456,8 +454,7 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)  		/* Disable display plane */  		temp = I915_READ(dspcntr_reg); -		if ((temp & DISPLAY_PLANE_ENABLE) != 0) -		{ +		if ((temp & DISPLAY_PLANE_ENABLE) != 0) {  			I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);  			/* Flush the plane changes */  			I915_WRITE(dspbase_reg, I915_READ(dspbase_reg)); @@ -719,11 +716,9 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,  			dpll |= DPLLB_MODE_LVDS;  		else  			dpll |= DPLLB_MODE_DAC_SERIAL; -		if (is_sdvo) -		{ +		if (is_sdvo) {  			dpll |= DPLL_DVO_HIGH_SPEED; -			if (IS_I945G(dev) || IS_I945GM(dev)) -			{ +			if (IS_I945G(dev) || IS_I945GM(dev)) {  				int sdvo_pixel_multiply = adjusted_mode->clock / mode->clock;  				dpll |= (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;  			} @@ -760,8 +755,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,  		}  	} -	if (is_tv) -	{ +	if (is_tv) {  		/* XXX: just matching BIOS for now */  /*	dpll |= PLL_REF_INPUT_TVCLKINBC; */  		dpll |= 3; @@ -801,8 +795,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,  		dspcntr |= DISPPLANE_SEL_PIPE_B;  	pipeconf = I915_READ(pipeconf_reg); -	if (pipe == 0 && !IS_I965G(dev)) -	{ +	if (pipe == 0 && !IS_I965G(dev)) {  		/* Enable pixel doubling when the dot clock is > 90% of the (display)  		 * core speed.  		 * | 
