[prev in list] [next in list] [prev in thread] [next in thread] 

List:       dri-patches
Subject:    drm: Branch 'modesetting-101' - 4 commits
From:       alanh () kemper ! freedesktop ! org (Alan Hourihane)
Date:       2008-02-26 15:22:06
Message-ID: 20080226152206.265F810096 () kemper ! freedesktop ! org
[Download RAW message or body]

 linux-core/drmP.h          |    3 -
 linux-core/drm_compat.h    |    4 +
 linux-core/drm_crtc.c      |   35 +++++++------
 linux-core/drm_crtc.h      |    2 
 linux-core/intel_display.c |   54 ++++++++++++--------
 linux-core/intel_fb.c      |  118 +++++++++++++++++++--------------------------
 6 files changed, 109 insertions(+), 107 deletions(-)

New commits:
commit 73cb02b5430b3881cbce5fb4852ac573c11ff831
Author: Alan Hourihane <alanh@tungstengraphics.com>
Date:   Tue Feb 26 15:21:44 2008 +0000

    DRM_INFO  -> DRM_DEBUG

diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c
index 003739d..4b48a0b 100644
--- a/linux-core/intel_display.c
+++ b/linux-core/intel_display.c
@@ -375,7 +375,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y)
 
 	/* no fb bound */
 	if (!crtc->fb) {
-		DRM_INFO("No FB bound\n");
+		DRM_DEBUG("No FB bound\n");
 		return;
 	}
 
commit 191385d51880d5757c8038ff4b46ee5ccb3561c1
Author: Alan Hourihane <alanh@tungstengraphics.com>
Date:   Tue Feb 26 15:20:59 2008 +0000

    DRM_INFO -> DRM_DEBUG

diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index 36d9fc5..1a4624c 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -1618,7 +1618,7 @@ int drm_mode_setcrtc(struct drm_device *dev,
 		if (crtc_req->fb_id == -1) {
 			list_for_each_entry(crtcfb, &dev->mode_config.crtc_list, head) {
 				if (crtcfb == crtc) {
-					DRM_INFO("Using current fb for setmode\n");
+					DRM_DEBUG("Using current fb for setmode\n");
 					fb = crtc->fb;		
 				}
 			}
commit 89f65c50d70fd2165433ead3cfaa88ee9519e261
Author: Alan Hourihane <alanh@tungstengraphics.com>
Date:   Tue Feb 26 15:20:29 2008 +0000

    define PRETHAW

diff --git a/linux-core/drm_compat.h b/linux-core/drm_compat.h
index 7854576..f5f0601 100644
--- a/linux-core/drm_compat.h
+++ b/linux-core/drm_compat.h
@@ -339,4 +339,8 @@ extern unsigned long round_jiffies_relative(unsigned long j);
 extern struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn);
 #endif
 
+#ifndef PM_EVENT_PRETHAW 
+#define PM_EVENT_PRETHAW 3
+#endif
+
 #endif
commit 2476cb209ebbb11edace4bbce0cfaff4e1599dca
Author: Alan Hourihane <alanh@tungstengraphics.com>
Date:   Fri Feb 22 11:46:22 2008 +0000

    Implement short circuit for base change only
    
    Allow mode to be set with fb_id set to -1, meaning set
    the mode with the current fb (if we have one bound).
    
    Allow intelfb to hook back up it's fb if modesetting
    clears it (maybe temporary).
    
    Move any crtc->fb related register changes to set_base
    in intel_fb.
    
    General intelfb cleanups.

diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 0f42d5b..181b3a9 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -173,8 +173,6 @@ struct drm_file;
 
 #include "drm_compat.h"
 
-#include "drm_crtc.h"
-
 /***********************************************************************/
 /** \name Macros to make printk easier */
 /*@{*/
@@ -610,6 +608,7 @@ struct drm_ati_pcigart_info {
 };
 
 #include "drm_objects.h"
+#include "drm_crtc.h"
 
 /* per-master structure */
 struct drm_master {
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index 73ab10e..36d9fc5 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -418,7 +418,6 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct \
drm_display_mode *mode,  struct drm_display_mode *adjusted_mode, saved_mode;
 	int saved_x, saved_y;
 	bool didLock = false;
-	bool ret = false;
 	struct drm_output *output;
 
 	adjusted_mode = drm_mode_duplicate(dev, mode);
@@ -442,8 +441,13 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct \
drm_display_mode *mode,  crtc->x = x;
 	crtc->y = y;
 
-	/* XXX short-circuit changes to base location only */
-	
+	if (drm_mode_equal(&saved_mode, &crtc->mode)) {
+		if (saved_x != crtc->x || saved_y != crtc->y) {
+			crtc->funcs->mode_set_base(crtc, crtc->x, crtc->y);
+			goto done;
+		}
+	}
+
 	/* Pass our mode to the outputs and the CRTC to give them a chance to
 	 * adjust it according to limitations or output properties, and also
 	 * a chance to reject the mode entirely.
@@ -507,22 +511,15 @@ bool drm_crtc_set_mode(struct drm_crtc *crtc, struct \
drm_display_mode *mode,  
 	/* XXX free adjustedmode */
 	drm_mode_destroy(dev, adjusted_mode);
-	ret = TRUE;
 	/* TODO */
 //	if (scrn->pScreen)
 //		drm_crtc_set_screen_sub_pixel_order(dev);
 
 done:
-	if (!ret) {
-		crtc->x = saved_x;
-		crtc->y = saved_y;
-		crtc->mode = saved_mode;
-	}
-	
 	if (didLock)
 		crtc->funcs->unlock (crtc);
 	
-	return ret;
+	return true;
 }
 EXPORT_SYMBOL(drm_crtc_set_mode);
 
@@ -1599,13 +1596,13 @@ int drm_mode_setcrtc(struct drm_device *dev,
 		     void *data, struct drm_file *file_priv)
 {
 	struct drm_mode_crtc *crtc_req = data;
-	struct drm_crtc *crtc;
+	struct drm_crtc *crtc, *crtcfb;
 	struct drm_output **output_set = NULL, *output;
 	struct drm_framebuffer *fb = NULL;
 	struct drm_display_mode *mode = NULL;
+	uint32_t __user *set_outputs_ptr;
 	int ret = 0;
 	int i;
-	uint32_t __user *set_outputs_ptr;
 
 	mutex_lock(&dev->mode_config.mutex);
 	crtc = idr_find(&dev->mode_config.crtc_idr, crtc_req->crtc_id);
@@ -1616,8 +1613,16 @@ int drm_mode_setcrtc(struct drm_device *dev,
 	}
 
 	if (crtc_req->mode_valid) {
-		/* if we have a mode we need a framebuffer */
-		if (crtc_req->fb_id) {
+		/* If we have a mode we need a framebuffer. */
+		/* If we pass -1, set the mode with the currently bound fb */
+		if (crtc_req->fb_id == -1) {
+			list_for_each_entry(crtcfb, &dev->mode_config.crtc_list, head) {
+				if (crtcfb == crtc) {
+					DRM_INFO("Using current fb for setmode\n");
+					fb = crtc->fb;		
+				}
+			}
+		} else {
 			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);
diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h
index d733d8c..bbeab60 100644
--- a/linux-core/drm_crtc.h
+++ b/linux-core/drm_crtc.h
@@ -244,7 +244,7 @@ struct drm_framebuffer {
 	struct drm_buffer_object *bo;
 	void *fbdev;
 	u32 pseudo_palette[17];
-	void *virtual_base;
+	struct drm_bo_kmap_obj kmap;
 	struct list_head filp_head;
 };
 
diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c
index 6a9d980..003739d 100644
--- a/linux-core/intel_display.c
+++ b/linux-core/intel_display.c
@@ -369,10 +369,42 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y)
 	unsigned long Start, Offset;
 	int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
 	int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
+	int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
+	int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
+	u32 dspcntr;
+
+	/* no fb bound */
+	if (!crtc->fb) {
+		DRM_INFO("No FB bound\n");
+		return;
+	}
 
 	Start = crtc->fb->bo->offset;
 	Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
 
+	I915_WRITE(dspstride, crtc->fb->pitch);
+
+	dspcntr = I915_READ(dspcntr_reg);
+	switch (crtc->fb->bits_per_pixel) {
+	case 8:
+		dspcntr |= DISPPLANE_8BPP;
+		break;
+	case 16:
+		if (crtc->fb->depth == 15)
+			dspcntr |= DISPPLANE_15_16BPP;
+		else
+			dspcntr |= DISPPLANE_16BPP;
+		break;
+	case 24:
+	case 32:
+		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
+		break;
+	default:
+		DRM_ERROR("Unknown color depth\n");
+		return;
+	}
+	I915_WRITE(dspcntr_reg, dspcntr);
+
 	DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
 	if (IS_I965G(dev)) {
 		I915_WRITE(dspbase, Offset);
@@ -691,7 +723,6 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
 	int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
 	int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
 	int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
-	int dspstride_reg = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
 	int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
 	int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
 	int refclk;
@@ -804,26 +835,6 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
 	/* Set up the display plane register */
 	dspcntr = DISPPLANE_GAMMA_ENABLE;
 
-	switch (crtc->fb->bits_per_pixel) {
-	case 8:
-		dspcntr |= DISPPLANE_8BPP;
-		break;
-	case 16:
-		if (crtc->fb->depth == 15)
-			dspcntr |= DISPPLANE_15_16BPP;
-		else
-			dspcntr |= DISPPLANE_16BPP;
-		break;
-	case 24:
-	case 32:
-		dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
-		break;
-	default:
-		DRM_ERROR("Unknown color depth\n");
-		return;
-	}
-	
-
 	if (pipe == 0)
 		dspcntr |= DISPPLANE_SEL_PIPE_A;
 	else
@@ -925,7 +936,6 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
 		   ((adjusted_mode->crtc_vblank_end - 1) << 16));
 	I915_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
 		   ((adjusted_mode->crtc_vsync_end - 1) << 16));
-	I915_WRITE(dspstride_reg, crtc->fb->pitch);
 	/* pipesrc and dspsize control the size that is scaled from, which should
 	 * always be the user's requested size.
 	 */
diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c
index 5640399..e33494c 100644
--- a/linux-core/intel_fb.c
+++ b/linux-core/intel_fb.c
@@ -48,6 +48,7 @@ struct intelfb_par {
 	struct drm_device *dev;
 	struct drm_crtc *crtc;
         struct drm_display_mode *fb_mode;
+	struct drm_framebuffer *fb;
 };
 /*
 static int
@@ -66,7 +67,7 @@ static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned \
green,  struct fb_info *info)
 {
 	struct intelfb_par *par = info->par;
-	struct drm_framebuffer *fb = par->crtc->fb;
+	struct drm_framebuffer *fb = par->fb;
 	struct drm_crtc *crtc = par->crtc;
 
 	if (regno > 255)
@@ -107,7 +108,7 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
 {
         struct intelfb_par *par = info->par;
         /*struct drm_device *dev = par->dev;*/
-	struct drm_framebuffer *fb = par->crtc->fb;
+	struct drm_framebuffer *fb = par->fb;
         /*struct drm_output *output;*/
         int depth/*, found = 0*/;
 
@@ -216,41 +217,15 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
 	return 0;
 }
 
-bool i915_drmfb_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode \
                *mode2, unsigned int pixclock)
