Subversion Repositories Kolibri OS

Rev

Rev 1963 | Rev 2997 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1963 Rev 1986
1
/*
1
/*
2
 * Copyright © 2007 David Airlie
2
 * Copyright © 2007 David Airlie
3
 *
3
 *
4
 * Permission is hereby granted, free of charge, to any person obtaining a
4
 * Permission is hereby granted, free of charge, to any person obtaining a
5
 * copy of this software and associated documentation files (the "Software"),
5
 * copy of this software and associated documentation files (the "Software"),
6
 * to deal in the Software without restriction, including without limitation
6
 * to deal in the Software without restriction, including without limitation
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8
 * and/or sell copies of the Software, and to permit persons to whom the
8
 * and/or sell copies of the Software, and to permit persons to whom the
9
 * Software is furnished to do so, subject to the following conditions:
9
 * Software is furnished to do so, subject to the following conditions:
10
 *
10
 *
11
 * The above copyright notice and this permission notice (including the next
11
 * The above copyright notice and this permission notice (including the next
12
 * paragraph) shall be included in all copies or substantial portions of the
12
 * paragraph) shall be included in all copies or substantial portions of the
13
 * Software.
13
 * Software.
14
 *
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
21
 * DEALINGS IN THE SOFTWARE.
22
 *
22
 *
23
 * Authors:
23
 * Authors:
24
 *     David Airlie
24
 *     David Airlie
25
 */
25
 */
26
#include 
26
#include 
-
 
27
#include 
27
#include 
28
#include 
28
 
29
 
29
#include "drmP.h"
30
#include "drmP.h"
30
#include "drm.h"
31
#include "drm.h"
31
#include "drm_crtc.h"
32
#include "drm_crtc.h"
32
#include "drm_crtc_helper.h"
33
#include "drm_crtc_helper.h"
33
#include "radeon_drm.h"
34
#include "radeon_drm.h"
34
#include "radeon.h"
35
#include "radeon.h"
35
 
36
 
36
#include "drm_fb_helper.h"
37
#include "drm_fb_helper.h"
37
 
38
 
38
#include 
39
#include 
39
#include "radeon_object.h"
40
#include "radeon_object.h"
-
 
41
 
-
 
42
int radeonfb_create_object(struct radeon_fbdev *rfbdev,
-
 
43
                     struct drm_mode_fb_cmd *mode_cmd,
-
 
44
                     struct drm_gem_object **gobj_p);
40
 
45
 
41
/* object hierarchy -
46
/* object hierarchy -
42
   this contains a helper + a radeon fb
47
   this contains a helper + a radeon fb
43
   the helper contains a pointer to radeon framebuffer baseclass.
48
   the helper contains a pointer to radeon framebuffer baseclass.
44
*/
49
*/
45
struct radeon_fbdev {
50
struct radeon_fbdev {
46
    struct drm_fb_helper        helper;
51
    struct drm_fb_helper        helper;
47
	struct radeon_framebuffer rfb;
52
	struct radeon_framebuffer rfb;
48
	struct list_head fbdev_list;
53
	struct list_head fbdev_list;
49
	struct radeon_device		*rdev;
54
	struct radeon_device		*rdev;
50
};
55
};
51
 
56
 
52
static struct fb_ops radeonfb_ops = {
57
static struct fb_ops radeonfb_ops = {
53
//   .owner = THIS_MODULE,
58
//   .owner = THIS_MODULE,
54
	.fb_check_var = drm_fb_helper_check_var,
59
	.fb_check_var = drm_fb_helper_check_var,
55
	.fb_set_par = drm_fb_helper_set_par,
60
	.fb_set_par = drm_fb_helper_set_par,
56
//	.fb_fillrect = cfb_fillrect,
61
//	.fb_fillrect = cfb_fillrect,
57
//	.fb_copyarea = cfb_copyarea,
62
//	.fb_copyarea = cfb_copyarea,
58
//	.fb_imageblit = cfb_imageblit,
63
//	.fb_imageblit = cfb_imageblit,
59
//	.fb_pan_display = drm_fb_helper_pan_display,
64
//	.fb_pan_display = drm_fb_helper_pan_display,
60
	.fb_blank = drm_fb_helper_blank,
65
	.fb_blank = drm_fb_helper_blank,
61
	.fb_setcmap = drm_fb_helper_setcmap,
66
	.fb_setcmap = drm_fb_helper_setcmap,
62
};
67
};
63
 
68
 
64
 
69
 
65
int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
70
int radeon_align_pitch(struct radeon_device *rdev, int width, int bpp, bool tiled)
66
{
71
{
67
	int aligned = width;
72
	int aligned = width;
68
	int align_large = (ASIC_IS_AVIVO(rdev)) || tiled;
73
	int align_large = (ASIC_IS_AVIVO(rdev)) || tiled;
69
	int pitch_mask = 0;
74
	int pitch_mask = 0;
70
 
75
 
71
	switch (bpp / 8) {
76
	switch (bpp / 8) {
72
	case 1:
77
	case 1:
73
		pitch_mask = align_large ? 255 : 127;
78
		pitch_mask = align_large ? 255 : 127;
74
		break;
79
		break;
75
	case 2:
80
	case 2:
76
		pitch_mask = align_large ? 127 : 31;
81
		pitch_mask = align_large ? 127 : 31;
77
		break;
82
		break;
78
	case 3:
83
	case 3:
79
	case 4:
84
	case 4:
80
		pitch_mask = align_large ? 63 : 15;
85
		pitch_mask = align_large ? 63 : 15;
81
		break;
86
		break;
82
	}
87
	}
83
 
88
 
84
	aligned += pitch_mask;
89
	aligned += pitch_mask;
85
	aligned &= ~pitch_mask;
90
	aligned &= ~pitch_mask;
86
	return aligned;
91
	return aligned;
87
}
92
}
88
 
-
 
89
static void radeonfb_destroy_pinned_object(struct drm_gem_object *gobj)
-
 
90
{
-
 
91
	struct radeon_bo *rbo = gobj->driver_private;
-
 
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_cmd *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
 
-
 
115
	/* need to align pitch with crtc limits */
-
 
116
	mode_cmd->pitch = radeon_align_pitch(rdev, mode_cmd->width, mode_cmd->bpp, fb_tiled) * ((mode_cmd->bpp + 1) / 8);
-
 
117
 
-
 
118
	size = mode_cmd->pitch * mode_cmd->height;
-
 
119
	aligned_size = ALIGN(size, PAGE_SIZE);
-
 
120
//   ret = radeon_gem_object_create(rdev, aligned_size, 0,
-
 
121
//           RADEON_GEM_DOMAIN_VRAM,
-
 
122
//                      false, true,
-
 
123
//           &gobj);
-
 
124
	if (ret) {
-
 
125
		printk(KERN_ERR "failed to allocate framebuffer (%d)\n",
-
 
126
		       aligned_size);
-
 
127
		return -ENOMEM;
-
 
128
	}
-
 
129
	rbo = gobj->driver_private;
-
 
130
 
-
 
131
	if (fb_tiled)
-
 
132
		tiling_flags = RADEON_TILING_MACRO;
-
 
133
 
-
 
134
#ifdef __BIG_ENDIAN
-
 
135
	switch (mode_cmd->bpp) {
-
 
136
	case 32:
-
 
137
		tiling_flags |= RADEON_TILING_SWAP_32BIT;
-
 
138
		break;
-
 
139
	case 16:
-
 
140
		tiling_flags |= RADEON_TILING_SWAP_16BIT;
-
 
141
	default:
-
 
142
		break;
-
 
143
	}
-
 
144
#endif
-
 
145
 
-
 
146
	if (tiling_flags) {
-
 
147
		ret = radeon_bo_set_tiling_flags(rbo,
-
 
148
					tiling_flags | RADEON_TILING_SURFACE,
-
 
149
						 mode_cmd->pitch);
-
 
150
		if (ret)
-
 
151
			dev_err(rdev->dev, "FB failed to set tiling flags\n");
-
 
152
	}
-
 
153
 
-
 
154
 
-
 
155
	ret = radeon_bo_reserve(rbo, false);
-
 
156
	if (unlikely(ret != 0))
-
 
157
		goto out_unref;
-
 
158
	ret = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, NULL);
-
 
159
	if (ret) {
-
 
160
		radeon_bo_unreserve(rbo);
-
 
161
		goto out_unref;
-
 
162
	}
-
 
163
	if (fb_tiled)
-
 
164
		radeon_bo_check_tiling(rbo, 0, 0);
-
 
165
	ret = radeon_bo_kmap(rbo, NULL);
-
 
166
	radeon_bo_unreserve(rbo);
-
 
167
	if (ret) {
-
 
168
		goto out_unref;
-
 
169
	}
-
 
170
 
-
 
171
	*gobj_p = gobj;
-
 
172
	return 0;
-
 
173
out_unref:
-
 
174
	radeonfb_destroy_pinned_object(gobj);
-
 
175
	*gobj_p = NULL;
-
 
176
	return ret;
-
 
177
}
93
 
178
 
94
 
179
static int radeonfb_create(struct radeon_fbdev *rfbdev,
95
static int radeonfb_create(struct radeon_fbdev *rfbdev,
180
			   struct drm_fb_helper_surface_size *sizes)
96
			   struct drm_fb_helper_surface_size *sizes)
181
{
97
{
182
	struct radeon_device *rdev = rfbdev->rdev;
98
	struct radeon_device *rdev = rfbdev->rdev;
183
	struct fb_info *info;
99
	struct fb_info *info;
184
	struct drm_framebuffer *fb = NULL;
100
	struct drm_framebuffer *fb = NULL;
185
	struct drm_mode_fb_cmd mode_cmd;
101
	struct drm_mode_fb_cmd mode_cmd;
186
	struct drm_gem_object *gobj = NULL;
102
	struct drm_gem_object *gobj = NULL;
187
	struct radeon_bo *rbo = NULL;
103
	struct radeon_bo *rbo = NULL;
188
	struct device *device = &rdev->pdev->dev;
104
	struct device *device = &rdev->pdev->dev;
189
	int ret;
105
	int ret;
190
	unsigned long tmp;
106
	unsigned long tmp;
191
 
107
 
192
    ENTER();
108
    ENTER();
193
 
109
 
194
	mode_cmd.width = sizes->surface_width;
110
	mode_cmd.width = sizes->surface_width;
195
	mode_cmd.height = sizes->surface_height;
111
	mode_cmd.height = sizes->surface_height;
196
 
112
 
197
	/* avivo can't scanout real 24bpp */
113
	/* avivo can't scanout real 24bpp */
198
	if ((sizes->surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
114
	if ((sizes->surface_bpp == 24) && ASIC_IS_AVIVO(rdev))
199
		sizes->surface_bpp = 32;
115
		sizes->surface_bpp = 32;
200
 
116
 
201
	mode_cmd.bpp = sizes->surface_bpp;
117
	mode_cmd.bpp = sizes->surface_bpp;
202
	mode_cmd.depth = sizes->surface_depth;
118
	mode_cmd.depth = sizes->surface_depth;
203
 
119
 
204
//   ret = radeonfb_create_pinned_object(rfbdev, &mode_cmd, &gobj);
120
    ret = radeonfb_create_object(rfbdev, &mode_cmd, &gobj);
205
//   rbo = gobj->driver_private;
121
	rbo = gem_to_radeon_bo(gobj);
206
 
122
 
207
	/* okay we have an object now allocate the framebuffer */
123
	/* okay we have an object now allocate the framebuffer */
208
	info = framebuffer_alloc(0, device);
124
	info = framebuffer_alloc(0, device);
209
	if (info == NULL) {
125
	if (info == NULL) {
210
		ret = -ENOMEM;
126
		ret = -ENOMEM;
211
		goto out_unref;
127
		goto out_unref;
212
	}
128
	}
213
 
129
 
214
	info->par = rfbdev;
130
	info->par = rfbdev;
215
 
-
 
216
#if 0
131
 
217
	radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
132
	radeon_framebuffer_init(rdev->ddev, &rfbdev->rfb, &mode_cmd, gobj);
218
 
133
 
219
	fb = &rfbdev->rfb.base;
134
	fb = &rfbdev->rfb.base;
220
 
135
 
221
	/* setup helper */
136
	/* setup helper */
222
	rfbdev->helper.fb = fb;
137
	rfbdev->helper.fb = fb;
223
	rfbdev->helper.fbdev = info;
138
	rfbdev->helper.fbdev = info;
224
 
139
 
225
//   memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo));
140
//   memset_io(rbo->kptr, 0x0, radeon_bo_size(rbo));
226
 
141
 
227
	strcpy(info->fix.id, "radeondrmfb");
142
	strcpy(info->fix.id, "radeondrmfb");
228
 
143
 
229
	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
144
	drm_fb_helper_fill_fix(info, fb->pitch, fb->depth);
230
 
145
 
231
	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
146
	info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
232
	info->fbops = &radeonfb_ops;
147
	info->fbops = &radeonfb_ops;
233
 
148
 
234
	tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start;
149
	tmp = radeon_bo_gpu_offset(rbo) - rdev->mc.vram_start;
235
	info->fix.smem_start = rdev->mc.aper_base + tmp;
150
	info->fix.smem_start = rdev->mc.aper_base + tmp;
236
	info->fix.smem_len = radeon_bo_size(rbo);
151
	info->fix.smem_len = radeon_bo_size(rbo);
237
	info->screen_base = rbo->kptr;
152
	info->screen_base = rbo->kptr;
238
	info->screen_size = radeon_bo_size(rbo);
153
	info->screen_size = radeon_bo_size(rbo);
239
 
154
 
240
	drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
155
	drm_fb_helper_fill_var(info, &rfbdev->helper, sizes->fb_width, sizes->fb_height);
241
 
156
 
242
	/* setup aperture base/size for vesafb takeover */
157
	/* setup aperture base/size for vesafb takeover */
243
	info->apertures = alloc_apertures(1);
158
	info->apertures = alloc_apertures(1);
244
	if (!info->apertures) {
159
	if (!info->apertures) {
245
		ret = -ENOMEM;
160
		ret = -ENOMEM;
246
		goto out_unref;
161
		goto out_unref;
247
	}
162
	}
248
	info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
163
	info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base;
249
	info->apertures->ranges[0].size = rdev->mc.aper_size;
164
	info->apertures->ranges[0].size = rdev->mc.aper_size;
250
 
165
 
251
//   info->pixmap.size = 64*1024;
166
//   info->pixmap.size = 64*1024;
252
//   info->pixmap.buf_align = 8;
167
//   info->pixmap.buf_align = 8;
253
//   info->pixmap.access_align = 32;
168
//   info->pixmap.access_align = 32;
254
//   info->pixmap.flags = FB_PIXMAP_SYSTEM;
169
//   info->pixmap.flags = FB_PIXMAP_SYSTEM;
255
//   info->pixmap.scan_align = 1;
170
//   info->pixmap.scan_align = 1;
256
 
171
 
257
	if (info->screen_base == NULL) {
172
	if (info->screen_base == NULL) {
258
		ret = -ENOSPC;
173
		ret = -ENOSPC;
259
		goto out_unref;
174
		goto out_unref;
260
	}
175
	}
261
	DRM_INFO("fb mappable at 0x%lX\n",  info->fix.smem_start);
176
	DRM_INFO("fb mappable at 0x%lX\n",  info->fix.smem_start);
262
	DRM_INFO("vram apper at 0x%lX\n",  (unsigned long)rdev->mc.aper_base);
177
	DRM_INFO("vram apper at 0x%lX\n",  (unsigned long)rdev->mc.aper_base);
263
	DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo));
178
	DRM_INFO("size %lu\n", (unsigned long)radeon_bo_size(rbo));
264
	DRM_INFO("fb depth is %d\n", fb->depth);
179
	DRM_INFO("fb depth is %d\n", fb->depth);
265
	DRM_INFO("   pitch is %d\n", fb->pitch);
180
	DRM_INFO("   pitch is %d\n", fb->pitch);
266
#endif
181
 
267
 
182
 
268
    LEAVE();
183
    LEAVE();
269
 
184
 
270
    return 0;
185
    return 0;
271
 
186
 
272
out_unref:
187
out_unref:
273
	if (rbo) {
188
	if (rbo) {
274
 
189
 
275
	}
190
	}
276
	if (fb && ret) {
191
	if (fb && ret) {
277
		kfree(fb);
192
		kfree(fb);
278
	}
193
	}
279
	return ret;
194
	return ret;
280
}
195
}
281
 
196
 
282
static int radeon_fb_find_or_create_single(struct drm_fb_helper *helper,
197
static int radeon_fb_find_or_create_single(struct drm_fb_helper *helper,
283
					   struct drm_fb_helper_surface_size *sizes)
198
					   struct drm_fb_helper_surface_size *sizes)
284
{
199
{
285
	struct radeon_fbdev *rfbdev = (struct radeon_fbdev *)helper;
200
	struct radeon_fbdev *rfbdev = (struct radeon_fbdev *)helper;
286
	int new_fb = 0;
201
	int new_fb = 0;
287
	int ret;
202
	int ret;
288
 
203
 
289
	if (!helper->fb) {
204
	if (!helper->fb) {
290
		ret = radeonfb_create(rfbdev, sizes);
205
		ret = radeonfb_create(rfbdev, sizes);
291
		if (ret)
206
		if (ret)
292
			return ret;
207
			return ret;
293
		new_fb = 1;
208
		new_fb = 1;
294
	}
209
	}
295
	return new_fb;
210
	return new_fb;
296
}
211
}
297
static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
212
static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
298
{
213
{
299
	struct fb_info *info;
214
	struct fb_info *info;
300
	struct radeon_framebuffer *rfb = &rfbdev->rfb;
215
	struct radeon_framebuffer *rfb = &rfbdev->rfb;
301
 
216
 
302
	if (rfbdev->helper.fbdev) {
217
	if (rfbdev->helper.fbdev) {
303
		info = rfbdev->helper.fbdev;
218
		info = rfbdev->helper.fbdev;
304
 
219
 
305
//       unregister_framebuffer(info);
220
//       unregister_framebuffer(info);
306
//       framebuffer_release(info);
221
//       framebuffer_release(info);
307
	}
222
	}
308
 
223
 
309
	if (rfb->obj) {
224
	if (rfb->obj) {
310
		radeonfb_destroy_pinned_object(rfb->obj);
-
 
311
		rfb->obj = NULL;
225
		rfb->obj = NULL;
312
	}
226
	}
313
//   drm_fb_helper_fini(&rfbdev->helper);
227
//   drm_fb_helper_fini(&rfbdev->helper);
314
	drm_framebuffer_cleanup(&rfb->base);
228
	drm_framebuffer_cleanup(&rfb->base);
315
 
229
 
316
	return 0;
230
	return 0;
317
}
231
}
318
 
232
 
319
static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
233
static struct drm_fb_helper_funcs radeon_fb_helper_funcs = {
320
	.gamma_set = radeon_crtc_fb_gamma_set,
234
	.gamma_set = radeon_crtc_fb_gamma_set,
321
	.gamma_get = radeon_crtc_fb_gamma_get,
235
	.gamma_get = radeon_crtc_fb_gamma_get,
322
	.fb_probe = radeon_fb_find_or_create_single,
236
	.fb_probe = radeon_fb_find_or_create_single,
323
};
237
};
-
 
238
 
-
 
239
extern struct radeon_fbdev *kos_rfbdev;
324
 
240
 
325
int radeon_fbdev_init(struct radeon_device *rdev)
241
int radeon_fbdev_init(struct radeon_device *rdev)
326
{
242
{
327
	struct radeon_fbdev *rfbdev;
243
	struct radeon_fbdev *rfbdev;
328
	int bpp_sel = 32;
244
	int bpp_sel = 32;
329
	int ret;
245
	int ret;
330
 
246
 
331
    ENTER();
247
    ENTER();
332
 
248
 
333
	/* select 8 bpp console on RN50 or 16MB cards */
249
	/* select 8 bpp console on RN50 or 16MB cards */
334
	if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
250
	if (ASIC_IS_RN50(rdev) || rdev->mc.real_vram_size <= (32*1024*1024))
335
		bpp_sel = 8;
251
		bpp_sel = 8;
336
 
252
 
337
	rfbdev = kzalloc(sizeof(struct radeon_fbdev), GFP_KERNEL);
253
	rfbdev = kzalloc(sizeof(struct radeon_fbdev), GFP_KERNEL);
338
	if (!rfbdev)
254
	if (!rfbdev)
339
		return -ENOMEM;
255
		return -ENOMEM;
340
 
256
 
341
	rfbdev->rdev = rdev;
257
	rfbdev->rdev = rdev;
342
	rdev->mode_info.rfbdev = rfbdev;
258
	rdev->mode_info.rfbdev = rfbdev;
343
	rfbdev->helper.funcs = &radeon_fb_helper_funcs;
259
	rfbdev->helper.funcs = &radeon_fb_helper_funcs;
344
 
260
 
345
	ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
261
	ret = drm_fb_helper_init(rdev->ddev, &rfbdev->helper,
346
				 rdev->num_crtc,
262
				 rdev->num_crtc,
347
				 RADEONFB_CONN_LIMIT);
263
				 RADEONFB_CONN_LIMIT);
348
	if (ret) {
264
	if (ret) {
349
		kfree(rfbdev);
265
		kfree(rfbdev);
350
		return ret;
266
		return ret;
351
	}
267
	}
352
 
268
 
353
	drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
269
	drm_fb_helper_single_add_all_connectors(&rfbdev->helper);
354
	drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
270
	drm_fb_helper_initial_config(&rfbdev->helper, bpp_sel);
-
 
271
 
-
 
272
    kos_rfbdev = rfbdev;
355
 
273
 
356
    LEAVE();
274
    LEAVE();
357
 
275
 
358
	return 0;
276
	return 0;
359
}
277
}
360
 
278
 
361
void radeon_fbdev_fini(struct radeon_device *rdev)
279
void radeon_fbdev_fini(struct radeon_device *rdev)
362
{
280
{
363
	if (!rdev->mode_info.rfbdev)
281
	if (!rdev->mode_info.rfbdev)
364
		return;
282
		return;
365
 
283
 
366
	radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev);
284
	radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev);
367
	kfree(rdev->mode_info.rfbdev);
285
	kfree(rdev->mode_info.rfbdev);
368
	rdev->mode_info.rfbdev = NULL;
286
	rdev->mode_info.rfbdev = NULL;
369
}
287
}
370
 
288
 
371
 
289
 
372
int radeon_fbdev_total_size(struct radeon_device *rdev)
290
int radeon_fbdev_total_size(struct radeon_device *rdev)
373
{
291
{
374
	struct radeon_bo *robj;
292
	struct radeon_bo *robj;
375
	int size = 0;
293
	int size = 0;
376
 
294
 
377
	robj = rdev->mode_info.rfbdev->rfb.obj->driver_private;
295
	robj = gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj);
378
	size += radeon_bo_size(robj);
296
	size += radeon_bo_size(robj);
379
	return size;
297
	return size;
380
}
298
}
381
 
299
 
382
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
300
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj)
383
{
301
{
384
	if (robj == rdev->mode_info.rfbdev->rfb.obj->driver_private)
302
	if (robj == gem_to_radeon_bo(rdev->mode_info.rfbdev->rfb.obj))
385
		return true;
303
		return true;
386
	return false;
304
	return false;
387
}
305
}