~ubuntu-branches/ubuntu/precise/xserver-xorg-video-intel/precise

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
Index: xserver-xorg-video-intel/src/intel.h
===================================================================
--- xserver-xorg-video-intel.orig/src/intel.h	2011-12-20 15:47:35.802985779 +1100
+++ xserver-xorg-video-intel/src/intel.h	2011-12-20 15:47:38.618985789 +1100
@@ -432,6 +432,7 @@
 	OptionInfoPtr Options;
 
 	/* Driver phase/state information */
+	Bool starting;
 	Bool suspended;
 
 	enum last_3d last_3d;
@@ -461,6 +462,7 @@
 extern int intel_get_pipe_from_crtc_id(drm_intel_bufmgr *bufmgr, xf86CrtcPtr crtc);
 extern int intel_crtc_id(xf86CrtcPtr crtc);
 extern int intel_output_dpms_status(xf86OutputPtr output);
+extern void intel_copy_fb(ScrnInfoPtr scrn);
 
 enum DRI2FrameEventType {
 	DRI2_SWAP,
Index: xserver-xorg-video-intel/src/intel_display.c
===================================================================
--- xserver-xorg-video-intel.orig/src/intel_display.c	2011-12-20 15:47:35.778985780 +1100
+++ xserver-xorg-video-intel/src/intel_display.c	2011-12-20 15:54:45.422987131 +1100
@@ -36,6 +36,8 @@
 #include <errno.h>
 #include <poll.h>
 
+#include <sys/ioctl.h>
+
 #include "xorgVersion.h"
 
 #include "intel.h"
@@ -45,6 +47,8 @@
 #include "X11/extensions/dpmsconst.h"
 #include "xf86DDC.h"
 
+#include "uxa.h"
+
 struct intel_mode {
 	int fd;
 	uint32_t fb_id;
@@ -939,6 +943,13 @@
 	drmModeConnectorPtr koutput = intel_output->mode_output;
 	struct intel_mode *mode = intel_output->mode;
 	int i;
+	intel_screen_private *intel = intel_get_screen_private(output->scrn);
+
+	/* xf86Crtc.c calls dpms off in set desired modes, so ignore
+	 * the request if we're starting up. */
+
+	if (intel->starting)
+		return;
 
 	for (i = 0; i < koutput->count_props; i++) {
 		drmModePropertyPtr props;
@@ -1632,6 +1643,11 @@
 	}
 
 	intel->modes = mode;
+
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) < 9
+	scrn->canDoBGNoneRoot = TRUE;
+#endif
+
 	return TRUE;
 }
 
@@ -1701,3 +1717,100 @@
 	struct intel_crtc *intel_crtc = crtc->driver_private;
 	return intel_crtc->pipe;
 }