-{
-
-	if (mode1->hdisplay == mode2->hdisplay &&
-	    mode1->hsync_start == mode2->hsync_start &&
-	    mode1->hsync_end == mode2->hsync_end &&
-	    mode1->htotal == mode2->htotal &&
-	    mode1->hskew == mode2->hskew &&
-	    mode1->vdisplay == mode2->vdisplay &&
-	    mode1->vsync_start == mode2->vsync_start &&
-	    mode1->vsync_end == mode2->vsync_end &&
-	    mode1->vtotal == mode2->vtotal &&
-	    mode1->vscan == mode2->vscan &&
-	    mode1->flags == mode2->flags) 
-	{
-		if (mode1->clock == mode2->clock)
-			return true;
-
-		if (KHZ2PICOS(mode2->clock) == pixclock)
-			return true;
-		return false;
-	}
-	
-	return false;
-}
-
 /* this will let fbcon do the mode init */
 /* FIXME: take mode config lock? */
 static int intelfb_set_par(struct fb_info *info)
 {
 	struct intelfb_par *par = info->par;
-	struct drm_framebuffer *fb = par->crtc->fb;
+	struct drm_framebuffer *fb = par->fb;
 	struct drm_device *dev = par->dev;
         struct drm_display_mode *drm_mode, *search_mode;
-        struct drm_output *output;
+        struct drm_output *output = NULL;
         struct fb_var_screeninfo *var = &info->var;
 	int found = 0;
 
@@ -295,15 +270,23 @@ static int intelfb_set_par(struct fb_info *info)
         drm_mode_set_name(drm_mode);
 	drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);
 
