Rev 1128 | Rev 1182 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 1128 | Rev 1179 | ||
---|---|---|---|
Line 25... | Line 25... | ||
25 | */ |
25 | */ |
26 | /* |
26 | /* |
27 | * Modularization |
27 | * Modularization |
28 | */ |
28 | */ |
Line 29... | Line 29... | ||
29 | 29 | ||
30 | //#include |
- | |
31 | //#include |
- | |
32 | //#include |
- | |
33 | //#include |
- | |
34 | //#include |
- | |
35 | //#include |
- | |
36 | //#include |
- | |
37 | //#include |
30 | #include |
38 | //#include |
- | |
Line 39... | Line 31... | ||
39 | //#include |
31 | #include |
40 | 32 | ||
41 | #include "drmP.h" |
33 | #include "drmP.h" |
42 | #include "drm.h" |
34 | #include "drm.h" |
43 | #include "drm_crtc.h" |
35 | #include "drm_crtc.h" |
44 | #include "drm_crtc_helper.h" |
36 | #include "drm_crtc_helper.h" |
Line -... | Line 37... | ||
- | 37 | #include "radeon_drm.h" |
|
- | 38 | #include "radeon.h" |
|
45 | #include "radeon_drm.h" |
39 | |
46 | #include "radeon.h" |
40 | #include "drm_fb_helper.h" |
Line 47... | Line -... | ||
47 | - | ||
48 | #include |
- | |
49 | #include "radeon_object.h" |
- | |
50 | - | ||
51 | - | ||
52 | #define FB_TYPE_PACKED_PIXELS 0 /* Packed Pixels */ |
- | |
53 | #define FB_VISUAL_TRUECOLOR 2 /* True color */ |
- | |
54 | - | ||
55 | struct fb_fix_screeninfo { |
- | |
56 | char id[16]; /* identification string eg "TT Builtin" */ |
- | |
57 | unsigned long smem_start; /* Start of frame buffer mem */ |
- | |
58 | /* (physical address) */ |
- | |
59 | __u32 smem_len; /* Length of frame buffer mem */ |
- | |
60 | __u32 type; /* see FB_TYPE_* */ |
- | |
61 | __u32 type_aux; /* Interleave for interleaved Planes */ |
- | |
62 | __u32 visual; /* see FB_VISUAL_* */ |
- | |
63 | __u16 xpanstep; /* zero if no hardware panning */ |
- | |
64 | __u16 ypanstep; /* zero if no hardware panning */ |
- | |
65 | __u16 ywrapstep; /* zero if no hardware ywrap */ |
- | |
66 | __u32 line_length; /* length of a line in bytes */ |
- | |
67 | unsigned long mmio_start; /* Start of Memory Mapped I/O */ |
- | |
68 | /* (physical address) */ |
- | |
69 | __u32 mmio_len; /* Length of Memory Mapped I/O */ |
- | |
70 | __u32 accel; /* Indicate to driver which */ |
- | |
71 | /* specific chip/card we have */ |
- | |
72 | __u16 reserved[3]; /* Reserved for future compatibility */ |
- | |
73 | }; |
- | |
74 | - | ||
75 | - | ||
76 | - | ||
77 | - | ||
78 | struct fb_bitfield { |
- | |
79 | __u32 offset; /* beginning of bitfield */ |
- | |
80 | __u32 length; /* length of bitfield */ |
- | |
81 | __u32 msb_right; /* != 0 : Most significant bit is */ |
- | |
82 | /* right */ |
- | |
83 | }; |
- | |
84 | - | ||
85 | - | ||
86 | struct fb_var_screeninfo { |
- | |
87 | __u32 xres; /* visible resolution */ |
- | |
88 | __u32 yres; |
- | |
89 | __u32 xres_virtual; /* virtual resolution */ |
- | |
90 | __u32 yres_virtual; |
- | |
91 | __u32 xoffset; /* offset from virtual to visible */ |
- | |
92 | __u32 yoffset; /* resolution */ |
- | |
93 | - | ||
94 | __u32 bits_per_pixel; /* guess what */ |
- | |
95 | __u32 grayscale; /* != 0 Graylevels instead of colors */ |
- | |
96 | - | ||
97 | struct fb_bitfield red; /* bitfield in fb mem if true color, */ |
- | |
98 | struct fb_bitfield green; /* else only length is significant */ |
- | |
99 | struct fb_bitfield blue; |
- | |
100 | struct fb_bitfield transp; /* transparency */ |
- | |
101 | - | ||
102 | __u32 nonstd; /* != 0 Non standard pixel format */ |
- | |
103 | - | ||
104 | __u32 activate; /* see FB_ACTIVATE_* */ |
- | |
105 | - | ||
106 | __u32 height; /* height of picture in mm */ |
- | |
107 | __u32 width; /* width of picture in mm */ |
- | |
108 | - | ||
109 | __u32 accel_flags; /* (OBSOLETE) see fb_info.flags */ |
- | |
110 | - | ||
111 | /* Timing: All values in pixclocks, except pixclock (of course) */ |
- | |
112 | __u32 pixclock; /* pixel clock in ps (pico seconds) */ |
- | |
113 | __u32 left_margin; /* time from sync to picture */ |
- | |
114 | __u32 right_margin; /* time from picture to sync */ |
- | |
115 | __u32 upper_margin; /* time from sync to picture */ |
- | |
116 | __u32 lower_margin; |
- | |
117 | __u32 hsync_len; /* length of horizontal sync */ |
- | |
118 | __u32 vsync_len; /* length of vertical sync */ |
- | |
119 | __u32 sync; /* see FB_SYNC_* */ |
- | |
120 | __u32 vmode; /* see FB_VMODE_* */ |
- | |
121 | __u32 rotate; /* angle we rotate counter clockwise */ |
- | |
122 | __u32 reserved[5]; /* Reserved for future compatibility */ |
- | |
123 | }; |
- | |
124 | - | ||
125 | - | ||
126 | - | ||
127 | struct fb_chroma { |
- | |
128 | __u32 redx; /* in fraction of 1024 */ |
- | |
129 | __u32 greenx; |
- | |
130 | __u32 bluex; |
- | |
131 | __u32 whitex; |
- | |
132 | __u32 redy; |
- | |
133 | __u32 greeny; |
- | |
134 | __u32 bluey; |
- | |
135 | __u32 whitey; |
- | |
136 | }; |
- | |
137 | - | ||
138 | struct fb_videomode { |
- | |
139 | const char *name; /* optional */ |
- | |
140 | u32 refresh; /* optional */ |
- | |
141 | u32 xres; |
- | |
142 | u32 yres; |
- | |
143 | u32 pixclock; |
- | |
144 | u32 left_margin; |
- | |
145 | u32 right_margin; |
- | |
146 | u32 upper_margin; |
- | |
147 | u32 lower_margin; |
- | |
148 | u32 hsync_len; |
- | |
149 | u32 vsync_len; |
- | |
150 | u32 sync; |
- | |
151 | u32 vmode; |
- | |
152 | u32 flag; |
- | |
153 | }; |
- | |
154 | - | ||
155 | - | ||
156 | struct fb_monspecs { |
- | |
157 | struct fb_chroma chroma; |
- | |
158 | struct fb_videomode *modedb; /* mode database */ |
- | |
159 | __u8 manufacturer[4]; /* Manufacturer */ |
- | |
160 | __u8 monitor[14]; /* Monitor String */ |
- | |
161 | __u8 serial_no[14]; /* Serial Number */ |
- | |
162 | __u8 ascii[14]; /* ? */ |
- | |
163 | __u32 modedb_len; /* mode database length */ |
- | |
164 | __u32 model; /* Monitor Model */ |
- | |
165 | __u32 serial; /* Serial Number - Integer */ |
- | |
166 | __u32 year; /* Year manufactured */ |
- | |
167 | __u32 week; /* Week Manufactured */ |
- | |
168 | __u32 hfmin; /* hfreq lower limit (Hz) */ |
- | |
169 | __u32 hfmax; /* hfreq upper limit (Hz) */ |
- | |
170 | __u32 dclkmin; /* pixelclock lower limit (Hz) */ |
- | |
171 | __u32 dclkmax; /* pixelclock upper limit (Hz) */ |
- | |
172 | __u16 input; /* display type - see FB_DISP_* */ |
- | |
173 | __u16 dpms; /* DPMS support - see FB_DPMS_ */ |
- | |
174 | __u16 signal; /* Signal Type - see FB_SIGNAL_* */ |
- | |
175 | __u16 vfmin; /* vfreq lower limit (Hz) */ |
- | |
176 | __u16 vfmax; /* vfreq upper limit (Hz) */ |
- | |
177 | __u16 gamma; /* Gamma - in fractions of 100 */ |
- | |
178 | __u16 gtf : 1; /* supports GTF */ |
- | |
179 | __u16 misc; /* Misc flags - see FB_MISC_* */ |
- | |
180 | __u8 version; /* EDID version... */ |
- | |
181 | __u8 revision; /* ...and revision */ |
- | |
182 | __u8 max_x; /* Maximum horizontal size (cm) */ |
- | |
183 | __u8 max_y; /* Maximum vertical size (cm) */ |
- | |
184 | }; |
- | |
185 | - | ||
186 | - | ||
187 | struct fb_info { |
- | |
188 | int node; |
- | |
189 | int flags; |
- | |
190 | // struct mutex lock; /* Lock for open/release/ioctl funcs */ |
- | |
191 | // struct mutex mm_lock; /* Lock for fb_mmap and smem_* fields */ |
- | |
192 | struct fb_var_screeninfo var; /* Current var */ |
- | |
193 | struct fb_fix_screeninfo fix; /* Current fix */ |
- | |
194 | struct fb_monspecs monspecs; /* Current Monitor specs */ |
- | |
195 | // struct work_struct queue; /* Framebuffer event queue */ |
- | |
196 | // struct fb_pixmap pixmap; /* Image hardware mapper */ |
- | |
197 | // struct fb_pixmap sprite; /* Cursor hardware mapper */ |
- | |
198 | // struct fb_cmap cmap; /* Current cmap */ |
- | |
199 | struct list_head modelist; /* mode list */ |
- | |
200 | struct fb_videomode *mode; /* current mode */ |
41 | |
201 | - | ||
202 | #ifdef CONFIG_FB_BACKLIGHT |
- | |
203 | /* assigned backlight device */ |
- | |
204 | /* set before framebuffer registration, |
- | |
205 | remove after unregister */ |
- | |
206 | struct backlight_device *bl_dev; |
- | |
207 | - | ||
208 | /* Backlight level curve */ |
- | |
209 | struct mutex bl_curve_mutex; |
- | |
210 | u8 bl_curve[FB_BACKLIGHT_LEVELS]; |
- | |
211 | #endif |
- | |
212 | #ifdef CONFIG_FB_DEFERRED_IO |
- | |
213 | struct delayed_work deferred_work; |
- | |
214 | struct fb_deferred_io *fbdefio; |
- | |
215 | #endif |
- | |
216 | - | ||
217 | struct fb_ops *fbops; |
- | |
218 | // struct device *device; /* This is the parent */ |
- | |
219 | // struct device *dev; /* This is this fb device */ |
- | |
220 | int class_flag; /* private sysfs flags */ |
- | |
221 | #ifdef CONFIG_FB_TILEBLITTING |
- | |
222 | struct fb_tile_ops *tileops; /* Tile Blitting */ |
- | |
223 | #endif |
- | |
224 | char __iomem *screen_base; /* Virtual address */ |
- | |
225 | unsigned long screen_size; /* Amount of ioremapped VRAM or 0 */ |
- | |
226 | void *pseudo_palette; /* Fake palette of 16 colors */ |
- | |
227 | #define FBINFO_STATE_RUNNING 0 |
- | |
228 | #define FBINFO_STATE_SUSPENDED 1 |
- | |
229 | u32 state; /* Hardware state i.e suspend */ |
- | |
230 | void *fbcon_par; /* fbcon use-only private area */ |
- | |
231 | /* From here on everything is device dependent */ |
- | |
232 | void *par; |
- | |
233 | /* we need the PCI or similiar aperture base/size not |
- | |
234 | smem_start/size as smem_start may just be an object |
- | |
235 | allocated inside the aperture so may not actually overlap */ |
- | |
236 | resource_size_t aperture_base; |
- | |
Line 237... | Line 42... | ||
237 | resource_size_t aperture_size; |
42 | #include |
238 | }; |
- | |
239 | 43 | #include "radeon_object.h" |
|
240 | 44 | ||
241 | - | ||
242 | struct radeon_fb_device { |
- | |
243 | struct radeon_device *rdev; |
45 | struct fb_info *framebuffer_alloc(size_t size); |
244 | struct drm_display_mode *mode; |
46 | |
Line 245... | Line -... | ||
245 | struct radeon_framebuffer *rfb; |
- | |
246 | int crtc_count; |
- | |
247 | /* crtc currently bound to this */ |
- | |
248 | uint32_t crtc_ids[2]; |
- | |
249 | }; |
- | |
250 | - | ||
251 | int radeon_gem_fb_object_create(struct radeon_device *rdev, int size, |
- | |
252 | int alignment, int initial_domain, |
- | |
253 | bool discardable, bool kernel, |
- | |
254 | bool interruptible, |
- | |
255 | struct drm_gem_object **obj); |
- | |
256 | - | ||
257 | struct fb_info *framebuffer_alloc(size_t size); |
- | |
258 | - | ||
259 | #if 0 |
- | |
260 | static int radeonfb_setcolreg(unsigned regno, |
- | |
261 | unsigned red, |
- | |
262 | unsigned green, |
- | |
263 | unsigned blue, |
- | |
264 | unsigned transp, |
- | |
265 | struct fb_info *info) |
- | |
266 | { |
- | |
267 | struct radeon_fb_device *rfbdev = info->par; |
- | |
268 | struct drm_device *dev = rfbdev->rdev->ddev; |
- | |
269 | struct drm_crtc *crtc; |
- | |
270 | int i; |
- | |
271 | - | ||
272 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
- | |
273 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
- | |
274 | struct drm_mode_set *modeset = &radeon_crtc->mode_set; |
- | |
275 | struct drm_framebuffer *fb = modeset->fb; |
- | |
276 | - | ||
277 | for (i = 0; i < rfbdev->crtc_count; i++) { |
- | |
278 | if (crtc->base.id == rfbdev->crtc_ids[i]) { |
- | |
279 | break; |
- | |
280 | } |
- | |
281 | } |
- | |
282 | if (i == rfbdev->crtc_count) { |
- | |
283 | continue; |
- | |
284 | } |
- | |
285 | if (regno > 255) { |
- | |
286 | return 1; |
- | |
287 | } |
- | |
288 | if (fb->depth == 8) { |
- | |
289 | radeon_crtc_fb_gamma_set(crtc, red, green, blue, regno); |
- | |
290 | return 0; |
- | |
291 | } |
- | |
292 | - | ||
293 | if (regno < 16) { |
- | |
294 | switch (fb->depth) { |
- | |
295 | case 15: |
- | |
296 | fb->pseudo_palette[regno] = ((red & 0xf800) >> 1) | |
- | |
297 | ((green & 0xf800) >> 6) | |
- | |
298 | ((blue & 0xf800) >> 11); |
- | |
299 | break; |
- | |
300 | case 16: |
- | |
301 | fb->pseudo_palette[regno] = (red & 0xf800) | |
- | |
302 | ((green & 0xfc00) >> 5) | |
- | |
303 | ((blue & 0xf800) >> 11); |
- | |
304 | break; |
- | |
305 | case 24: |
- | |
306 | case 32: |
- | |
307 | fb->pseudo_palette[regno] = ((red & 0xff00) << 8) | |
- | |
308 | (green & 0xff00) | |
- | |
309 | ((blue & 0xff00) >> 8); |
- | |
310 | break; |
- | |
311 | } |
- | |
312 | } |
- | |
313 | } |
- | |
314 | return 0; |
- | |
315 | } |
- | |
316 | - | ||
317 | static int radeonfb_check_var(struct fb_var_screeninfo *var, |
- | |
318 | struct fb_info *info) |
- | |
319 | { |
- | |
320 | struct radeon_fb_device *rfbdev = info->par; |
- | |
321 | struct radeon_framebuffer *rfb = rfbdev->rfb; |
- | |
322 | struct drm_framebuffer *fb = &rfb->base; |
- | |
323 | int depth; |
- | |
324 | - | ||
325 | if (var->pixclock == -1 || !var->pixclock) { |
- | |
326 | return -EINVAL; |
- | |
327 | } |
- | |
328 | /* Need to resize the fb object !!! */ |
- | |
329 | if (var->xres > fb->width || var->yres > fb->height) { |
- | |
330 | DRM_ERROR("Requested width/height is greater than current fb " |
- | |
331 | "object %dx%d > %dx%d\n", var->xres, var->yres, |
- | |
332 | fb->width, fb->height); |
- | |
333 | DRM_ERROR("Need resizing code.\n"); |
- | |
334 | return -EINVAL; |
- | |
335 | } |
- | |
336 | - | ||
337 | switch (var->bits_per_pixel) { |
- | |
338 | case 16: |
- | |
339 | depth = (var->green.length == 6) ? 16 : 15; |
- | |
340 | break; |
- | |
341 | case 32: |
- | |
342 | depth = (var->transp.length > 0) ? 32 : 24; |
- | |
343 | break; |
- | |
344 | default: |
- | |
345 | depth = var->bits_per_pixel; |
- | |
346 | break; |
- | |
347 | } |
- | |
348 | - | ||
349 | switch (depth) { |
- | |
350 | case 8: |
- | |
351 | var->red.offset = 0; |
- | |
352 | var->green.offset = 0; |
- | |
353 | var->blue.offset = 0; |
- | |
354 | var->red.length = 8; |
- | |
355 | var->green.length = 8; |
- | |
356 | var->blue.length = 8; |
- | |
357 | var->transp.length = 0; |
- | |
358 | var->transp.offset = 0; |
- | |
359 | break; |
- | |
360 | case 15: |
- | |
361 | var->red.offset = 10; |
- | |
362 | var->green.offset = 5; |
- | |
363 | var->blue.offset = 0; |
- | |
364 | var->red.length = 5; |
- | |
365 | var->green.length = 5; |
- | |
366 | var->blue.length = 5; |
- | |
367 | var->transp.length = 1; |
- | |
368 | var->transp.offset = 15; |
- | |
369 | break; |
- | |
370 | case 16: |
- | |
371 | var->red.offset = 11; |
- | |
372 | var->green.offset = 5; |
- | |
373 | var->blue.offset = 0; |
- | |
374 | var->red.length = 5; |
- | |
375 | var->green.length = 6; |
- | |
376 | var->blue.length = 5; |
- | |
377 | var->transp.length = 0; |
- | |
378 | var->transp.offset = 0; |
- | |
379 | break; |
- | |
380 | case 24: |
- | |
381 | var->red.offset = 16; |
- | |
382 | var->green.offset = 8; |
- | |
383 | var->blue.offset = 0; |
- | |
384 | var->red.length = 8; |
- | |
385 | var->green.length = 8; |
- | |
386 | var->blue.length = 8; |
- | |
387 | var->transp.length = 0; |
- | |
388 | var->transp.offset = 0; |
- | |
389 | break; |
- | |
390 | case 32: |
- | |
391 | var->red.offset = 16; |
- | |
392 | var->green.offset = 8; |
- | |
393 | var->blue.offset = 0; |
- | |
394 | var->red.length = 8; |
- | |
395 | var->green.length = 8; |
- | |
396 | var->blue.length = 8; |
- | |
397 | var->transp.length = 8; |
- | |
398 | var->transp.offset = 24; |
- | |
399 | break; |
- | |
400 | default: |
- | |
401 | return -EINVAL; |
- | |
402 | } |
- | |
403 | return 0; |
- | |
404 | } |
- | |
405 | - | ||
406 | #endif |
- | |
407 | - | ||
408 | - | ||
409 | /* this will let fbcon do the mode init */ |
- | |
410 | static int radeonfb_set_par(struct fb_info *info) |
- | |
411 | { |
- | |
412 | struct radeon_fb_device *rfbdev = info->par; |
- | |
413 | struct drm_device *dev = rfbdev->rdev->ddev; |
- | |
414 | struct fb_var_screeninfo *var = &info->var; |
- | |
415 | struct drm_crtc *crtc; |
- | |
416 | int ret; |
- | |
417 | int i; |
- | |
418 | - | ||
419 | if (var->pixclock != -1) { |
- | |
420 | DRM_ERROR("PIXEL CLCOK SET\n"); |
- | |
421 | return -EINVAL; |
- | |
422 | } |
- | |
423 | - | ||
424 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
- | |
425 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
- | |
426 | - | ||
427 | for (i = 0; i < rfbdev->crtc_count; i++) { |
- | |
428 | if (crtc->base.id == rfbdev->crtc_ids[i]) { |
- | |
429 | break; |
- | |
430 | } |
- | |
431 | } |
- | |
432 | if (i == rfbdev->crtc_count) { |
- | |
433 | continue; |
- | |
434 | } |
- | |
435 | if (crtc->fb == radeon_crtc->mode_set.fb) { |
- | |
436 | // mutex_lock(&dev->mode_config.mutex); |
- | |
437 | ret = crtc->funcs->set_config(&radeon_crtc->mode_set); |
- | |
438 | // mutex_unlock(&dev->mode_config.mutex); |
- | |
439 | if (ret) { |
- | |
440 | return ret; |
- | |
441 | } |
- | |
442 | } |
- | |
443 | } |
- | |
444 | return 0; |
- | |
445 | } |
- | |
446 | - | ||
447 | #if 0 |
- | |
448 | - | ||
449 | static int radeonfb_pan_display(struct fb_var_screeninfo *var, |
- | |
450 | struct fb_info *info) |
- | |
451 | { |
- | |
452 | struct radeon_fb_device *rfbdev = info->par; |
- | |
453 | struct drm_device *dev = rfbdev->rdev->ddev; |
- | |
454 | struct drm_mode_set *modeset; |
- | |
455 | struct drm_crtc *crtc; |
- | |
456 | struct radeon_crtc *radeon_crtc; |
- | |
457 | int ret = 0; |
- | |
458 | int i; |
- | |
459 | - | ||
460 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
- | |
461 | for (i = 0; i < rfbdev->crtc_count; i++) { |
- | |
462 | if (crtc->base.id == rfbdev->crtc_ids[i]) { |
- | |
463 | break; |
- | |
464 | } |
- | |
465 | } |
- | |
466 | - | ||
467 | if (i == rfbdev->crtc_count) { |
- | |
468 | continue; |
- | |
469 | } |
- | |
470 | - | ||
471 | radeon_crtc = to_radeon_crtc(crtc); |
- | |
472 | modeset = &radeon_crtc->mode_set; |
- | |
473 | - | ||
474 | modeset->x = var->xoffset; |
- | |
475 | modeset->y = var->yoffset; |
- | |
476 | - | ||
477 | if (modeset->num_connectors) { |
- | |
478 | mutex_lock(&dev->mode_config.mutex); |
- | |
479 | ret = crtc->funcs->set_config(modeset); |
- | |
480 | mutex_unlock(&dev->mode_config.mutex); |
- | |
481 | if (!ret) { |
- | |
482 | info->var.xoffset = var->xoffset; |
- | |
483 | info->var.yoffset = var->yoffset; |
- | |
484 | } |
- | |
485 | } |
- | |
486 | } |
- | |
487 | return ret; |
- | |
488 | } |
- | |
489 | - | ||
490 | static void radeonfb_on(struct fb_info *info) |
- | |
491 | { |
- | |
492 | struct radeon_fb_device *rfbdev = info->par; |
- | |
493 | struct drm_device *dev = rfbdev->rdev->ddev; |
- | |
494 | struct drm_crtc *crtc; |
- | |
495 | struct drm_encoder *encoder; |
- | |
496 | int i; |
- | |
497 | - | ||
498 | /* |
- | |
499 | * For each CRTC in this fb, find all associated encoders |
- | |
500 | * and turn them off, then turn off the CRTC. |
- | |
501 | */ |
- | |
502 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
- | |
503 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
- | |
504 | - | ||
505 | for (i = 0; i < rfbdev->crtc_count; i++) { |
- | |
506 | if (crtc->base.id == rfbdev->crtc_ids[i]) { |
- | |
507 | break; |
- | |
508 | } |
- | |
509 | } |
- | |
510 | - | ||
511 | mutex_lock(&dev->mode_config.mutex); |
- | |
512 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); |
- | |
513 | mutex_unlock(&dev->mode_config.mutex); |
- | |
514 | - | ||
515 | /* Found a CRTC on this fb, now find encoders */ |
- | |
516 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
- | |
517 | if (encoder->crtc == crtc) { |
- | |
518 | struct drm_encoder_helper_funcs *encoder_funcs; |
- | |
519 | - | ||
520 | encoder_funcs = encoder->helper_private; |
- | |
521 | mutex_lock(&dev->mode_config.mutex); |
- | |
522 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); |
- | |
523 | mutex_unlock(&dev->mode_config.mutex); |
- | |
524 | } |
- | |
525 | } |
- | |
526 | } |
- | |
527 | } |
- | |
528 | - | ||
529 | static void radeonfb_off(struct fb_info *info, int dpms_mode) |
- | |
530 | { |
- | |
531 | struct radeon_fb_device *rfbdev = info->par; |
- | |
532 | struct drm_device *dev = rfbdev->rdev->ddev; |
- | |
533 | struct drm_crtc *crtc; |
- | |
534 | struct drm_encoder *encoder; |
- | |
535 | int i; |
- | |
536 | - | ||
537 | /* |
- | |
538 | * For each CRTC in this fb, find all associated encoders |
- | |
539 | * and turn them off, then turn off the CRTC. |
- | |
540 | */ |
- | |
541 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
- | |
542 | struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private; |
- | |
543 | - | ||
544 | for (i = 0; i < rfbdev->crtc_count; i++) { |
- | |
545 | if (crtc->base.id == rfbdev->crtc_ids[i]) { |
- | |
546 | break; |
- | |
547 | } |
- | |
548 | } |
- | |
549 | - | ||
550 | /* Found a CRTC on this fb, now find encoders */ |
- | |
551 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
- | |
552 | if (encoder->crtc == crtc) { |
- | |
553 | struct drm_encoder_helper_funcs *encoder_funcs; |
- | |
554 | - | ||
555 | encoder_funcs = encoder->helper_private; |
- | |
556 | mutex_lock(&dev->mode_config.mutex); |
- | |
557 | encoder_funcs->dpms(encoder, dpms_mode); |
- | |
558 | mutex_unlock(&dev->mode_config.mutex); |
- | |
559 | } |
- | |
560 | } |
- | |
561 | if (dpms_mode == DRM_MODE_DPMS_OFF) { |
- | |
562 | mutex_lock(&dev->mode_config.mutex); |
- | |
563 | crtc_funcs->dpms(crtc, dpms_mode); |
- | |
564 | mutex_unlock(&dev->mode_config.mutex); |
- | |
565 | } |
- | |
566 | } |
- | |
567 | } |
- | |
568 | - | ||
569 | int radeonfb_blank(int blank, struct fb_info *info) |
- | |
570 | { |
- | |
571 | switch (blank) { |
- | |
572 | case FB_BLANK_UNBLANK: |
- | |
573 | radeonfb_on(info); |
- | |
574 | break; |
- | |
575 | case FB_BLANK_NORMAL: |
- | |
576 | radeonfb_off(info, DRM_MODE_DPMS_STANDBY); |
- | |
577 | break; |
- | |
578 | case FB_BLANK_HSYNC_SUSPEND: |
- | |
579 | radeonfb_off(info, DRM_MODE_DPMS_STANDBY); |
- | |
580 | break; |
- | |
581 | case FB_BLANK_VSYNC_SUSPEND: |
- | |
582 | radeonfb_off(info, DRM_MODE_DPMS_SUSPEND); |
- | |
583 | break; |
- | |
584 | case FB_BLANK_POWERDOWN: |
- | |
585 | radeonfb_off(info, DRM_MODE_DPMS_OFF); |
47 | struct radeon_fb_device { |
586 | break; |
48 | struct drm_fb_helper helper; |
587 | } |
49 | struct radeon_framebuffer *rfb; |
588 | return 0; |
50 | struct radeon_device *rdev; |
589 | } |
51 | }; |
590 | 52 | ||
591 | static struct fb_ops radeonfb_ops = { |
53 | static struct fb_ops radeonfb_ops = { |
592 | .owner = THIS_MODULE, |
54 | // .owner = THIS_MODULE, |
593 | .fb_check_var = radeonfb_check_var, |
55 | .fb_check_var = drm_fb_helper_check_var, |
594 | .fb_set_par = radeonfb_set_par, |
56 | .fb_set_par = drm_fb_helper_set_par, |
595 | .fb_setcolreg = radeonfb_setcolreg, |
57 | .fb_setcolreg = drm_fb_helper_setcolreg, |
Line 596... | Line 58... | ||
596 | .fb_fillrect = cfb_fillrect, |
58 | // .fb_fillrect = cfb_fillrect, |
597 | .fb_copyarea = cfb_copyarea, |
59 | // .fb_copyarea = cfb_copyarea, |
598 | .fb_imageblit = cfb_imageblit, |
60 | // .fb_imageblit = cfb_imageblit, |
Line 638... | Line 100... | ||
638 | 100 | ||
639 | return 0; |
101 | return 0; |
640 | } |
102 | } |
Line 641... | Line -... | ||
641 | EXPORT_SYMBOL(radeonfb_resize); |
- | |
642 | - | ||
643 | static struct drm_mode_set panic_mode; |
- | |
644 | - | ||
645 | int radeonfb_panic(struct notifier_block *n, unsigned long ununsed, |
- | |
646 | void *panic_str) |
- | |
647 | { |
- | |
648 | DRM_ERROR("panic occurred, switching back to text console\n"); |
- | |
649 | drm_crtc_helper_set_config(&panic_mode); |
- | |
650 | return 0; |
- | |
651 | } |
- | |
652 | EXPORT_SYMBOL(radeonfb_panic); |
- | |
653 | - | ||
654 | static struct notifier_block paniced = { |
- | |
655 | .notifier_call = radeonfb_panic, |
- | |
656 | }; |
- | |
657 | #endif |
103 | EXPORT_SYMBOL(radeonfb_resize); |
658 | 104 | ||
659 | static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp) |
105 | static int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled) |
660 | { |
106 | { |
661 | int aligned = width; |
107 | int aligned = width; |
Line 662... | Line 108... | ||
662 | int align_large = (ASIC_IS_AVIVO(rdev)); |
108 | int align_large = (ASIC_IS_AVIVO(rdev)) || tiled; |
663 | int pitch_mask = 0; |
109 | int pitch_mask = 0; |
664 | 110 | ||
Line 678... | Line 124... | ||
678 | aligned += pitch_mask; |
124 | aligned += pitch_mask; |
679 | aligned &= ~pitch_mask; |
125 | aligned &= ~pitch_mask; |
680 | return aligned; |
126 | return aligned; |
681 | } |
127 | } |
Line -... | Line 128... | ||
- | 128 | ||
- | 129 | static struct drm_fb_helper_funcs radeon_fb_helper_funcs = { |
|
- | 130 | .gamma_set = radeon_crtc_fb_gamma_set, |
|
- | 131 | }; |
|
682 | 132 | ||
683 | int radeonfb_create(struct radeon_device *rdev, |
133 | int radeonfb_create(struct drm_device *dev, |
684 | uint32_t fb_width, uint32_t fb_height, |
134 | uint32_t fb_width, uint32_t fb_height, |
685 | uint32_t surface_width, uint32_t surface_height, |
135 | uint32_t surface_width, uint32_t surface_height, |
686 | struct radeon_framebuffer **rfb_p) |
136 | struct drm_framebuffer **fb_p) |
- | 137 | { |
|
687 | { |
138 | struct radeon_device *rdev = dev->dev_private; |
688 | struct fb_info *info; |
139 | struct fb_info *info; |
689 | struct radeon_fb_device *rfbdev; |
140 | struct radeon_fb_device *rfbdev; |
690 | struct drm_framebuffer *fb = NULL; |
141 | struct drm_framebuffer *fb = NULL; |
691 | struct radeon_framebuffer *rfb; |
142 | struct radeon_framebuffer *rfb; |
Line 695... | Line 146... | ||
695 | // struct device *device = &rdev->pdev->dev; |
146 | // struct device *device = &rdev->pdev->dev; |
696 | int size, aligned_size, ret; |
147 | int size, aligned_size, ret; |
697 | u64 fb_gpuaddr; |
148 | u64 fb_gpuaddr; |
698 | void *fbptr = NULL; |
149 | void *fbptr = NULL; |
699 | unsigned long tmp; |
150 | unsigned long tmp; |
700 | - | ||
- | 151 | bool fb_tiled = false; /* useful for testing */ |
|
701 | ENTRY(); |
152 | u32 tiling_flags = 0; |
Line 702... | Line 153... | ||
702 | 153 | ||
703 | mode_cmd.width = surface_width; |
154 | mode_cmd.width = surface_width; |
704 | mode_cmd.height = surface_height; |
155 | mode_cmd.height = surface_height; |
705 | mode_cmd.bpp = 32; |
156 | mode_cmd.bpp = 32; |
706 | /* need to align pitch with crtc limits */ |
157 | /* need to align pitch with crtc limits */ |
707 | mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp) * ((mode_cmd.bpp + 1) / 8); |
158 | mode_cmd.pitch = radeon_align_pitch(rdev, mode_cmd.width, mode_cmd.bpp, fb_tiled) * ((mode_cmd.bpp + 1) / 8); |
Line 708... | Line 159... | ||
708 | mode_cmd.depth = 32; |
159 | mode_cmd.depth = 24; |
709 | 160 | ||
Line 710... | Line 161... | ||
710 | size = mode_cmd.pitch * mode_cmd.height; |
161 | size = mode_cmd.pitch * mode_cmd.height; |
711 | aligned_size = ALIGN(size, PAGE_SIZE); |
162 | aligned_size = ALIGN(size, PAGE_SIZE); |
712 | 163 | ||
713 | ret = radeon_gem_fb_object_create(rdev, aligned_size, 0, |
164 | ret = radeon_gem_fb_object_create(rdev, aligned_size, 0, |
Line 714... | Line -... | ||
714 | RADEON_GEM_DOMAIN_VRAM, |
- | |
715 | false, 0, |
165 | RADEON_GEM_DOMAIN_VRAM, |
716 | false, &gobj); |
166 | false, 0, |
717 | 167 | false, &gobj); |
|
718 | 168 | ||
719 | if (ret) { |
169 | if (ret) { |
720 | printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", |
170 | printk(KERN_ERR "failed to allocate framebuffer (%d %d)\n", |
721 | surface_width, surface_height); |
171 | surface_width, surface_height); |
Line 722... | Line 172... | ||
722 | ret = -ENOMEM; |
172 | ret = -ENOMEM; |
723 | goto out; |
173 | goto out; |
724 | } |
174 | } |
725 | robj = gobj->driver_private; |
175 | robj = gobj->driver_private; |
726 | 176 | ||
727 | // mutex_lock(&rdev->ddev->struct_mutex); |
177 | mutex_lock(&rdev->ddev->struct_mutex); |
Line 738... | Line 188... | ||
738 | goto out_unref; |
188 | goto out_unref; |
739 | } |
189 | } |
Line 740... | Line 190... | ||
740 | 190 | ||
Line -... | Line 191... | ||
- | 191 | list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); |
|
741 | list_add(&fb->filp_head, &rdev->ddev->mode_config.fb_kernel_list); |
192 | |
742 | - | ||
743 | rfb = to_radeon_framebuffer(fb); |
193 | *fb_p = fb; |
744 | *rfb_p = rfb; |
194 | rfb = to_radeon_framebuffer(fb); |
Line 745... | Line 195... | ||
745 | rdev->fbdev_rfb = rfb; |
195 | rdev->fbdev_rfb = rfb; |
746 | rdev->fbdev_robj = robj; |
196 | rdev->fbdev_robj = robj; |
747 | 197 | ||
748 | info = framebuffer_alloc(sizeof(struct radeon_fb_device)); |
198 | info = framebuffer_alloc(sizeof(struct radeon_fb_device)); |
749 | if (info == NULL) { |
199 | if (info == NULL) { |
- | 200 | ret = -ENOMEM; |
|
- | 201 | goto out_unref; |
|
750 | ret = -ENOMEM; |
202 | } |
- | 203 | ||
- | 204 | rdev->fbdev_info = info; |
|
- | 205 | rfbdev = info->par; |
|
- | 206 | rfbdev->helper.funcs = &radeon_fb_helper_funcs; |
|
- | 207 | rfbdev->helper.dev = dev; |
|
- | 208 | ret = drm_fb_helper_init_crtc_count(&rfbdev->helper, 2, |
|
Line 751... | Line 209... | ||
751 | goto out_unref; |
209 | RADEONFB_CONN_LIMIT); |
752 | } |
210 | if (ret) |
753 | rfbdev = info->par; |
211 | goto out_unref; |
754 | 212 | ||
Line 755... | Line -... | ||
755 | // ret = radeon_object_kmap(robj, &fbptr); |
- | |
Line -... | Line 213... | ||
- | 213 | // ret = radeon_object_kmap(robj, &fbptr); |
|
Line 756... | Line 214... | ||
756 | // if (ret) { |
214 | // if (ret) { |
- | 215 | // goto out_unref; |
|
757 | // goto out_unref; |
216 | // } |
758 | // } |
- | |
759 | - | ||
760 | fbptr = (void*)0xFE000000; // LFB_BASE |
- | |
761 | - | ||
762 | - | ||
763 | strcpy(info->fix.id, "radeondrmfb"); |
- | |
764 | info->fix.type = FB_TYPE_PACKED_PIXELS; |
- | |
- | 217 | ||
765 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
218 | |
766 | info->fix.type_aux = 0; |
219 | fbptr = (void*)0xFE000000; // LFB_BASE |
767 | info->fix.xpanstep = 1; /* doing it in hw */ |
- | |
- | 220 | ||
768 | info->fix.ypanstep = 1; /* doing it in hw */ |
221 | strcpy(info->fix.id, "radeondrmfb"); |
769 | info->fix.ywrapstep = 0; |
222 | |
770 | // info->fix.accel = FB_ACCEL_NONE; |
223 | drm_fb_helper_fill_fix(info, fb->pitch); |
771 | info->fix.type_aux = 0; |
224 | |
772 | // info->flags = FBINFO_DEFAULT; |
225 | info->flags = FBINFO_DEFAULT; |
- | 226 | info->fbops = &radeonfb_ops; |
|
773 | // info->fbops = &radeonfb_ops; |
227 | |
- | 228 | tmp = fb_gpuaddr - rdev->mc.vram_location; |
|
774 | info->fix.line_length = fb->pitch; |
229 | info->fix.smem_start = rdev->mc.aper_base + tmp; |
775 | tmp = fb_gpuaddr - rdev->mc.vram_location; |
230 | info->fix.smem_len = size; |
776 | info->fix.smem_start = rdev->mc.aper_base + tmp; |
231 | info->screen_base = fbptr; |
777 | info->fix.smem_len = size; |
- | |
778 | info->screen_base = fbptr; |
- | |
779 | info->screen_size = size; |
- | |
780 | info->pseudo_palette = fb->pseudo_palette; |
- | |
781 | info->var.xres_virtual = fb->width; |
- | |
782 | info->var.yres_virtual = fb->height; |
- | |
783 | info->var.bits_per_pixel = fb->bits_per_pixel; |
- | |
- | 232 | info->screen_size = size; |
|
784 | info->var.xoffset = 0; |
233 | |
785 | info->var.yoffset = 0; |
234 | drm_fb_helper_fill_var(info, fb, fb_width, fb_height); |
786 | // info->var.activate = FB_ACTIVATE_NOW; |
235 | |
787 | info->var.height = -1; |
236 | /* setup aperture base/size for vesafb takeover */ |
788 | info->var.width = -1; |
237 | info->aperture_base = rdev->ddev->mode_config.fb_base; |
Line 803... | Line 252... | ||
803 | DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base); |
252 | DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base); |
804 | DRM_INFO("size %lu\n", (unsigned long)size); |
253 | DRM_INFO("size %lu\n", (unsigned long)size); |
805 | DRM_INFO("fb depth is %d\n", fb->depth); |
254 | DRM_INFO("fb depth is %d\n", fb->depth); |
806 | DRM_INFO(" pitch is %d\n", fb->pitch); |
255 | DRM_INFO(" pitch is %d\n", fb->pitch); |
Line 807... | Line -... | ||
807 | - | ||
808 | switch (fb->depth) { |
- | |
809 | case 8: |
- | |
810 | info->var.red.offset = 0; |
- | |
811 | info->var.green.offset = 0; |
- | |
812 | info->var.blue.offset = 0; |
- | |
813 | info->var.red.length = 8; /* 8bit DAC */ |
- | |
814 | info->var.green.length = 8; |
- | |
815 | info->var.blue.length = 8; |
- | |
816 | info->var.transp.offset = 0; |
- | |
817 | info->var.transp.length = 0; |
- | |
818 | break; |
- | |
819 | case 15: |
- | |
820 | info->var.red.offset = 10; |
- | |
821 | info->var.green.offset = 5; |
- | |
822 | info->var.blue.offset = 0; |
- | |
823 | info->var.red.length = 5; |
- | |
824 | info->var.green.length = 5; |
- | |
825 | info->var.blue.length = 5; |
- | |
826 | info->var.transp.offset = 15; |
- | |
827 | info->var.transp.length = 1; |
- | |
828 | break; |
- | |
829 | case 16: |
- | |
830 | info->var.red.offset = 11; |
- | |
831 | info->var.green.offset = 5; |
- | |
832 | info->var.blue.offset = 0; |
- | |
833 | info->var.red.length = 5; |
- | |
834 | info->var.green.length = 6; |
- | |
835 | info->var.blue.length = 5; |
- | |
836 | info->var.transp.offset = 0; |
- | |
837 | break; |
- | |
838 | case 24: |
- | |
839 | info->var.red.offset = 16; |
- | |
840 | info->var.green.offset = 8; |
- | |
841 | info->var.blue.offset = 0; |
- | |
842 | info->var.red.length = 8; |
- | |
843 | info->var.green.length = 8; |
- | |
844 | info->var.blue.length = 8; |
- | |
845 | info->var.transp.offset = 0; |
- | |
846 | info->var.transp.length = 0; |
- | |
847 | break; |
- | |
848 | case 32: |
- | |
849 | info->var.red.offset = 16; |
- | |
850 | info->var.green.offset = 8; |
- | |
851 | info->var.blue.offset = 0; |
- | |
852 | info->var.red.length = 8; |
- | |
853 | info->var.green.length = 8; |
- | |
854 | info->var.blue.length = 8; |
- | |
855 | info->var.transp.offset = 24; |
- | |
856 | info->var.transp.length = 8; |
- | |
857 | break; |
- | |
858 | default: |
- | |
859 | break; |
- | |
860 | } |
- | |
861 | 256 | ||
Line 862... | Line 257... | ||
862 | dbgprintf("fb = %x\n", fb); |
257 | dbgprintf("fb = %x\n", fb); |
863 | 258 | ||
864 | fb->fbdev = info; |
259 | fb->fbdev = info; |
Line 865... | Line 260... | ||
865 | rfbdev->rfb = rfb; |
260 | rfbdev->rfb = rfb; |
866 | rfbdev->rdev = rdev; |
261 | rfbdev->rdev = rdev; |
Line 867... | Line 262... | ||
867 | 262 | ||
868 | // mutex_unlock(&rdev->ddev->struct_mutex); |
263 | mutex_unlock(&rdev->ddev->struct_mutex); |
869 | return 0; |
264 | return 0; |
Line 877... | Line 272... | ||
877 | // drm_gem_object_unreference(gobj); |
272 | // drm_gem_object_unreference(gobj); |
878 | // drm_framebuffer_cleanup(fb); |
273 | // drm_framebuffer_cleanup(fb); |
879 | kfree(fb); |
274 | kfree(fb); |
880 | } |
275 | } |
881 | // drm_gem_object_unreference(gobj); |
276 | // drm_gem_object_unreference(gobj); |
882 | // mutex_unlock(&rdev->ddev->struct_mutex); |
277 | mutex_unlock(&rdev->ddev->struct_mutex); |
883 | out: |
278 | out: |
884 | return ret; |
279 | return ret; |
885 | } |
280 | } |
Line 886... | Line -... | ||
886 | - | ||
887 | static int radeonfb_single_fb_probe(struct radeon_device *rdev) |
- | |
888 | { |
- | |
889 | struct drm_crtc *crtc; |
- | |
890 | struct drm_connector *connector; |
- | |
891 | unsigned int fb_width = (unsigned)-1, fb_height = (unsigned)-1; |
- | |
892 | unsigned int surface_width = 0, surface_height = 0; |
- | |
893 | int new_fb = 0; |
- | |
894 | int crtc_count = 0; |
- | |
895 | int ret, i, conn_count = 0; |
- | |
896 | struct radeon_framebuffer *rfb; |
- | |
897 | struct fb_info *info; |
- | |
898 | struct radeon_fb_device *rfbdev; |
- | |
899 | struct drm_mode_set *modeset = NULL; |
- | |
900 | - | ||
901 | ENTRY(); |
- | |
902 | - | ||
903 | /* first up get a count of crtcs now in use and new min/maxes width/heights */ |
- | |
904 | list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) { |
- | |
905 | if (drm_helper_crtc_in_use(crtc)) { |
- | |
906 | if (crtc->desired_mode) { |
- | |
907 | if (crtc->desired_mode->hdisplay < fb_width) |
- | |
908 | fb_width = crtc->desired_mode->hdisplay; |
- | |
909 | - | ||
910 | if (crtc->desired_mode->vdisplay < fb_height) |
- | |
911 | fb_height = crtc->desired_mode->vdisplay; |
- | |
912 | - | ||
913 | if (crtc->desired_mode->hdisplay > surface_width) |
- | |
914 | surface_width = crtc->desired_mode->hdisplay; |
- | |
915 | - | ||
916 | if (crtc->desired_mode->vdisplay > surface_height) |
- | |
917 | surface_height = crtc->desired_mode->vdisplay; |
- | |
918 | } |
- | |
919 | crtc_count++; |
- | |
920 | } |
- | |
921 | } |
- | |
922 | - | ||
923 | if (crtc_count == 0 || fb_width == -1 || fb_height == -1) { |
- | |
924 | /* hmm everyone went away - assume VGA cable just fell out |
- | |
925 | and will come back later. */ |
- | |
926 | - | ||
927 | dbgprintf("crtc count %x width %x height %x\n", |
- | |
928 | crtc_count, fb_width, fb_height); |
- | |
929 | return 0; |
- | |
930 | } |
- | |
931 | - | ||
932 | /* do we have an fb already? */ |
- | |
933 | if (list_empty(&rdev->ddev->mode_config.fb_kernel_list)) { |
- | |
934 | /* create an fb if we don't have one */ |
- | |
935 | ret = radeonfb_create(rdev, fb_width, fb_height, surface_width, surface_height, &rfb); |
- | |
936 | if (ret) { |
- | |
937 | return -EINVAL; |
- | |
938 | } |
- | |
939 | new_fb = 1; |
- | |
940 | } else { |
- | |
941 | struct drm_framebuffer *fb; |
- | |
942 | fb = list_first_entry(&rdev->ddev->mode_config.fb_kernel_list, struct drm_framebuffer, filp_head); |
- | |
943 | rfb = to_radeon_framebuffer(fb); |
- | |
944 | - | ||
945 | /* if someone hotplugs something bigger than we have already allocated, we are pwned. |
- | |
946 | As really we can't resize an fbdev that is in the wild currently due to fbdev |
- | |
947 | not really being designed for the lower layers moving stuff around under it. |
- | |
948 | - so in the grand style of things - punt. */ |
- | |
949 | if ((fb->width < surface_width) || (fb->height < surface_height)) { |
- | |
950 | DRM_ERROR("Framebuffer not large enough to scale console onto.\n"); |
- | |
951 | return -EINVAL; |
- | |
952 | } |
- | |
953 | } |
- | |
954 | - | ||
955 | info = rfb->base.fbdev; |
- | |
956 | rdev->fbdev_info = info; |
- | |
957 | rfbdev = info->par; |
- | |
958 | - | ||
959 | crtc_count = 0; |
- | |
960 | /* okay we need to setup new connector sets in the crtcs */ |
- | |
961 | list_for_each_entry(crtc, &rdev->ddev->mode_config.crtc_list, head) { |
- | |
962 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
- | |
963 | modeset = &radeon_crtc->mode_set; |
- | |
964 | modeset->fb = &rfb->base; |
- | |
965 | conn_count = 0; |
- | |
966 | list_for_each_entry(connector, &rdev->ddev->mode_config.connector_list, head) { |
- | |
967 | if (connector->encoder) |
- | |
968 | if (connector->encoder->crtc == modeset->crtc) { |
- | |
969 | modeset->connectors[conn_count] = connector; |
- | |
970 | conn_count++; |
- | |
971 | if (conn_count > RADEONFB_CONN_LIMIT) |
- | |
972 | BUG(); |
- | |
973 | } |
- | |
974 | } |
- | |
975 | - | ||
976 | for (i = conn_count; i < RADEONFB_CONN_LIMIT; i++) |
- | |
977 | modeset->connectors[i] = NULL; |
- | |
978 | - | ||
979 | - | ||
980 | rfbdev->crtc_ids[crtc_count++] = crtc->base.id; |
- | |
981 | - | ||
982 | modeset->num_connectors = conn_count; |
- | |
983 | if (modeset->crtc->desired_mode) { |
- | |
984 | if (modeset->mode) { |
- | |
985 | drm_mode_destroy(rdev->ddev, modeset->mode); |
- | |
986 | } |
- | |
987 | modeset->mode = drm_mode_duplicate(rdev->ddev, |
- | |
988 | modeset->crtc->desired_mode); |
- | |
989 | } |
- | |
990 | } |
- | |
991 | rfbdev->crtc_count = crtc_count; |
- | |
992 | - | ||
993 | if (new_fb) { |
- | |
994 | info->var.pixclock = -1; |
- | |
995 | // if (register_framebuffer(info) < 0) |
- | |
996 | // return -EINVAL; |
- | |
997 | } else { |
- | |
998 | radeonfb_set_par(info); |
- | |
999 | } |
- | |
1000 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, |
- | |
1001 | info->fix.id); |
- | |
1002 | - | ||
1003 | /* Switch back to kernel console on panic */ |
- | |
1004 | // panic_mode = *modeset; |
- | |
1005 | // atomic_notifier_chain_register(&panic_notifier_list, &paniced); |
- | |
1006 | // printk(KERN_INFO "registered panic notifier\n"); |
- | |
1007 | LEAVE(); |
- | |
1008 | - | ||
1009 | return 0; |
- | |
1010 | } |
- | |
1011 | 281 | ||
1012 | int radeonfb_probe(struct drm_device *dev) |
282 | int radeonfb_probe(struct drm_device *dev) |
1013 | { |
283 | { |
1014 | int ret; |
- | |
1015 | - | ||
1016 | /* something has changed in the lower levels of hell - deal with it |
- | |
1017 | here */ |
- | |
1018 | - | ||
1019 | /* two modes : a) 1 fb to rule all crtcs. |
- | |
1020 | b) one fb per crtc. |
- | |
1021 | two actions 1) new connected device |
- | |
1022 | 2) device removed. |
- | |
1023 | case a/1 : if the fb surface isn't big enough - resize the surface fb. |
- | |
1024 | if the fb size isn't big enough - resize fb into surface. |
- | |
1025 | if everything big enough configure the new crtc/etc. |
- | |
1026 | case a/2 : undo the configuration |
- | |
1027 | possibly resize down the fb to fit the new configuration. |
- | |
1028 | case b/1 : see if it is on a new crtc - setup a new fb and add it. |
- | |
1029 | case b/2 : teardown the new fb. |
- | |
1030 | */ |
284 | int ret; |
1031 | ret = radeonfb_single_fb_probe(dev->dev_private); |
285 | ret = drm_fb_helper_single_fb_probe(dev, &radeonfb_create); |
1032 | return ret; |
286 | return ret; |
1033 | } |
287 | } |
Line 1034... | Line 288... | ||
1034 | EXPORT_SYMBOL(radeonfb_probe); |
288 | EXPORT_SYMBOL(radeonfb_probe); |
Line 1042... | Line 296... | ||
1042 | if (!fb) { |
296 | if (!fb) { |
1043 | return -EINVAL; |
297 | return -EINVAL; |
1044 | } |
298 | } |
1045 | info = fb->fbdev; |
299 | info = fb->fbdev; |
1046 | if (info) { |
300 | if (info) { |
- | 301 | struct radeon_fb_device *rfbdev = info->par; |
|
1047 | robj = rfb->obj->driver_private; |
302 | robj = rfb->obj->driver_private; |
1048 | // unregister_framebuffer(info); |
303 | // unregister_framebuffer(info); |
1049 | // radeon_object_kunmap(robj); |
304 | // radeon_object_kunmap(robj); |
1050 | // radeon_object_unpin(robj); |
305 | // radeon_object_unpin(robj); |
1051 | // framebuffer_release(info); |
306 | // framebuffer_release(info); |
1052 | } |
307 | } |
Line 1053... | Line 308... | ||
1053 | 308 | ||
1054 | printk(KERN_INFO "unregistered panic notifier\n"); |
- | |
1055 | // atomic_notifier_chain_unregister(&panic_notifier_list, &paniced); |
- | |
- | 309 | printk(KERN_INFO "unregistered panic notifier\n"); |
|
1056 | // memset(&panic_mode, 0, sizeof(struct drm_mode_set)); |
310 | |
1057 | return 0; |
311 | return 0; |
1058 | } |
312 | } |
Line 1190... | Line 444... | ||
1190 | { |
444 | { |
1191 | struct drm_connector *connector; |
445 | struct drm_connector *connector; |
Line 1192... | Line 446... | ||
1192 | 446 | ||
Line 1193... | Line -... | ||
1193 | bool ret; |
- | |
1194 | - | ||
1195 | ENTRY(); |
447 | bool ret; |
1196 | 448 | ||
1197 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
449 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) |
Line 1198... | Line 450... | ||
1198 | { |
450 | { |
Line 1242... | Line 494... | ||
1242 | dbgprintf("set mode %d %d connector %s encoder %s\n", |
494 | dbgprintf("set mode %d %d connector %s encoder %s\n", |
1243 | width, height, con_name, enc_name); |
495 | width, height, con_name, enc_name); |
Line 1244... | Line 496... | ||
1244 | 496 | ||
1245 | fb->width = width; |
497 | fb->width = width; |
1246 | fb->height = height; |
498 | fb->height = height; |
1247 | fb->pitch = radeon_align_pitch(dev->dev_private, width, 32) |
- | |
Line 1248... | Line 499... | ||
1248 | * ((32 + 1) / 8); |
499 | fb->pitch = radeon_align_pitch(dev->dev_private, width, 32, false) * ((32 + 1) / 8); |
Line 1249... | Line 500... | ||
1249 | 500 | ||
Line 1250... | Line 501... | ||
1250 | crtc->fb = fb; |
501 | crtc->fb = fb; |
Line 1251... | Line 502... | ||
1251 | 502 | ||
1252 | ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb); |
503 | ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb); |
- | 504 | ||
1253 | 505 | sysSetScreen(width, height, fb->pitch); |
|
1254 | sysSetScreen(width,height); |
506 | |
1255 | 507 | if (ret == true) |
|
1256 | if (ret == true) |
508 | { |
1257 | { |
509 | dbgprintf("new mode %d %d pitch %d\n", width, height, fb->pitch); |