Subversion Repositories Kolibri OS

Rev

Rev 5367 | Rev 6088 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5367 Rev 6084
Line 27... Line 27...
27
#include 
27
#include 
28
#include 
28
#include 
29
#include 
29
#include 
30
#include 
30
#include 
31
#include 
31
#include 
32
//#include 
32
#include 
33
//#include 
33
//#include 
34
#include 
34
#include 
35
#include 
35
#include 
36
#include 
36
#include 
37
//#include 
37
//#include 
Line 42... Line 42...
42
#include 
42
#include 
43
#include "intel_drv.h"
43
#include "intel_drv.h"
44
#include 
44
#include 
45
#include "i915_drv.h"
45
#include "i915_drv.h"
Line 46... Line -...
46
 
-
 
47
 
46
 
48
struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
47
struct fb_info *framebuffer_alloc(size_t size, struct device *dev)
49
{
48
{
50
#define BYTES_PER_LONG (BITS_PER_LONG/8)
49
#define BYTES_PER_LONG (BITS_PER_LONG/8)
51
#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
50
#define PADDING (BYTES_PER_LONG - (sizeof(struct fb_info) % BYTES_PER_LONG))
Line 79... Line 78...
79
	int ret;
78
	int ret;
Line 80... Line 79...
80
 
79
 
Line 81... Line 80...
81
	ret = drm_fb_helper_set_par(info);
80
	ret = drm_fb_helper_set_par(info);
82
 
-
 
83
	if (ret == 0) {
-
 
84
		/*
-
 
85
		 * FIXME: fbdev presumes that all callbacks also work from
-
 
86
		 * atomic contexts and relies on that for emergency oops
-
 
87
		 * printing. KMS totally doesn't do that and the locking here is
-
 
88
		 * by far not the only place this goes wrong.  Ignore this for
-
 
89
		 * now until we solve this for real.
81
 
90
		 */
82
	if (ret == 0) {
-
 
83
		mutex_lock(&fb_helper->dev->struct_mutex);
-
 
84
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
-
 
85
		mutex_unlock(&fb_helper->dev->struct_mutex);
-
 
86
	}
-
 
87
 
-
 
88
	return ret;
-
 
89
}
-
 
90
 
-
 
91
static int intel_fbdev_blank(int blank, struct fb_info *info)
-
 
92
{
-
 
93
	struct drm_fb_helper *fb_helper = info->par;
-
 
94
	struct intel_fbdev *ifbdev =
-
 
95
		container_of(fb_helper, struct intel_fbdev, helper);
-
 
96
	int ret;
-
 
97
 
-
 
98
	ret = drm_fb_helper_blank(blank, info);
-
 
99
 
-
 
100
	if (ret == 0) {
-
 
101
		mutex_lock(&fb_helper->dev->struct_mutex);
-
 
102
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
-
 
103
		mutex_unlock(&fb_helper->dev->struct_mutex);
91
		mutex_lock(&fb_helper->dev->struct_mutex);
104
	}
-
 
105
 
-
 
106
	return ret;
-
 
107
}
-
 
108
 
-
 
109
static int intel_fbdev_pan_display(struct fb_var_screeninfo *var,
-
 
110
				   struct fb_info *info)
-
 
111
{
-
 
112
	struct drm_fb_helper *fb_helper = info->par;
-
 
113
	struct intel_fbdev *ifbdev =
-
 
114
		container_of(fb_helper, struct intel_fbdev, helper);
-
 
115
 
-
 
116
	int ret;
-
 
117
	ret = drm_fb_helper_pan_display(var, info);
-
 
118
 
-
 
119
	if (ret == 0) {
92
		ret = i915_gem_object_set_to_gtt_domain(ifbdev->fb->obj,
120
		mutex_lock(&fb_helper->dev->struct_mutex);
93
							true);
121
		intel_fb_obj_invalidate(ifbdev->fb->obj, ORIGIN_GTT);
Line 94... Line 122...
94
		mutex_unlock(&fb_helper->dev->struct_mutex);
122
		mutex_unlock(&fb_helper->dev->struct_mutex);
95
	}
123
	}
Line 102... Line 130...
102
	.fb_check_var = drm_fb_helper_check_var,
130
	.fb_check_var = drm_fb_helper_check_var,
103
	.fb_set_par = intel_fbdev_set_par,
131
	.fb_set_par = intel_fbdev_set_par,
104
//   .fb_fillrect = cfb_fillrect,
132
//   .fb_fillrect = cfb_fillrect,
105
//   .fb_copyarea = cfb_copyarea,
133
//   .fb_copyarea = cfb_copyarea,
106
//   .fb_imageblit = cfb_imageblit,
134
//   .fb_imageblit = cfb_imageblit,
107
//   .fb_pan_display = drm_fb_helper_pan_display,
135
	.fb_pan_display = intel_fbdev_pan_display,
108
	.fb_blank = drm_fb_helper_blank,
136
	.fb_blank = intel_fbdev_blank,
109
//   .fb_setcmap = drm_fb_helper_setcmap,
137
//   .fb_setcmap = drm_fb_helper_setcmap,
110
//   .fb_debug_enter = drm_fb_helper_debug_enter,
138
//   .fb_debug_enter = drm_fb_helper_debug_enter,
111
//   .fb_debug_leave = drm_fb_helper_debug_leave,
139
//   .fb_debug_leave = drm_fb_helper_debug_leave,
112
};
140
};
Line 116... Line 144...
116
{
144
{
117
	struct intel_fbdev *ifbdev =
145
	struct intel_fbdev *ifbdev =
118
		container_of(helper, struct intel_fbdev, helper);
146
		container_of(helper, struct intel_fbdev, helper);
119
	struct drm_framebuffer *fb;
147
	struct drm_framebuffer *fb;
120
	struct drm_device *dev = helper->dev;
148
	struct drm_device *dev = helper->dev;
-
 
149
	struct drm_i915_private *dev_priv = to_i915(dev);
121
	struct drm_mode_fb_cmd2 mode_cmd = {};
150
	struct drm_mode_fb_cmd2 mode_cmd = {};
122
	struct drm_i915_gem_object *obj;
151
	struct drm_i915_gem_object *obj = NULL;
123
	int size, ret;
152
	int size, ret;
Line 124... Line 153...
124
 
153
 
125
	/* we don't do packed 24bpp */
154
	/* we don't do packed 24bpp */
126
	if (sizes->surface_bpp == 24)
155
	if (sizes->surface_bpp == 24)
Line 133... Line 162...
133
				    DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
162
				    DIV_ROUND_UP(sizes->surface_bpp, 8), 64);
134
	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
163
	mode_cmd.pixel_format = drm_mode_legacy_fb_format(sizes->surface_bpp,
135
							  sizes->surface_depth);
164
							  sizes->surface_depth);