+	found = 0;
         list_for_each_entry(output, &dev->mode_config.output_list, head) {
-                if (output->crtc == par->crtc)
+                if (output->crtc == par->crtc){
+			found = 1;
                         break;
+		}
         }
 
+	/* no output bound, bail */
+	if (!found)
+		return -EINVAL;
+
+	found = 0;
 	drm_mode_debug_printmodeline(dev, drm_mode);    
         list_for_each_entry(search_mode, &output->modes, head) {
 		drm_mode_debug_printmodeline(dev, search_mode);
-		if (i915_drmfb_mode_equal(drm_mode, search_mode, var->pixclock)) {
+		if (drm_mode_equal(drm_mode, search_mode)) {
 			drm_mode_destroy(dev, drm_mode);
 			drm_mode = search_mode;
 			found = 1;
@@ -311,8 +294,12 @@ static int intelfb_set_par(struct fb_info *info)
 		}
 	}
 	
+	/* If we didn't find a matching mode that exists on our output,
+	 * create a new attachment for the incoming user specified mode
+	 */
 	if (!found) {
 		if (par->fb_mode) {
+			/* this also destroys the mode */
 			drm_mode_detachmode_crtc(dev, par->fb_mode);
 		}
 	
@@ -322,21 +309,13 @@ static int intelfb_set_par(struct fb_info *info)
 		drm_mode_attachmode_crtc(dev, par->crtc, par->fb_mode);
 	}
 
-	if (par->crtc->enabled) {
-		if (!drm_mode_equal(&par->crtc->mode, drm_mode)) {
-			if (!drm_crtc_set_mode(par->crtc, drm_mode, var->xoffset, var->yoffset))
-				return -EINVAL;
-		} else if (par->crtc->x != var->xoffset || par->crtc->y != var->yoffset) {
-			if (!par->crtc->funcs->mode_set_base) {
-				if (!drm_crtc_set_mode(par->crtc, drm_mode, var->xoffset, var->yoffset))
-					return -EINVAL;
-			} else {
-				par->crtc->funcs->mode_set_base(par->crtc, var->xoffset, var->yoffset);
-				par->crtc->x = var->xoffset;
-				par->crtc->y = var->yoffset;
-			}
-		}
-	}
+	/* re-attach fb */
+	if (!par->crtc->fb)
+		par->crtc->fb = par->fb;
+
+	if (!drm_crtc_set_mode(par->crtc, drm_mode, var->xoffset, var->yoffset))
+		return -EINVAL;
+
 	return 0;
 }
 
