Rev 4389 | Rev 4557 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4389 | Rev 4398 | ||
---|---|---|---|
1 | #define iowrite32(v, addr) writel((v), (addr)) |
1 | #define iowrite32(v, addr) writel((v), (addr)) |
2 | 2 | ||
3 | #include "drmP.h" |
3 | #include "drmP.h" |
4 | #include "drm.h" |
4 | #include "drm.h" |
5 | #include "i915_drm.h" |
5 | #include "i915_drm.h" |
6 | #include "i915_drv.h" |
6 | #include "i915_drv.h" |
7 | #include "intel_drv.h" |
7 | #include "intel_drv.h" |
8 | 8 | ||
9 | #include |
9 | #include |
10 | #include |
10 | #include |
11 | #include |
11 | #include |
12 | #include |
12 | #include |
13 | #include |
13 | #include |
14 | 14 | ||
15 | #include |
15 | #include |
16 | 16 | ||
17 | #include "bitmap.h" |
17 | #include "bitmap.h" |
18 | 18 | ||
19 | typedef struct |
19 | typedef struct |
20 | { |
20 | { |
21 | kobj_t header; |
21 | kobj_t header; |
22 | 22 | ||
23 | uint32_t *data; |
23 | uint32_t *data; |
24 | uint32_t hot_x; |
24 | uint32_t hot_x; |
25 | uint32_t hot_y; |
25 | uint32_t hot_y; |
26 | 26 | ||
27 | struct list_head list; |
27 | struct list_head list; |
28 | struct drm_i915_gem_object *cobj; |
28 | struct drm_i915_gem_object *cobj; |
29 | }cursor_t; |
29 | }cursor_t; |
30 | 30 | ||
31 | #define CURSOR_WIDTH 64 |
31 | #define CURSOR_WIDTH 64 |
32 | #define CURSOR_HEIGHT 64 |
32 | #define CURSOR_HEIGHT 64 |
33 | 33 | ||
34 | 34 | ||
35 | struct tag_display |
35 | struct tag_display |
36 | { |
36 | { |
37 | int x; |
37 | int x; |
38 | int y; |
38 | int y; |
39 | int width; |
39 | int width; |
40 | int height; |
40 | int height; |
41 | int bpp; |
41 | int bpp; |
42 | int vrefresh; |
42 | int vrefresh; |
43 | int pitch; |
43 | int pitch; |
44 | int lfb; |
44 | int lfb; |
45 | 45 | ||
46 | int supported_modes; |
46 | int supported_modes; |
47 | struct drm_device *ddev; |
47 | struct drm_device *ddev; |
48 | struct drm_connector *connector; |
48 | struct drm_connector *connector; |
49 | struct drm_crtc *crtc; |
49 | struct drm_crtc *crtc; |
50 | 50 | ||
51 | struct list_head cursors; |
51 | struct list_head cursors; |
52 | 52 | ||
53 | cursor_t *cursor; |
53 | cursor_t *cursor; |
54 | int (*init_cursor)(cursor_t*); |
54 | int (*init_cursor)(cursor_t*); |
55 | cursor_t* (__stdcall *select_cursor)(cursor_t*); |
55 | cursor_t* (__stdcall *select_cursor)(cursor_t*); |
56 | void (*show_cursor)(int show); |
56 | void (*show_cursor)(int show); |
57 | void (__stdcall *move_cursor)(cursor_t *cursor, int x, int y); |
57 | void (__stdcall *move_cursor)(cursor_t *cursor, int x, int y); |
58 | void (__stdcall *restore_cursor)(int x, int y); |
58 | void (__stdcall *restore_cursor)(int x, int y); |
59 | void (*disable_mouse)(void); |
59 | void (*disable_mouse)(void); |
60 | u32 mask_seqno; |
60 | u32 mask_seqno; |
61 | u32 check_mouse; |
61 | u32 check_mouse; |
62 | u32 check_m_pixel; |
62 | u32 check_m_pixel; |
63 | 63 | ||
64 | }; |
64 | }; |
65 | 65 | ||
66 | 66 | ||
67 | static display_t *os_display; |
67 | static display_t *os_display; |
68 | 68 | ||
69 | u32_t cmd_buffer; |
69 | u32_t cmd_buffer; |
70 | u32_t cmd_offset; |
70 | u32_t cmd_offset; |
71 | 71 | ||
72 | void init_render(); |
72 | void init_render(); |
73 | int sna_init(); |
73 | int sna_init(); |
74 | 74 | ||
75 | int init_cursor(cursor_t *cursor); |
75 | int init_cursor(cursor_t *cursor); |
76 | static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor); |
76 | static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor); |
77 | static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y); |
77 | static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y); |
78 | 78 | ||
79 | void __stdcall restore_cursor(int x, int y) |
79 | void __stdcall restore_cursor(int x, int y) |
80 | {}; |
80 | {}; |
81 | 81 | ||
82 | void disable_mouse(void) |
82 | void disable_mouse(void) |
83 | {}; |
83 | {}; |
84 | 84 | ||
85 | static char *manufacturer_name(unsigned char *x) |
85 | static char *manufacturer_name(unsigned char *x) |
86 | { |
86 | { |
87 | static char name[4]; |
87 | static char name[4]; |
88 | 88 | ||
89 | name[0] = ((x[0] & 0x7C) >> 2) + '@'; |
89 | name[0] = ((x[0] & 0x7C) >> 2) + '@'; |
90 | name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@'; |
90 | name[1] = ((x[0] & 0x03) << 3) + ((x[1] & 0xE0) >> 5) + '@'; |
91 | name[2] = (x[1] & 0x1F) + '@'; |
91 | name[2] = (x[1] & 0x1F) + '@'; |
92 | name[3] = 0; |
92 | name[3] = 0; |
93 | 93 | ||
94 | return name; |
94 | return name; |
95 | } |
95 | } |
96 | 96 | ||
97 | bool set_mode(struct drm_device *dev, struct drm_connector *connector, |
97 | bool set_mode(struct drm_device *dev, struct drm_connector *connector, |
98 | videomode_t *reqmode, bool strict) |
98 | videomode_t *reqmode, bool strict) |
99 | { |
99 | { |
100 | drm_i915_private_t *dev_priv = dev->dev_private; |
100 | drm_i915_private_t *dev_priv = dev->dev_private; |
101 | struct drm_fb_helper *fb_helper = &dev_priv->fbdev->helper; |
101 | struct drm_fb_helper *fb_helper = &dev_priv->fbdev->helper; |
102 | 102 | ||
103 | struct drm_mode_config *config = &dev->mode_config; |
103 | struct drm_mode_config *config = &dev->mode_config; |
104 | struct drm_display_mode *mode = NULL, *tmpmode; |
104 | struct drm_display_mode *mode = NULL, *tmpmode; |
105 | struct drm_framebuffer *fb = NULL; |
105 | struct drm_framebuffer *fb = NULL; |
106 | struct drm_crtc *crtc; |
106 | struct drm_crtc *crtc; |
107 | struct drm_encoder *encoder; |
107 | struct drm_encoder *encoder; |
108 | struct drm_i915_gem_object *fb_obj; |
108 | struct drm_i915_gem_object *fb_obj; |
109 | struct drm_mode_set set; |
109 | struct drm_mode_set set; |
110 | const char *con_name; |
110 | const char *con_name; |
111 | const char *enc_name; |
111 | const char *enc_name; |
112 | unsigned hdisplay, vdisplay; |
112 | unsigned hdisplay, vdisplay; |
113 | int ret; |
113 | int ret; |
114 | 114 | ||
115 | mutex_lock(&dev->mode_config.mutex); |
115 | mutex_lock(&dev->mode_config.mutex); |
116 | 116 | ||
117 | list_for_each_entry(tmpmode, &connector->modes, head) |
117 | list_for_each_entry(tmpmode, &connector->modes, head) |
118 | { |
118 | { |
119 | if( (drm_mode_width(tmpmode) == reqmode->width) && |
119 | if( (drm_mode_width(tmpmode) == reqmode->width) && |
120 | (drm_mode_height(tmpmode) == reqmode->height) && |
120 | (drm_mode_height(tmpmode) == reqmode->height) && |
121 | (drm_mode_vrefresh(tmpmode) == reqmode->freq) ) |
121 | (drm_mode_vrefresh(tmpmode) == reqmode->freq) ) |
122 | { |
122 | { |
123 | mode = tmpmode; |
123 | mode = tmpmode; |
124 | goto do_set; |
124 | goto do_set; |
125 | } |
125 | } |
126 | }; |
126 | }; |
127 | 127 | ||
128 | if( (mode == NULL) && (strict == false) ) |
128 | if( (mode == NULL) && (strict == false) ) |
129 | { |
129 | { |
130 | list_for_each_entry(tmpmode, &connector->modes, head) |
130 | list_for_each_entry(tmpmode, &connector->modes, head) |
131 | { |
131 | { |
132 | if( (drm_mode_width(tmpmode) == reqmode->width) && |
132 | if( (drm_mode_width(tmpmode) == reqmode->width) && |
133 | (drm_mode_height(tmpmode) == reqmode->height) ) |
133 | (drm_mode_height(tmpmode) == reqmode->height) ) |
134 | { |
134 | { |
135 | mode = tmpmode; |
135 | mode = tmpmode; |
136 | goto do_set; |
136 | goto do_set; |
137 | } |
137 | } |
138 | }; |
138 | }; |
139 | }; |
139 | }; |
140 | 140 | ||
141 | DRM_ERROR("%s failed\n", __FUNCTION__); |
141 | DRM_ERROR("%s failed\n", __FUNCTION__); |
142 | 142 | ||
143 | return -1; |
143 | return -1; |
144 | 144 | ||
145 | do_set: |
145 | do_set: |
146 | 146 | ||
147 | encoder = connector->encoder; |
147 | encoder = connector->encoder; |
148 | crtc = encoder->crtc; |
148 | crtc = encoder->crtc; |
149 | 149 | ||
150 | con_name = drm_get_connector_name(connector); |
150 | con_name = drm_get_connector_name(connector); |
151 | enc_name = drm_get_encoder_name(encoder); |
151 | enc_name = drm_get_encoder_name(encoder); |
152 | 152 | ||
153 | DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s encoder %s\n", |
153 | DRM_DEBUG_KMS("set mode %d %d: crtc %d connector %s encoder %s\n", |
154 | reqmode->width, reqmode->height, crtc->base.id, |
154 | reqmode->width, reqmode->height, crtc->base.id, |
155 | con_name, enc_name); |
155 | con_name, enc_name); |
156 | 156 | ||
157 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
157 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
158 | 158 | ||
159 | hdisplay = mode->hdisplay; |
159 | hdisplay = mode->hdisplay; |
160 | vdisplay = mode->vdisplay; |
160 | vdisplay = mode->vdisplay; |
161 | 161 | ||
162 | if (crtc->invert_dimensions) |
162 | if (crtc->invert_dimensions) |
163 | swap(hdisplay, vdisplay); |
163 | swap(hdisplay, vdisplay); |
164 | 164 | ||
165 | fb_obj = get_fb_obj(); |
165 | fb_obj = get_fb_obj(); |
166 | fb = fb_helper->fb; |
166 | fb = fb_helper->fb; |
167 | 167 | ||
168 | fb->width = reqmode->width; |
168 | fb->width = reqmode->width; |
169 | fb->height = reqmode->height; |
169 | fb->height = reqmode->height; |
170 | 170 | ||
171 | fb->pitches[0] = fb->pitches[1] = fb->pitches[2] = |
171 | fb->pitches[0] = fb->pitches[1] = fb->pitches[2] = |
172 | fb->pitches[3] = ALIGN(reqmode->width * 4, 512); |
172 | fb->pitches[3] = ALIGN(reqmode->width * 4, 512); |
173 | 173 | ||
174 | fb_obj->stride = fb->pitches[0]; |
174 | fb_obj->stride = fb->pitches[0]; |
175 | 175 | ||
176 | fb->bits_per_pixel = 32; |
176 | fb->bits_per_pixel = 32; |
177 | fb->depth = 24; |
177 | fb->depth = 24; |
178 | 178 | ||
179 | crtc->fb = fb; |
179 | crtc->fb = fb; |
180 | crtc->enabled = true; |
180 | crtc->enabled = true; |
181 | os_display->crtc = crtc; |
181 | os_display->crtc = crtc; |
182 | 182 | ||
183 | i915_gem_object_put_fence(fb_obj); |
183 | i915_gem_object_put_fence(fb_obj); |
184 | 184 | ||
185 | set.crtc = crtc; |
185 | set.crtc = crtc; |
186 | set.x = 0; |
186 | set.x = 0; |
187 | set.y = 0; |
187 | set.y = 0; |
188 | set.mode = mode; |
188 | set.mode = mode; |
189 | set.connectors = &connector; |
189 | set.connectors = &connector; |
190 | set.num_connectors = 1; |
190 | set.num_connectors = 1; |
191 | set.fb = fb; |
191 | set.fb = fb; |
192 | ret = crtc->funcs->set_config(&set); |
192 | ret = crtc->funcs->set_config(&set); |
193 | mutex_unlock(&dev->mode_config.mutex); |
193 | mutex_unlock(&dev->mode_config.mutex); |
194 | 194 | ||
195 | if ( !ret ) |
195 | if ( !ret ) |
196 | { |
196 | { |
197 | os_display->width = fb->width; |
197 | os_display->width = fb->width; |
198 | os_display->height = fb->height; |
198 | os_display->height = fb->height; |
199 | os_display->vrefresh = drm_mode_vrefresh(mode); |
199 | os_display->vrefresh = drm_mode_vrefresh(mode); |
200 | 200 | ||
201 | sysSetScreen(fb->width, fb->height, fb->pitches[0]); |
201 | sysSetScreen(fb->width, fb->height, fb->pitches[0]); |
202 | 202 | ||
203 | DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", |
203 | DRM_DEBUG_KMS("new mode %d x %d pitch %d\n", |
204 | fb->width, fb->height, fb->pitches[0]); |
204 | fb->width, fb->height, fb->pitches[0]); |
205 | } |
205 | } |
206 | else |
206 | else |
207 | DRM_ERROR("failed to set mode %d_%d on crtc %p\n", |
207 | DRM_ERROR("failed to set mode %d_%d on crtc %p\n", |
208 | fb->width, fb->height, crtc); |
208 | fb->width, fb->height, crtc); |
209 | 209 | ||
210 | return ret; |
210 | return ret; |
211 | } |
211 | } |
212 | 212 | ||
213 | static int count_connector_modes(struct drm_connector* connector) |
213 | static int count_connector_modes(struct drm_connector* connector) |
214 | { |
214 | { |
215 | struct drm_display_mode *mode; |
215 | struct drm_display_mode *mode; |
216 | int count = 0; |
216 | int count = 0; |
217 | 217 | ||
218 | list_for_each_entry(mode, &connector->modes, head) |
218 | list_for_each_entry(mode, &connector->modes, head) |
219 | { |
219 | { |
220 | count++; |
220 | count++; |
221 | }; |
221 | }; |
222 | return count; |
222 | return count; |
223 | }; |
223 | }; |
224 | 224 | ||
225 | static struct drm_connector* get_def_connector(struct drm_device *dev) |
225 | static struct drm_connector* get_def_connector(struct drm_device *dev) |
226 | { |
226 | { |
227 | struct drm_connector *connector; |
227 | struct drm_connector *connector; |
228 | struct drm_connector_helper_funcs *connector_funcs; |
228 | struct drm_connector_helper_funcs *connector_funcs; |
229 | 229 | ||
230 | struct drm_connector *def_connector = NULL; |
230 | struct drm_connector *def_connector = NULL; |
231 | 231 | ||
232 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
232 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
233 | { |
233 | { |
234 | struct drm_encoder *encoder; |
234 | struct drm_encoder *encoder; |
235 | struct drm_crtc *crtc; |
235 | struct drm_crtc *crtc; |
236 | 236 | ||
237 | if( connector->status != connector_status_connected) |
237 | if( connector->status != connector_status_connected) |
238 | continue; |
238 | continue; |
239 | 239 | ||
240 | connector_funcs = connector->helper_private; |
240 | connector_funcs = connector->helper_private; |
241 | encoder = connector_funcs->best_encoder(connector); |
241 | encoder = connector_funcs->best_encoder(connector); |
242 | if( encoder == NULL) |
242 | if( encoder == NULL) |
243 | continue; |
243 | continue; |
244 | 244 | ||
245 | connector->encoder = encoder; |
245 | connector->encoder = encoder; |
246 | 246 | ||
247 | crtc = encoder->crtc; |
247 | crtc = encoder->crtc; |
248 | 248 | ||
249 | DRM_DEBUG_KMS("CONNECTOR %x ID: %d status %d encoder %x\n crtc %x", |
249 | DRM_DEBUG_KMS("CONNECTOR %x ID: %d status %d encoder %x\n crtc %x", |
250 | connector, connector->base.id, |
250 | connector, connector->base.id, |
251 | connector->status, connector->encoder, |
251 | connector->status, connector->encoder, |
252 | crtc); |
252 | crtc); |
253 | 253 | ||
254 | // if (crtc == NULL) |
254 | // if (crtc == NULL) |
255 | // continue; |
255 | // continue; |
256 | 256 | ||
257 | def_connector = connector; |
257 | def_connector = connector; |
258 | 258 | ||
259 | break; |
259 | break; |
260 | }; |
260 | }; |
261 | 261 | ||
262 | return def_connector; |
262 | return def_connector; |
263 | }; |
263 | }; |
264 | 264 | ||
265 | struct drm_connector *get_active_connector(struct drm_device *dev) |
265 | struct drm_connector *get_active_connector(struct drm_device *dev) |
266 | { |
266 | { |
267 | struct drm_connector *tmp = NULL; |
267 | struct drm_connector *tmp = NULL; |
268 | struct drm_connector_helper_funcs *connector_funcs; |
268 | struct drm_connector_helper_funcs *connector_funcs; |
269 | struct drm_encoder *encoder; |
269 | struct drm_encoder *encoder; |
270 | 270 | ||
271 | list_for_each_entry(tmp, &dev->mode_config.connector_list, head) |
271 | list_for_each_entry(tmp, &dev->mode_config.connector_list, head) |
272 | { |
272 | { |
273 | if( tmp->status != connector_status_connected) |
273 | if( tmp->status != connector_status_connected) |
274 | continue; |
274 | continue; |
275 | 275 | ||
276 | connector_funcs = tmp->helper_private; |
276 | connector_funcs = tmp->helper_private; |
277 | encoder = connector_funcs->best_encoder(tmp); |
277 | encoder = connector_funcs->best_encoder(tmp); |
278 | if( encoder == NULL) |
278 | if( encoder == NULL) |
279 | { |
279 | { |
280 | DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n", |
280 | DRM_DEBUG_KMS("CONNECTOR %x ID: %d no active encoders\n", |
281 | tmp, tmp->base.id); |
281 | tmp, tmp->base.id); |
282 | continue; |
282 | continue; |
283 | }; |
283 | }; |
284 | 284 | ||
285 | tmp->encoder = encoder; |
285 | tmp->encoder = encoder; |
286 | 286 | ||
287 | DRM_DEBUG_KMS("CONNECTOR %p ID:%d status:%d ENCODER %x CRTC %p ID:%d\n", |
287 | DRM_DEBUG_KMS("CONNECTOR %p ID:%d status:%d ENCODER %x CRTC %p ID:%d\n", |
288 | tmp, tmp->base.id, tmp->status, tmp->encoder, |
288 | tmp, tmp->base.id, tmp->status, tmp->encoder, |
289 | tmp->encoder->crtc, tmp->encoder->crtc->base.id ); |
289 | tmp->encoder->crtc, tmp->encoder->crtc->base.id ); |
290 | 290 | ||
291 | return tmp; |
291 | return tmp; |
292 | }; |
292 | }; |
293 | 293 | ||
294 | return NULL; |
294 | return NULL; |
295 | } |
295 | } |
296 | 296 | ||
297 | struct drm_crtc *get_possible_crtc(struct drm_device *dev, struct drm_encoder *encoder) |
297 | struct drm_crtc *get_possible_crtc(struct drm_device *dev, struct drm_encoder *encoder) |
298 | { |
298 | { |
299 | struct drm_crtc *tmp_crtc; |
299 | struct drm_crtc *tmp_crtc; |
300 | int crtc_mask = 1; |
300 | int crtc_mask = 1; |
301 | 301 | ||
302 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) |
302 | list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) |
303 | { |
303 | { |
304 | if (encoder->possible_crtcs & crtc_mask) |
304 | if (encoder->possible_crtcs & crtc_mask) |
305 | { |
305 | { |
306 | encoder->crtc = tmp_crtc; |
306 | encoder->crtc = tmp_crtc; |
307 | dbgprintf("CRTC %p\n", tmp_crtc); |
307 | dbgprintf("CRTC %p\n", tmp_crtc); |
308 | return tmp_crtc; |
308 | return tmp_crtc; |
309 | }; |
309 | }; |
310 | crtc_mask <<= 1; |
310 | crtc_mask <<= 1; |
311 | }; |
311 | }; |
312 | return NULL; |
312 | return NULL; |
313 | }; |
313 | }; |
314 | 314 | ||
315 | int get_boot_mode(struct drm_connector *connector, videomode_t *usermode) |
315 | int get_boot_mode(struct drm_connector *connector, videomode_t *usermode) |
316 | { |
316 | { |
317 | struct drm_display_mode *mode; |
317 | struct drm_display_mode *mode; |
318 | 318 | ||
319 | list_for_each_entry(mode, &connector->modes, head) |
319 | list_for_each_entry(mode, &connector->modes, head) |
320 | { |
320 | { |
321 | DRM_DEBUG_KMS("check mode w:%d h:%d %dHz\n", |
321 | DRM_DEBUG_KMS("check mode w:%d h:%d %dHz\n", |
322 | drm_mode_width(mode), drm_mode_height(mode), |
322 | drm_mode_width(mode), drm_mode_height(mode), |
323 | drm_mode_vrefresh(mode)); |
323 | drm_mode_vrefresh(mode)); |
324 | 324 | ||
325 | if( os_display->width == drm_mode_width(mode) && |
325 | if( os_display->width == drm_mode_width(mode) && |
326 | os_display->height == drm_mode_height(mode) && |
326 | os_display->height == drm_mode_height(mode) && |
327 | drm_mode_vrefresh(mode) == 60) |
327 | drm_mode_vrefresh(mode) == 60) |
328 | { |
328 | { |
329 | usermode->width = os_display->width; |
329 | usermode->width = os_display->width; |
330 | usermode->height = os_display->height; |
330 | usermode->height = os_display->height; |
331 | usermode->freq = 60; |
331 | usermode->freq = 60; |
332 | return 1; |
332 | return 1; |
333 | } |
333 | } |
334 | } |
334 | } |
335 | return 0; |
335 | return 0; |
336 | } |
336 | } |
337 | 337 | ||
338 | int init_display_kms(struct drm_device *dev, videomode_t *usermode) |
338 | int init_display_kms(struct drm_device *dev, videomode_t *usermode) |
339 | { |
339 | { |
340 | struct drm_connector *connector; |
340 | struct drm_connector *connector; |
341 | struct drm_connector_helper_funcs *connector_funcs; |
341 | struct drm_connector_helper_funcs *connector_funcs; |
342 | struct drm_encoder *encoder; |
342 | struct drm_encoder *encoder; |
343 | struct drm_crtc *crtc; |
343 | struct drm_crtc *crtc; |
344 | struct drm_framebuffer *fb; |
344 | struct drm_framebuffer *fb; |
345 | 345 | ||
346 | cursor_t *cursor; |
346 | cursor_t *cursor; |
347 | u32_t ifl; |
347 | u32_t ifl; |
348 | int err; |
348 | int err; |
349 | 349 | ||
350 | mutex_lock(&dev->mode_config.mutex); |
350 | mutex_lock(&dev->mode_config.mutex); |
351 | 351 | ||
352 | connector = get_active_connector(dev) ; |
352 | connector = get_active_connector(dev) ; |
353 | if(connector == NULL) |
353 | if(connector == NULL) |
354 | { |
354 | { |
355 | DRM_DEBUG_KMS("No active connectors!\n"); |
355 | DRM_DEBUG_KMS("No active connectors!\n"); |
356 | mutex_unlock(&dev->mode_config.mutex); |
356 | mutex_unlock(&dev->mode_config.mutex); |
357 | return -1; |
357 | return -1; |
358 | }; |
358 | }; |
359 | 359 | ||
360 | encoder = connector->encoder; |
360 | encoder = connector->encoder; |
361 | crtc = encoder->crtc; |
361 | crtc = encoder->crtc; |
362 | 362 | ||
363 | if(crtc == NULL) |
363 | if(crtc == NULL) |
364 | crtc = get_possible_crtc(dev, encoder); |
364 | crtc = get_possible_crtc(dev, encoder); |
365 | 365 | ||
366 | if(crtc == NULL) |
366 | if(crtc == NULL) |
367 | { |
367 | { |
368 | DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id); |
368 | DRM_DEBUG_KMS("No CRTC for encoder %d\n", encoder->base.id); |
369 | mutex_unlock(&dev->mode_config.mutex); |
369 | mutex_unlock(&dev->mode_config.mutex); |
370 | return -1; |
370 | return -1; |
371 | }; |
371 | }; |
372 | 372 | ||
373 | DRM_DEBUG_KMS("[Select CRTC: %p ID:%d]\n",crtc, crtc->base.id); |
373 | DRM_DEBUG_KMS("[Select CRTC: %p ID:%d]\n",crtc, crtc->base.id); |
374 | 374 | ||
375 | os_display = GetDisplay(); |
375 | os_display = GetDisplay(); |
376 | os_display->ddev = dev; |
376 | os_display->ddev = dev; |
377 | os_display->connector = connector; |
377 | os_display->connector = connector; |
378 | os_display->crtc = crtc; |
378 | os_display->crtc = crtc; |
379 | 379 | ||
380 | os_display->supported_modes = count_connector_modes(connector); |
380 | os_display->supported_modes = count_connector_modes(connector); |
381 | 381 | ||
382 | 382 | ||
383 | ifl = safe_cli(); |
383 | ifl = safe_cli(); |
384 | { |
384 | { |
385 | struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); |
385 | struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); |
386 | 386 | ||
387 | list_for_each_entry(cursor, &os_display->cursors, list) |
387 | list_for_each_entry(cursor, &os_display->cursors, list) |
388 | { |
388 | { |
389 | init_cursor(cursor); |
389 | init_cursor(cursor); |
390 | }; |
390 | }; |
391 | 391 | ||
392 | os_display->restore_cursor(0,0); |
392 | os_display->restore_cursor(0,0); |
393 | os_display->init_cursor = init_cursor; |
393 | os_display->init_cursor = init_cursor; |
394 | os_display->select_cursor = select_cursor_kms; |
394 | os_display->select_cursor = select_cursor_kms; |
395 | os_display->show_cursor = NULL; |
395 | os_display->show_cursor = NULL; |
396 | os_display->move_cursor = move_cursor_kms; |
396 | os_display->move_cursor = move_cursor_kms; |
397 | os_display->restore_cursor = restore_cursor; |
397 | os_display->restore_cursor = restore_cursor; |
398 | os_display->disable_mouse = disable_mouse; |
398 | os_display->disable_mouse = disable_mouse; |
399 | 399 | ||
400 | intel_crtc->cursor_x = os_display->width/2; |
400 | intel_crtc->cursor_x = os_display->width/2; |
401 | intel_crtc->cursor_y = os_display->height/2; |
401 | intel_crtc->cursor_y = os_display->height/2; |
402 | 402 | ||
403 | select_cursor_kms(os_display->cursor); |
403 | select_cursor_kms(os_display->cursor); |
404 | }; |
404 | }; |
405 | safe_sti(ifl); |
405 | safe_sti(ifl); |
406 | 406 | ||
407 | if( (usermode->width == 0) || |
407 | if( (usermode->width == 0) || |
408 | (usermode->height == 0)) |
408 | (usermode->height == 0)) |
409 | { |
409 | { |
410 | if( !get_boot_mode(connector, usermode)) |
410 | if( !get_boot_mode(connector, usermode)) |
411 | { |
411 | { |
412 | struct drm_display_mode *mode; |
412 | struct drm_display_mode *mode; |
413 | 413 | ||
414 | mode = list_entry(connector->modes.next, typeof(*mode), head); |
414 | mode = list_entry(connector->modes.next, typeof(*mode), head); |
415 | usermode->width = drm_mode_width(mode); |
415 | usermode->width = drm_mode_width(mode); |
416 | usermode->height = drm_mode_height(mode); |
416 | usermode->height = drm_mode_height(mode); |
417 | usermode->freq = drm_mode_vrefresh(mode); |
417 | usermode->freq = drm_mode_vrefresh(mode); |
418 | }; |
418 | }; |
419 | }; |
419 | }; |
420 | 420 | ||
421 | mutex_unlock(&dev->mode_config.mutex); |
421 | mutex_unlock(&dev->mode_config.mutex); |
422 | 422 | ||
423 | set_mode(dev, os_display->connector, usermode, false); |
423 | set_mode(dev, os_display->connector, usermode, false); |
424 | 424 | ||
425 | #ifdef __HWA__ |
425 | #ifdef __HWA__ |
426 | err = init_bitmaps(); |
426 | err = init_bitmaps(); |
427 | #endif |
427 | #endif |
428 | 428 | ||
429 | LEAVE(); |
429 | LEAVE(); |
430 | 430 | ||
431 | return 0; |
431 | return 0; |
432 | }; |
432 | }; |
433 | 433 | ||
434 | 434 | ||
435 | int get_videomodes(videomode_t *mode, int *count) |
435 | int get_videomodes(videomode_t *mode, int *count) |
436 | { |
436 | { |
437 | int err = -1; |
437 | int err = -1; |
438 | 438 | ||
439 | // dbgprintf("mode %x count %d\n", mode, *count); |
439 | // dbgprintf("mode %x count %d\n", mode, *count); |
440 | 440 | ||
441 | if( *count == 0 ) |
441 | if( *count == 0 ) |
442 | { |
442 | { |
443 | *count = os_display->supported_modes; |
443 | *count = os_display->supported_modes; |
444 | err = 0; |
444 | err = 0; |
445 | } |
445 | } |
446 | else if( mode != NULL ) |
446 | else if( mode != NULL ) |
447 | { |
447 | { |
448 | struct drm_display_mode *drmmode; |
448 | struct drm_display_mode *drmmode; |
449 | int i = 0; |
449 | int i = 0; |
450 | 450 | ||
451 | if( *count > os_display->supported_modes) |
451 | if( *count > os_display->supported_modes) |
452 | *count = os_display->supported_modes; |
452 | *count = os_display->supported_modes; |
453 | 453 | ||
454 | list_for_each_entry(drmmode, &os_display->connector->modes, head) |
454 | list_for_each_entry(drmmode, &os_display->connector->modes, head) |
455 | { |
455 | { |
456 | if( i < *count) |
456 | if( i < *count) |
457 | { |
457 | { |
458 | mode->width = drm_mode_width(drmmode); |
458 | mode->width = drm_mode_width(drmmode); |
459 | mode->height = drm_mode_height(drmmode); |
459 | mode->height = drm_mode_height(drmmode); |
460 | mode->bpp = 32; |
460 | mode->bpp = 32; |
461 | mode->freq = drm_mode_vrefresh(drmmode); |
461 | mode->freq = drm_mode_vrefresh(drmmode); |
462 | i++; |
462 | i++; |
463 | mode++; |
463 | mode++; |
464 | } |
464 | } |
465 | else break; |
465 | else break; |
466 | }; |
466 | }; |
467 | *count = i; |
467 | *count = i; |
468 | err = 0; |
468 | err = 0; |
469 | }; |
469 | }; |
470 | return err; |
470 | return err; |
471 | }; |
471 | }; |
472 | 472 | ||
473 | int set_user_mode(videomode_t *mode) |
473 | int set_user_mode(videomode_t *mode) |
474 | { |
474 | { |
475 | int err = -1; |
475 | int err = -1; |
476 | 476 | ||
477 | // dbgprintf("width %d height %d vrefresh %d\n", |
477 | // dbgprintf("width %d height %d vrefresh %d\n", |
478 | // mode->width, mode->height, mode->freq); |
478 | // mode->width, mode->height, mode->freq); |
479 | 479 | ||
480 | if( (mode->width != 0) && |
480 | if( (mode->width != 0) && |
481 | (mode->height != 0) && |
481 | (mode->height != 0) && |
482 | (mode->freq != 0 ) && |
482 | (mode->freq != 0 ) && |
483 | ( (mode->width != os_display->width) || |
483 | ( (mode->width != os_display->width) || |
484 | (mode->height != os_display->height) || |
484 | (mode->height != os_display->height) || |
485 | (mode->freq != os_display->vrefresh) ) ) |
485 | (mode->freq != os_display->vrefresh) ) ) |
486 | { |
486 | { |
487 | if( set_mode(os_display->ddev, os_display->connector, mode, true) ) |
487 | if( set_mode(os_display->ddev, os_display->connector, mode, true) ) |
488 | err = 0; |
488 | err = 0; |
489 | }; |
489 | }; |
490 | 490 | ||
491 | return err; |
491 | return err; |
492 | }; |
492 | }; |
493 | 493 | ||
494 | void i915_dpms(struct drm_device *dev, int mode) |
494 | void i915_dpms(struct drm_device *dev, int mode) |
495 | { |
495 | { |
496 | const struct drm_connector_funcs *f = os_display->connector->funcs; |
496 | const struct drm_connector_funcs *f = os_display->connector->funcs; |
497 | 497 | ||
498 | f->dpms(os_display->connector, mode); |
498 | f->dpms(os_display->connector, mode); |
499 | }; |
499 | }; |
500 | 500 | ||
501 | void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor) |
501 | void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor) |
502 | { |
502 | { |
503 | list_del(&cursor->list); |
503 | list_del(&cursor->list); |
504 | 504 | ||
505 | i915_gem_object_unpin(cursor->cobj); |
505 | i915_gem_object_unpin(cursor->cobj); |
506 | 506 | ||
507 | mutex_lock(&main_device->struct_mutex); |
507 | mutex_lock(&main_device->struct_mutex); |
508 | drm_gem_object_unreference(&cursor->cobj->base); |
508 | drm_gem_object_unreference(&cursor->cobj->base); |
509 | mutex_unlock(&main_device->struct_mutex); |
509 | mutex_unlock(&main_device->struct_mutex); |
510 | 510 | ||
511 | __DestroyObject(cursor); |
511 | __DestroyObject(cursor); |
512 | }; |
512 | }; |
513 | 513 | ||
514 | int init_cursor(cursor_t *cursor) |
514 | int init_cursor(cursor_t *cursor) |
515 | { |
515 | { |
516 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
516 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
517 | struct drm_i915_gem_object *obj; |
517 | struct drm_i915_gem_object *obj; |
518 | uint32_t *bits; |
518 | uint32_t *bits; |
519 | uint32_t *src; |
519 | uint32_t *src; |
520 | void *mapped; |
520 | void *mapped; |
521 | 521 | ||
522 | int i,j; |
522 | int i,j; |
523 | int ret; |
523 | int ret; |
524 | 524 | ||
525 | if (dev_priv->info->cursor_needs_physical) |
525 | if (dev_priv->info->cursor_needs_physical) |
526 | { |
526 | { |
527 | bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4); |
527 | bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4); |
528 | if (unlikely(bits == NULL)) |
528 | if (unlikely(bits == NULL)) |
529 | return ENOMEM; |
529 | return ENOMEM; |
530 | cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits); |
530 | cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits); |
531 | } |
531 | } |
532 | else |
532 | else |
533 | { |
533 | { |
534 | obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4); |
534 | obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4); |
535 | if (unlikely(obj == NULL)) |
535 | if (unlikely(obj == NULL)) |
536 | return -ENOMEM; |
536 | return -ENOMEM; |
537 | 537 | ||
538 | ret = i915_gem_obj_ggtt_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true, true); |
538 | ret = i915_gem_obj_ggtt_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true, true); |
539 | if (ret) { |
539 | if (ret) { |
540 | drm_gem_object_unreference(&obj->base); |
540 | drm_gem_object_unreference(&obj->base); |
541 | return ret; |
541 | return ret; |
542 | } |
542 | } |
543 | 543 | ||
544 | ret = i915_gem_object_set_to_gtt_domain(obj, true); |
544 | ret = i915_gem_object_set_to_gtt_domain(obj, true); |
545 | if (ret) |
545 | if (ret) |
546 | { |
546 | { |
547 | i915_gem_object_unpin(obj); |
547 | i915_gem_object_unpin(obj); |
548 | drm_gem_object_unreference(&obj->base); |
548 | drm_gem_object_unreference(&obj->base); |
549 | return ret; |
549 | return ret; |
550 | } |
550 | } |
551 | /* You don't need to worry about fragmentation issues. |
551 | /* You don't need to worry about fragmentation issues. |
552 | * GTT space is continuous. I guarantee it. */ |
552 | * GTT space is continuous. I guarantee it. */ |
553 | 553 | ||
554 | mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), |
554 | mapped = bits = (u32*)MapIoMem(dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(obj), |
555 | CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW); |
555 | CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW); |
556 | 556 | ||
557 | if (unlikely(bits == NULL)) |
557 | if (unlikely(bits == NULL)) |
558 | { |
558 | { |
559 | i915_gem_object_unpin(obj); |
559 | i915_gem_object_unpin(obj); |
560 | drm_gem_object_unreference(&obj->base); |
560 | drm_gem_object_unreference(&obj->base); |
561 | return -ENOMEM; |
561 | return -ENOMEM; |
562 | }; |
562 | }; |
563 | cursor->cobj = obj; |
563 | cursor->cobj = obj; |
564 | }; |
564 | }; |
565 | 565 | ||
566 | src = cursor->data; |
566 | src = cursor->data; |
567 | 567 | ||
568 | for(i = 0; i < 32; i++) |
568 | for(i = 0; i < 32; i++) |
569 | { |
569 | { |
570 | for(j = 0; j < 32; j++) |
570 | for(j = 0; j < 32; j++) |
571 | *bits++ = *src++; |
571 | *bits++ = *src++; |
572 | for(j = 32; j < CURSOR_WIDTH; j++) |
572 | for(j = 32; j < CURSOR_WIDTH; j++) |
573 | *bits++ = 0; |
573 | *bits++ = 0; |
574 | } |
574 | } |
575 | for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++) |
575 | for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++) |
576 | *bits++ = 0; |
576 | *bits++ = 0; |
577 | 577 | ||
578 | FreeKernelSpace(mapped); |
578 | FreeKernelSpace(mapped); |
579 | 579 | ||
580 | // release old cursor |
580 | // release old cursor |
581 | 581 | ||
582 | KernelFree(cursor->data); |
582 | KernelFree(cursor->data); |
583 | 583 | ||
584 | cursor->data = bits; |
584 | cursor->data = bits; |
585 | 585 | ||
586 | cursor->header.destroy = destroy_cursor; |
586 | cursor->header.destroy = destroy_cursor; |
587 | 587 | ||
588 | return 0; |
588 | return 0; |
589 | } |
589 | } |
590 | 590 | ||
591 | 591 | ||
592 | static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) |
592 | static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) |
593 | { |
593 | { |
594 | struct drm_device *dev = crtc->dev; |
594 | struct drm_device *dev = crtc->dev; |
595 | struct drm_i915_private *dev_priv = dev->dev_private; |
595 | struct drm_i915_private *dev_priv = dev->dev_private; |
596 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
596 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
597 | int pipe = intel_crtc->pipe; |
597 | int pipe = intel_crtc->pipe; |
598 | bool visible = base != 0; |
598 | bool visible = base != 0; |
599 | 599 | ||
600 | if (intel_crtc->cursor_visible != visible) { |
600 | if (intel_crtc->cursor_visible != visible) { |
601 | uint32_t cntl = I915_READ(CURCNTR(pipe)); |
601 | uint32_t cntl = I915_READ(CURCNTR(pipe)); |
602 | if (base) { |
602 | if (base) { |
603 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); |
603 | cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); |
604 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; |
604 | cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; |
605 | cntl |= pipe << 28; /* Connect to correct pipe */ |
605 | cntl |= pipe << 28; /* Connect to correct pipe */ |
606 | } else { |
606 | } else { |
607 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); |
607 | cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); |
608 | cntl |= CURSOR_MODE_DISABLE; |
608 | cntl |= CURSOR_MODE_DISABLE; |
609 | } |
609 | } |
610 | I915_WRITE(CURCNTR(pipe), cntl); |
610 | I915_WRITE(CURCNTR(pipe), cntl); |
611 | 611 | ||
612 | intel_crtc->cursor_visible = visible; |
612 | intel_crtc->cursor_visible = visible; |
613 | } |
613 | } |
614 | /* and commit changes on next vblank */ |
614 | /* and commit changes on next vblank */ |
615 | I915_WRITE(CURBASE(pipe), base); |
615 | I915_WRITE(CURBASE(pipe), base); |
616 | } |
616 | } |
617 | 617 | ||
618 | void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) |
618 | void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) |
619 | { |
619 | { |
620 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
620 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
621 | struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); |
621 | struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); |
622 | u32 base, pos; |
622 | u32 base, pos; |
623 | bool visible; |
623 | bool visible; |
624 | 624 | ||
625 | int pipe = intel_crtc->pipe; |
625 | int pipe = intel_crtc->pipe; |
626 | 626 | ||
627 | intel_crtc->cursor_x = x; |
627 | intel_crtc->cursor_x = x; |
628 | intel_crtc->cursor_y = y; |
628 | intel_crtc->cursor_y = y; |
629 | 629 | ||
630 | x = x - cursor->hot_x; |
630 | x = x - cursor->hot_x; |
631 | y = y - cursor->hot_y; |
631 | y = y - cursor->hot_y; |
632 | 632 | ||
633 | 633 | ||
634 | pos = 0; |
634 | pos = 0; |
635 | 635 | ||
636 | base = intel_crtc->cursor_addr; |
636 | base = intel_crtc->cursor_addr; |
637 | if (x >= os_display->width) |
637 | if (x >= os_display->width) |
638 | base = 0; |
638 | base = 0; |
639 | 639 | ||
640 | if (y >= os_display->height) |
640 | if (y >= os_display->height) |
641 | base = 0; |
641 | base = 0; |
642 | 642 | ||
643 | if (x < 0) |
643 | if (x < 0) |
644 | { |
644 | { |
645 | if (x + intel_crtc->cursor_width < 0) |
645 | if (x + intel_crtc->cursor_width < 0) |
646 | base = 0; |
646 | base = 0; |
647 | 647 | ||
648 | pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; |
648 | pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; |
649 | x = -x; |
649 | x = -x; |
650 | } |
650 | } |
651 | pos |= x << CURSOR_X_SHIFT; |
651 | pos |= x << CURSOR_X_SHIFT; |
652 | 652 | ||
653 | if (y < 0) |
653 | if (y < 0) |
654 | { |
654 | { |
655 | if (y + intel_crtc->cursor_height < 0) |
655 | if (y + intel_crtc->cursor_height < 0) |
656 | base = 0; |
656 | base = 0; |
657 | 657 | ||
658 | pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; |
658 | pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; |
659 | y = -y; |
659 | y = -y; |
660 | } |
660 | } |
661 | pos |= y << CURSOR_Y_SHIFT; |
661 | pos |= y << CURSOR_Y_SHIFT; |
662 | 662 | ||
663 | visible = base != 0; |
663 | visible = base != 0; |
664 | if (!visible && !intel_crtc->cursor_visible) |
664 | if (!visible && !intel_crtc->cursor_visible) |
665 | return; |
665 | return; |
666 | 666 | ||
667 | I915_WRITE(CURPOS(pipe), pos); |
667 | I915_WRITE(CURPOS(pipe), pos); |
668 | // if (IS_845G(dev) || IS_I865G(dev)) |
668 | // if (IS_845G(dev) || IS_I865G(dev)) |
669 | // i845_update_cursor(crtc, base); |
669 | // i845_update_cursor(crtc, base); |
670 | // else |
670 | // else |
671 | i9xx_update_cursor(os_display->crtc, base); |
671 | i9xx_update_cursor(os_display->crtc, base); |
672 | 672 | ||
673 | }; |
673 | }; |
674 | 674 | ||
675 | 675 | ||
676 | cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) |
676 | cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) |
677 | { |
677 | { |
678 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
678 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
679 | struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); |
679 | struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); |
680 | cursor_t *old; |
680 | cursor_t *old; |
681 | 681 | ||
682 | old = os_display->cursor; |
682 | old = os_display->cursor; |
683 | os_display->cursor = cursor; |
683 | os_display->cursor = cursor; |
684 | 684 | ||
685 | if (!dev_priv->info->cursor_needs_physical) |
685 | if (!dev_priv->info->cursor_needs_physical) |
686 | intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj); |
686 | intel_crtc->cursor_addr = i915_gem_obj_ggtt_offset(cursor->cobj); |
687 | else |
687 | else |
688 | intel_crtc->cursor_addr = (addr_t)cursor->cobj; |
688 | intel_crtc->cursor_addr = (addr_t)cursor->cobj; |
689 | 689 | ||
690 | intel_crtc->cursor_width = 32; |
690 | intel_crtc->cursor_width = 32; |
691 | intel_crtc->cursor_height = 32; |
691 | intel_crtc->cursor_height = 32; |
692 | 692 | ||
693 | move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y); |
693 | move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y); |
694 | return old; |
694 | return old; |
695 | }; |
695 | }; |
696 | 696 | ||
697 | int i915_fbinfo(struct drm_i915_fb_info *fb) |
697 | int i915_fbinfo(struct drm_i915_fb_info *fb) |
698 | { |
698 | { |
699 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
699 | struct drm_i915_private *dev_priv = os_display->ddev->dev_private; |
700 | struct intel_crtc *crtc = to_intel_crtc(os_display->crtc); |
700 | struct intel_crtc *crtc = to_intel_crtc(os_display->crtc); |
701 | 701 | ||
702 | struct drm_i915_gem_object *obj = get_fb_obj(); |
702 | struct drm_i915_gem_object *obj = get_fb_obj(); |
703 | 703 | ||
704 | fb->name = obj->base.name; |
704 | fb->name = obj->base.name; |
705 | fb->width = os_display->width; |
705 | fb->width = os_display->width; |
706 | fb->height = os_display->height; |
706 | fb->height = os_display->height; |
707 | fb->pitch = obj->stride; |
707 | fb->pitch = obj->stride; |
708 | fb->tiling = obj->tiling_mode; |
708 | fb->tiling = obj->tiling_mode; |
709 | fb->crtc = crtc->base.base.id; |
709 | fb->crtc = crtc->base.base.id; |
710 | fb->pipe = crtc->pipe; |
710 | fb->pipe = crtc->pipe; |
711 | 711 | ||
712 | return 0; |
712 | return 0; |
713 | } |
713 | } |
714 | 714 | ||
715 | 715 | ||
716 | typedef struct |
716 | typedef struct |
717 | { |
717 | { |
718 | int left; |
718 | int left; |
719 | int top; |
719 | int top; |
720 | int right; |
720 | int right; |
721 | int bottom; |
721 | int bottom; |
722 | }rect_t; |
722 | }rect_t; |
723 | 723 | ||
724 | 724 | ||
725 | #define CURRENT_TASK (0x80003000) |
725 | #define CURRENT_TASK (0x80003000) |
726 | 726 | ||
727 | static u32_t get_display_map() |
727 | static u32_t get_display_map() |
728 | { |
728 | { |
729 | u32_t addr; |
729 | u32_t addr; |
730 | 730 | ||
731 | addr = (u32_t)os_display; |
731 | addr = (u32_t)os_display; |
732 | addr+= sizeof(display_t); /* shoot me */ |
732 | addr+= sizeof(display_t); /* shoot me */ |
733 | return *(u32_t*)addr; |
733 | return *(u32_t*)addr; |
734 | } |
734 | } |
735 | 735 | ||
736 | void FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect"); |
736 | void FASTCALL GetWindowRect(rect_t *rc)__asm__("GetWindowRect"); |
737 | 737 | ||
738 | int i915_mask_update(struct drm_device *dev, void *data, |
738 | int i915_mask_update(struct drm_device *dev, void *data, |
739 | struct drm_file *file) |
739 | struct drm_file *file) |
740 | { |
740 | { |
741 | struct drm_i915_mask *mask = data; |
741 | struct drm_i915_mask *mask = data; |
742 | struct drm_gem_object *obj; |
742 | struct drm_gem_object *obj; |
743 | static unsigned int mask_seqno[256]; |
743 | static unsigned int mask_seqno[256]; |
744 | rect_t winrc; |
744 | rect_t winrc; |
745 | u32 slot; |
745 | u32 slot; |
746 | int ret=0; |
746 | int ret=0; |
747 | 747 | ||
748 | if(mask->handle == -2) |
- | |
749 | { |
- | |
750 | printf("%s handle %d\n", __FUNCTION__, mask->handle); |
- | |
751 | return 0; |
- | |
752 | } |
- | |
753 | - | ||
754 | obj = drm_gem_object_lookup(dev, file, mask->handle); |
748 | obj = drm_gem_object_lookup(dev, file, mask->handle); |
755 | if (obj == NULL) |
749 | if (obj == NULL) |
756 | return -ENOENT; |
750 | return -ENOENT; |
757 | 751 | ||
758 | if (!obj->filp) { |
752 | if (!obj->filp) { |
759 | drm_gem_object_unreference_unlocked(obj); |
753 | drm_gem_object_unreference_unlocked(obj); |
760 | return -EINVAL; |
754 | return -EINVAL; |
761 | } |
755 | } |
762 | 756 | ||
763 | GetWindowRect(&winrc); |
757 | GetWindowRect(&winrc); |
764 | { |
758 | { |
765 | // static warn_count; |
759 | // static warn_count; |
766 | 760 | ||
767 | mask->width = winrc.right - winrc.left + 1; |
761 | mask->width = winrc.right - winrc.left + 1; |
768 | mask->height = winrc.bottom - winrc.top + 1; |
762 | mask->height = winrc.bottom - winrc.top + 1; |
769 | mask->bo_pitch = (mask->width+15) & ~15; |
763 | mask->bo_pitch = (mask->width+15) & ~15; |
770 | 764 | ||
771 | #if 0 |
765 | #if 0 |
772 | if(warn_count < 1) |
766 | if(warn_count < 1) |
773 | { |
767 | { |
774 | printf("left %d top %d right %d bottom %d\n", |
768 | printf("left %d top %d right %d bottom %d\n", |
775 | winrc.left, winrc.top, winrc.right, winrc.bottom); |
769 | winrc.left, winrc.top, winrc.right, winrc.bottom); |
776 | printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size); |
770 | printf("mask pitch %d data %p\n", mask->bo_pitch, mask->bo_size); |
777 | warn_count++; |
771 | warn_count++; |
778 | }; |
772 | }; |
779 | #endif |
773 | #endif |
780 | 774 | ||
781 | }; |
775 | }; |
782 | 776 | ||
783 | 777 | ||
784 | slot = *((u8*)CURRENT_TASK); |
778 | slot = *((u8*)CURRENT_TASK); |
785 | 779 | ||
786 | if( mask_seqno[slot] != os_display->mask_seqno) |
780 | if( mask_seqno[slot] != os_display->mask_seqno) |
787 | { |
781 | { |
788 | u8* src_offset; |
782 | u8* src_offset; |
789 | u8* dst_offset; |
783 | u8* dst_offset; |
790 | u32 ifl; |
784 | u32 ifl; |
791 | 785 | ||
792 | ret = i915_mutex_lock_interruptible(dev); |
786 | ret = i915_mutex_lock_interruptible(dev); |
793 | if (ret) |
787 | if (ret) |
794 | goto err1; |
788 | goto err1; |
795 | 789 | ||
796 | ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true); |
790 | ret = i915_gem_object_set_to_cpu_domain(to_intel_bo(obj), true); |
797 | if(ret !=0 ) |
791 | if(ret != 0 ) |
798 | { |
792 | { |
799 | dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__); |
793 | dbgprintf("%s: i915_gem_object_set_to_cpu_domain failed\n", __FUNCTION__); |
800 | goto err2; |
794 | goto err2; |
801 | }; |
795 | }; |
802 | 796 | ||
803 | // printf("width %d height %d\n", winrc.right, winrc.bottom); |
797 | // printf("width %d height %d\n", winrc.right, winrc.bottom); |
804 | 798 | ||
805 | // slot = 0x01; |
799 | // slot = 0x01; |
806 | 800 | ||
807 | 801 | ||
808 | src_offset = (u8*)( winrc.top*os_display->width + winrc.left); |
802 | src_offset = (u8*)( winrc.top*os_display->width + winrc.left); |
809 | src_offset+= get_display_map(); |
803 | src_offset+= get_display_map(); |
810 | dst_offset = (u8*)mask->bo_map; |
804 | dst_offset = (u8*)mask->bo_map; |
811 | 805 | ||
812 | u32_t tmp_h = mask->height; |
806 | u32_t tmp_h = mask->height; |
813 | 807 | ||
814 | ifl = safe_cli(); |
808 | ifl = safe_cli(); |
815 | { |
809 | { |
816 | mask_seqno[slot] = os_display->mask_seqno; |
810 | mask_seqno[slot] = os_display->mask_seqno; |
817 | 811 | ||
818 | slot|= (slot<<8)|(slot<<16)|(slot<<24); |
812 | slot|= (slot<<8)|(slot<<16)|(slot<<24); |
819 | 813 | ||
820 | __asm__ __volatile__ ( |
814 | __asm__ __volatile__ ( |
821 | "movd %[slot], %%xmm6 \n" |
815 | "movd %[slot], %%xmm6 \n" |
822 | "punpckldq %%xmm6, %%xmm6 \n" |
816 | "punpckldq %%xmm6, %%xmm6 \n" |
823 | "punpcklqdq %%xmm6, %%xmm6 \n" |
817 | "punpcklqdq %%xmm6, %%xmm6 \n" |
824 | :: [slot] "m" (slot) |
818 | :: [slot] "m" (slot) |
825 | :"xmm6"); |
819 | :"xmm6"); |
826 | 820 | ||
827 | while( tmp_h--) |
821 | while( tmp_h--) |
828 | { |
822 | { |
829 | int tmp_w = mask->bo_pitch; |
823 | int tmp_w = mask->width; |
830 | 824 | ||
831 | u8* tmp_src = src_offset; |
825 | u8* tmp_src = src_offset; |
832 | u8* tmp_dst = dst_offset; |
826 | u8* tmp_dst = dst_offset; |
833 | 827 | ||
834 | src_offset+= os_display->width; |
828 | src_offset+= os_display->width; |
835 | dst_offset+= mask->bo_pitch; |
829 | dst_offset+= mask->bo_pitch; |
836 | 830 | ||
837 | while(tmp_w >= 64) |
831 | while(tmp_w >= 64) |
838 | { |
832 | { |
839 | __asm__ __volatile__ ( |
833 | __asm__ __volatile__ ( |
840 | "movdqu (%0), %%xmm0 \n" |
834 | "movdqu (%0), %%xmm0 \n" |
841 | "movdqu 16(%0), %%xmm1 \n" |
835 | "movdqu 16(%0), %%xmm1 \n" |
842 | "movdqu 32(%0), %%xmm2 \n" |
836 | "movdqu 32(%0), %%xmm2 \n" |
843 | "movdqu 48(%0), %%xmm3 \n" |
837 | "movdqu 48(%0), %%xmm3 \n" |
844 | "pcmpeqb %%xmm6, %%xmm0 \n" |
838 | "pcmpeqb %%xmm6, %%xmm0 \n" |
845 | "pcmpeqb %%xmm6, %%xmm1 \n" |
839 | "pcmpeqb %%xmm6, %%xmm1 \n" |
846 | "pcmpeqb %%xmm6, %%xmm2 \n" |
840 | "pcmpeqb %%xmm6, %%xmm2 \n" |
847 | "pcmpeqb %%xmm6, %%xmm3 \n" |
841 | "pcmpeqb %%xmm6, %%xmm3 \n" |
848 | "movdqa %%xmm0, (%%edi) \n" |
842 | "movdqa %%xmm0, (%%edi) \n" |
849 | "movdqa %%xmm1, 16(%%edi) \n" |
843 | "movdqa %%xmm1, 16(%%edi) \n" |
850 | "movdqa %%xmm2, 32(%%edi) \n" |
844 | "movdqa %%xmm2, 32(%%edi) \n" |
851 | "movdqa %%xmm3, 48(%%edi) \n" |
845 | "movdqa %%xmm3, 48(%%edi) \n" |
852 | 846 | ||
853 | :: "r" (tmp_src), "D" (tmp_dst) |
847 | :: "r" (tmp_src), "D" (tmp_dst) |
854 | :"xmm0","xmm1","xmm2","xmm3"); |
848 | :"xmm0","xmm1","xmm2","xmm3"); |
855 | tmp_w -= 64; |
849 | tmp_w -= 64; |
856 | tmp_src += 64; |
850 | tmp_src += 64; |
857 | tmp_dst += 64; |
851 | tmp_dst += 64; |
858 | } |
852 | } |
859 | 853 | ||
860 | if( tmp_w >= 32 ) |
854 | if( tmp_w >= 32 ) |
861 | { |
855 | { |
862 | __asm__ __volatile__ ( |
856 | __asm__ __volatile__ ( |
863 | "movdqu (%0), %%xmm0 \n" |
857 | "movdqu (%0), %%xmm0 \n" |
864 | "movdqu 16(%0), %%xmm1 \n" |
858 | "movdqu 16(%0), %%xmm1 \n" |
865 | "pcmpeqb %%xmm6, %%xmm0 \n" |
859 | "pcmpeqb %%xmm6, %%xmm0 \n" |
866 | "pcmpeqb %%xmm6, %%xmm1 \n" |
860 | "pcmpeqb %%xmm6, %%xmm1 \n" |
867 | "movdqa %%xmm0, (%%edi) \n" |
861 | "movdqa %%xmm0, (%%edi) \n" |
868 | "movdqa %%xmm1, 16(%%edi) \n" |
862 | "movdqa %%xmm1, 16(%%edi) \n" |
869 | 863 | ||
870 | :: "r" (tmp_src), "D" (tmp_dst) |
864 | :: "r" (tmp_src), "D" (tmp_dst) |
871 | :"xmm0","xmm1"); |
865 | :"xmm0","xmm1"); |
872 | tmp_w -= 32; |
866 | tmp_w -= 32; |
873 | tmp_src += 32; |
867 | tmp_src += 32; |
874 | tmp_dst += 32; |
868 | tmp_dst += 32; |
875 | } |
869 | } |
876 | 870 | ||
877 | while( tmp_w > 0 ) |
871 | if( tmp_w >= 16 ) |
878 | { |
872 | { |
879 | __asm__ __volatile__ ( |
873 | __asm__ __volatile__ ( |
880 | "movdqu (%0), %%xmm0 \n" |
874 | "movdqu (%0), %%xmm0 \n" |
881 | "pcmpeqb %%xmm6, %%xmm0 \n" |
875 | "pcmpeqb %%xmm6, %%xmm0 \n" |
882 | "movdqa %%xmm0, (%%edi) \n" |
876 | "movdqa %%xmm0, (%%edi) \n" |
883 | :: "r" (tmp_src), "D" (tmp_dst) |
877 | :: "r" (tmp_src), "D" (tmp_dst) |
884 | :"xmm0"); |
878 | :"xmm0"); |
885 | tmp_w -= 16; |
879 | tmp_w -= 16; |
886 | tmp_src += 16; |
880 | tmp_src += 16; |
887 | tmp_dst += 16; |
881 | tmp_dst += 16; |
888 | } |
882 | } |
889 | }; |
883 | |
- | 884 | if( tmp_w >= 8 ) |
|
- | 885 | { |
|
- | 886 | __asm__ __volatile__ ( |
|
- | 887 | "movq (%0), %%xmm0 \n" |
|
- | 888 | "pcmpeqb %%xmm6, %%xmm0 \n" |
|
- | 889 | "movq %%xmm0, (%%edi) \n" |
|
- | 890 | :: "r" (tmp_src), "D" (tmp_dst) |
|
- | 891 | :"xmm0"); |
|
- | 892 | tmp_w -= 8; |
|
- | 893 | tmp_src += 8; |
|
- | 894 | tmp_dst += 8; |
|
- | 895 | } |
|
- | 896 | if( tmp_w >= 4 ) |
|
- | 897 | { |
|
- | 898 | __asm__ __volatile__ ( |
|
- | 899 | "movd (%0), %%xmm0 \n" |
|
- | 900 | "pcmpeqb %%xmm6, %%xmm0 \n" |
|
- | 901 | "movd %%xmm0, (%%edi) \n" |
|
- | 902 | :: "r" (tmp_src), "D" (tmp_dst) |
|
- | 903 | :"xmm0"); |
|
- | 904 | tmp_w -= 4; |
|
- | 905 | tmp_src += 4; |
|
- | 906 | tmp_dst += 4; |
|
- | 907 | } |
|
- | 908 | while(tmp_w--) |
|
- | 909 | *tmp_dst++ = (*tmp_src++ == (u8)slot) ? 0xFF:0x00; |
|
- | 910 | }; |
|
890 | }; |
911 | }; |
891 | safe_sti(ifl); |
912 | safe_sti(ifl); |
892 | 913 | ||
893 | ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false); |
914 | ret = i915_gem_object_set_to_gtt_domain(to_intel_bo(obj), false); |
894 | if(ret != 0 ) |
915 | if(ret != 0 ) |
895 | { |
916 | { |
896 | dbgprintf("%s: i915_gem_object_set_to_gtt_domain failed\n", __FUNCTION__); |
917 | dbgprintf("%s: i915_gem_object_set_to_gtt_domain failed\n", __FUNCTION__); |
897 | }; |
918 | }; |
898 | } |
919 | } |
899 | 920 | ||
900 | err2: |
921 | err2: |
901 | mutex_unlock(&dev->struct_mutex); |
922 | mutex_unlock(&dev->struct_mutex); |
902 | err1: |
923 | err1: |
903 | drm_gem_object_unreference(obj); |
924 | drm_gem_object_unreference(obj); |
904 | 925 | ||
905 | return ret; |
926 | return ret; |
906 | } |
927 | } |
907 | 928 | ||
908 | 929 | ||
909 | 930 | ||
910 | 931 | ||
911 | 932 | ||
912 | 933 | ||
913 | 934 | ||
914 | 935 | ||
915 | 936 | ||
916 | 937 | ||
917 | 938 | ||
918 | 939 | ||
919 | #define NSEC_PER_SEC 1000000000L |
940 | #define NSEC_PER_SEC 1000000000L |
920 | 941 | ||
921 | void getrawmonotonic(struct timespec *ts) |
942 | void getrawmonotonic(struct timespec *ts) |
922 | { |
943 | { |
923 | u32 tmp = GetTimerTicks(); |
944 | u32 tmp = GetTimerTicks(); |
924 | 945 | ||
925 | ts->tv_sec = tmp/100; |
946 | ts->tv_sec = tmp/100; |
926 | ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000; |
947 | ts->tv_nsec = (tmp - ts->tv_sec*100)*10000000; |
927 | } |
948 | } |
928 | 949 | ||
929 | void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec) |
950 | void set_normalized_timespec(struct timespec *ts, time_t sec, s64 nsec) |
930 | { |
951 | { |
931 | while (nsec >= NSEC_PER_SEC) { |
952 | while (nsec >= NSEC_PER_SEC) { |
932 | /* |
953 | /* |
933 | * The following asm() prevents the compiler from |
954 | * The following asm() prevents the compiler from |
934 | * optimising this loop into a modulo operation. See |
955 | * optimising this loop into a modulo operation. See |
935 | * also __iter_div_u64_rem() in include/linux/time.h |
956 | * also __iter_div_u64_rem() in include/linux/time.h |
936 | */ |
957 | */ |
937 | asm("" : "+rm"(nsec)); |
958 | asm("" : "+rm"(nsec)); |
938 | nsec -= NSEC_PER_SEC; |
959 | nsec -= NSEC_PER_SEC; |
939 | ++sec; |
960 | ++sec; |
940 | } |
961 | } |
941 | while (nsec < 0) { |
962 | while (nsec < 0) { |
942 | asm("" : "+rm"(nsec)); |
963 | asm("" : "+rm"(nsec)); |
943 | nsec += NSEC_PER_SEC; |
964 | nsec += NSEC_PER_SEC; |
944 | --sec; |
965 | --sec; |
945 | } |
966 | } |
946 | ts->tv_sec = sec; |
967 | ts->tv_sec = sec; |
947 | ts->tv_nsec = nsec; |
968 | ts->tv_nsec = nsec; |
948 | } |
969 | } |
949 | 970 | ||
950 | void |
971 | void |
951 | prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) |
972 | prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state) |
952 | { |
973 | { |
953 | unsigned long flags; |
974 | unsigned long flags; |
954 | 975 | ||
955 | // wait->flags &= ~WQ_FLAG_EXCLUSIVE; |
976 | // wait->flags &= ~WQ_FLAG_EXCLUSIVE; |
956 | spin_lock_irqsave(&q->lock, flags); |
977 | spin_lock_irqsave(&q->lock, flags); |
957 | if (list_empty(&wait->task_list)) |
978 | if (list_empty(&wait->task_list)) |
958 | __add_wait_queue(q, wait); |
979 | __add_wait_queue(q, wait); |
959 | spin_unlock_irqrestore(&q->lock, flags); |
980 | spin_unlock_irqrestore(&q->lock, flags); |
960 | } |
981 | } |
961 | 982 | ||
962 | /** |
983 | /** |
963 | * finish_wait - clean up after waiting in a queue |
984 | * finish_wait - clean up after waiting in a queue |
964 | * @q: waitqueue waited on |
985 | * @q: waitqueue waited on |
965 | * @wait: wait descriptor |
986 | * @wait: wait descriptor |
966 | * |
987 | * |
967 | * Sets current thread back to running state and removes |
988 | * Sets current thread back to running state and removes |
968 | * the wait descriptor from the given waitqueue if still |
989 | * the wait descriptor from the given waitqueue if still |
969 | * queued. |
990 | * queued. |
970 | */ |
991 | */ |
971 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) |
992 | void finish_wait(wait_queue_head_t *q, wait_queue_t *wait) |
972 | { |
993 | { |
973 | unsigned long flags; |
994 | unsigned long flags; |
974 | 995 | ||
975 | // __set_current_state(TASK_RUNNING); |
996 | // __set_current_state(TASK_RUNNING); |
976 | /* |
997 | /* |
977 | * We can check for list emptiness outside the lock |
998 | * We can check for list emptiness outside the lock |
978 | * IFF: |
999 | * IFF: |
979 | * - we use the "careful" check that verifies both |
1000 | * - we use the "careful" check that verifies both |
980 | * the next and prev pointers, so that there cannot |
1001 | * the next and prev pointers, so that there cannot |
981 | * be any half-pending updates in progress on other |
1002 | * be any half-pending updates in progress on other |
982 | * CPU's that we haven't seen yet (and that might |
1003 | * CPU's that we haven't seen yet (and that might |
983 | * still change the stack area. |
1004 | * still change the stack area. |
984 | * and |
1005 | * and |
985 | * - all other users take the lock (ie we can only |
1006 | * - all other users take the lock (ie we can only |
986 | * have _one_ other CPU that looks at or modifies |
1007 | * have _one_ other CPU that looks at or modifies |
987 | * the list). |
1008 | * the list). |
988 | */ |
1009 | */ |
989 | if (!list_empty_careful(&wait->task_list)) { |
1010 | if (!list_empty_careful(&wait->task_list)) { |
990 | spin_lock_irqsave(&q->lock, flags); |
1011 | spin_lock_irqsave(&q->lock, flags); |
991 | list_del_init(&wait->task_list); |
1012 | list_del_init(&wait->task_list); |
992 | spin_unlock_irqrestore(&q->lock, flags); |
1013 | spin_unlock_irqrestore(&q->lock, flags); |
993 | } |
1014 | } |
994 | 1015 | ||
995 | DestroyEvent(wait->evnt); |
1016 | DestroyEvent(wait->evnt); |
996 | } |
1017 | } |
997 | 1018 | ||
998 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) |
1019 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key) |
999 | { |
1020 | { |
1000 | list_del_init(&wait->task_list); |
1021 | list_del_init(&wait->task_list); |
1001 | return 1; |
1022 | return 1; |
1002 | } |
1023 | } |
1003 | 1024 | ||
1004 | unsigned int hweight16(unsigned int w) |
1025 | unsigned int hweight16(unsigned int w) |
1005 | { |
1026 | { |
1006 | unsigned int res = w - ((w >> 1) & 0x5555); |
1027 | unsigned int res = w - ((w >> 1) & 0x5555); |
1007 | res = (res & 0x3333) + ((res >> 2) & 0x3333); |
1028 | res = (res & 0x3333) + ((res >> 2) & 0x3333); |
1008 | res = (res + (res >> 4)) & 0x0F0F; |
1029 | res = (res + (res >> 4)) & 0x0F0F; |
1009 | return (res + (res >> 8)) & 0x00FF; |
1030 | return (res + (res >> 8)) & 0x00FF; |
1010 | } |
1031 | } |
1011 | 1032 | ||
1012 | 1033 | ||
1013 | unsigned long round_jiffies_up_relative(unsigned long j) |
1034 | unsigned long round_jiffies_up_relative(unsigned long j) |
1014 | { |
1035 | { |
1015 | unsigned long j0 = GetTimerTicks(); |
1036 | unsigned long j0 = GetTimerTicks(); |
1016 | 1037 | ||
1017 | /* Use j0 because jiffies might change while we run */ |
1038 | /* Use j0 because jiffies might change while we run */ |
1018 | return round_jiffies_common(j + j0, true) - j0; |
1039 | return round_jiffies_common(j + j0, true) - j0; |
1019 | }>24); |
1040 | }>24); |
1020 | 1041 | ||
1021 | ><24); |
1042 | ><24); |
1022 | 1043 | ||
1023 | >16)|(slot<<24); |
1044 | >16)|(slot<<24); |
1024 | 1045 | ||
1025 | ><16)|(slot<<24); |
1046 | ><16)|(slot<<24); |
1026 | 1047 | ||
1027 | >8)|(slot<<16)|(slot<<24); |
1048 | >8)|(slot<<16)|(slot<<24); |
1028 | 1049 | ||
1029 | ><8)|(slot<<16)|(slot<<24); |
1050 | ><8)|(slot<<16)|(slot<<24); |
1030 | 1051 | ||
1031 | >>><>><>>>><>><>>>><>>>>>>=><=>><> |
1052 | >>><>><>>>><>><>>>><>>>>>>=><=>><> |