+
+static PixmapPtr
+intel_create_pixmap_for_fbcon(ScrnInfoPtr scrn)
+{
+	xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(scrn);
+	struct intel_crtc *intel_crtc = xf86_config->crtc[0]->driver_private;
+	ScreenPtr pScreen = screenInfo.screens[scrn->scrnIndex];
+	struct intel_mode *mode = intel_crtc->mode;
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	drmModeFBPtr fbcon = NULL;
+	struct drm_gem_flink flink;
+	drm_intel_bo *bo;
+	PixmapPtr pixmap = NULL;
+	int i;
+
+	for (i = 0; i < mode->mode_res->count_crtcs; i++) {
+		intel_crtc = xf86_config->crtc[i]->driver_private;
+		if (intel_crtc->mode_crtc->buffer_id == 0)
+			continue;
+		fbcon = drmModeGetFB(mode->fd,
+				     intel_crtc->mode_crtc->buffer_id);
+		if (fbcon != NULL)
+			break;
+	}
+	if (i == mode->mode_res->count_crtcs)
+		return NULL;
+
+	flink.handle = fbcon->handle;
+	if (ioctl(mode->fd, DRM_IOCTL_GEM_FLINK, &flink) < 0) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't flink fbcon handle\n");
+		return NULL;
+	}
+
+	bo = drm_intel_bo_gem_create_from_name(intel->bufmgr,
+					       "fbcon", flink.name);
+	if (bo == NULL) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate bo for fbcon handle\n");
+		return NULL;
+	}
+	if (!CreateScratchPixmapsForScreen(pScreen->myNum))
+		return NULL;
+
+	pixmap = GetScratchPixmapHeader(pScreen,
+					fbcon->width, fbcon->height,
+					fbcon->depth, fbcon->bpp,
+					fbcon->pitch, NULL);
+	if (pixmap == NULL) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't allocate pixmap fbcon contents\n");
+		return NULL;
+	}
+
+	intel_set_pixmap_bo(pixmap, bo);
+	drm_intel_bo_unreference(bo);
+	drmModeFreeFB(fbcon);
+
+	return pixmap;
+}
+
+void intel_copy_fb(ScrnInfoPtr scrn)
+{
+	ScreenPtr pScreen = screenInfo.screens[scrn->scrnIndex];
+	intel_screen_private *intel = intel_get_screen_private(scrn);
+	PixmapPtr src, dst;
+	unsigned int pitch = scrn->displayWidth * intel->cpp;
+
+	src = intel_create_pixmap_for_fbcon(scrn);
+	if (src == NULL) {
+		xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+			   "Couldn't create pixmap for fbcon\n");
+		return;
+	}
+
+	/* We dont have a screen Pixmap yet */
+	dst = GetScratchPixmapHeader(pScreen,
+				     scrn->virtualX, scrn->virtualY,
+				     scrn->depth, scrn->bitsPerPixel,
+				     pitch,
+				     NULL);
+	intel_set_pixmap_bo(dst, intel->front_buffer);
+
+	intel->uxa_driver->prepare_copy(src, dst, -1, -1, GXcopy, FB_ALLONES);
+
+	intel->uxa_driver->copy(dst, 0, 0, 0, 0,
+				scrn->virtualX, scrn->virtualY);
+
+	intel->uxa_driver->done_copy(dst);
+
+	intel_batch_submit(scrn);
+
+	(*pScreen->DestroyPixmap)(src);
+	(*pScreen->DestroyPixmap)(dst);
+	FreeScratchPixmapsForScreen(pScreen->myNum);
+}
+
Index: xserver-xorg-video-intel/src/intel_driver.c
===================================================================
--- xserver-xorg-video-intel.orig/src/intel_driver.c	2011-12-20 15:47:35.762985780 +1100
+++ xserver-xorg-video-intel/src/intel_driver.c	2011-12-20 15:47:38.618985789 +1100
@@ -950,6 +950,10 @@
 		intel->directRenderingType = DRI_DRI2;
 #endif
 
+#if GET_ABI_MAJOR(ABI_VIDEODRV_VERSION) >= 9
+	screen->canDoBGNoneRoot = TRUE;
+#endif
+
 	if (!intel_init_initial_framebuffer(scrn))
 		return FALSE;
 
@@ -958,6 +962,8 @@
 	if (INTEL_INFO(intel)->gen >= 40)
 		gen4_render_state_init(scrn);
 
+	intel->starting = FALSE;
+
 	miClearVisualTypes();
 	if (!miSetVisualTypes(scrn->depth,
 			      miGetDefaultVisualMask(scrn->depth),
@@ -1093,6 +1099,7 @@
 
 	intel_mode_init(intel);
 
+	intel->starting = FALSE;
 	intel->suspended = FALSE;
 
 #if HAVE_UDEV
@@ -1159,6 +1166,8 @@
 
 	intel_set_gem_max_sizes(scrn);
 
+	intel_copy_fb(scrn);
+
 	if (!xf86SetDesiredModes(scrn))
 		return FALSE;