Rev 6088 | Rev 6131 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6088 | Rev 6103 | ||
---|---|---|---|
1 | #define iowrite32(v, addr) writel((v), (addr)) |
1 | #define iowrite32(v, addr) writel((v), (addr)) |
2 | 2 | ||
3 | #include |
3 | #include |
4 | #include |
4 | #include |
5 | #include "i915_drv.h" |
5 | #include "i915_drv.h" |
6 | #include "intel_drv.h" |
6 | #include "intel_drv.h" |
7 | #include |
7 | #include |
8 | #include |
8 | #include |
9 | #include |
9 | #include |
10 | 10 | ||
11 | #include |
11 | #include |
12 | 12 | ||
13 | #include "bitmap.h" |
13 | #include "bitmap.h" |
14 | #include |
14 | #include |
15 | 15 | ||
16 | 16 | ||
17 | display_t *os_display; |
17 | display_t *os_display; |
18 | struct drm_i915_gem_object *main_fb_obj; |
18 | struct drm_i915_gem_object *main_fb_obj; |
19 | struct drm_framebuffer *main_framebuffer; |
19 | struct drm_framebuffer *main_framebuffer; |
20 | 20 | ||
21 | u32 cmd_buffer; |
21 | u32 cmd_buffer; |
22 | u32 cmd_offset; |
22 | u32 cmd_offset; |
23 | 23 | ||
24 | void init_render(); |
24 | void init_render(); |
25 | int sna_init(); |
25 | int sna_init(); |
26 | 26 | ||
27 | static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor); |
27 | static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor); |
28 | static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y); |
28 | static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y); |
29 | 29 | ||
30 | void __stdcall restore_cursor(int x, int y) |
30 | void __stdcall restore_cursor(int x, int y) |
31 | {}; |
31 | {}; |
32 | 32 | ||
33 | void disable_mouse(void) |
33 | void disable_mouse(void) |
34 | {}; |
34 | {}; |
35 | 35 | ||
36 | struct mutex cursor_lock; |
36 | struct mutex cursor_lock; |
37 | 37 | ||
38 | static char *manufacturer_name(unsigned char *x) |
38 | static char *manufacturer_name(unsigned char *x) |
39 | { |
39 | { |
40 | static char name[4]; |
40 | static char name[4]; |
41 | 41 | ||
42 | name[0] = ((x[0] & 0x7C) >> 2) + '@'; |
42 | name[0] = ((x[0] & 0x7C) >> 2) + '@'; |
43 | name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@'; |
43 | name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@'; |
44 | name[2] = (x[1] & 0x1F) + '@'; |
44 | name[2] = (x[1] & 0x1F) + '@'; |
45 | name[3] = 0; |
45 | name[3] = 0; |
46 | 46 | ||
47 | return name; |
47 | return name; |
48 | } |
48 | } |
49 | 49 | ||
50 | static int count_connector_modes(struct drm_connector* connector) |
50 | static int count_connector_modes(struct drm_connector* connector) |
51 | { |
51 | { |
52 | struct drm_display_mode *mode; |
52 | struct drm_display_mode *mode; |
53 | int count = 0; |
53 | int count = 0; |
54 | 54 | ||
55 | list_for_each_entry(mode, &connector->modes, head) |
55 | list_for_each_entry(mode, &connector->modes, head) |
56 | count++; |
56 | count++; |
57 | 57 | ||
58 | return count; |
58 | return count; |
59 | }; |
59 | }; |
60 | 60 | ||
61 | static int set_mode(struct drm_device *dev, struct drm_connector *connector, |
61 | static int set_mode(struct drm_device *dev, struct drm_connector *connector, |
62 | struct drm_crtc *crtc, videomode_t *reqmode, bool strict) |
62 | struct drm_crtc *crtc, videomode_t *reqmode, bool strict) |
63 | { |
63 | { |
64 | struct drm_i915_private *dev_priv = dev->dev_private; |
64 | struct drm_i915_private *dev_priv = dev->dev_private; |
65 | 65 | ||
66 | struct drm_mode_config *config = &dev->mode_config; |
66 | struct drm_mode_config *config = &dev->mode_config; |
67 | struct drm_display_mode *mode = NULL, *tmpmode; |
67 | struct drm_display_mode *mode = NULL, *tmpmode; |
68 | struct drm_connector *tmpc; |
68 | struct drm_connector *tmpc; |
69 | struct drm_framebuffer *fb = NULL; |
69 | struct drm_framebuffer *fb = NULL; |
70 | struct drm_mode_set set; |
70 | struct drm_mode_set set; |
71 | const char *con_name; |
71 | const char *con_name; |
72 | unsigned hdisplay, vdisplay; |
72 | unsigned hdisplay, vdisplay; |
73 | int stride; |
73 | int stride; |
74 | int ret; |
74 | int ret; |
75 | 75 | ||
76 | ENTER(); |
- | |
77 | - | ||
78 | drm_modeset_lock_all(dev); |
76 | drm_modeset_lock_all(dev); |
79 | 77 | ||
80 | list_for_each_entry(tmpc, &dev->mode_config.connector_list, head) |
78 | list_for_each_entry(tmpc, &dev->mode_config.connector_list, head) |
81 | { |
79 | { |
82 | const struct drm_connector_funcs *f = tmpc->funcs; |
80 | const struct drm_connector_funcs *f = tmpc->funcs; |
83 | if(tmpc == connector) |
81 | if(tmpc == connector) |
84 | continue; |
82 | continue; |
85 | f->dpms(tmpc, DRM_MODE_DPMS_OFF); |
83 | f->dpms(tmpc, DRM_MODE_DPMS_OFF); |
86 | }; |
84 | }; |
87 | 85 | ||
88 | list_for_each_entry(tmpmode, &connector->modes, head) |
86 | list_for_each_entry(tmpmode, &connector->modes, head) |
89 | { |
87 | { |
90 | if( (tmpmode->hdisplay == reqmode->width) && |
88 | if( (tmpmode->hdisplay == reqmode->width) && |
91 | (tmpmode->vdisplay == reqmode->height) && |
89 | (tmpmode->vdisplay == reqmode->height) && |
92 | (drm_mode_vrefresh(tmpmode) == reqmode->freq) ) |
90 | (drm_mode_vrefresh(tmpmode) == reqmode->freq) ) |
93 | { |
91 | { |
94 | mode = tmpmode; |
92 | mode = tmpmode; |
95 | goto do_set; |
93 | goto do_set; |
96 | } |
94 | } |
97 | }; |
95 | }; |
98 | 96 | ||
99 | if( (mode == NULL) && (strict == false) ) |
97 | if( (mode == NULL) && (strict == false) ) |
100 | { |
98 | { |
101 | list_for_each_entry(tmpmode, &connector->modes, head) |
99 | list_for_each_entry(tmpmode, &connector->modes, head) |
102 | { |
100 | { |
103 | if( (tmpmode->hdisplay == reqmode->width) && |
101 | if( (tmpmode->hdisplay == reqmode->width) && |
104 | (tmpmode->vdisplay == reqmode->height) ) |
102 | (tmpmode->vdisplay == reqmode->height) ) |
105 | { |
103 | { |
106 | mode = tmpmode; |
104 | mode = tmpmode; |
107 | goto do_set; |
105 | goto do_set; |
108 | } |
106 | } |
109 | }; |
107 | }; |
110 | }; |
108 | }; |
111 | 109 | ||
112 | DRM_ERROR("%s failed\n", __FUNCTION__); |
110 | DRM_ERROR("%s failed\n", __FUNCTION__); |
113 | 111 | ||
114 | return -1; |
112 | return -1; |
115 | 113 | ||
116 | do_set: |
114 | do_set: |
117 | 115 | ||
118 | 116 | ||
119 | con_name = connector->name; |
117 | con_name = connector->name; |
120 | 118 | ||
121 | char con_edid[128]; |
119 | char con_edid[128]; |
122 | 120 | ||
123 | memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
121 | memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
124 | DRM_DEBUG_KMS("Manufacturer: %s Model %x Serial Number %u\n", |
122 | DRM_DEBUG_KMS("Manufacturer: %s Model %x Serial Number %u\n", |
125 | manufacturer_name(con_edid + 0x08), |
123 | manufacturer_name(con_edid + 0x08), |
126 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
124 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
127 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
125 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
128 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
126 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
129 | 127 | ||
130 | DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s\n", |
128 | DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s\n", |
131 | reqmode->width, reqmode->height, crtc->base.id, |
129 | reqmode->width, reqmode->height, crtc->base.id, |
132 | con_name); |
130 | con_name); |
133 | 131 | ||
134 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
132 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
135 | 133 | ||
136 | hdisplay = mode->hdisplay; |
134 | hdisplay = mode->hdisplay; |
137 | vdisplay = mode->vdisplay; |
135 | vdisplay = mode->vdisplay; |
138 | 136 | ||
139 | // if (crtc->invert_dimensions) |
137 | // if (crtc->invert_dimensions) |
140 | // swap(hdisplay, vdisplay); |
138 | // swap(hdisplay, vdisplay); |
141 | 139 | ||
142 | fb = crtc->primary->fb; |
140 | fb = crtc->primary->fb; |
143 | if(fb == NULL) |
141 | if(fb == NULL) |
144 | fb = main_framebuffer; |
142 | fb = main_framebuffer; |
145 | 143 | ||
146 | fb->width = reqmode->width; |
144 | fb->width = reqmode->width; |
147 | fb->height = reqmode->height; |
145 | fb->height = reqmode->height; |
148 | 146 | ||
149 | main_fb_obj->tiling_mode = I915_TILING_X; |
147 | main_fb_obj->tiling_mode = I915_TILING_X; |
150 | 148 | ||
151 | if( main_fb_obj->tiling_mode == I915_TILING_X) |
149 | if( main_fb_obj->tiling_mode == I915_TILING_X) |
152 | { |
150 | { |
153 | if(IS_GEN3(dev)) |
151 | if(IS_GEN3(dev)) |
154 | for (stride = 512; stride < reqmode->width * 4; stride <<= 1); |
152 | for (stride = 512; stride < reqmode->width * 4; stride <<= 1); |
155 | else |
153 | else |
156 | stride = ALIGN(reqmode->width * 4, 512); |
154 | stride = ALIGN(reqmode->width * 4, 512); |
157 | } |
155 | } |
158 | else |
156 | else |
159 | { |
157 | { |
160 | stride = ALIGN(reqmode->width * 4, 64); |
158 | stride = ALIGN(reqmode->width * 4, 64); |
161 | } |
159 | } |
162 | 160 | ||
163 | fb->pitches[0] = |
161 | fb->pitches[0] = |
164 | fb->pitches[1] = |
162 | fb->pitches[1] = |
165 | fb->pitches[2] = |
163 | fb->pitches[2] = |
166 | fb->pitches[3] = stride; |
164 | fb->pitches[3] = stride; |
167 | 165 | ||
168 | main_fb_obj->stride = stride; |
166 | main_fb_obj->stride = stride; |
169 | 167 | ||
170 | fb->bits_per_pixel = 32; |
168 | fb->bits_per_pixel = 32; |
171 | fb->depth = 24; |
169 | fb->depth = 24; |
172 | 170 | ||
173 | crtc->enabled = true; |
171 | crtc->enabled = true; |
174 | os_display->crtc = crtc; |
172 | os_display->crtc = crtc; |
175 | 173 | ||
176 | i915_gem_object_put_fence(main_fb_obj); |
174 | i915_gem_object_put_fence(main_fb_obj); |
177 | 175 | ||
178 | printf("fb:%p %dx%dx pitch %d format %x\n", |
176 | printf("fb:%p %dx%dx pitch %d format %x\n", |
179 | fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); |
177 | fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); |
180 | 178 | ||
181 | set.crtc = crtc; |
179 | set.crtc = crtc; |
182 | set.x = 0; |
180 | set.x = 0; |
183 | set.y = 0; |
181 | set.y = 0; |
184 | set.mode = mode; |
182 | set.mode = mode; |
185 | set.connectors = &connector; |
183 | set.connectors = &connector; |
186 | set.num_connectors = 1; |
184 | set.num_connectors = 1; |
187 | set.fb = fb; |
185 | set.fb = fb; |
188 | 186 | ||
189 | ret = drm_mode_set_config_internal(&set); |
187 | ret = drm_mode_set_config_internal(&set); |
190 | 188 | ||
191 | if ( !ret ) |
189 | if ( !ret ) |
192 | { |
190 | { |
193 | os_display->width = fb->width; |
191 | os_display->width = fb->width; |
194 | os_display->height = fb->height; |
192 | os_display->height = fb->height; |
195 | os_display->vrefresh = drm_mode_vrefresh(mode); |
193 | os_display->vrefresh = drm_mode_vrefresh(mode); |
196 | 194 | ||
197 | sysSetScreen(fb->width, fb->height, fb->pitches[0]); |
195 | sysSetScreen(fb->width, fb->height, fb->pitches[0]); |
198 | 196 | ||
199 | DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", |
197 | DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", |
200 | fb->width, fb->height, fb->pitches[0]); |
198 | fb->width, fb->height, fb->pitches[0]); |
201 | } |
199 | } |
202 | else |
200 | else |
203 | DRM_ERROR("failed to set mode %d_%d on crtc %p\n", |
201 | DRM_ERROR("failed to set mode %d_%d on crtc %p\n", |
204 | fb->width, fb->height, crtc); |
202 | fb->width, fb->height, crtc); |
205 | 203 | ||
206 | drm_modeset_unlock_all(dev); |
204 | drm_modeset_unlock_all(dev); |
207 | 205 | ||
208 | LEAVE(); |
- | |
209 | - | ||
210 | return ret; |
206 | return ret; |
211 | } |
207 | } |
212 | 208 | ||
213 | static int set_mode_ex(struct drm_device *dev, |
209 | static int set_mode_ex(struct drm_device *dev, |
214 | struct drm_connector *connector, struct drm_display_mode *mode) |
210 | struct drm_connector *connector, struct drm_display_mode *mode) |
215 | { |
211 | { |
216 | struct drm_i915_private *dev_priv = dev->dev_private; |
212 | struct drm_i915_private *dev_priv = dev->dev_private; |
217 | struct drm_connector *tmpc; |
213 | struct drm_connector *tmpc; |
218 | struct drm_mode_config *config = &dev->mode_config; |
214 | struct drm_mode_config *config = &dev->mode_config; |
219 | struct drm_framebuffer *fb = NULL; |
215 | struct drm_framebuffer *fb = NULL; |
220 | struct drm_mode_set set; |
216 | struct drm_mode_set set; |
221 | char con_edid[128]; |
217 | char con_edid[128]; |
222 | int stride; |
218 | int stride; |
223 | int ret; |
219 | int ret; |
224 | 220 | ||
225 | ENTER(); |
- | |
226 | - | ||
227 | drm_modeset_lock_all(dev); |
221 | drm_modeset_lock_all(dev); |
228 | 222 | ||
229 | list_for_each_entry(tmpc, &dev->mode_config.connector_list, head) |
223 | list_for_each_entry(tmpc, &dev->mode_config.connector_list, head) |
230 | { |
224 | { |
231 | const struct drm_connector_funcs *f = tmpc->funcs; |
225 | const struct drm_connector_funcs *f = tmpc->funcs; |
232 | if(tmpc == connector) |
226 | if(tmpc == connector) |
233 | continue; |
227 | continue; |
234 | f->dpms(tmpc, DRM_MODE_DPMS_OFF); |
228 | f->dpms(tmpc, DRM_MODE_DPMS_OFF); |
235 | }; |
229 | }; |
236 | 230 | ||
237 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
231 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
238 | 232 | ||
239 | fb = connector->encoder->crtc->primary->fb; |
233 | fb = connector->encoder->crtc->primary->fb; |
240 | if(fb == NULL) |
234 | if(fb == NULL) |
241 | fb = main_framebuffer; |
235 | fb = main_framebuffer; |
242 | 236 | ||
243 | fb->width = mode->hdisplay; |
237 | fb->width = mode->hdisplay; |
244 | fb->height = mode->vdisplay;; |
238 | fb->height = mode->vdisplay;; |
245 | 239 | ||
246 | main_fb_obj->tiling_mode = I915_TILING_X; |
240 | main_fb_obj->tiling_mode = I915_TILING_X; |
247 | 241 | ||
248 | if( main_fb_obj->tiling_mode == I915_TILING_X) |
242 | if( main_fb_obj->tiling_mode == I915_TILING_X) |
249 | { |
243 | { |
250 | if(IS_GEN3(dev)) |
244 | if(IS_GEN3(dev)) |
251 | for (stride = 512; stride < mode->hdisplay * 4; stride <<= 1); |
245 | for (stride = 512; stride < mode->hdisplay * 4; stride <<= 1); |
252 | else |
246 | else |
253 | stride = ALIGN(mode->hdisplay * 4, 512); |
247 | stride = ALIGN(mode->hdisplay * 4, 512); |
254 | } |
248 | } |
255 | else |
249 | else |
256 | { |
250 | { |
257 | stride = ALIGN(mode->hdisplay * 4, 64); |
251 | stride = ALIGN(mode->hdisplay * 4, 64); |
258 | } |
252 | } |
259 | 253 | ||
260 | fb->pitches[0] = |
254 | fb->pitches[0] = |
261 | fb->pitches[1] = |
255 | fb->pitches[1] = |
262 | fb->pitches[2] = |
256 | fb->pitches[2] = |
263 | fb->pitches[3] = stride; |
257 | fb->pitches[3] = stride; |
264 | 258 | ||
265 | main_fb_obj->stride = stride; |
259 | main_fb_obj->stride = stride; |
266 | 260 | ||
267 | fb->bits_per_pixel = 32; |
261 | fb->bits_per_pixel = 32; |
268 | fb->depth = 24; |
262 | fb->depth = 24; |
269 | 263 | ||
270 | connector->encoder->crtc->enabled = true; |
264 | connector->encoder->crtc->enabled = true; |
271 | 265 | ||
272 | i915_gem_object_put_fence(main_fb_obj); |
266 | i915_gem_object_put_fence(main_fb_obj); |
273 | 267 | ||
274 | memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
268 | memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
275 | DRM_DEBUG_KMS("set mode %dx%d: crtc %d connector %s\n" |
269 | DRM_DEBUG_KMS("set mode %dx%d: crtc %d connector %s\n" |
276 | "monitor: %s model %x serial number %u\n", |
270 | "monitor: %s model %x serial number %u\n", |
277 | fb->width, fb->height, |
271 | fb->width, fb->height, |
278 | connector->encoder->crtc->base.id, connector->name, |
272 | connector->encoder->crtc->base.id, connector->name, |
279 | manufacturer_name(con_edid + 0x08), |
273 | manufacturer_name(con_edid + 0x08), |
280 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
274 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
281 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
275 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
282 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
276 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
283 | 277 | ||
284 | DRM_DEBUG_KMS("use framebuffer %p %dx%d pitch %d format %x\n", |
278 | DRM_DEBUG_KMS("use framebuffer %p %dx%d pitch %d format %x\n", |
285 | fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); |
279 | fb,fb->width,fb->height,fb->pitches[0],fb->pixel_format); |
286 | 280 | ||
287 | set.crtc = connector->encoder->crtc; |
281 | set.crtc = connector->encoder->crtc; |
288 | set.x = 0; |
282 | set.x = 0; |
289 | set.y = 0; |
283 | set.y = 0; |
290 | set.mode = mode; |
284 | set.mode = mode; |
291 | set.connectors = &connector; |
285 | set.connectors = &connector; |
292 | set.num_connectors = 1; |
286 | set.num_connectors = 1; |
293 | set.fb = fb; |
287 | set.fb = fb; |
294 | 288 | ||
295 | ret = drm_mode_set_config_internal(&set); |
289 | ret = drm_mode_set_config_internal(&set); |
296 | if ( !ret ) |
290 | if ( !ret ) |
297 | { |
291 | { |
298 | struct drm_crtc *crtc = os_display->crtc; |
292 | struct drm_crtc *crtc = os_display->crtc; |
299 | 293 | ||
300 | os_display->width = fb->width; |
294 | os_display->width = fb->width; |
301 | os_display->height = fb->height; |
295 | os_display->height = fb->height; |
302 | os_display->vrefresh = drm_mode_vrefresh(mode); |
296 | os_display->vrefresh = drm_mode_vrefresh(mode); |
303 | 297 | ||
304 | sysSetScreen(fb->width, fb->height, fb->pitches[0]); |
298 | sysSetScreen(fb->width, fb->height, fb->pitches[0]); |
305 | 299 | ||
306 | os_display->connector = connector; |
300 | os_display->connector = connector; |
307 | os_display->crtc = connector->encoder->crtc; |
301 | os_display->crtc = connector->encoder->crtc; |
308 | os_display->supported_modes = count_connector_modes(connector); |
302 | os_display->supported_modes = count_connector_modes(connector); |
309 | 303 | ||
310 | crtc->cursor_x = os_display->width/2; |
304 | crtc->cursor_x = os_display->width/2; |
311 | crtc->cursor_y = os_display->height/2; |
305 | crtc->cursor_y = os_display->height/2; |
312 | 306 | ||
313 | select_cursor_kms(os_display->cursor); |
307 | select_cursor_kms(os_display->cursor); |
314 | 308 | ||
315 | DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", |
309 | DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", |
316 | fb->width, fb->height, fb->pitches[0]); |
310 | fb->width, fb->height, fb->pitches[0]); |
317 | } |
311 | } |
318 | else |
312 | else |
319 | DRM_ERROR(" failed to set mode %d_%d on crtc %p\n", |
313 | DRM_ERROR(" failed to set mode %d_%d on crtc %p\n", |
320 | fb->width, fb->height, connector->encoder->crtc); |
314 | fb->width, fb->height, connector->encoder->crtc); |
321 | 315 | ||
322 | drm_modeset_unlock_all(dev); |
316 | drm_modeset_unlock_all(dev); |
323 | 317 | ||
324 | LEAVE(); |
- | |
325 | - | ||
326 | return ret; |
318 | return ret; |
327 | } |
319 | } |
328 | 320 | ||
329 | static int set_cmdline_mode(struct drm_device *dev, struct drm_connector *connector) |
321 | static int set_cmdline_mode(struct drm_device *dev, struct drm_connector *connector) |
330 | { |
322 | { |
331 | struct drm_display_mode *mode; |
323 | struct drm_display_mode *mode; |
332 | int retval; |
324 | int retval; |
333 | 325 | ||
334 | mode = drm_mode_create_from_cmdline_mode(dev, &connector->cmdline_mode); |
326 | mode = drm_mode_create_from_cmdline_mode(dev, &connector->cmdline_mode); |
335 | if(mode == NULL) |
327 | if(mode == NULL) |
336 | return EINVAL; |
328 | return EINVAL; |
337 | 329 | ||
338 | retval = set_mode_ex(dev, connector, mode); |
330 | retval = set_mode_ex(dev, connector, mode); |
339 | 331 | ||
340 | drm_mode_destroy(dev, mode); |
332 | drm_mode_destroy(dev, mode); |
341 | return retval; |
333 | return retval; |
342 | }; |
334 | }; |
343 | 335 | ||
344 | static struct drm_crtc *get_possible_crtc(struct drm_device *dev, struct drm_encoder *encoder) |
336 | static struct drm_crtc *get_possible_crtc(struct drm_device *dev, struct drm_encoder *encoder) |
345 | { |
337 | { |
346 | struct drm_crtc *tmp_crtc; |
338 | struct drm_crtc *tmp_crtc; |
347 | int crtc_mask = 1; |
339 | int crtc_mask = 1; |
348 | 340 | ||
349 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) |
341 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) |
350 | { |
342 | { |
351 | if (encoder->possible_crtcs & crtc_mask) |
343 | if (encoder->possible_crtcs & crtc_mask) |
352 | { |
344 | { |
353 | encoder->crtc = tmp_crtc; |
345 | encoder->crtc = tmp_crtc; |
354 | DRM_DEBUG_KMS("use CRTC %p ID %d\n", tmp_crtc, tmp_crtc->base.id); |
346 | DRM_DEBUG_KMS("use CRTC %p ID %d\n", tmp_crtc, tmp_crtc->base.id); |
355 | return tmp_crtc; |
347 | return tmp_crtc; |
356 | }; |
348 | }; |
357 | crtc_mask <<= 1; |
349 | crtc_mask <<= 1; |
358 | }; |
350 | }; |
359 | return NULL; |
351 | return NULL; |
360 | }; |
352 | }; |
361 | 353 | ||
362 | static int check_connector(struct drm_device *dev, struct drm_connector *connector) |
354 | static int check_connector(struct drm_device *dev, struct drm_connector *connector) |
363 | { |
355 | { |
364 | const struct drm_connector_helper_funcs *connector_funcs; |
356 | const struct drm_connector_helper_funcs *connector_funcs; |
365 | struct drm_encoder *encoder; |
357 | struct drm_encoder *encoder; |
366 | struct drm_crtc *crtc; |
358 | struct drm_crtc *crtc; |
367 | 359 | ||
368 | if( connector->status != connector_status_connected) |
360 | if( connector->status != connector_status_connected) |
369 | return -EINVAL; |
361 | return -EINVAL; |
370 | 362 | ||
371 | encoder = connector->encoder; |
363 | encoder = connector->encoder; |
372 | 364 | ||
373 | if(encoder == NULL) |
365 | if(encoder == NULL) |
374 | { |
366 | { |
375 | connector_funcs = connector->helper_private; |
367 | connector_funcs = connector->helper_private; |
376 | encoder = connector_funcs->best_encoder(connector); |
368 | encoder = connector_funcs->best_encoder(connector); |
377 | 369 | ||
378 | if( encoder == NULL) |
370 | if( encoder == NULL) |
379 | { |
371 | { |
380 | DRM_DEBUG_KMS("CONNECTOR %s ID: %d no active encoders\n", |
372 | DRM_DEBUG_KMS("CONNECTOR %s ID: %d no active encoders\n", |
381 | connector->name, connector->base.id); |
373 | connector->name, connector->base.id); |
382 | return -EINVAL; |
374 | return -EINVAL; |
383 | }; |
375 | }; |
384 | } |
376 | } |
385 | 377 | ||
386 | crtc = encoder->crtc; |
378 | crtc = encoder->crtc; |
387 | if(crtc == NULL) |
379 | if(crtc == NULL) |
388 | crtc = get_possible_crtc(dev, encoder); |
380 | crtc = get_possible_crtc(dev, encoder); |
389 | 381 | ||
390 | if(crtc != NULL) |
382 | if(crtc != NULL) |
391 | { |
383 | { |
392 | encoder->crtc = crtc; |
384 | encoder->crtc = crtc; |
393 | return 0; |
385 | return 0; |
394 | } |
386 | } |
395 | else |
387 | else |
396 | DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id); |
388 | DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id); |
397 | return -EINVAL; |
389 | return -EINVAL; |
398 | } |
390 | } |
399 | 391 | ||
400 | static struct drm_connector* get_cmdline_connector(struct drm_device *dev, const char *cmdline) |
392 | static struct drm_connector* get_cmdline_connector(struct drm_device *dev, const char *cmdline) |
401 | { |
393 | { |
402 | struct drm_connector *connector; |
394 | struct drm_connector *connector; |
403 | 395 | ||
404 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
396 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
405 | { |
397 | { |
406 | int name_len = __builtin_strlen(connector->name); |
398 | int name_len = __builtin_strlen(connector->name); |
407 | 399 | ||
408 | if (name_len == 0) |
400 | if (name_len == 0) |
409 | continue; |
401 | continue; |
410 | 402 | ||
411 | if (__builtin_strncmp(connector->name, cmdline, name_len)) |
403 | if (__builtin_strncmp(connector->name, cmdline, name_len)) |
412 | continue; |
404 | continue; |
413 | 405 | ||
414 | if(check_connector(dev, connector) == 0) |
406 | if(check_connector(dev, connector) == 0) |
415 | return connector; |
407 | return connector; |
416 | } |
408 | } |
417 | return NULL; |
409 | return NULL; |
418 | } |
410 | } |
419 | 411 | ||
420 | 412 | ||
421 | static int choose_config(struct drm_device *dev, struct drm_connector **boot_connector, |
413 | static int choose_config(struct drm_device *dev, struct drm_connector **boot_connector, |
422 | struct drm_crtc **boot_crtc) |
414 | struct drm_crtc **boot_crtc) |
423 | { |
415 | { |
424 | const struct drm_connector_helper_funcs *connector_funcs; |
416 | struct drm_connector *connector; |
425 | struct drm_connector *connector = NULL; |
- | |
426 | struct drm_encoder *encoder = NULL; |
417 | |
427 | struct drm_crtc *crtc = NULL; |
- | |
428 | - | ||
429 | if((i915.cmdline_mode != NULL) && (*i915.cmdline_mode != 0)) |
418 | if((i915.cmdline_mode != NULL) && (*i915.cmdline_mode != 0)) |
430 | { |
419 | { |
431 | connector = get_cmdline_connector(dev, i915.cmdline_mode); |
420 | connector = get_cmdline_connector(dev, i915.cmdline_mode); |
432 | if(connector != NULL) |
421 | if(connector != NULL) |
433 | { |
422 | { |
434 | *boot_connector = connector; |
423 | *boot_connector = connector; |
435 | *boot_crtc = connector->encoder->crtc; |
424 | *boot_crtc = connector->encoder->crtc; |
436 | return 0; |
425 | return 0; |
437 | } |
426 | } |
438 | } |
427 | } |
439 | 428 | ||
440 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
429 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
441 | { |
430 | { |
442 | if(check_connector(dev, connector) == 0) |
431 | if(check_connector(dev, connector) == 0) |
443 | { |
432 | { |
444 | *boot_connector = connector; |
433 | *boot_connector = connector; |
445 | *boot_crtc = connector->encoder->crtc; |
434 | *boot_crtc = connector->encoder->crtc; |
446 | return 0; |
435 | return 0; |
447 | }; |
436 | }; |
448 | }; |
437 | }; |
449 | 438 | ||
450 | return -ENOENT; |
439 | return -ENOENT; |
451 | }; |
440 | }; |
452 | 441 | ||
- | 442 | ||
453 | static int get_boot_mode(struct drm_connector *connector, videomode_t *usermode) |
443 | static int get_boot_mode(struct drm_connector *connector, videomode_t *usermode) |
454 | { |
444 | { |
455 | struct drm_display_mode *mode; |
445 | struct drm_display_mode *mode; |
456 | 446 | ||
457 | list_for_each_entry(mode, &connector->modes, head) |
447 | list_for_each_entry(mode, &connector->modes, head) |
458 | { |
448 | { |
459 | if( os_display->width == mode->hdisplay && |
449 | if( os_display->width == mode->hdisplay && |
460 | os_display->height == mode->vdisplay && |
450 | os_display->height == mode->vdisplay && |
461 | drm_mode_vrefresh(mode) == 60) |
451 | drm_mode_vrefresh(mode) == 60) |
462 | { |
452 | { |
463 | usermode->width = os_display->width; |
453 | usermode->width = os_display->width; |
464 | usermode->height = os_display->height; |
454 | usermode->height = os_display->height; |
465 | usermode->freq = 60; |
455 | usermode->freq = 60; |
466 | return 1; |
456 | return 1; |
467 | } |
457 | } |
468 | } |
458 | } |
469 | return 0; |
459 | return 0; |
470 | } |
460 | } |
471 | 461 | ||
472 | int init_display_kms(struct drm_device *dev, videomode_t *usermode) |
462 | int init_display_kms(struct drm_device *dev, videomode_t *usermode) |
473 | { |
463 | { |
474 | struct drm_connector_helper_funcs *connector_funcs; |
464 | struct drm_connector_helper_funcs *connector_funcs; |
475 | struct drm_connector *connector = NULL; |
465 | struct drm_connector *connector = NULL; |
476 | struct drm_crtc *crtc = NULL; |
466 | struct drm_crtc *crtc = NULL; |
477 | struct drm_framebuffer *fb; |
467 | struct drm_framebuffer *fb; |
478 | 468 | ||
479 | cursor_t *cursor; |
469 | cursor_t *cursor; |
480 | u32 ifl; |
470 | u32 ifl; |
481 | int ret; |
471 | int ret; |
482 | 472 | ||
483 | ENTER(); |
- | |
484 | - | ||
485 | mutex_lock(&dev->mode_config.mutex); |
473 | mutex_lock(&dev->mode_config.mutex); |
486 | ret = choose_config(dev, &connector, &crtc); |
474 | ret = choose_config(dev, &connector, &crtc); |
487 | if(ret) |
475 | if(ret) |
488 | { |
476 | { |
489 | mutex_unlock(&dev->mode_config.mutex); |
477 | mutex_unlock(&dev->mode_config.mutex); |
490 | DRM_DEBUG_KMS("No active connectors!\n"); |
478 | DRM_DEBUG_KMS("No active connectors!\n"); |
491 | return -1; |
479 | return -1; |
492 | }; |
480 | }; |
493 | 481 | ||
494 | mutex_lock(&dev->object_name_lock); |
482 | mutex_lock(&dev->object_name_lock); |
495 | idr_preload(GFP_KERNEL); |
483 | idr_preload(GFP_KERNEL); |
496 | 484 | ||
497 | if (!main_fb_obj->base.name) { |
485 | if (!main_fb_obj->base.name) { |
498 | ret = idr_alloc(&dev->object_name_idr, &main_fb_obj->base, 1, 0, GFP_NOWAIT); |
486 | ret = idr_alloc(&dev->object_name_idr, &main_fb_obj->base, 1, 0, GFP_NOWAIT); |
499 | 487 | ||
500 | main_fb_obj->base.name = ret; |
488 | main_fb_obj->base.name = ret; |
501 | main_fb_obj->base.handle_count++; |
489 | main_fb_obj->base.handle_count++; |
502 | DRM_DEBUG_KMS("%s allocate fb name %d\n", __FUNCTION__, main_fb_obj->base.name ); |
490 | DRM_DEBUG_KMS("%s allocate fb name %d\n", __FUNCTION__, main_fb_obj->base.name ); |
503 | } |
491 | } |
504 | 492 | ||
505 | idr_preload_end(); |
493 | idr_preload_end(); |
506 | mutex_unlock(&dev->object_name_lock); |
494 | mutex_unlock(&dev->object_name_lock); |
507 | 495 | ||
508 | os_display = GetDisplay(); |
496 | os_display = GetDisplay(); |
509 | os_display->ddev = dev; |
497 | os_display->ddev = dev; |
510 | os_display->connector = connector; |
498 | os_display->connector = connector; |
511 | os_display->crtc = crtc; |
499 | os_display->crtc = crtc; |
512 | os_display->supported_modes = count_connector_modes(connector); |
500 | os_display->supported_modes = count_connector_modes(connector); |
513 | mutex_unlock(&dev->mode_config.mutex); |
501 | mutex_unlock(&dev->mode_config.mutex); |
514 | 502 | ||
515 | mutex_init(&cursor_lock); |
503 | mutex_init(&cursor_lock); |
516 | mutex_lock(&dev->struct_mutex); |
504 | mutex_lock(&dev->struct_mutex); |
517 | 505 | ||
518 | ifl = safe_cli(); |
506 | ifl = safe_cli(); |
519 | { |
507 | { |
520 | list_for_each_entry(cursor, &os_display->cursors, list) |
508 | list_for_each_entry(cursor, &os_display->cursors, list) |
521 | { |
509 | { |
522 | init_cursor(cursor); |
510 | init_cursor(cursor); |
523 | }; |
511 | }; |
524 | 512 | ||
525 | os_display->restore_cursor(0,0); |
513 | os_display->restore_cursor(0,0); |
526 | os_display->init_cursor = init_cursor; |
514 | os_display->init_cursor = init_cursor; |
527 | os_display->select_cursor = select_cursor_kms; |
515 | os_display->select_cursor = select_cursor_kms; |
528 | os_display->show_cursor = NULL; |
516 | os_display->show_cursor = NULL; |
529 | os_display->move_cursor = move_cursor_kms; |
517 | os_display->move_cursor = move_cursor_kms; |
530 | os_display->restore_cursor = restore_cursor; |
518 | os_display->restore_cursor = restore_cursor; |
531 | os_display->disable_mouse = disable_mouse; |
519 | os_display->disable_mouse = disable_mouse; |
532 | 520 | ||
533 | crtc->cursor_x = os_display->width/2; |
521 | crtc->cursor_x = os_display->width/2; |
534 | crtc->cursor_y = os_display->height/2; |
522 | crtc->cursor_y = os_display->height/2; |
535 | 523 | ||
536 | select_cursor_kms(os_display->cursor); |
524 | select_cursor_kms(os_display->cursor); |
537 | }; |
525 | }; |
538 | safe_sti(ifl); |
526 | safe_sti(ifl); |
539 | 527 | ||
540 | mutex_unlock(&dev->struct_mutex); |
528 | mutex_unlock(&dev->struct_mutex); |
541 | 529 | ||
542 | ret = -1; |
530 | ret = -1; |
543 | 531 | ||
544 | if(connector->cmdline_mode.specified == true) |
532 | if(connector->cmdline_mode.specified == true) |
545 | ret = set_cmdline_mode(dev, connector); |
533 | ret = set_cmdline_mode(dev, connector); |
546 | 534 | ||
547 | if(ret !=0) |
535 | if(ret !=0) |
548 | { |
536 | { |
549 | mutex_lock(&dev->mode_config.mutex); |
537 | mutex_lock(&dev->mode_config.mutex); |
550 | 538 | ||
551 | if( (usermode->width == 0) || |
539 | if( (usermode->width == 0) || |
552 | (usermode->height == 0)) |
540 | (usermode->height == 0)) |
553 | { |
541 | { |
554 | if( !get_boot_mode(connector, usermode)) |
542 | if( !get_boot_mode(connector, usermode)) |
555 | { |
543 | { |
556 | struct drm_display_mode *mode; |
544 | struct drm_display_mode *mode; |
557 | 545 | ||
558 | mode = list_entry(connector->modes.next, typeof(*mode), head); |
546 | mode = list_entry(connector->modes.next, typeof(*mode), head); |
559 | usermode->width = mode->hdisplay; |
547 | usermode->width = mode->hdisplay; |
560 | usermode->height = mode->vdisplay; |
548 | usermode->height = mode->vdisplay; |
561 | usermode->freq = drm_mode_vrefresh(mode); |
549 | usermode->freq = drm_mode_vrefresh(mode); |
562 | }; |
550 | }; |
563 | }; |
551 | }; |
564 | mutex_unlock(&dev->mode_config.mutex); |
552 | mutex_unlock(&dev->mode_config.mutex); |
565 | 553 | ||
566 | set_mode(dev, os_display->connector, os_display->crtc, usermode, false); |
554 | set_mode(dev, os_display->connector, os_display->crtc, usermode, false); |
567 | }; |
555 | }; |
568 | 556 | ||
569 | #ifdef __HWA__ |
557 | #ifdef __HWA__ |
570 | err = init_bitmaps(); |
558 | err = init_bitmaps(); |
571 | #endif |
559 | #endif |
572 | 560 | ||
573 | LEAVE(); |
- | |
574 | - | ||
575 | return ret; |
561 | return ret; |
576 | }; |
562 | }; |
577 | 563 | ||
578 | 564 | ||
579 | int set_cmdline_mode_ext(struct drm_device *dev, const char *cmdline) |
565 | int set_cmdline_mode_ext(struct drm_device *dev, const char *cmdline) |
580 | { |
566 | { |
581 | struct drm_connector_helper_funcs *connector_funcs; |
567 | struct drm_connector_helper_funcs *connector_funcs; |
582 | struct drm_connector *connector; |
568 | struct drm_connector *connector; |
583 | struct drm_cmdline_mode cmd_mode; |
569 | struct drm_cmdline_mode cmd_mode = {0}; |
584 | struct drm_display_mode *mode; |
570 | struct drm_display_mode *mode; |
585 | char *mode_option; |
571 | char *mode_option; |
586 | int retval = 0; |
572 | int retval = 0; |
587 | char con_edid[128]; |
573 | char con_edid[128]; |
588 | 574 | ||
589 | ENTER(); |
- | |
590 | if((cmdline == NULL) || (*cmdline == 0)) |
575 | if((cmdline == NULL) || (*cmdline == 0)) |
591 | return EINVAL; |
576 | return EINVAL; |
592 | 577 | ||
593 | mutex_lock(&dev->mode_config.mutex); |
578 | mutex_lock(&dev->mode_config.mutex); |
594 | connector = get_cmdline_connector(dev, cmdline); |
579 | connector = get_cmdline_connector(dev, cmdline); |
595 | mutex_unlock(&dev->mode_config.mutex); |
580 | mutex_unlock(&dev->mode_config.mutex); |
596 | 581 | ||
597 | if(connector == NULL) |
582 | if(connector == NULL) |
598 | return EINVAL; |
583 | return EINVAL; |
599 | 584 | ||
600 | mode_option = __builtin_strchr(cmdline,':'); |
585 | mode_option = __builtin_strchr(cmdline,':'); |
601 | if(mode_option == NULL) |
586 | if(mode_option == NULL) |
602 | return EINVAL; |
587 | return EINVAL; |
603 | 588 | ||
604 | mode_option++; |
589 | mode_option++; |
605 | 590 | ||
606 | __builtin_memset(&cmd_mode, 0, sizeof(cmd_mode)); |
- | |
607 | - | ||
608 | if( !drm_mode_parse_command_line_for_connector(mode_option, connector, &cmd_mode)) |
591 | if( !drm_mode_parse_command_line_for_connector(mode_option, connector, &cmd_mode)) |
609 | return EINVAL; |
592 | return EINVAL; |
610 | 593 | ||
611 | DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", |
594 | DRM_DEBUG_KMS("cmdline mode for connector %s %dx%d@%dHz%s%s%s\n", |
612 | connector->name, |
595 | connector->name, |
613 | cmd_mode.xres, cmd_mode.yres, |
596 | cmd_mode.xres, cmd_mode.yres, |
614 | cmd_mode.refresh_specified ? cmd_mode.refresh : 60, |
597 | cmd_mode.refresh_specified ? cmd_mode.refresh : 60, |
615 | cmd_mode.rb ? " reduced blanking" : "", |
598 | cmd_mode.rb ? " reduced blanking" : "", |
616 | cmd_mode.margins ? " with margins" : "", |
599 | cmd_mode.margins ? " with margins" : "", |
617 | cmd_mode.interlace ? " interlaced" : ""); |
600 | cmd_mode.interlace ? " interlaced" : ""); |
618 | 601 | ||
619 | mode = drm_mode_create_from_cmdline_mode(dev, &cmd_mode); |
602 | mode = drm_mode_create_from_cmdline_mode(dev, &cmd_mode); |
620 | if(mode == NULL) |
603 | if(mode == NULL) |
621 | return EINVAL; |
604 | return EINVAL; |
622 | 605 | ||
623 | memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
606 | memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
624 | DRM_DEBUG_KMS("connector: %s monitor: %s model %x serial number %u\n", |
607 | DRM_DEBUG_KMS("connector: %s monitor: %s model %x serial number %u\n", |
625 | connector->name, |
608 | connector->name, |
626 | manufacturer_name(con_edid + 0x08), |
609 | manufacturer_name(con_edid + 0x08), |
627 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
610 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
628 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
611 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
629 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
612 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
630 | 613 | ||
631 | retval = set_mode_ex(dev, connector, mode); |
614 | retval = set_mode_ex(dev, connector, mode); |
632 | 615 | ||
633 | drm_mode_destroy(dev, mode); |
616 | drm_mode_destroy(dev, mode); |
634 | 617 | ||
635 | LEAVE(); |
- | |
636 | return retval; |
618 | return retval; |
637 | } |
619 | } |
638 | 620 | ||
- | 621 | void list_connectors(struct drm_device *dev) |
|
- | 622 | { |
|
- | 623 | struct drm_connector *connector; |
|
- | 624 | char con_edid[128]; |
|
- | 625 | ||
- | 626 | mutex_lock(&dev->mode_config.mutex); |
|
- | 627 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
|
- | 628 | { |
|
- | 629 | if( connector->status != connector_status_connected) |
|
- | 630 | continue; |
|
- | 631 | ||
- | 632 | memcpy(con_edid, connector->edid_blob_ptr->data, 128); |
|
- | 633 | ||
- | 634 | if(connector == os_display->connector) |
|
- | 635 | { |
|
- | 636 | printf("%s mode %dx%d connected %s model %x serial number %u\n", |
|
- | 637 | connector->name, os_display->width, os_display->height, |
|
- | 638 | manufacturer_name(con_edid + 0x08), |
|
- | 639 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
|
- | 640 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
|
- | 641 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
|
- | 642 | continue; |
|
- | 643 | } |
|
- | 644 | else |
|
- | 645 | { |
|
- | 646 | printf("%s connected: %s model %x serial number %u\n", |
|
- | 647 | connector->name, manufacturer_name(con_edid + 0x08), |
|
- | 648 | (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), |
|
- | 649 | (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) |
|
- | 650 | + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); |
|
- | 651 | } |
|
- | 652 | }; |
|
- | 653 | mutex_unlock(&dev->mode_config.mutex); |
|
- | 654 | } |
|
- | 655 | ||
- | 656 | int list_connector_modes(struct drm_device *dev, const char* name) |
|
- | 657 | { |
|
- | 658 | struct drm_connector *connector; |
|
- | 659 | struct drm_display_mode *drmmode; |
|
- | 660 | ||
- | 661 | mutex_lock(&dev->mode_config.mutex); |
|
- | 662 | ||
- | 663 | connector = get_cmdline_connector(dev, name); |
|
- | 664 | if(connector == NULL) |
|
- | 665 | { |
|
- | 666 | mutex_unlock(&dev->mode_config.mutex); |
|
- | 667 | return EINVAL; |
|
- | 668 | }; |
|
- | 669 | ||
- | 670 | printf("connector %s probed modes :\n", connector->name); |
|
- | 671 | ||
- | 672 | list_for_each_entry(drmmode, &connector->modes, head) |
|
- | 673 | { |
|
- | 674 | printf("%dx%d@%d\n", drmmode->hdisplay, drmmode->vdisplay, drm_mode_vrefresh(drmmode)); |
|
- | 675 | }; |
|
- | 676 | ||
- | 677 | mutex_unlock(&dev->mode_config.mutex); |
|
- | 678 | return 0; |
|
- | 679 | }; |
|
- | 680 | ||
639 | int get_videomodes(videomode_t *mode, int *count) |
681 | int get_videomodes(videomode_t *mode, int *count) |
640 | { |
682 | { |
641 | int err = -1; |
683 | int err = -1; |
642 | 684 | ||
643 | // dbgprintf("mode %x count %d\n", mode, *count); |
685 | // dbgprintf("mode %x count %d\n", mode, *count); |
644 | 686 | ||
645 | if( *count == 0 ) |
687 | if( *count == 0 ) |
646 | { |
688 | { |
647 | *count = os_display->supported_modes; |
689 | *count = os_display->supported_modes; |
648 | err = 0; |
690 | err = 0; |
649 | } |
691 | } |
650 | else if( mode != NULL ) |
692 | else if( mode != NULL ) |
651 | { |
693 | { |
652 | struct drm_display_mode *drmmode; |
694 | struct drm_display_mode *drmmode; |
653 | int i = 0; |
695 | int i = 0; |
654 | 696 | ||
655 | if( *count > os_display->supported_modes) |
697 | if( *count > os_display->supported_modes) |
656 | *count = os_display->supported_modes; |
698 | *count = os_display->supported_modes; |
657 | 699 | ||
658 | list_for_each_entry(drmmode, &os_display->connector->modes, head) |
700 | list_for_each_entry(drmmode, &os_display->connector->modes, head) |
659 | { |
701 | { |
660 | if( i < *count) |
702 | if( i < *count) |
661 | { |
703 | { |
662 | mode->width = drmmode->hdisplay; |
704 | mode->width = drmmode->hdisplay; |
663 | mode->height = drmmode->vdisplay; |
705 | mode->height = drmmode->vdisplay; |
664 | mode->bpp = 32; |
706 | mode->bpp = 32; |
665 | mode->freq = drm_mode_vrefresh(drmmode); |
707 | mode->freq = drm_mode_vrefresh(drmmode); |
666 | i++; |
708 | i++; |
667 | mode++; |
709 | mode++; |
668 | } |
710 | } |
669 | else break; |
711 | else break; |
670 | }; |
712 | }; |
671 | *count = i; |
713 | *count = i; |
672 | err = 0; |
714 | err = 0; |
673 | }; |
715 | }; |
674 | return err; |
716 | return err; |
675 | }; |
717 | }; |
676 | 718 | ||
677 | int set_user_mode(videomode_t *mode) |
719 | int set_user_mode(videomode_t *mode) |
678 | { |
720 | { |
679 | 721 | ||
680 | // dbgprintf("width %d height %d vrefresh %d\n", |
722 | // dbgprintf("width %d height %d vrefresh %d\n", |
681 | // mode->width, mode->height, mode->freq); |
723 | // mode->width, mode->height, mode->freq); |
682 | 724 | ||
683 | if( (mode->width != 0) && |
725 | if( (mode->width != 0) && |
684 | (mode->height != 0) && |
726 | (mode->height != 0) && |
685 | (mode->freq != 0 ) && |
727 | (mode->freq != 0 ) && |
686 | ( (mode->width != os_display->width) || |
728 | ( (mode->width != os_display->width) || |
687 | (mode->height != os_display->height) || |
729 | (mode->height != os_display->height) || |
688 | (mode->freq != os_display->vrefresh) ) ) |
730 | (mode->freq != os_display->vrefresh) ) ) |
689 | { |
731 | { |
690 | return set_mode(os_display->ddev, os_display->connector, os_display->crtc, mode, true); |
732 | return set_mode(os_display->ddev, os_display->connector, os_display->crtc, mode, true); |
691 | }; |
733 | }; |
692 | 734 | ||
693 | return -1; |
735 | return -1; |
694 | }; |
736 | }; |
695 | 737 | ||
696 | void i915_dpms(struct drm_device *dev, int mode) |
738 | void i915_dpms(struct drm_device *dev, int mode) |
697 | { |
739 | { |
698 | const struct drm_connector_funcs *f = os_display->connector->funcs; |
740 | const struct drm_connector_funcs *f = os_display->connector->funcs; |
699 | 741 | ||
700 | f->dpms(os_display->connector, mode); |
742 | f->dpms(os_display->connector, mode); |
701 | }; |
743 | }; |
702 | 744 | ||
703 | void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor) |
745 | void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor) |
704 | { |
746 | { |
705 | struct drm_i915_gem_object *obj = cursor->cobj; |
747 | struct drm_i915_gem_object *obj = cursor->cobj; |
706 | list_del(&cursor->list); |
748 | list_del(&cursor->list); |
707 | 749 | ||
708 | i915_gem_object_ggtt_unpin(cursor->cobj); |
750 | i915_gem_object_ggtt_unpin(cursor->cobj); |
709 | 751 | ||
710 | mutex_lock(&main_device->struct_mutex); |
752 | mutex_lock(&main_device->struct_mutex); |
711 | drm_gem_object_unreference(&obj->base); |
753 | drm_gem_object_unreference(&obj->base); |
712 | mutex_unlock(&main_device->struct_mutex); |
754 | mutex_unlock(&main_device->struct_mutex); |
713 | 755 | ||
714 | __DestroyObject(cursor); |
756 | __DestroyObject(cursor); |
715 | }; |
757 | }; |
716 | 758 | ||
717 | int init_cursor(cursor_t *cursor) |
759 | int init_cursor(cursor_t *cursor) |
718 | { |
760 | { |
719 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
761 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
720 | struct drm_i915_gem_object *obj; |
762 | struct drm_i915_gem_object *obj; |
721 | uint32_t *bits; |
763 | uint32_t *bits; |
722 | uint32_t *src; |
764 | uint32_t *src; |
723 | void *mapped; |
765 | void *mapped; |
724 | 766 | ||
725 | int i,j; |
767 | int i,j; |
726 | int ret; |
768 | int ret; |
727 | 769 | ||
728 | if (dev_priv->info.cursor_needs_physical) |
770 | if (dev_priv->info.cursor_needs_physical) |
729 | { |
771 | { |
730 | bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8); |
772 | bits = (uint32_t*)KernelAlloc(KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*8); |
731 | if (unlikely(bits == NULL)) |
773 | if (unlikely(bits == NULL)) |
732 | return ENOMEM; |
774 | return ENOMEM; |
733 | cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits); |
775 | cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits); |
734 | } |
776 | } |
735 | else |
777 | else |
736 | { |
778 | { |
737 | obj = i915_gem_alloc_object(os_display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4); |
779 | obj = i915_gem_alloc_object(os_display->ddev, KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4); |
738 | if (unlikely(obj == NULL)) |
780 | if (unlikely(obj == NULL)) |
739 | return -ENOMEM; |
781 | return -ENOMEM; |
740 | 782 | ||
741 | ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL); |
783 | ret = i915_gem_object_ggtt_pin(obj, &i915_ggtt_view_normal, 128*1024, PIN_GLOBAL); |
742 | if (ret) { |
784 | if (ret) { |
743 | drm_gem_object_unreference(&obj->base); |
785 | drm_gem_object_unreference(&obj->base); |
744 | return ret; |
786 | return ret; |
745 | } |
787 | } |
746 | 788 | ||
747 | ret = i915_gem_object_set_to_gtt_domain(obj, true); |
789 | ret = i915_gem_object_set_to_gtt_domain(obj, true); |
748 | if (ret) |
790 | if (ret) |
749 | { |
791 | { |
750 | i915_gem_object_ggtt_unpin(obj); |
792 | i915_gem_object_ggtt_unpin(obj); |
751 | drm_gem_object_unreference(&obj->base); |
793 | drm_gem_object_unreference(&obj->base); |
752 | return ret; |
794 | return ret; |
753 | } |
795 | } |
754 | /* You don't need to worry about fragmentation issues. |
796 | /* You don't need to worry about fragmentation issues. |
755 | * GTT space is continuous. I guarantee it. */ |
797 | * GTT space is continuous. I guarantee it. */ |
756 | 798 | ||
757 | mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), |
799 | mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), |
758 | KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW); |
800 | KMS_CURSOR_WIDTH*KMS_CURSOR_HEIGHT*4, PG_SW); |
759 | 801 | ||
760 | if (unlikely(bits == NULL)) |
802 | if (unlikely(bits == NULL)) |
761 | { |
803 | { |
762 | i915_gem_object_ggtt_unpin(obj); |
804 | i915_gem_object_ggtt_unpin(obj); |
763 | drm_gem_object_unreference(&obj->base); |
805 | drm_gem_object_unreference(&obj->base); |
764 | return -ENOMEM; |
806 | return -ENOMEM; |
765 | }; |
807 | }; |
766 | cursor->cobj = obj; |
808 | cursor->cobj = obj; |
767 | }; |
809 | }; |
768 | 810 | ||
769 | src = cursor->data; |
811 | src = cursor->data; |
770 | 812 | ||
771 | for(i = 0; i < 32; i++) |
813 | for(i = 0; i < 32; i++) |
772 | { |
814 | { |
773 | for(j = 0; j < 32; j++) |
815 | for(j = 0; j < 32; j++) |
774 | *bits++ = *src++; |
816 | *bits++ = *src++; |
775 | for(j = 32; j < KMS_CURSOR_WIDTH; j++) |
817 | for(j = 32; j < KMS_CURSOR_WIDTH; j++) |
776 | *bits++ = 0; |
818 | *bits++ = 0; |
777 | } |
819 | } |
778 | for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++) |
820 | for(i = 0; i < KMS_CURSOR_WIDTH*(KMS_CURSOR_HEIGHT-32); i++) |
779 | *bits++ = 0; |
821 | *bits++ = 0; |
780 | 822 | ||
781 | FreeKernelSpace(mapped); |
823 | FreeKernelSpace(mapped); |
782 | 824 | ||
783 | // release old cursor |
825 | // release old cursor |
784 | 826 | ||
785 | KernelFree(cursor->data); |
827 | KernelFree(cursor->data); |
786 | 828 | ||
787 | cursor->data = bits; |
829 | cursor->data = bits; |
788 | 830 | ||
789 | cursor->header.destroy = destroy_cursor; |
831 | cursor->header.destroy = destroy_cursor; |
790 | 832 | ||
791 | return 0; |
833 | return 0; |
792 | } |
834 | } |
793 | 835 | ||
794 | 836 | ||
795 | void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) |
837 | void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) |
796 | { |
838 | { |
797 | struct drm_crtc *crtc = os_display->crtc; |
839 | struct drm_crtc *crtc = os_display->crtc; |
798 | struct drm_plane_state *cursor_state = crtc->cursor->state; |
840 | struct drm_plane_state *cursor_state = crtc->cursor->state; |
799 | 841 | ||
800 | x-= cursor->hot_x; |
842 | x-= cursor->hot_x; |
801 | y-= cursor->hot_y; |
843 | y-= cursor->hot_y; |
802 | 844 | ||
803 | crtc->cursor_x = x; |
845 | crtc->cursor_x = x; |
804 | crtc->cursor_y = y; |
846 | crtc->cursor_y = y; |
805 | 847 | ||
806 | cursor_state->crtc_x = x; |
848 | cursor_state->crtc_x = x; |
807 | cursor_state->crtc_y = y; |
849 | cursor_state->crtc_y = y; |
808 | 850 | ||
809 | intel_crtc_update_cursor(crtc, 1); |
851 | intel_crtc_update_cursor(crtc, 1); |
810 | 852 | ||
811 | }; |
853 | }; |
812 | 854 | ||
813 | cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) |
855 | cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) |
814 | { |
856 | { |
815 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
857 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
816 | struct drm_crtc *crtc = os_display->crtc; |
858 | struct drm_crtc *crtc = os_display->crtc; |
817 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
859 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
818 | 860 | ||
819 | cursor_t *old; |
861 | cursor_t *old; |
820 | 862 | ||
821 | old = os_display->cursor; |
863 | old = os_display->cursor; |
822 | 864 | ||
823 | mutex_lock(&cursor_lock); |
865 | mutex_lock(&cursor_lock); |
824 | 866 | ||
825 | os_display->cursor = cursor; |
867 | os_display->cursor = cursor; |
826 | 868 | ||
827 | if (!dev_priv->info.cursor_needs_physical) |
869 | if (!dev_priv->info.cursor_needs_physical) |
828 | intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj); |
870 | intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj); |
829 | else |
871 | else |
830 | intel_crtc->cursor_addr = (addr_t)cursor->cobj; |
872 | intel_crtc->cursor_addr = (addr_t)cursor->cobj; |
831 | 873 | ||
832 | intel_crtc->base.cursor->state->crtc_w = 64; |
874 | intel_crtc->base.cursor->state->crtc_w = 64; |
833 | intel_crtc->base.cursor->state->crtc_h = 64; |
875 | intel_crtc->base.cursor->state->crtc_h = 64; |
834 | intel_crtc->base.cursor->state->rotation = 0; |
876 | intel_crtc->base.cursor->state->rotation = 0; |
835 | mutex_unlock(&cursor_lock); |
877 | mutex_unlock(&cursor_lock); |
836 | 878 | ||
837 | move_cursor_kms(cursor, crtc->cursor_x, crtc->cursor_y); |
879 | move_cursor_kms(cursor, crtc->cursor_x, crtc->cursor_y); |
838 | return old; |
880 | return old; |
839 | }; |
881 | }; |
840 | 882 | ||
841 | int i915_fbinfo(struct drm_i915_fb_info *fb) |
883 | int i915_fbinfo(struct drm_i915_fb_info *fb) |
842 | { |
884 | { |
843 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
885 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
844 | struct intel_crtc *crtc = to_intel_crtc(os_display->crtc); |
886 | struct intel_crtc *crtc = to_intel_crtc(os_display->crtc); |
845 | struct drm_i915_gem_object *obj = get_fb_obj(); |
887 | struct drm_i915_gem_object *obj = get_fb_obj(); |
846 | 888 | ||
847 | fb->name = obj->base.name; |
889 | fb->name = obj->base.name; |
848 | fb->width = os_display->width; |
890 | fb->width = os_display->width; |
849 | fb->height = os_display->height; |
891 | fb->height = os_display->height; |
850 | fb->pitch = obj->stride; |
892 | fb->pitch = obj->stride; |
851 | fb->tiling = obj->tiling_mode; |
893 | fb->tiling = obj->tiling_mode; |
852 | fb->crtc = crtc->base.base.id; |
894 | fb->crtc = crtc->base.base.id; |
853 | fb->pipe = crtc->pipe; |
895 | fb->pipe = crtc->pipe; |
854 | 896 | ||
855 | return 0; |
897 | return 0; |
856 | } |
898 | } |
857 | 899 | ||
858 | 900 | ||
859 | typedef struct |
901 | typedef struct |
860 | { |
902 | { |
861 | int left; |
903 | int left; |
862 | int top; |
904 | int top; |
863 | int right; |
905 | int right; |
864 | int bottom; |
906 | int bottom; |
865 | }rect_t; |
907 | }rect_t; |
866 | 908 | ||
867 | 909 | ||
868 | #define CURRENT_TASK (0x80003000) |
910 | #define CURRENT_TASK (0x80003000) |
869 | 911 | ||
870 | void FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect"); |
912 | void FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect"); |
871 | 913 | ||
872 | int i915_mask_update(struct drm_device *dev, void *data, |
914 | int i915_mask_update(struct drm_device *dev, void *data, |
873 | struct drm_file *file) |
915 | struct drm_file *file) |
874 | { |
916 | { |
875 | struct drm_i915_mask *mask = data; |
917 | struct drm_i915_mask *mask = data; |
876 | struct drm_gem_object *obj; |
918 | struct drm_gem_object *obj; |
877 | static unsigned int mask_seqno[256]; |
919 | static unsigned int mask_seqno[256]; |
878 | rect_t winrc; |
920 | rect_t winrc; |
879 | u32 slot; |
921 | u32 slot; |
880 | int ret=0; |
922 | int ret=0; |
881 | 923 | ||
882 | obj = drm_gem_object_lookup(dev, file, mask->handle); |
924 | obj = drm_gem_object_lookup(dev, file, mask->handle); |
883 | if (obj == NULL) |
925 | if (obj == NULL) |
884 | return -ENOENT; |
926 | return -ENOENT; |
885 | 927 | ||
886 | if (!obj->filp) { |
928 | if (!obj->filp) { |
887 | drm_gem_object_unreference_unlocked(obj); |
929 | drm_gem_object_unreference_unlocked(obj); |
888 | return -EINVAL; |
930 | return -EINVAL; |
889 | } |
931 | } |
890 | 932 | ||
891 | GetWindowRect(&winrc); |
933 | GetWindowRect(&winrc); |
892 | { |
934 | { |
893 | // static warn_count; |
935 | // static warn_count; |
894 | 936 | ||
895 | mask->width = winrc.right - winrc.left + 1; |
937 | mask->width = winrc.right - winrc.left + 1; |
896 | mask->height = winrc.bottom - winrc.top + 1; |
938 | mask->height = winrc.bottom - winrc.top + 1; |
897 | mask->bo_pitch = (mask->width+15) & ~15; |
939 | mask->bo_pitch = (mask->width+15) & ~15; |
898 | 940 | ||
899 | #if 0 |
941 | #if 0 |
900 | if(warn_count < 1) |
942 | if(warn_count < 1) |
901 | { |
943 | { |
902 | printf("left %d top %d right %d bottom %d\n", |
944 | printf("left %d top %d right %d bottom %d\n", |
903 | winrc.left, winrc.top, winrc.right, winrc.bottom); |
945 | winrc.left, winrc.top, winrc.right, winrc.bottom); |
904 | printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_map); |
946 | printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_map); |
905 | warn_count++; |
947 | warn_count++; |
906 | }; |
948 | }; |
907 | #endif |
949 | #endif |
908 | 950 | ||
909 | }; |
951 | }; |
910 | 952 | ||
911 | 953 | ||
912 | slot = *((u8*)CURRENT_TASK); |
954 | slot = *((u8*)CURRENT_TASK); |
913 | 955 | ||
914 | if( mask_seqno[slot] != os_display->mask_seqno) |
956 | if( mask_seqno[slot] != os_display->mask_seqno) |
915 | { |
957 | { |
916 | u8* src_offset; |
958 | u8* src_offset; |
917 | u8* dst_offset; |
959 | u8* dst_offset; |
918 | u32 ifl; |
960 | u32 ifl; |
919 | 961 | ||
920 | ret = i915_mutex_lock_interruptible(dev); |
962 | ret = i915_mutex_lock_interruptible(dev); |
921 | if (ret) |
963 | if (ret) |
922 | goto err1; |
964 | goto err1; |
923 | 965 | ||
924 | ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true); |
966 | ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true); |
925 | if(ret != 0 ) |
967 | if(ret != 0 ) |
926 | { |
968 | { |
927 | dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__); |
969 | dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__); |
928 | goto err2; |
970 | goto err2; |
929 | }; |
971 | }; |
930 | 972 | ||
931 | // printf("width %d height %d\n", winrc.right, winrc.bottom); |
973 | // printf("width %d height %d\n", winrc.right, winrc.bottom); |
932 | 974 | ||
933 | // slot = 0x01; |
975 | // slot = 0x01; |
934 | 976 | ||
935 | src_offset = os_display->win_map; |
977 | src_offset = os_display->win_map; |
936 | src_offset+= winrc.top*os_display->width + winrc.left; |
978 | src_offset+= winrc.top*os_display->width + winrc.left; |
937 | 979 | ||
938 | dst_offset = (u8*)mask->bo_map; |
980 | dst_offset = (u8*)mask->bo_map; |
939 | 981 | ||
940 | u32 tmp_h = mask->height; |
982 | u32 tmp_h = mask->height; |
941 | 983 | ||
942 | ifl = safe_cli(); |
984 | ifl = safe_cli(); |
943 | { |
985 | { |
944 | mask_seqno[slot] = os_display->mask_seqno; |
986 | mask_seqno[slot] = os_display->mask_seqno; |
945 | 987 | ||
946 | slot|= (slot<<8)|(slot<<16)|(slot<<24); |
988 | slot|= (slot<<8)|(slot<<16)|(slot<<24); |
947 | 989 | ||
948 | __asm__ __volatile__ ( |
990 | __asm__ __volatile__ ( |
949 | "movd %[slot], %%xmm6 \n" |
991 | "movd %[slot], %%xmm6 \n" |
950 | "punpckldq %%xmm6, %%xmm6 \n" |
992 | "punpckldq %%xmm6, %%xmm6 \n" |
951 | "punpcklqdq %%xmm6, %%xmm6 \n" |
993 | "punpcklqdq %%xmm6, %%xmm6 \n" |
952 | :: [slot] "m" (slot) |
994 | :: [slot] "m" (slot) |
953 | :"xmm6"); |
995 | :"xmm6"); |
954 | 996 | ||
955 | while( tmp_h--) |
997 | while( tmp_h--) |
956 | { |
998 | { |
957 | int tmp_w = mask->width; |
999 | int tmp_w = mask->width; |
958 | 1000 | ||
959 | u8* tmp_src = src_offset; |
1001 | u8* tmp_src = src_offset; |
960 | u8* tmp_dst = dst_offset; |
1002 | u8* tmp_dst = dst_offset; |
961 | 1003 | ||
962 | src_offset+= os_display->width; |
1004 | src_offset+= os_display->width; |
963 | dst_offset+= mask->bo_pitch; |
1005 | dst_offset+= mask->bo_pitch; |
964 | 1006 | ||
965 | while(tmp_w >= 64) |
1007 | while(tmp_w >= 64) |
966 | { |
1008 | { |
967 | __asm__ __volatile__ ( |
1009 | __asm__ __volatile__ ( |
968 | "movdqu (%0), %%xmm0 \n" |
1010 | "movdqu (%0), %%xmm0 \n" |
969 | "movdqu 16(%0), %%xmm1 \n" |
1011 | "movdqu 16(%0), %%xmm1 \n" |
970 | "movdqu 32(%0), %%xmm2 \n" |
1012 | "movdqu 32(%0), %%xmm2 \n" |
971 | "movdqu 48(%0), %%xmm3 \n" |
1013 | "movdqu 48(%0), %%xmm3 \n" |
972 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1014 | "pcmpeqb %%xmm6, %%xmm0 \n" |
973 | "pcmpeqb %%xmm6, %%xmm1 \n" |
1015 | "pcmpeqb %%xmm6, %%xmm1 \n" |
974 | "pcmpeqb %%xmm6, %%xmm2 \n" |
1016 | "pcmpeqb %%xmm6, %%xmm2 \n" |
975 | "pcmpeqb %%xmm6, %%xmm3 \n" |
1017 | "pcmpeqb %%xmm6, %%xmm3 \n" |
976 | "movdqa %%xmm0, (%%edi) \n" |
1018 | "movdqa %%xmm0, (%%edi) \n" |
977 | "movdqa %%xmm1, 16(%%edi) \n" |
1019 | "movdqa %%xmm1, 16(%%edi) \n" |
978 | "movdqa %%xmm2, 32(%%edi) \n" |
1020 | "movdqa %%xmm2, 32(%%edi) \n" |
979 | "movdqa %%xmm3, 48(%%edi) \n" |
1021 | "movdqa %%xmm3, 48(%%edi) \n" |
980 | 1022 | ||
981 | :: "r" (tmp_src), "D" (tmp_dst) |
1023 | :: "r" (tmp_src), "D" (tmp_dst) |
982 | :"xmm0","xmm1","xmm2","xmm3"); |
1024 | :"xmm0","xmm1","xmm2","xmm3"); |
983 | tmp_w -= 64; |
1025 | tmp_w -= 64; |
984 | tmp_src += 64; |
1026 | tmp_src += 64; |
985 | tmp_dst += 64; |
1027 | tmp_dst += 64; |
986 | } |
1028 | } |
987 | 1029 | ||
988 | if( tmp_w >= 32 ) |
1030 | if( tmp_w >= 32 ) |
989 | { |
1031 | { |
990 | __asm__ __volatile__ ( |
1032 | __asm__ __volatile__ ( |
991 | "movdqu (%0), %%xmm0 \n" |
1033 | "movdqu (%0), %%xmm0 \n" |
992 | "movdqu 16(%0), %%xmm1 \n" |
1034 | "movdqu 16(%0), %%xmm1 \n" |
993 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1035 | "pcmpeqb %%xmm6, %%xmm0 \n" |
994 | "pcmpeqb %%xmm6, %%xmm1 \n" |
1036 | "pcmpeqb %%xmm6, %%xmm1 \n" |
995 | "movdqa %%xmm0, (%%edi) \n" |
1037 | "movdqa %%xmm0, (%%edi) \n" |
996 | "movdqa %%xmm1, 16(%%edi) \n" |
1038 | "movdqa %%xmm1, 16(%%edi) \n" |
997 | 1039 | ||
998 | :: "r" (tmp_src), "D" (tmp_dst) |
1040 | :: "r" (tmp_src), "D" (tmp_dst) |
999 | :"xmm0","xmm1"); |
1041 | :"xmm0","xmm1"); |
1000 | tmp_w -= 32; |
1042 | tmp_w -= 32; |
1001 | tmp_src += 32; |
1043 | tmp_src += 32; |
1002 | tmp_dst += 32; |
1044 | tmp_dst += 32; |
1003 | } |
1045 | } |
1004 | 1046 | ||
1005 | if( tmp_w >= 16 ) |
1047 | if( tmp_w >= 16 ) |
1006 | { |
1048 | { |
1007 | __asm__ __volatile__ ( |
1049 | __asm__ __volatile__ ( |
1008 | "movdqu (%0), %%xmm0 \n" |
1050 | "movdqu (%0), %%xmm0 \n" |
1009 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1051 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1010 | "movdqa %%xmm0, (%%edi) \n" |
1052 | "movdqa %%xmm0, (%%edi) \n" |
1011 | :: "r" (tmp_src), "D" (tmp_dst) |
1053 | :: "r" (tmp_src), "D" (tmp_dst) |
1012 | :"xmm0"); |
1054 | :"xmm0"); |
1013 | tmp_w -= 16; |
1055 | tmp_w -= 16; |
1014 | tmp_src += 16; |
1056 | tmp_src += 16; |
1015 | tmp_dst += 16; |
1057 | tmp_dst += 16; |
1016 | } |
1058 | } |
1017 | 1059 | ||
1018 | if( tmp_w >= 8 ) |
1060 | if( tmp_w >= 8 ) |
1019 | { |
1061 | { |
1020 | __asm__ __volatile__ ( |
1062 | __asm__ __volatile__ ( |
1021 | "movq (%0), %%xmm0 \n" |
1063 | "movq (%0), %%xmm0 \n" |
1022 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1064 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1023 | "movq %%xmm0, (%%edi) \n" |
1065 | "movq %%xmm0, (%%edi) \n" |
1024 | :: "r" (tmp_src), "D" (tmp_dst) |
1066 | :: "r" (tmp_src), "D" (tmp_dst) |
1025 | :"xmm0"); |
1067 | :"xmm0"); |
1026 | tmp_w -= 8; |
1068 | tmp_w -= 8; |
1027 | tmp_src += 8; |
1069 | tmp_src += 8; |
1028 | tmp_dst += 8; |
1070 | tmp_dst += 8; |
1029 | } |
1071 | } |
1030 | if( tmp_w >= 4 ) |
1072 | if( tmp_w >= 4 ) |
1031 | { |
1073 | { |
1032 | __asm__ __volatile__ ( |
1074 | __asm__ __volatile__ ( |
1033 | "movd (%0), %%xmm0 \n" |
1075 | "movd (%0), %%xmm0 \n" |
1034 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1076 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1035 | "movd %%xmm0, (%%edi) \n" |
1077 | "movd %%xmm0, (%%edi) \n" |
1036 | :: "r" (tmp_src), "D" (tmp_dst) |
1078 | :: "r" (tmp_src), "D" (tmp_dst) |
1037 | :"xmm0"); |
1079 | :"xmm0"); |
1038 | tmp_w -= 4; |
1080 | tmp_w -= 4; |
1039 | tmp_src += 4; |
1081 | tmp_src += 4; |
1040 | tmp_dst += 4; |
1082 | tmp_dst += 4; |
1041 | } |
1083 | } |
1042 | while(tmp_w--) |
1084 | while(tmp_w--) |
1043 | *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00; |
1085 | *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00; |
1044 | }; |
1086 | }; |
1045 | }; |
1087 | }; |
1046 | safe_sti(ifl); |
1088 | safe_sti(ifl); |
1047 | 1089 | ||
1048 | ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false); |
1090 | ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false); |
1049 | } |
1091 | } |
1050 | 1092 | ||
1051 | err2: |
1093 | err2: |
1052 | mutex_unlock(&dev->struct_mutex); |
1094 | mutex_unlock(&dev->struct_mutex); |
1053 | err1: |
1095 | err1: |
1054 | drm_gem_object_unreference(obj); |
1096 | drm_gem_object_unreference(obj); |
1055 | 1097 | ||
1056 | return ret; |
1098 | return ret; |
1057 | } |
1099 | } |
1058 | 1100 | ||
1059 | int i915_mask_update_ex(struct drm_device *dev, void *data, |
1101 | int i915_mask_update_ex(struct drm_device *dev, void *data, |
1060 | struct drm_file *file) |
1102 | struct drm_file *file) |
1061 | { |
1103 | { |
1062 | struct drm_i915_mask_update *mask = data; |
1104 | struct drm_i915_mask_update *mask = data; |
1063 | struct drm_gem_object *obj; |
1105 | struct drm_gem_object *obj; |
1064 | static unsigned int mask_seqno[256]; |
1106 | static unsigned int mask_seqno[256]; |
1065 | static warn_count; |
1107 | static warn_count; |
1066 | 1108 | ||
1067 | rect_t win; |
1109 | rect_t win; |
1068 | u32 winw,winh; |
1110 | u32 winw,winh; |
1069 | u32 ml,mt,mr,mb; |
1111 | u32 ml,mt,mr,mb; |
1070 | u32 slot; |
1112 | u32 slot; |
1071 | int ret = 0; |
1113 | int ret = 0; |
1072 | slot = *((u8*)CURRENT_TASK); |
1114 | slot = *((u8*)CURRENT_TASK); |
1073 | 1115 | ||
1074 | if( mask->forced == 0 && mask_seqno[slot] == os_display->mask_seqno) |
1116 | if( mask->forced == 0 && mask_seqno[slot] == os_display->mask_seqno) |
1075 | return 0; |
1117 | return 0; |
1076 | 1118 | ||
1077 | if(mask->forced) |
1119 | if(mask->forced) |
1078 | memset((void*)mask->bo_map,0,mask->width * mask->height); |
1120 | memset((void*)mask->bo_map,0,mask->width * mask->height); |
1079 | 1121 | ||
1080 | GetWindowRect(&win); |
1122 | GetWindowRect(&win); |
1081 | win.right+= 1; |
1123 | win.right+= 1; |
1082 | win.bottom+= 1; |
1124 | win.bottom+= 1; |
1083 | 1125 | ||
1084 | winw = win.right - win.left; |
1126 | winw = win.right - win.left; |
1085 | winh = win.bottom - win.top; |
1127 | winh = win.bottom - win.top; |
1086 | 1128 | ||
1087 | if(mask->dx >= winw || |
1129 | if(mask->dx >= winw || |
1088 | mask->dy >= winh) |
1130 | mask->dy >= winh) |
1089 | return 1; |
1131 | return 1; |
1090 | 1132 | ||
1091 | ml = win.left + mask->dx; |
1133 | ml = win.left + mask->dx; |
1092 | mt = win.top + mask->dy; |
1134 | mt = win.top + mask->dy; |
1093 | mr = ml + mask->width; |
1135 | mr = ml + mask->width; |
1094 | mb = mt + mask->height; |
1136 | mb = mt + mask->height; |
1095 | 1137 | ||
1096 | if( ml >= win.right || mt >= win.bottom || |
1138 | if( ml >= win.right || mt >= win.bottom || |
1097 | mr < win.left || mb < win.top ) |
1139 | mr < win.left || mb < win.top ) |
1098 | return 1; |
1140 | return 1; |
1099 | 1141 | ||
1100 | if( mr > win.right ) |
1142 | if( mr > win.right ) |
1101 | mr = win.right; |
1143 | mr = win.right; |
1102 | 1144 | ||
1103 | if( mb > win.bottom ) |
1145 | if( mb > win.bottom ) |
1104 | mb = win.bottom; |
1146 | mb = win.bottom; |
1105 | 1147 | ||
1106 | mask->width = mr - ml; |
1148 | mask->width = mr - ml; |
1107 | mask->height = mb - mt; |
1149 | mask->height = mb - mt; |
1108 | 1150 | ||
1109 | if( mask->width == 0 || |
1151 | if( mask->width == 0 || |
1110 | mask->height== 0 ) |
1152 | mask->height== 0 ) |
1111 | return 1; |
1153 | return 1; |
1112 | 1154 | ||
1113 | obj = drm_gem_object_lookup(dev, file, mask->handle); |
1155 | obj = drm_gem_object_lookup(dev, file, mask->handle); |
1114 | if (obj == NULL) |
1156 | if (obj == NULL) |
1115 | return -ENOENT; |
1157 | return -ENOENT; |
1116 | 1158 | ||
1117 | if (!obj->filp) { |
1159 | if (!obj->filp) { |
1118 | drm_gem_object_unreference_unlocked(obj); |
1160 | drm_gem_object_unreference_unlocked(obj); |
1119 | return -EINVAL; |
1161 | return -EINVAL; |
1120 | } |
1162 | } |
1121 | 1163 | ||
1122 | #if 0 |
1164 | #if 0 |
1123 | if(warn_count < 100) |
1165 | if(warn_count < 100) |
1124 | { |
1166 | { |
1125 | printf("left %d top %d right %d bottom %d\n", |
1167 | printf("left %d top %d right %d bottom %d\n", |
1126 | ml, mt, mr, mb); |
1168 | ml, mt, mr, mb); |
1127 | warn_count++; |
1169 | warn_count++; |
1128 | }; |
1170 | }; |
1129 | #endif |
1171 | #endif |
1130 | 1172 | ||
1131 | 1173 | ||
1132 | #if 1 |
1174 | #if 1 |
1133 | 1175 | ||
1134 | { |
1176 | { |
1135 | u8* src_offset; |
1177 | u8* src_offset; |
1136 | u8* dst_offset; |
1178 | u8* dst_offset; |
1137 | u32 ifl; |
1179 | u32 ifl; |
1138 | 1180 | ||
1139 | ret = i915_mutex_lock_interruptible(dev); |
1181 | ret = i915_mutex_lock_interruptible(dev); |
1140 | if (ret) |
1182 | if (ret) |
1141 | goto err1; |
1183 | goto err1; |
1142 | 1184 | ||
1143 | i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true); |
1185 | i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true); |
1144 | 1186 | ||
1145 | src_offset = os_display->win_map; |
1187 | src_offset = os_display->win_map; |
1146 | src_offset+= mt*os_display->width + ml; |
1188 | src_offset+= mt*os_display->width + ml; |
1147 | dst_offset = (u8*)mask->bo_map; |
1189 | dst_offset = (u8*)mask->bo_map; |
1148 | 1190 | ||
1149 | u32 tmp_h = mask->height; |
1191 | u32 tmp_h = mask->height; |
1150 | 1192 | ||
1151 | ifl = safe_cli(); |
1193 | ifl = safe_cli(); |
1152 | { |
1194 | { |
1153 | mask_seqno[slot] = os_display->mask_seqno; |
1195 | mask_seqno[slot] = os_display->mask_seqno; |
1154 | 1196 | ||
1155 | slot|= (slot<<8)|(slot<<16)|(slot<<24); |
1197 | slot|= (slot<<8)|(slot<<16)|(slot<<24); |
1156 | 1198 | ||
1157 | __asm__ __volatile__ ( |
1199 | __asm__ __volatile__ ( |
1158 | "movd %[slot], %%xmm6 \n" |
1200 | "movd %[slot], %%xmm6 \n" |
1159 | "punpckldq %%xmm6, %%xmm6 \n" |
1201 | "punpckldq %%xmm6, %%xmm6 \n" |
1160 | "punpcklqdq %%xmm6, %%xmm6 \n" |
1202 | "punpcklqdq %%xmm6, %%xmm6 \n" |
1161 | :: [slot] "m" (slot) |
1203 | :: [slot] "m" (slot) |
1162 | :"xmm6"); |
1204 | :"xmm6"); |
1163 | 1205 | ||
1164 | while( tmp_h--) |
1206 | while( tmp_h--) |
1165 | { |
1207 | { |
1166 | int tmp_w = mask->width; |
1208 | int tmp_w = mask->width; |
1167 | 1209 | ||
1168 | u8* tmp_src = src_offset; |
1210 | u8* tmp_src = src_offset; |
1169 | u8* tmp_dst = dst_offset; |
1211 | u8* tmp_dst = dst_offset; |
1170 | 1212 | ||
1171 | src_offset+= os_display->width; |
1213 | src_offset+= os_display->width; |
1172 | dst_offset+= mask->bo_pitch; |
1214 | dst_offset+= mask->bo_pitch; |
1173 | 1215 | ||
1174 | while(tmp_w >= 64) |
1216 | while(tmp_w >= 64) |
1175 | { |
1217 | { |
1176 | __asm__ __volatile__ ( |
1218 | __asm__ __volatile__ ( |
1177 | "movdqu (%0), %%xmm0 \n" |
1219 | "movdqu (%0), %%xmm0 \n" |
1178 | "movdqu 16(%0), %%xmm1 \n" |
1220 | "movdqu 16(%0), %%xmm1 \n" |
1179 | "movdqu 32(%0), %%xmm2 \n" |
1221 | "movdqu 32(%0), %%xmm2 \n" |
1180 | "movdqu 48(%0), %%xmm3 \n" |
1222 | "movdqu 48(%0), %%xmm3 \n" |
1181 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1223 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1182 | "pcmpeqb %%xmm6, %%xmm1 \n" |
1224 | "pcmpeqb %%xmm6, %%xmm1 \n" |
1183 | "pcmpeqb %%xmm6, %%xmm2 \n" |
1225 | "pcmpeqb %%xmm6, %%xmm2 \n" |
1184 | "pcmpeqb %%xmm6, %%xmm3 \n" |
1226 | "pcmpeqb %%xmm6, %%xmm3 \n" |
1185 | "movdqa %%xmm0, (%%edi) \n" |
1227 | "movdqa %%xmm0, (%%edi) \n" |
1186 | "movdqa %%xmm1, 16(%%edi) \n" |
1228 | "movdqa %%xmm1, 16(%%edi) \n" |
1187 | "movdqa %%xmm2, 32(%%edi) \n" |
1229 | "movdqa %%xmm2, 32(%%edi) \n" |
1188 | "movdqa %%xmm3, 48(%%edi) \n" |
1230 | "movdqa %%xmm3, 48(%%edi) \n" |
1189 | 1231 | ||
1190 | :: "r" (tmp_src), "D" (tmp_dst) |
1232 | :: "r" (tmp_src), "D" (tmp_dst) |
1191 | :"xmm0","xmm1","xmm2","xmm3"); |
1233 | :"xmm0","xmm1","xmm2","xmm3"); |
1192 | tmp_w -= 64; |
1234 | tmp_w -= 64; |
1193 | tmp_src += 64; |
1235 | tmp_src += 64; |
1194 | tmp_dst += 64; |
1236 | tmp_dst += 64; |
1195 | } |
1237 | } |
1196 | 1238 | ||
1197 | if( tmp_w >= 32 ) |
1239 | if( tmp_w >= 32 ) |
1198 | { |
1240 | { |
1199 | __asm__ __volatile__ ( |
1241 | __asm__ __volatile__ ( |
1200 | "movdqu (%0), %%xmm0 \n" |
1242 | "movdqu (%0), %%xmm0 \n" |
1201 | "movdqu 16(%0), %%xmm1 \n" |
1243 | "movdqu 16(%0), %%xmm1 \n" |
1202 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1244 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1203 | "pcmpeqb %%xmm6, %%xmm1 \n" |
1245 | "pcmpeqb %%xmm6, %%xmm1 \n" |
1204 | "movdqa %%xmm0, (%%edi) \n" |
1246 | "movdqa %%xmm0, (%%edi) \n" |
1205 | "movdqa %%xmm1, 16(%%edi) \n" |
1247 | "movdqa %%xmm1, 16(%%edi) \n" |
1206 | 1248 | ||
1207 | :: "r" (tmp_src), "D" (tmp_dst) |
1249 | :: "r" (tmp_src), "D" (tmp_dst) |
1208 | :"xmm0","xmm1"); |
1250 | :"xmm0","xmm1"); |
1209 | tmp_w -= 32; |
1251 | tmp_w -= 32; |
1210 | tmp_src += 32; |
1252 | tmp_src += 32; |
1211 | tmp_dst += 32; |
1253 | tmp_dst += 32; |
1212 | } |
1254 | } |
1213 | 1255 | ||
1214 | if( tmp_w >= 16 ) |
1256 | if( tmp_w >= 16 ) |
1215 | { |
1257 | { |
1216 | __asm__ __volatile__ ( |
1258 | __asm__ __volatile__ ( |
1217 | "movdqu (%0), %%xmm0 \n" |
1259 | "movdqu (%0), %%xmm0 \n" |
1218 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1260 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1219 | "movdqa %%xmm0, (%%edi) \n" |
1261 | "movdqa %%xmm0, (%%edi) \n" |
1220 | :: "r" (tmp_src), "D" (tmp_dst) |
1262 | :: "r" (tmp_src), "D" (tmp_dst) |
1221 | :"xmm0"); |
1263 | :"xmm0"); |
1222 | tmp_w -= 16; |
1264 | tmp_w -= 16; |
1223 | tmp_src += 16; |
1265 | tmp_src += 16; |
1224 | tmp_dst += 16; |
1266 | tmp_dst += 16; |
1225 | } |
1267 | } |
1226 | 1268 | ||
1227 | if( tmp_w >= 8 ) |
1269 | if( tmp_w >= 8 ) |
1228 | { |
1270 | { |
1229 | __asm__ __volatile__ ( |
1271 | __asm__ __volatile__ ( |
1230 | "movq (%0), %%xmm0 \n" |
1272 | "movq (%0), %%xmm0 \n" |
1231 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1273 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1232 | "movq %%xmm0, (%%edi) \n" |
1274 | "movq %%xmm0, (%%edi) \n" |
1233 | :: "r" (tmp_src), "D" (tmp_dst) |
1275 | :: "r" (tmp_src), "D" (tmp_dst) |
1234 | :"xmm0"); |
1276 | :"xmm0"); |
1235 | tmp_w -= 8; |
1277 | tmp_w -= 8; |
1236 | tmp_src += 8; |
1278 | tmp_src += 8; |
1237 | tmp_dst += 8; |
1279 | tmp_dst += 8; |
1238 | } |
1280 | } |
1239 | if( tmp_w >= 4 ) |
1281 | if( tmp_w >= 4 ) |
1240 | { |
1282 | { |
1241 | __asm__ __volatile__ ( |
1283 | __asm__ __volatile__ ( |
1242 | "movd (%0), %%xmm0 \n" |
1284 | "movd (%0), %%xmm0 \n" |
1243 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1285 | "pcmpeqb %%xmm6, %%xmm0 \n" |
1244 | "movd %%xmm0, (%%edi) \n" |
1286 | "movd %%xmm0, (%%edi) \n" |
1245 | :: "r" (tmp_src), "D" (tmp_dst) |
1287 | :: "r" (tmp_src), "D" (tmp_dst) |
1246 | :"xmm0"); |
1288 | :"xmm0"); |
1247 | tmp_w -= 4; |
1289 | tmp_w -= 4; |
1248 | tmp_src += 4; |
1290 | tmp_src += 4; |
1249 | tmp_dst += 4; |
1291 | tmp_dst += 4; |
1250 | } |
1292 | } |
1251 | while(tmp_w--) |
1293 | while(tmp_w--) |
1252 | *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00; |
1294 | *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00; |
1253 | }; |
1295 | }; |
1254 | }; |
1296 | }; |
1255 | safe_sti(ifl); |
1297 | safe_sti(ifl); |
1256 | 1298 | ||
1257 | i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false); |
1299 | i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false); |
1258 | } |
1300 | } |
1259 | #endif |
1301 | #endif |
1260 | 1302 | ||
1261 | err2: |
1303 | err2: |
1262 | mutex_unlock(&dev->struct_mutex); |
1304 | mutex_unlock(&dev->struct_mutex); |
1263 | err1: |
1305 | err1: |
1264 | drm_gem_object_unreference(obj); |
1306 | drm_gem_object_unreference(obj); |
1265 | 1307 | ||
1266 | return ret; |
1308 | return ret; |
1267 | } |
1309 | } |
1268 | 1310 | ||
1269 | 1311 | ||
1270 | 1312 | ||
1271 | 1313 | ||
1272 | #define NSEC_PER_SEC 1000000000L |
1314 | #define NSEC_PER_SEC 1000000000L |
1273 | 1315 | ||
1274 | void getrawmonotonic(struct timespec *ts) |
1316 | void getrawmonotonic(struct timespec *ts) |
1275 | { |
1317 | { |
1276 | u32 tmp = GetTimerTicks(); |
1318 | u32 tmp = GetTimerTicks(); |
1277 | 1319 | ||
1278 | ts->tv_sec = tmp/100; |
1320 | ts->tv_sec = tmp/100; |
1279 | ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000; |
1321 | ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000; |
1280 | } |
1322 | } |
1281 | 1323 | ||
1282 | void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) |
1324 | void prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) |
1283 | { |
1325 | { |
1284 | unsigned long flags; |
1326 | unsigned long flags; |
1285 | 1327 | ||
1286 | // wait->flags &= ~WQ_FLAG_EXCLUSIVE; |
1328 | // wait->flags &= ~WQ_FLAG_EXCLUSIVE; |
1287 | spin_lock_irqsave(&q->lock, flags); |
1329 | spin_lock_irqsave(&q->lock, flags); |
1288 | if (list_empty(&wait->task_list)) |
1330 | if (list_empty(&wait->task_list)) |
1289 | __add_wait_queue(q, wait); |
1331 | __add_wait_queue(q, wait); |
1290 | spin_unlock_irqrestore(&q->lock, flags); |
1332 | spin_unlock_irqrestore(&q->lock, flags); |
1291 | } |
1333 | } |
1292 | 1334 | ||
1293 | /** |
1335 | /** |
1294 | * finish_wait - clean up after waiting in a queue |
1336 | * finish_wait - clean up after waiting in a queue |
1295 | * @q: waitqueue waited on |
1337 | * @q: waitqueue waited on |
1296 | * @wait: wait descriptor |
1338 | * @wait: wait descriptor |
1297 | * |
1339 | * |
1298 | * Sets current thread back to running state and removes |
1340 | * Sets current thread back to running state and removes |
1299 | * the wait descriptor from the given waitqueue if still |
1341 | * the wait descriptor from the given waitqueue if still |
1300 | * queued. |
1342 | * queued. |
1301 | */ |
1343 | */ |
1302 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) |
1344 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) |
1303 | { |
1345 | { |
1304 | unsigned long flags; |
1346 | unsigned long flags; |
1305 | 1347 | ||
1306 | // __set_current_state(TASK_RUNNING); |
1348 | // __set_current_state(TASK_RUNNING); |
1307 | /* |
1349 | /* |
1308 | * We can check for list emptiness outside the lock |
1350 | * We can check for list emptiness outside the lock |
1309 | * IFF: |
1351 | * IFF: |
1310 | * - we use the "careful" check that verifies both |
1352 | * - we use the "careful" check that verifies both |
1311 | * the next and prev pointers, so that there cannot |
1353 | * the next and prev pointers, so that there cannot |
1312 | * be any half-pending updates in progress on other |
1354 | * be any half-pending updates in progress on other |
1313 | * CPU's that we haven't seen yet (and that might |
1355 | * CPU's that we haven't seen yet (and that might |
1314 | * still change the stack area. |
1356 | * still change the stack area. |
1315 | * and |
1357 | * and |
1316 | * - all other users take the lock (ie we can only |
1358 | * - all other users take the lock (ie we can only |
1317 | * have _one_ other CPU that looks at or modifies |
1359 | * have _one_ other CPU that looks at or modifies |
1318 | * the list). |
1360 | * the list). |
1319 | */ |
1361 | */ |
1320 | if (!list_empty_careful(&wait->task_list)) { |
1362 | if (!list_empty_careful(&wait->task_list)) { |
1321 | spin_lock_irqsave(&q->lock, flags); |
1363 | spin_lock_irqsave(&q->lock, flags); |
1322 | list_del_init(&wait->task_list); |
1364 | list_del_init(&wait->task_list); |
1323 | spin_unlock_irqrestore(&q->lock, flags); |
1365 | spin_unlock_irqrestore(&q->lock, flags); |
1324 | } |
1366 | } |
1325 | 1367 | ||
1326 | DestroyEvent(wait->evnt); |
1368 | DestroyEvent(wait->evnt); |
1327 | } |
1369 | } |
1328 | 1370 | ||
1329 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) |
1371 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) |
1330 | { |
1372 | { |
1331 | list_del_init(&wait->task_list); |
1373 | list_del_init(&wait->task_list); |
1332 | return 1; |
1374 | return 1; |
1333 | }24); |
1375 | }24); |
1334 | 1376 | ||
1335 | ><24); |
1377 | ><24); |
1336 | 1378 | ||
1337 | >16)|(slot<<24); |
1379 | >16)|(slot<<24); |
1338 | 1380 | ||
1339 | ><16)|(slot<<24); |
1381 | ><16)|(slot<<24); |
1340 | 1382 | ||
1341 | >8)|(slot<<16)|(slot<<24); |
1383 | >8)|(slot<<16)|(slot<<24); |
1342 | 1384 | ||
1343 | ><8)|(slot<<16)|(slot<<24); |
1385 | ><8)|(slot<<16)|(slot<<24); |
1344 | 1386 | ||
1345 | >>>>24); |
1387 | >>>>24); |
1346 | 1388 | ||
1347 | ><24); |
1389 | ><24); |
1348 | 1390 | ||
1349 | >16)|(slot<<24); |
1391 | >16)|(slot<<24); |
1350 | 1392 | ||
1351 | ><16)|(slot<<24); |
1393 | ><16)|(slot<<24); |
1352 | 1394 | ||
1353 | >8)|(slot<<16)|(slot<<24); |
1395 | >8)|(slot<<16)|(slot<<24); |
1354 | 1396 | ||
1355 | ><8)|(slot<<16)|(slot<<24); |
1397 | ><8)|(slot<<16)|(slot<<24); |
1356 | 1398 | ||
1357 | >>>>>>>><>><>><>><>=><=>><>><>><>><>=><=>>=><=>>><>><>><>><>><> |
1399 | >>>>>>>><>><>><>><>><>><>><>><>><>><>><>><>=><=>><>><>><>><>=><=>>=><=>>><>><>><>><>><> |