Rev 2997 | Rev 5271 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2997 | Rev 5078 | ||
---|---|---|---|
Line 33... | Line 33... | ||
33 | #include |
33 | #include |
34 | #include "radeon.h" |
34 | #include "radeon.h" |
Line 35... | Line 35... | ||
35 | 35 | ||
Line 36... | Line -... | ||
36 | #include |
- | |
37 | - | ||
38 | 36 | #include |
|
39 | int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, |
37 | |
Line 40... | Line 38... | ||
40 | struct drm_mode_fb_cmd2 *mode_cmd, |
38 | struct drm_framebuffer *main_fb; |
41 | struct drm_gem_object **gobj_p); |
39 | struct drm_gem_object *main_fb_obj; |
42 | 40 | ||
43 | /* object hierarchy - |
41 | /* object hierarchy - |
Line 86... | Line 84... | ||
86 | aligned += pitch_mask; |
84 | aligned += pitch_mask; |
87 | aligned &= ~pitch_mask; |
85 | aligned &= ~pitch_mask; |
88 | return aligned; |
86 | return aligned; |
89 | } |
87 | } |
Line -... | Line 88... | ||
- | 88 | ||
- | 89 | static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj) |
|
- | 90 | { |
|
- | 91 | struct radeon_bo *rbo = gem_to_radeon_bo(gobj); |
|
- | 92 | int ret; |
|
- | 93 | ||
- | 94 | ret = radeon_bo_reserve(rbo, false); |
|
- | 95 | if (likely(ret == 0)) { |
|
- | 96 | radeon_bo_kunmap(rbo); |
|
- | 97 | radeon_bo_unpin(rbo); |
|
- | 98 | radeon_bo_unreserve(rbo); |
|
- | 99 | } |
|
- | 100 | drm_gem_object_unreference_unlocked(gobj); |
|
- | 101 | } |
|
- | 102 | ||
- | 103 | static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, |
|
- | 104 | struct drm_mode_fb_cmd2 *mode_cmd, |
|
- | 105 | struct drm_gem_object **gobj_p) |
|
- | 106 | { |
|
- | 107 | struct radeon_device *rdev = rfbdev->rdev; |
|
- | 108 | struct drm_gem_object *gobj = NULL; |
|
- | 109 | struct radeon_bo *rbo = NULL; |
|
- | 110 | bool fb_tiled = false; /* useful for testing */ |
|
- | 111 | u32 tiling_flags = 0; |
|
- | 112 | int ret; |
|
- | 113 | int aligned_size, size; |
|
- | 114 | int height = mode_cmd->height; |
|
- | 115 | u32 bpp, depth; |
|
- | 116 | ||
- | 117 | drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp); |
|
- | 118 | ||
- | 119 | /* need to align pitch with crtc limits */ |
|
- | 120 | mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, bpp, |
|
- | 121 | fb_tiled) * ((bpp + 1) / 8); |
|
- | 122 | ||
- | 123 | if (rdev->family >= CHIP_R600) |
|
- | 124 | height = ALIGN(mode_cmd->height, 8); |
|
- | 125 | size = mode_cmd->pitches[0] * height; |
|
- | 126 | aligned_size = ALIGN(size, PAGE_SIZE); |
|
- | 127 | ||
- | 128 | rbo = rdev->stollen_vga_memory; |
|
- | 129 | gobj = &rbo->gem_base; |
|
- | 130 | mutex_lock(&rdev->gem.mutex); |
|
- | 131 | list_add_tail(&rbo->list, &rdev->gem.objects); |
|
- | 132 | mutex_unlock(&rdev->gem.mutex); |
|
- | 133 | ||
- | 134 | rbo = gem_to_radeon_bo(gobj); |
|
- | 135 | ||
- | 136 | if (fb_tiled) |
|
- | 137 | tiling_flags = RADEON_TILING_MACRO; |
|
- | 138 | ||
- | 139 | #ifdef __BIG_ENDIAN |
|
- | 140 | switch (bpp) { |
|
- | 141 | case 32: |
|
- | 142 | tiling_flags |= RADEON_TILING_SWAP_32BIT; |
|
- | 143 | break; |
|
- | 144 | case 16: |
|
- | 145 | tiling_flags |= RADEON_TILING_SWAP_16BIT; |
|
- | 146 | default: |
|
- | 147 | break; |
|
- | 148 | } |
|
- | 149 | #endif |
|
- | 150 | ||
- | 151 | // if (tiling_flags) { |
|
- | 152 | // ret = radeon_bo_set_tiling_flags(rbo, |
|
- | 153 | // tiling_flags | RADEON_TILING_SURFACE, |
|
- | 154 | // mode_cmd->pitches[0]); |
|
- | 155 | // if (ret) |
|
- | 156 | // dev_err(rdev->dev, "FB failed to set tiling flags\n"); |
|
- | 157 | // } |
|
- | 158 | ||
- | 159 | ||
- | 160 | ret = radeon_bo_reserve(rbo, false); |
|
- | 161 | if (unlikely(ret != 0)) |
|
- | 162 | goto out_unref; |
|
- | 163 | /* Only 27 bit offset for legacy CRTC */ |
|
- | 164 | ret = radeon_bo_pin_restricted(rbo, RADEON_GEM_DOMAIN_VRAM, |
|
- | 165 | ASIC_IS_AVIVO(rdev) ? 0 : 1 << 27, |
|
- | 166 | NULL); |
|
- | 167 | if (ret) { |
|
- | 168 | radeon_bo_unreserve(rbo); |
|
- | 169 | goto out_unref; |
|
- | 170 | } |
|
- | 171 | radeon_bo_unreserve(rbo); |
|
- | 172 | if (ret) { |
|
- | 173 | goto out_unref; |
|
- | 174 | } |
|
- | 175 | ||
- | 176 | *gobj_p = gobj; |
|
- | 177 | return 0; |
|
- | 178 | out_unref: |
|
- | 179 | radeonfb_destroy_pinned_object(gobj); |
|
- | 180 | *gobj_p = NULL; |
|
- | 181 | return ret; |
|
Line 90... | Line 182... | ||
90 | 182 | } |
|
91 | 183 | ||
92 | static int radeonfb_create(struct radeon_fbdev *rfbdev, |
184 | static int radeonfb_create(struct drm_fb_helper *helper, |
- | 185 | struct drm_fb_helper_surface_size *sizes) |
|
93 | struct drm_fb_helper_surface_size *sizes) |
186 | { |
94 | { |
187 | struct radeon_fbdev *rfbdev = (struct radeon_fbdev *)helper; |
95 | struct radeon_device *rdev = rfbdev->rdev; |
188 | struct radeon_device *rdev = rfbdev->rdev; |
96 | struct fb_info *info; |
189 | struct fb_info *info; |
97 | struct drm_framebuffer *fb = NULL; |
190 | struct drm_framebuffer *fb = NULL; |
98 | struct drm_mode_fb_cmd2 mode_cmd; |
191 | struct drm_mode_fb_cmd2 mode_cmd; |
99 | struct drm_gem_object *gobj = NULL; |
192 | struct drm_gem_object *gobj = NULL; |
100 | struct radeon_bo *rbo = NULL; |
193 | struct radeon_bo *rbo = NULL; |
101 | struct device *device = &rdev->pdev->dev; |
194 | struct device *device = &rdev->pdev->dev; |
Line 102... | Line -... | ||
102 | int ret; |
- | |
103 | unsigned long tmp; |
- | |
104 | 195 | int ret; |
|
105 | ENTER(); |
196 | unsigned long tmp; |
Line 106... | Line 197... | ||
106 | 197 | ||
107 | mode_cmd.width = sizes->surface_width; |
198 | mode_cmd.width = sizes->surface_width; |
Line 123... | Line 214... | ||
123 | rbo = gem_to_radeon_bo(gobj); |
214 | rbo = gem_to_radeon_bo(gobj); |
Line 124... | Line 215... | ||
124 | 215 | ||
125 | /* okay we have an object now allocate the framebuffer */ |
216 | /* okay we have an object now allocate the framebuffer */ |
126 | info = framebuffer_alloc(0, device); |
217 | info = framebuffer_alloc(0, device); |
127 | if (info == NULL) { |
- | |
128 | dbgprintf("framebuffer_alloc\n"); |
218 | if (info == NULL) { |
129 | ret = -ENOMEM; |
219 | ret = -ENOMEM; |
130 | goto out_unref; |
220 | goto out_unref; |
Line 131... | Line 221... | ||
131 | } |
221 | } |
Line 132... | Line 222... | ||
132 | 222 | ||
133 | info->par = rfbdev; |
223 | info->par = rfbdev; |
134 | 224 | ||
135 | ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); |
225 | ret = radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj); |
136 | if (ret) { |
226 | if (ret) { |
Line 137... | Line 227... | ||
137 | DRM_ERROR("failed to initalise framebuffer %d\n", ret); |
227 | DRM_ERROR("failed to initialize framebuffer %d\n", ret); |
Line 170... | Line 260... | ||
170 | info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; |
260 | info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; |
171 | info->apertures->ranges[0].size = rdev->mc.aper_size; |
261 | info->apertures->ranges[0].size = rdev->mc.aper_size; |
Line 172... | Line 262... | ||
172 | 262 | ||
Line 173... | Line -... | ||
173 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
- | |
174 | - | ||
175 | // if (info->screen_base == NULL) { |
- | |
176 | // ret = -ENOSPC; |
263 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
177 | // goto out_unref; |
264 | |
178 | // } |
265 | |
179 | DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); |
266 | DRM_INFO("fb mappable at 0x%lX\n", info->fix.smem_start); |
180 | DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base); |
267 | DRM_INFO("vram apper at 0x%lX\n", (unsigned long)rdev->mc.aper_base); |
181 | DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo)); |
268 | DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo)); |
Line 182... | Line -... | ||
182 | DRM_INFO("fb depth is %d\n", fb->depth); |
- | |
183 | DRM_INFO(" pitch is %d\n", fb->pitches[0]); |
269 | DRM_INFO("fb depth is %d\n", fb->depth); |
- | 270 | DRM_INFO(" pitch is %d\n", fb->pitches[0]); |
|
Line 184... | Line 271... | ||
184 | 271 | ||
Line 185... | Line 272... | ||
185 | 272 | main_fb = fb; |
|
186 | LEAVE(); |
273 | main_fb_obj = gobj; |
Line 195... | Line 282... | ||
195 | kfree(fb); |
282 | kfree(fb); |
196 | } |
283 | } |
197 | return ret; |
284 | return ret; |
198 | } |
285 | } |
Line 199... | Line -... | ||
199 | - | ||
200 | static int radeon_fb_find_or_create_single(struct drm_fb_helper *helper, |
- | |
201 | struct drm_fb_helper_surface_size *sizes) |
- | |
202 | { |
- | |
203 | struct radeon_fbdev *rfbdev = (struct radeon_fbdev *)helper; |
- | |
204 | int new_fb = 0; |
- | |
Line 205... | Line -... | ||
205 | int ret; |
- | |
206 | - | ||
207 | if (!helper->fb) { |
- | |
208 | ret = radeonfb_create(rfbdev, sizes); |
- | |
209 | if (ret) |
- | |
210 | return ret; |
- | |
211 | new_fb = 1; |
- | |
212 | } |
- | |
213 | return new_fb; |
286 | |
214 | } |
287 | |
215 | static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev) |
288 | static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev) |
216 | { |
289 | { |
Line 231... | Line 304... | ||
231 | drm_framebuffer_cleanup(&rfb->base); |
304 | drm_framebuffer_cleanup(&rfb->base); |
Line 232... | Line 305... | ||
232 | 305 | ||
233 | return 0; |
306 | return 0; |
Line 234... | Line 307... | ||
234 | } |
307 | } |
235 | 308 | ||
236 | static struct drm_fb_helper_funcs radeon_fb_helper_funcs = { |
309 | static const struct drm_fb_helper_funcs radeon_fb_helper_funcs = { |
237 | .gamma_set = radeon_crtc_fb_gamma_set, |
310 | .gamma_set = radeon_crtc_fb_gamma_set, |
238 | .gamma_get = radeon_crtc_fb_gamma_get, |
311 | .gamma_get = radeon_crtc_fb_gamma_get, |
Line 239... | Line -... | ||
239 | .fb_probe = radeon_fb_find_or_create_single, |
- | |
240 | }; |
- | |
241 | 312 | .fb_probe = radeonfb_create, |
|
242 | extern struct radeon_fbdev *kos_rfbdev; |
313 | }; |
243 | 314 | ||
244 | int radeon_fbdev_init(struct radeon_device *rdev) |
315 | int radeon_fbdev_init(struct radeon_device *rdev) |
245 | { |
316 | { |
246 | struct radeon_fbdev *rfbdev; |
- | |
247 | int bpp_sel = 32; |
317 | struct radeon_fbdev *rfbdev; |
Line 248... | Line 318... | ||
248 | int ret; |
318 | int bpp_sel = 32; |
249 | 319 | int ret; |
|
250 | ENTER(); |
320 | ENTER(); |
Line 257... | Line 327... | ||
257 | if (!rfbdev) |
327 | if (!rfbdev) |
258 | return -ENOMEM; |
328 | return -ENOMEM; |
Line 259... | Line 329... | ||
259 | 329 | ||
260 | rfbdev->rdev = rdev; |
330 | rfbdev->rdev = rdev; |
- | 331 | rdev->mode_info.rfbdev = rfbdev; |
|
- | 332 | ||
261 | rdev->mode_info.rfbdev = rfbdev; |
333 | drm_fb_helper_prepare(rdev->ddev, &rfbdev->helper, |
Line 262... | Line 334... | ||
262 | rfbdev->helper.funcs = &radeon_fb_helper_funcs; |
334 | &radeon_fb_helper_funcs); |
263 | 335 | ||
264 | ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper, |
336 | ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper, |
265 | rdev->num_crtc, |
337 | rdev->num_crtc, |
266 | RADEONFB_CONN_LIMIT); |
338 | RADEONFB_CONN_LIMIT); |
267 | if (ret) { |
339 | if (ret) { |
268 | kfree(rfbdev); |
340 | kfree(rfbdev); |
Line 269... | Line 341... | ||
269 | return ret; |
341 | return ret; |
270 | } |
- | |
Line -... | Line 342... | ||
- | 342 | } |
|
271 | 343 | ||
Line -... | Line 344... | ||
- | 344 | drm_fb_helper_single_add_all_connectors(&rfbdev->helper); |
|
272 | drm_fb_helper_single_add_all_connectors(&rfbdev->helper); |
345 | |
Line 273... | Line 346... | ||
273 | drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel); |
346 | /* disable all the possible outputs/crtcs before entering KMS mode */ |
274 | 347 | drm_helper_disable_unused_functions(rdev->ddev); |