Line 136... Line 165...
136
 
165
 
137
	size = mode_cmd.pitches[0] * mode_cmd.height;
166
	size = mode_cmd.pitches[0] * mode_cmd.height;
138
	size = ALIGN(size, PAGE_SIZE);
167
	size = PAGE_ALIGN(size);
139
	obj = main_fb_obj;
168
	obj = main_fb_obj;
140
    obj->stride = mode_cmd.pitches[0];
169
	obj->map_and_fenceable=true;
141
	if (!obj) {
170
	if (!obj) {
142
		DRM_ERROR("failed to allocate framebuffer\n");
171
		DRM_ERROR("failed to allocate framebuffer\n");
143
		ret = -ENOMEM;
172
		ret = -ENOMEM;
144
		goto out;
173
		goto out;
Line 149... Line 178...
149
		ret = PTR_ERR(fb);
178
		ret = PTR_ERR(fb);
150
		goto out_unref;
179
		goto out_unref;
151
	}
180
	}
Line 152... Line 181...
152
 
181
 
153
	/* Flush everything out, we'll be doing GTT only from now on */
182
	/* Flush everything out, we'll be doing GTT only from now on */
154
	ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL);
183
	ret = intel_pin_and_fence_fb_obj(NULL, fb, NULL, NULL, NULL);