@@ -493,17 +472,14 @@ static int intelfb_pan_display(struct fb_var_screeninfo *var,
 
 	DRM_DEBUG("\n");
 
-	if (!crtc->funcs->mode_set_base) {
-		DRM_ERROR("panning not supported\n");
-		return -EFAULT;
-	}
-
 	/* TODO add check size and pos*/
 
-	crtc->funcs->mode_set_base(crtc, var->xoffset, var->yoffset);
+	/* re-attach fb */
+	if (!crtc->fb)
+		crtc->fb = par->fb;
+
+	drm_crtc_set_mode(crtc, &crtc->mode, var->xoffset, var->yoffset);
 
-	par->crtc->x = var->xoffset;
-	par->crtc->y = var->yoffset;
 	info->var.xoffset = var->xoffset;
 	info->var.yoffset = var->yoffset;
 
@@ -535,7 +511,7 @@ static struct fb_ops intelfb_ops = {
  */
 int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
 {
-    struct fb_info *info;
+	struct fb_info *info;
 	struct drm_framebuffer *fb;
 	struct drm_display_mode *mode = crtc->desired_mode;
 
@@ -559,7 +535,7 @@ int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
 	info->var.vsync_len = mode->vsync_end - mode->vsync_start;
 	info->var.upper_margin = mode->vtotal - mode->vsync_end;
 	info->var.pixclock = 10000000 / mode->htotal * 1000 / mode->vtotal * 100;
-    /* avoid overflow */
+	/* avoid overflow */
 	info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
 
 	return 0;
@@ -596,7 +572,7 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
 	fb->bits_per_pixel = 32;
 	fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8);
 	fb->depth = 24;
-	ret = drm_buffer_object_create(dev, fb->width * fb->height * 4, 
+	ret = drm_buffer_object_create(dev, fb->pitch * fb->height * 4, 
 				       drm_bo_type_kernel,
 				       DRM_BO_FLAG_READ |
 				       DRM_BO_FLAG_WRITE |
@@ -623,6 +599,7 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
 
 	par->dev = dev;
 	par->crtc = crtc;
+	par->fb = fb;
 
 	info->fbops = &intelfb_ops;
 
@@ -635,19 +612,26 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc \
*crtc)  info->fix.ywrapstep = 0;
 	info->fix.accel = FB_ACCEL_I830;
 	info->fix.type_aux = 0;
-	info->fix.mmio_start = 0;
-	info->fix.mmio_len = 0;
+ 
+ 	if (IS_I9XX(dev)) {
+ 		info->fix.mmio_start = pci_resource_start(dev->pdev, 0);
+ 		info->fix.mmio_len = pci_resource_len(dev->pdev, 0);
+ 	} else {
+ 		info->fix.mmio_start = pci_resource_start(dev->pdev, 1);
+ 		info->fix.mmio_len = pci_resource_len(dev->pdev, 1);
+ 	}
+
 	info->fix.line_length = fb->pitch;
 	info->fix.smem_start = fb->bo->offset + dev->mode_config.fb_base;
 	info->fix.smem_len = info->fix.line_length * fb->height;
 
 	info->flags = FBINFO_DEFAULT;
 
-	ret = drm_mem_reg_ioremap(dev, &fb->bo->mem, &fb->virtual_base);
-	if (ret)
-		DRM_ERROR("error mapping fb: %d\n", ret);
-
-	info->screen_base = fb->virtual_base;
+ 	ret = drm_bo_kmap(fb->bo, 0, fb->bo->num_pages, &fb->kmap);
+  	if (ret)
+  		DRM_ERROR("error mapping fb: %d\n", ret);
+  
+ 	info->screen_base = fb->kmap.virtual;
 	info->screen_size = info->fix.smem_len; /* FIXME */
 	info->pseudo_palette = fb->pseudo_palette;
 	info->var.xres_virtual = fb->width;
@@ -757,10 +741,10 @@ int intelfb_remove(struct drm_device *dev, struct drm_crtc \
*crtc)  
 	if (info) {
 		unregister_framebuffer(info);
-		framebuffer_release(info);
-		drm_mem_reg_iounmap(dev, &fb->bo->mem, fb->virtual_base);
+		drm_bo_kunmap(&fb->kmap);
 		drm_bo_usage_deref_unlocked(&fb->bo);
 		drm_framebuffer_destroy(fb);
+		framebuffer_release(info);
 	}
 	return 0;
 }

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2008.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/
--
_______________________________________________
Dri-patches mailing list
Dri-patches@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-patches


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic