diff options
| -rw-r--r-- | libdrm/xf86drmMode.c | 56 | ||||
| -rw-r--r-- | libdrm/xf86drmMode.h | 19 | ||||
| -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 | ||||
| -rw-r--r-- | shared-core/drm.h | 1 | ||||
| -rw-r--r-- | shared-core/i915_init.c | 2 | 
9 files changed, 113 insertions, 86 deletions
diff --git a/libdrm/xf86drmMode.c b/libdrm/xf86drmMode.c index 04fb07dc..b695467b 100644 --- a/libdrm/xf86drmMode.c +++ b/libdrm/xf86drmMode.c @@ -106,7 +106,7 @@ void drmModeFreeResources(drmModeResPtr ptr)  } -void drmModeFreeFrameBuffer(drmModeFrameBufferPtr ptr) +void drmModeFreeFB(drmModeFBPtr ptr)  {  	if (!ptr)  		return; @@ -215,51 +215,33 @@ int drmModeRmFB(int fd, uint32_t bufferId)  	return ioctl(fd, DRM_IOCTL_MODE_RMFB, bufferId);  } -#if 0 -int drmModeForceProbe(int fd, uint32_t outputId) +drmModeFBPtr drmModeGetFB(int fd, uint32_t buf)  { -	/* TODO impl/keep? */ -} +	struct drm_mode_fb_cmd info; +	drmModeFBPtr r; -drmModeFrameBufferPtr drmModeGetFrameBuffer(int fd, uint32_t buf) -{ -//	struct drm_mode_fb_cmd info; -	drmModeFrameBufferPtr r; +	info.buffer_id = buf; -	//	if (ioctl(fd, DRM_IOCTL_MODE_GETFRAMEBUFFER, &info)) -		return 0; +	if (ioctl(fd, DRM_IOCTL_MODE_GETFB, &info)) +		return NULL;  	if (!(r = drmMalloc(sizeof(*r)))) -		return 0; +		return NULL; -	/* TODO change to new code -	r->minWidth  = info.minWidth; -	r->maxWidth  = info.maxWidth; -	r->minHeight = info.minHeight; -	r->maxHeight = info.maxHeight;*/ +	r->buffer_id = info.buffer_id; +	r->width = info.width; +	r->height = info.height; +	r->pitch = info.pitch; +	r->bpp = info.bpp; +	r->handle = info.handle; +	r->depth = info.depth;  	return r;  } - -uint32_t drmModeNewFrameBuffer(int fd, uint32_t width, uint32_t height, -		uint8_t bpp, uint32_t pitch, drmBO *bo) -{ -	drm_mode_fb_cmd_t f; - -	f.handle = bo->handle; -	f.width  = width; -	f.height = height; -	f.pitch  = pitch; - -	//	if (ioctl(fd, DRM_IOCTL_MODE_NEWFRAMEBUFFER, &f)) -		return 0; - -	return f.bufferId; -} - -int drmModeDesFrameBuffer(int fd, uint32_t bufferId) +#if 0 +int drmModeForceProbe(int fd, uint32_t outputId)  { -  //	return ioctl(fd, DRM_IOCTL_MODE_DESFRAMEBUFFER, bufferId); +	/* TODO impl/keep? */  }  #endif @@ -294,7 +276,7 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)  	r->mode            = crtc.mode;  //	r->width           = crtc.width;  //	r->height          = crtc.height; -	r->bufferId        = crtc.fb_id; +	r->buffer_id        = crtc.fb_id;  	r->gamma_size      = crtc.gamma_size;  	r->count_outputs   = crtc.count_outputs;  	r->count_possibles = crtc.count_possibles; diff --git a/libdrm/xf86drmMode.h b/libdrm/xf86drmMode.h index cdc82f7d..6aa104a9 100644 --- a/libdrm/xf86drmMode.h +++ b/libdrm/xf86drmMode.h @@ -76,18 +76,11 @@ typedef struct _drmModeRes {  } drmModeRes, *drmModeResPtr; -typedef struct _drmModeFrameBuffer { - -	uint32_t width; -	uint32_t height; -	uint32_t pitch; -	uint8_t bpp; - -} drmModeFrameBuffer, *drmModeFrameBufferPtr; +typedef struct drm_mode_fb_cmd drmModeFB, *drmModeFBPtr;  typedef struct _drmModeCrtc { -	unsigned int bufferId; /**< Buffer currently connected to */ +	unsigned int buffer_id; /**< FB id to connect to 0 = disconnect*/  	uint32_t x, y; /**< Position on the frameuffer */  	uint32_t width, height; @@ -187,7 +180,7 @@ typedef struct _drmModeOutput {  extern void drmModeFreeModeInfo( struct drm_mode_modeinfo *ptr );  extern void drmModeFreeResources( drmModeResPtr ptr ); -extern void drmModeFreeFrameBuffer( drmModeFrameBufferPtr ptr ); +extern void drmModeFreeFB( drmModeFBPtr ptr );  extern void drmModeFreeCrtc( drmModeCrtcPtr ptr );  extern void drmModeFreeOutput( drmModeOutputPtr ptr ); @@ -209,14 +202,14 @@ extern int drmModeForceProbe(int fd, uint32_t outputId);  /**   * Retrive information about framebuffer bufferId   */ -extern drmModeFrameBufferPtr drmModeGetFB(int fd, -		uint32_t bufferId); +extern drmModeFBPtr drmModeGetFB(int fd, uint32_t bufferId);  /**   * Creates a new framebuffer with an buffer object as its scanout buffer.   */  extern int drmModeAddFB(int fd, uint32_t width, uint32_t height, uint8_t depth, -			uint8_t bpp, uint32_t pitch, drmBO *bo, uint32_t *buf_id); +			uint8_t bpp, uint32_t pitch, drmBO *bo, +			uint32_t *buf_id);  /**   * Destroies the given framebuffer.   */ 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.  		 * diff --git a/shared-core/drm.h b/shared-core/drm.h index 698f851b..b5b0aa52 100644 --- a/shared-core/drm.h +++ b/shared-core/drm.h @@ -1051,6 +1051,7 @@ struct drm_mode_fb_cmd {  #define DRM_IOCTL_MODE_SETCRTC          DRM_IOWR(0xA3, struct drm_mode_crtc)  #define DRM_IOCTL_MODE_ADDFB            DRM_IOWR(0xA4, struct drm_mode_fb_cmd)  #define DRM_IOCTL_MODE_RMFB             DRM_IOWR(0xA5, unsigned int) +#define DRM_IOCTL_MODE_GETFB             DRM_IOWR(0xA6, struct drm_mode_fb_cmd)  /*@}*/  /** diff --git a/shared-core/i915_init.c b/shared-core/i915_init.c index 7616b33e..1a8af0ab 100644 --- a/shared-core/i915_init.c +++ b/shared-core/i915_init.c @@ -211,8 +211,6 @@ int i915_driver_load(drm_device_t *dev, unsigned long flags)  	drm_initial_config(dev, fb, false);  	drmfb_probe(dev, fb); -        drm_set_desired_modes(dev); -  #if 0  	/* FIXME: command ring needs AGP space, do we own it at this point? */  	dev_priv->ring.Start = dev_priv->baseaddr;  | 
