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