155
	if (ret) {
184
	if (ret) {
156
		DRM_ERROR("failed to pin obj: %d\n", ret);
185
		DRM_ERROR("failed to pin obj: %d\n", ret);
157
		goto out_fb;
186
		goto out_fb;
Line 212... Line 241...
212
	}
241
	}
Line 213... Line 242...
213
 
242
 
214
	obj = intel_fb->obj;
243
	obj = intel_fb->obj;
Line 215... Line 244...
215
	size = obj->base.size;
244
	size = obj->base.size;
216
 
245
 
217
	info = framebuffer_alloc(0, &dev->pdev->dev);
246
	info = drm_fb_helper_alloc_fbi(helper);
218
	if (!info) {
247
	if (IS_ERR(info)) {
219
		ret = -ENOMEM;
248
		ret = PTR_ERR(info);
Line 220... Line 249...
220
		goto out_unpin;
249
		goto out_unpin;
Line 221... Line 250...
221
	}
250
	}
Line -... Line 251...
-
 
251
 
-
 
252
	info->par = helper;
-
 
253
 
222
 
254
	fb = &ifbdev->fb->base;
223
	info->par = helper;
-
 
Line 224... Line 255...
224
 
255
 
Line 225... Line 256...
225
	fb = &ifbdev->fb->base;
256
    if(main_framebuffer == NULL)
226
 
257
        main_framebuffer = fb;
Line 227... Line 258...
227
	ifbdev->helper.fb = fb;
258
 
228
	ifbdev->helper.fbdev = info;
-
 
229
 
-
 
230
    strcpy(info->fix.id, "inteldrmfb");
-
 
231
 
-
 
232
    info->flags = FBINFO_DEFAULT | FBINFO_CAN_FORCE_OUTPUT;
-
 
233
    info->fbops = &intelfb_ops;
259
	ifbdev->helper.fb = fb;
234
 
260
 
Line 235... Line 261...
235
    /* setup aperture base/size for vesafb takeover */
261
	strcpy(info->fix.id, "inteldrmfb");
Line 251... Line 277...
251
	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
277
	drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth);
252
	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
278
	drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height);
Line 253... Line 279...
253
 
279
 
Line 254... Line 280...
254
	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
280
	/* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */
255
 
281
 
256
	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08lx, bo %p\n",
282
	DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08llx, bo %p\n",
Line 257... Line 283...
257
		      fb->width, fb->height,
283
		      fb->width, fb->height,
258
		      i915_gem_obj_ggtt_offset(obj), obj);
284
		      i915_gem_obj_ggtt_offset(obj), obj);
Line -... Line 285...
-
 
285
 
-
 
286
	mutex_unlock(&dev->struct_mutex);
259
 
287
	return 0;
260
	mutex_unlock(&dev->struct_mutex);
288
 
261
	return 0;
289
out_destroy_fbi:
262
 
290
	drm_fb_helper_release_fbi(helper);
263
out_unpin:
291
out_unpin:
Line 438... Line 466...
438
		if (!modes[i]) {
466
		if (!modes[i]) {
439
			/*
467
			/*
440
			 * IMPORTANT: We want to use the adjusted mode (i.e.
468
			 * IMPORTANT: We want to use the adjusted mode (i.e.
441
			 * after the panel fitter upscaling) as the initial
469
			 * after the panel fitter upscaling) as the initial
442
			 * config, not the input mode, which is what crtc->mode
470
			 * config, not the input mode, which is what crtc->mode
443
			 * usually contains. But since our current fastboot
471
			 * usually contains. But since our current
444
			 * code puts a mode derived from the post-pfit timings
472
			 * code puts a mode derived from the post-pfit timings
445
			 * into crtc->mode this works out correctly. We don't
473
			 * into crtc->mode this works out correctly.
446
			 * use hwmode anywhere right now, so use it for this
-
 
447
			 * since the fb helper layer wants a pointer to
-
 
448
			 * something we own.
-
 
449
			 */
474
			 */
450
			DRM_DEBUG_KMS("looking for current mode on connector %s\n",
475
			DRM_DEBUG_KMS("looking for current mode on connector %s\n",
451
				      connector->name);
476
				      connector->name);
452
			intel_mode_from_pipe_config(&encoder->crtc->hwmode,
-
 
453
						    &to_intel_crtc(encoder->crtc)->config);
-
 
454
			modes[i] = &encoder->crtc->hwmode;
477
			modes[i] = &encoder->crtc->mode;
455
		}
478
		}
