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