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