456
		crtcs[i] = new_crtc;
479
		crtcs[i] = new_crtc;
Line 457... Line 480...
457
 
480
 
458
		DRM_DEBUG_KMS("connector %s on pipe %c [CRTC:%d]: %dx%d%s\n",
481
		DRM_DEBUG_KMS("connector %s on pipe %c [CRTC:%d]: %dx%d%s\n",
Line 516... Line 539...
516
				 struct intel_fbdev *ifbdev)
539
				 struct intel_fbdev *ifbdev)
517
{
540
{
518
	struct intel_framebuffer *fb = NULL;
541
	struct intel_framebuffer *fb = NULL;
519
	struct drm_crtc *crtc;
542
	struct drm_crtc *crtc;
520
	struct intel_crtc *intel_crtc;
543
	struct intel_crtc *intel_crtc;
521
	struct intel_plane_config *plane_config = NULL;
-
 
522
	unsigned int max_size = 0;
544
	unsigned int max_size = 0;
Line 523... Line -...
523
 
-
 
524
	if (!i915.fastboot)
-
 
525
		return false;
-
 
526
 
545
 
527
	/* Find the largest fb */
546
	/* Find the largest fb */
-
 
547
	for_each_crtc(dev, crtc) {
-
 
548
		struct drm_i915_gem_object *obj =
528
	for_each_crtc(dev, crtc) {
549
			intel_fb_obj(crtc->primary->state->fb);
Line 529... Line 550...
529
		intel_crtc = to_intel_crtc(crtc);
550
		intel_crtc = to_intel_crtc(crtc);
530
 
551
 
531
		if (!intel_crtc->active || !crtc->primary->fb) {
552
		if (!crtc->state->active || !obj) {
532
			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
553
			DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
533
				      pipe_name(intel_crtc->pipe));
554
				      pipe_name(intel_crtc->pipe));
Line 534... Line 555...
534
			continue;
555
			continue;
535
		}
556
		}
536
 
557
 
537
		if (intel_crtc->plane_config.size > max_size) {
-
 
538
			DRM_DEBUG_KMS("found possible fb from plane %c\n",
558
		if (obj->base.size > max_size) {
539
				      pipe_name(intel_crtc->pipe));
559
			DRM_DEBUG_KMS("found possible fb from plane %c\n",
540
			plane_config = &intel_crtc->plane_config;
560
				      pipe_name(intel_crtc->pipe));
541
			fb = to_intel_framebuffer(crtc->primary->fb);
561
			fb = to_intel_framebuffer(crtc->primary->state->fb);
Line 542... Line 562...
542
			max_size = plane_config->size;
562
			max_size = obj->base.size;
543
		}
563
		}
Line 552... Line 572...
552
	for_each_crtc(dev, crtc) {
572
	for_each_crtc(dev, crtc) {
553
		unsigned int cur_size;
573
		unsigned int cur_size;
Line 554... Line 574...
554
 
574
 
Line 555... Line 575...
555
		intel_crtc = to_intel_crtc(crtc);
575
		intel_crtc = to_intel_crtc(crtc);
556
 
576
 
557
		if (!intel_crtc->active) {
577
		if (!crtc->state->active) {
558
			DRM_DEBUG_KMS("pipe %c not active, skipping\n",
578
			DRM_DEBUG_KMS("pipe %c not active, skipping\n",
559
				      pipe_name(intel_crtc->pipe));
579
				      pipe_name(intel_crtc->pipe));
Line 566... Line 586...
566
		/*
586
		/*
567
		 * See if the plane fb we found above will fit on this
587
		 * See if the plane fb we found above will fit on this
568
		 * pipe.  Note we need to use the selected fb's pitch and bpp
588
		 * pipe.  Note we need to use the selected fb's pitch and bpp
569
		 * rather than the current pipe's, since they differ.
589
		 * rather than the current pipe's, since they differ.
570
		 */
590
		 */
571
		cur_size = intel_crtc->config.adjusted_mode.crtc_hdisplay;
591
		cur_size = intel_crtc->config->base.adjusted_mode.crtc_hdisplay;
572
		cur_size = cur_size * fb->base.bits_per_pixel / 8;
592
		cur_size = cur_size * fb->base.bits_per_pixel / 8;
573
		if (fb->base.pitches[0] < cur_size) {
593
		if (fb->base.pitches[0] < cur_size) {
574
			DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
594
			DRM_DEBUG_KMS("fb not wide enough for plane %c (%d vs %d)\n",
575
				      pipe_name(intel_crtc->pipe),
595
				      pipe_name(intel_crtc->pipe),
576
				      cur_size, fb->base.pitches[0]);
596
				      cur_size, fb->base.pitches[0]);
577
			plane_config = NULL;
-
 
578
			fb = NULL;
597
			fb = NULL;
579
			break;
598
			break;
580
		}
599
		}
Line 581... Line 600...
581
 
600
 
582
		cur_size = intel_crtc->config.adjusted_mode.crtc_vdisplay;
601
		cur_size = intel_crtc->config->base.adjusted_mode.crtc_vdisplay;
-
 
602
		cur_size = intel_fb_align_height(dev, cur_size,
-
 
603
						 fb->base.pixel_format,
583
		cur_size = ALIGN(cur_size, plane_config->tiled ? (IS_GEN2(dev) ? 16 : 8) : 1);
604
						 fb->base.modifier[0]);
584
		cur_size *= fb->base.pitches[0];
605
		cur_size *= fb->base.pitches[0];
585
		DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
606
		DRM_DEBUG_KMS("pipe %c area: %dx%d, bpp: %d, size: %d\n",
586
			      pipe_name(intel_crtc->pipe),
607
			      pipe_name(intel_crtc->pipe),
587
			      intel_crtc->config.adjusted_mode.crtc_hdisplay,
608
			      intel_crtc->config->base.adjusted_mode.crtc_hdisplay,
588
			      intel_crtc->config.adjusted_mode.crtc_vdisplay,
609
			      intel_crtc->config->base.adjusted_mode.crtc_vdisplay,
589
			      fb->base.bits_per_pixel,
610
			      fb->base.bits_per_pixel,
Line 590... Line 611...
590
			      cur_size);
611
			      cur_size);
591
 
612
 
592
		if (cur_size > max_size) {
613
		if (cur_size > max_size) {
593
			DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
614
			DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
594
				      pipe_name(intel_crtc->pipe),
-
 
595
				      cur_size, max_size);
615
				      pipe_name(intel_crtc->pipe),
596
			plane_config = NULL;
616
				      cur_size, max_size);
597
			fb = NULL;
617
			fb = NULL;
Line 598... Line 618...
598
			break;
618
			break;
Line 615... Line 635...
615
 
635
 
616
	/* Final pass to check if any active pipes don't have fbs */
636
	/* Final pass to check if any active pipes don't have fbs */
617
	for_each_crtc(dev, crtc) {
637
	for_each_crtc(dev, crtc) {
Line 618... Line 638...
618
		intel_crtc = to_intel_crtc(crtc);
638
		intel_crtc = to_intel_crtc(crtc);
619
 
639
 
Line 620... Line 640...
620
		if (!intel_crtc->active)
640
		if (!crtc->state->active)
621
			continue;
641
			continue;
622
 
642
 
Line 657... Line 677...
657
	if (ret) {
677
	if (ret) {
658
		kfree(ifbdev);
678
		kfree(ifbdev);
659
		return ret;
679
		return ret;
660
	}
680
	}
Line -... Line 681...
-
 
681
 
-
 
682
	ifbdev->helper.atomic = true;
661
 
683
 
662
	dev_priv->fbdev = ifbdev;
684
	dev_priv->fbdev = ifbdev;
Line 663... Line 685...
663
	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
685
	drm_fb_helper_single_add_all_connectors(&ifbdev->helper);
664
 
686