Subversion Repositories Kolibri OS

Rev

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

Rev 3298 Rev 3480
Line 50... Line 50...
50
 *
50
 *
51
 * The fb helper functions are useful to provide an fbdev on top of a drm kernel
51
 * The fb helper functions are useful to provide an fbdev on top of a drm kernel
52
 * mode setting driver. They can be used mostly independantely from the crtc
52
 * mode setting driver. They can be used mostly independantely from the crtc
53
 * helper functions used by many drivers to implement the kernel mode setting
53
 * helper functions used by many drivers to implement the kernel mode setting
54
 * interfaces.
54
 * interfaces.
-
 
55
 *
-
 
56
 * Initialization is done as a three-step process with drm_fb_helper_init(),
-
 
57
 * drm_fb_helper_single_add_all_connectors() and drm_fb_helper_initial_config().
-
 
58
 * Drivers with fancier requirements than the default beheviour can override the
-
 
59
 * second step with their own code.  Teardown is done with drm_fb_helper_fini().
-
 
60
 *
-
 
61
 * At runtime drivers should restore the fbdev console by calling
-
 
62
 * drm_fb_helper_restore_fbdev_mode() from their ->lastclose callback. They
-
 
63
 * should also notify the fb helper code from updates to the output
-
 
64
 * configuration by calling drm_fb_helper_hotplug_event(). For easier
-
 
65
 * integration with the output polling code in drm_crtc_helper.c the modeset
-
 
66
 * code proves a ->output_poll_changed callback.
-
 
67
 *
-
 
68
 * All other functions exported by the fb helper library can be used to
-
 
69
 * implement the fbdev driver interface by the driver.
55
 */
70
 */
Line -... Line 71...
-
 
71
 
-
 
72
/**
-
 
73
 * drm_fb_helper_single_add_all_connectors() - add all connectors to fbdev
-
 
74
 * 					       emulation helper
-
 
75
 * @fb_helper: fbdev initialized with drm_fb_helper_init
-
 
76
 *
-
 
77
 * This functions adds all the available connectors for use with the given
-
 
78
 * fb_helper. This is a separate step to allow drivers to freely assign
56
 
79
 * connectors to the fbdev, e.g. if some are reserved for special purposes or
-
 
80
 * not adequate to be used for the fbcon.
-
 
81
 *
-
 
82
 * Since this is part of the initial setup before the fbdev is published, no
-
 
83
 * locking is required.
57
/* simple single crtc case helper function */
84
 */
58
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
85
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper)
59
{
86
{
60
	struct drm_device *dev = fb_helper->dev;
87
	struct drm_device *dev = fb_helper->dev;
61
	struct drm_connector *connector;
88
	struct drm_connector *connector;
Line 108... Line 135...
108
 
135
 
109
	crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
136
	crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
Line -... Line 137...
-
 
137
}
-
 
138
 
-
 
139
 
-
 
140
static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
-
 
141
{
-
 
142
	struct drm_device *dev = fb_helper->dev;
-
 
143
	struct drm_crtc *crtc;
-
 
144
	int bound = 0, crtcs_bound = 0;
-
 
145
 
-
 
146
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-
 
147
		if (crtc->fb)
-
 
148
			crtcs_bound++;
-
 
149
		if (crtc->fb == fb_helper->fb)
-
 
150
			bound++;
-
 
151
	}
-
 
152
 
-
 
153
	if (bound < crtcs_bound)
Line 110... Line 154...
110
}
154
		return false;
111
 
155
	return true;
112
 
156
}
113
 
157
 
114
static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
158
static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
115
{
159
{
116
	struct drm_fb_helper *fb_helper = info->par;
160
	struct drm_fb_helper *fb_helper = info->par;
Line 117... Line 161...
117
	struct drm_device *dev = fb_helper->dev;
161
	struct drm_device *dev = fb_helper->dev;
-
 
162
	struct drm_crtc *crtc;
-
 
163
	struct drm_connector *connector;
-
 
164
	int i, j;
-
 
165
 
-
 
166
	/*
-
 
167
	 * fbdev->blank can be called from irq context in case of a panic.
118
	struct drm_crtc *crtc;
168
	 * Since we already have our own special panic handler which will
119
	struct drm_connector *connector;
169
	 * restore the fbdev console mode completely, just bail out early.
-
 
170
	 */
-
 
171
 
120
	int i, j;
172
	/*
-
 
173
	 * For each CRTC in this fb, turn the connectors on/off.
-
 
174
	 */
-
 
175
	drm_modeset_lock_all(dev);
121
 
176
	if (!drm_fb_helper_is_bound(fb_helper)) {
122
	/*
177
		drm_modeset_unlock_all(dev);
Line 123... Line 178...
123
	 * For each CRTC in this fb, turn the connectors on/off.
178
		return;
124
	 */
179
	}
Line 135... Line 190...
135
			connector->funcs->dpms(connector, dpms_mode);
190
			connector->funcs->dpms(connector, dpms_mode);
136
			drm_object_property_set_value(&connector->base,
191
			drm_object_property_set_value(&connector->base,
137
				dev->mode_config.dpms_property, dpms_mode);
192
				dev->mode_config.dpms_property, dpms_mode);
138
		}
193
		}
139
	}
194
	}
140
				mutex_unlock(&dev->mode_config.mutex);
195
	drm_modeset_unlock_all(dev);
141
}
196
}
Line -... Line 197...
-
 
197
 
-
 
198
/**
-
 
199
 * drm_fb_helper_blank - implementation for ->fb_blank
-
 
200
 * @blank: desired blanking state
-
 
201
 * @info: fbdev registered by the helper
142
 
202
 */
143
int drm_fb_helper_blank(int blank, struct fb_info *info)
203
int drm_fb_helper_blank(int blank, struct fb_info *info)
144
{
204
{
145
	switch (blank) {
205
	switch (blank) {
146
	/* Display: On; HSync: On, VSync: On */
206
	/* Display: On; HSync: On, VSync: On */
Line 181... Line 241...
181
			drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
241
			drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
182
	}
242
	}
183
	kfree(helper->crtc_info);
243
	kfree(helper->crtc_info);
184
}
244
}
Line -... Line 245...
-
 
245
 
-
 
246
/**
-
 
247
 * drm_fb_helper_init - initialize a drm_fb_helper structure
-
 
248
 * @dev: drm device
-
 
249
 * @fb_helper: driver-allocated fbdev helper structure to initialize
-
 
250
 * @crtc_count: maximum number of crtcs to support in this fbdev emulation
-
 
251
 * @max_conn_count: max connector count
-
 
252
 *
-
 
253
 * This allocates the structures for the fbdev helper with the given limits.
-
 
254
 * Note that this won't yet touch the hardware (through the driver interfaces)
-
 
255
 * nor register the fbdev. This is only done in drm_fb_helper_initial_config()
-
 
256
 * to allow driver writes more control over the exact init sequence.
-
 
257
 *
-
 
258
 * Drivers must set fb_helper->funcs before calling
-
 
259
 * drm_fb_helper_initial_config().
-
 
260
 *
-
 
261
 * RETURNS:
-
 
262
 * Zero if everything went ok, nonzero otherwise.
185
 
263
 */
186
int drm_fb_helper_init(struct drm_device *dev,
264
int drm_fb_helper_init(struct drm_device *dev,
187
		       struct drm_fb_helper *fb_helper,
265
		       struct drm_fb_helper *fb_helper,
188
		       int crtc_count, int max_conn_count)
266
		       int crtc_count, int max_conn_count)
189
{
267
{
Line 292... Line 370...
292
	if (fb->depth != 16)
370
	if (fb->depth != 16)
293
		fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
371
		fb_helper->funcs->gamma_set(crtc, red, green, blue, pindex);
294
	return 0;
372
	return 0;
295
}
373
}
Line -... Line 374...
-
 
374
 
-
 
375
/**
-
 
376
 * drm_fb_helper_setcmap - implementation for ->fb_setcmap
-
 
377
 * @cmap: cmap to set
-
 
378
 * @info: fbdev registered by the helper
296
 
379
 */
297
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
380
int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
298
{
381
{
299
	struct drm_fb_helper *fb_helper = info->par;
382
	struct drm_fb_helper *fb_helper = info->par;
300
	struct drm_crtc_helper_funcs *crtc_funcs;
383
	struct drm_crtc_helper_funcs *crtc_funcs;
Line 331... Line 414...
331
	}
414
	}
332
	return rc;
415
	return rc;
333
}
416
}
334
EXPORT_SYMBOL(drm_fb_helper_setcmap);
417
EXPORT_SYMBOL(drm_fb_helper_setcmap);
Line -... Line 418...
-
 
418
 
-
 
419
/**
-
 
420
 * drm_fb_helper_check_var - implementation for ->fb_check_var
-
 
421
 * @var: screeninfo to check
-
 
422
 * @info: fbdev registered by the helper
335
 
423
 */
336
int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
424
int drm_fb_helper_check_var(struct fb_var_screeninfo *var,
337
			    struct fb_info *info)
425
			    struct fb_info *info)
338
{
426
{
339
	struct drm_fb_helper *fb_helper = info->par;
427
	struct drm_fb_helper *fb_helper = info->par;
Line 423... Line 511...
423
	}
511
	}
424
	return 0;
512
	return 0;
425
}
513
}
426
EXPORT_SYMBOL(drm_fb_helper_check_var);
514
EXPORT_SYMBOL(drm_fb_helper_check_var);
Line -... Line 515...
-
 
515
 
-
 
516
/**
-
 
517
 * drm_fb_helper_set_par - implementation for ->fb_set_par
-
 
518
 * @info: fbdev registered by the helper
427
 
519
 *
-
 
520
 * This will let fbcon do the mode init and is called at initialization time by
-
 
521
 * the fbdev core when registering the driver, and later on through the hotplug
-
 
522
 * callback.
428
/* this will let fbcon do the mode init */
523
 */
429
int drm_fb_helper_set_par(struct fb_info *info)
524
int drm_fb_helper_set_par(struct fb_info *info)
430
{
525
{
431
	struct drm_fb_helper *fb_helper = info->par;
526
	struct drm_fb_helper *fb_helper = info->par;
432
	struct drm_device *dev = fb_helper->dev;
527
	struct drm_device *dev = fb_helper->dev;
433
	struct fb_var_screeninfo *var = &info->var;
-
 
434
	struct drm_crtc *crtc;
528
	struct fb_var_screeninfo *var = &info->var;
435
	int ret;
529
	int ret;
Line 436... Line 530...
436
	int i;
530
	int i;
437
 
531
 
438
	if (var->pixclock != 0) {
532
	if (var->pixclock != 0) {
439
		DRM_ERROR("PIXEL CLOCK SET\n");
533
		DRM_ERROR("PIXEL CLOCK SET\n");
Line 440... Line 534...
440
		return -EINVAL;
534
		return -EINVAL;
441
	}
535
	}
442
 
-
 
443
	mutex_lock(&dev->mode_config.mutex);
536
 
444
		for (i = 0; i < fb_helper->crtc_count; i++) {
537
	drm_modeset_lock_all(dev);
445
		crtc = fb_helper->crtc_info[i].mode_set.crtc;
538
		for (i = 0; i < fb_helper->crtc_count; i++) {
446
			ret = crtc->funcs->set_config(&fb_helper->crtc_info[i].mode_set);
539
		ret = drm_mode_set_config_internal(&fb_helper->crtc_info[i].mode_set);
447
		if (ret) {
540
		if (ret) {
448
			mutex_unlock(&dev->mode_config.mutex);
541
			drm_modeset_unlock_all(dev);
449
				return ret;
542
				return ret;
Line 450... Line 543...
450
		}
543
		}
451
	}
544
	}
452
	mutex_unlock(&dev->mode_config.mutex);
545
	drm_modeset_unlock_all(dev);
453
 
546
 
454
	if (fb_helper->delayed_hotplug) {
547
	if (fb_helper->delayed_hotplug) {
455
		fb_helper->delayed_hotplug = false;
548
		fb_helper->delayed_hotplug = false;
456
//       drm_fb_helper_hotplug_event(fb_helper);
549
		drm_fb_helper_hotplug_event(fb_helper);
Line -... Line 550...
-
 
550
	}
-
 
551
	return 0;
-
 
552
}
-
 
553
EXPORT_SYMBOL(drm_fb_helper_set_par);
-
 
554
 
457
	}
555
/**
458
	return 0;
556
 * drm_fb_helper_pan_display - implementation for ->fb_pan_display
459
}
557
 * @var: updated screen information
460
EXPORT_SYMBOL(drm_fb_helper_set_par);
558
 * @info: fbdev registered by the helper
461
 
559
 */
462
int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
560
int drm_fb_helper_pan_display(struct fb_var_screeninfo *var,
463
			      struct fb_info *info)
561
			      struct fb_info *info)
464
{
562
{
465
	struct drm_fb_helper *fb_helper = info->par;
563
	struct drm_fb_helper *fb_helper = info->par;
Line -... Line 564...
-
 
564
	struct drm_device *dev = fb_helper->dev;
-
 
565
	struct drm_mode_set *modeset;
466
	struct drm_device *dev = fb_helper->dev;
566
	struct drm_crtc *crtc;
-
 
567
	int ret = 0;
-
 
568
	int i;
-
 
569
 
467
	struct drm_mode_set *modeset;
570
	drm_modeset_lock_all(dev);
468
	struct drm_crtc *crtc;
571
	if (!drm_fb_helper_is_bound(fb_helper)) {
Line 469... Line 572...
469
	int ret = 0;
572
		drm_modeset_unlock_all(dev);
Line 470... Line 573...
470
	int i;
573
		return -EBUSY;
471
 
574
	}
Line 472... Line 575...
472
	mutex_lock(&dev->mode_config.mutex);
575
 
473
		for (i = 0; i < fb_helper->crtc_count; i++) {
576
		for (i = 0; i < fb_helper->crtc_count; i++) {
474
		crtc = fb_helper->crtc_info[i].mode_set.crtc;
577
		crtc = fb_helper->crtc_info[i].mode_set.crtc;
475
 
578
 
476
		modeset = &fb_helper->crtc_info[i].mode_set;
579
		modeset = &fb_helper->crtc_info[i].mode_set;
477
 
580
 
478
		modeset->x = var->xoffset;
581
		modeset->x = var->xoffset;
479
		modeset->y = var->yoffset;
582
		modeset->y = var->yoffset;
480
 
583
 
481
		if (modeset->num_connectors) {
584
		if (modeset->num_connectors) {
482
			ret = crtc->funcs->set_config(modeset);
585
			ret = drm_mode_set_config_internal(modeset);
483
			if (!ret) {
586
			if (!ret) {
Line -... Line 587...
-
 
587
				info->var.xoffset = var->xoffset;
-
 
588
				info->var.yoffset = var->yoffset;
-
 
589
			}
-
 
590
		}
-
 
591
	}
484
				info->var.xoffset = var->xoffset;
592
	drm_modeset_unlock_all(dev);
485
				info->var.yoffset = var->yoffset;
593
	return ret;
486
			}
594
}
487
		}
595
EXPORT_SYMBOL(drm_fb_helper_pan_display);
488
	}
596
 
489
	mutex_unlock(&dev->mode_config.mutex);
597
/*
490
	return ret;
598
 * Allocates the backing storage and sets up the fbdev info structure through
491
}
599
 * the ->fb_probe callback and then registers the fbdev and sets up the panic
492
EXPORT_SYMBOL(drm_fb_helper_pan_display);
600
 * notifier.
Line 570... Line 678...
570
		sizes.fb_width = sizes.surface_width = 1024;
678
		sizes.fb_width = sizes.surface_width = 1024;
571
		sizes.fb_height = sizes.surface_height = 768;
679
		sizes.fb_height = sizes.surface_height = 768;
572
	}
680
	}
Line 573... Line 681...
573
 
681
 
574
	/* push down into drivers */
682
	/* push down into drivers */
575
    new_fb = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes);
683
	ret = (*fb_helper->funcs->fb_probe)(fb_helper, &sizes);
576
	if (new_fb < 0)
684
	if (ret < 0)
Line 577... Line 685...
577
		return new_fb;
685
		return ret;
Line -... Line 686...
-
 
686
 
-
 
687
	info = fb_helper->fbdev;
-
 
688
 
-
 
689
	/*
-
 
690
	 * Set the fb pointer - usually drm_setup_crtcs does this for hotplug
578
 
691
	 * events, but at init time drm_setup_crtcs needs to be called before
-
 
692
	 * the fb is allocated (since we need to figure out the desired size of
579
	info = fb_helper->fbdev;
693
	 * the fb before we can allocate it ...). Hence we need to fix things up
-
 
694
	 * here again.
580
 
695
	 */
Line 581... Line -...
581
	/* set the fb pointer */
-
 
582
	for (i = 0; i < fb_helper->crtc_count; i++)
-
 
583
		fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
-
 
584
 
-
 
585
	if (new_fb) {
-
 
586
		info->var.pixclock = 0;
-
 
587
 
-
 
588
//       dev_info(fb_helper->dev->dev, "fb%d: %s frame buffer device\n",
-
 
589
//               info->node, info->fix.id);
-
 
Line -... Line 696...
-
 
696
	for (i = 0; i < fb_helper->crtc_count; i++)
Line 590... Line -...
590
 
-
 
591
	} else {
697
		if (fb_helper->crtc_info[i].mode_set.num_connectors)
Line 592... Line 698...
592
		drm_fb_helper_set_par(info);
698
		fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
593
	}
699
 
594
 
-
 
Line -... Line 700...
-
 
700
 
-
 
701
		info->var.pixclock = 0;
-
 
702
 
-
 
703
        list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
-
 
704
 
-
 
705
	return 0;
-
 
706
}
-
 
707
 
-
 
708
/**
-
 
709
 * drm_fb_helper_fill_fix - initializes fixed fbdev information
-
 
710
 * @info: fbdev registered by the helper
-
 
711
 * @pitch: desired pitch
-
 
712
 * @depth: desired depth
595
 
713
 *
596
	if (new_fb)
714
 * Helper to fill in the fixed fbdev information useful for a non-accelerated
597
        list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
715
 * fbdev emulations. Drivers which support acceleration methods which impose
598
 
716
 * additional constraints need to set up their own limits.
599
	return 0;
717
 *
Line 618... Line 736...
618
	info->fix.line_length = pitch;
736
	info->fix.line_length = pitch;
619
	return;
737
	return;
620
}
738
}
621
EXPORT_SYMBOL(drm_fb_helper_fill_fix);
739
EXPORT_SYMBOL(drm_fb_helper_fill_fix);
Line -... Line 740...
-
 
740
 
-
 
741
/**
-
 
742
 * drm_fb_helper_fill_var - initalizes variable fbdev information
-
 
743
 * @info: fbdev instance to set up
-
 
744
 * @fb_helper: fb helper instance to use as template
-
 
745
 * @fb_width: desired fb width
-
 
746
 * @fb_height: desired fb height
-
 
747
 *
-
 
748
 * Sets up the variable fbdev metainformation from the given fb helper instance
-
 
749
 * and the drm framebuffer allocated in fb_helper->fb.
-
 
750
 *
-
 
751
 * Drivers should call this (or their equivalent setup code) from their
-
 
752
 * ->fb_probe callback after having allocated the fbdev backing
-
 
753
 * storage framebuffer.
622
 
754
 */
623
void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper,
755
void drm_fb_helper_fill_var(struct fb_info *info, struct drm_fb_helper *fb_helper,
624
			    uint32_t fb_width, uint32_t fb_height)
756
			    uint32_t fb_width, uint32_t fb_height)
625
{
757
{
626
	struct drm_framebuffer *fb = fb_helper->fb;
758
	struct drm_framebuffer *fb = fb_helper->fb;
Line 935... Line 1067...
935
	/* need to set the modesets up here for use later */
1067
	/* need to set the modesets up here for use later */
936
	/* fill out the connector<->crtc mappings into the modesets */
1068
	/* fill out the connector<->crtc mappings into the modesets */
937
	for (i = 0; i < fb_helper->crtc_count; i++) {
1069
	for (i = 0; i < fb_helper->crtc_count; i++) {
938
		modeset = &fb_helper->crtc_info[i].mode_set;
1070
		modeset = &fb_helper->crtc_info[i].mode_set;
939
		modeset->num_connectors = 0;
1071
		modeset->num_connectors = 0;
-
 
1072
		modeset->fb = NULL;
940
	}
1073
	}
Line 941... Line 1074...
941
 
1074
 
942
	for (i = 0; i < fb_helper->connector_count; i++) {
1075
	for (i = 0; i < fb_helper->connector_count; i++) {
943
		struct drm_display_mode *mode = modes[i];
1076
		struct drm_display_mode *mode = modes[i];
Line 951... Line 1084...
951
			if (modeset->mode)
1084
			if (modeset->mode)
952
				drm_mode_destroy(dev, modeset->mode);
1085
				drm_mode_destroy(dev, modeset->mode);
953
			modeset->mode = drm_mode_duplicate(dev,
1086
			modeset->mode = drm_mode_duplicate(dev,
954
							   fb_crtc->desired_mode);
1087
							   fb_crtc->desired_mode);
955
			modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
1088
			modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
-
 
1089
			modeset->fb = fb_helper->fb;
956
		}
1090
		}
957
	}
1091
	}
Line -... Line 1092...
-
 
1092
 
-
 
1093
	/* Clear out any old modes if there are no more connected outputs. */
-
 
1094
	for (i = 0; i < fb_helper->crtc_count; i++) {
-
 
1095
		modeset = &fb_helper->crtc_info[i].mode_set;
-
 
1096
		if (modeset->num_connectors == 0) {
-
 
1097
			BUG_ON(modeset->fb);
-
 
1098
			BUG_ON(modeset->num_connectors);
-
 
1099
			if (modeset->mode)
-
 
1100
				drm_mode_destroy(dev, modeset->mode);
-
 
1101
			modeset->mode = NULL;
-
 
1102
		}
958
 
1103
	}
959
out:
1104
out:
960
	kfree(crtcs);
1105
	kfree(crtcs);
961
	kfree(modes);
1106
	kfree(modes);
962
	kfree(enabled);
1107
	kfree(enabled);
Line 963... Line 1108...
963
}
1108
}
964
 
1109
 
965
/**
1110
/**
966
 * drm_helper_initial_config - setup a sane initial connector configuration
1111
 * drm_fb_helper_initial_config - setup a sane initial connector configuration
967
 * @fb_helper: fb_helper device struct
1112
 * @fb_helper: fb_helper device struct
968
 * @bpp_sel: bpp value to use for the framebuffer configuration
-
 
969
 *
-
 
970
 * LOCKING:
-
 
971
 * Called at init time by the driver to set up the @fb_helper initial
-
 
972
 * configuration, must take the mode config lock.
1113
 * @bpp_sel: bpp value to use for the framebuffer configuration
973
 *
1114
 *
974
 * Scans the CRTCs and connectors and tries to put together an initial setup.
1115
 * Scans the CRTCs and connectors and tries to put together an initial setup.
975
 * At the moment, this is a cloned configuration across all heads with
1116
 * At the moment, this is a cloned configuration across all heads with
-
 
1117
 * a new framebuffer object as the backing store.
-
 
1118
 *
-
 
1119
 * Note that this also registers the fbdev and so allows userspace to call into
-
 
1120
 * the driver through the fbdev interfaces.
-
 
1121
 *
-
 
1122
 * This function will call down into the ->fb_probe callback to let
-
 
1123
 * the driver allocate and initialize the fbdev info structure and the drm
-
 
1124
 * framebuffer used to back the fbdev. drm_fb_helper_fill_var() and
-
 
1125
 * drm_fb_helper_fill_fix() are provided as helpers to setup simple default
976
 * a new framebuffer object as the backing store.
1126
 * values for the fbdev info structure.
977
 *
1127
 *
978
 * RETURNS:
1128
 * RETURNS:
979
 * Zero if everything went ok, nonzero otherwise.
1129
 * Zero if everything went ok, nonzero otherwise.
980
 */
1130
 */
981
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
1131
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper, int bpp_sel)
982
{
1132
{
Line 983... Line -...
983
	struct drm_device *dev = fb_helper->dev;
-
 
984
	int count = 0;
-
 
985
 
-
 
986
	/* disable all the possible outputs/crtcs before entering KMS mode */
1133
	struct drm_device *dev = fb_helper->dev;
Line 987... Line 1134...
987
	drm_helper_disable_unused_functions(fb_helper->dev);
1134
	int count = 0;
988
 
1135
 
989
//   drm_fb_helper_parse_command_line(fb_helper);
1136
//   drm_fb_helper_parse_command_line(fb_helper);
Line 1001... Line 1148...
1001
 
1148
 
1002
	return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
1149
	return drm_fb_helper_single_fb_probe(fb_helper, bpp_sel);
1003
}
1150
}
Line 1004... Line -...
1004
EXPORT_SYMBOL(drm_fb_helper_initial_config);
-
 
1005
 
1151
EXPORT_SYMBOL(drm_fb_helper_initial_config);
1006
#if 0
1152
 
1007
/**
1153
/**
1008
 * drm_fb_helper_hotplug_event - respond to a hotplug notification by
1154
 * drm_fb_helper_hotplug_event - respond to a hotplug notification by
1009
 *                               probing all the outputs attached to the fb
1155
 *                               probing all the outputs attached to the fb
1010
 * @fb_helper: the drm_fb_helper
-
 
1011
 *
-
 
1012
 * LOCKING:
-
 
1013
 * Called at runtime, must take mode config lock.
1156
 * @fb_helper: the drm_fb_helper
1014
 *
1157
 *
1015
 * Scan the connectors attached to the fb_helper and try to put together a
1158
 * Scan the connectors attached to the fb_helper and try to put together a
-
 
1159
 * setup after *notification of a change in output configuration.
-
 
1160
 *
-
 
1161
 * Called at runtime, takes the mode config locks to be able to check/change the
-
 
1162
 * modeset configuration. Must be run from process context (which usually means
-
 
1163
 * either the output polling work or a work item launched from the driver's
-
 
1164
 * hotplug interrupt).
-
 
1165
 *
-
 
1166
 * Note that the driver must ensure that this is only called _after_ the fb has
1016
 * setup after *notification of a change in output configuration.
1167
 * been fully set up, i.e. after the call to drm_fb_helper_initial_config.
1017
 *
1168
 *
1018
 * RETURNS:
1169
 * RETURNS:
1019
 * 0 on success and a non-zero error code otherwise.
1170
 * 0 on success and a non-zero error code otherwise.
1020
 */
1171
 */
1021
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
1172
int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper)
1022
{
1173
{
1023
	struct drm_device *dev = fb_helper->dev;
1174
	struct drm_device *dev = fb_helper->dev;
1024
	int count = 0;
-
 
1025
	u32 max_width, max_height, bpp_sel;
-
 
Line 1026... Line 1175...
1026
	int bound = 0, crtcs_bound = 0;
1175
	int count = 0;
1027
	struct drm_crtc *crtc;
1176
	u32 max_width, max_height, bpp_sel;
Line 1028... Line 1177...
1028
 
1177
 
1029
	if (!fb_helper->fb)
-
 
1030
		return 0;
-
 
1031
 
-
 
1032
	mutex_lock(&dev->mode_config.mutex);
-
 
1033
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
-
 
1034
		if (crtc->fb)
-
 
1035
			crtcs_bound++;
-
 
1036
		if (crtc->fb == fb_helper->fb)
1178
	if (!fb_helper->fb)
1037
			bound++;
1179
		return 0;
1038
	}
1180
 
1039
 
1181
	mutex_lock(&fb_helper->dev->mode_config.mutex);
1040
	if (bound < crtcs_bound) {
1182
	if (!drm_fb_helper_is_bound(fb_helper)) {
1041
		fb_helper->delayed_hotplug = true;
1183
		fb_helper->delayed_hotplug = true;
Line 1042... Line 1184...
1042
		mutex_unlock(&dev->mode_config.mutex);
1184
		mutex_unlock(&fb_helper->dev->mode_config.mutex);
1043
		return 0;
1185
		return 0;
1044
	}
1186
	}
Line 1045... Line 1187...
1045
	DRM_DEBUG_KMS("\n");
1187
	DRM_DEBUG_KMS("\n");
1046
 
1188
 
-
 
1189
	max_width = fb_helper->fb->width;
-
 
1190
	max_height = fb_helper->fb->height;
-
 
1191
	bpp_sel = fb_helper->fb->bits_per_pixel;
1047
	max_width = fb_helper->fb->width;
1192
 
-
 
1193
	count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
1048
	max_height = fb_helper->fb->height;
1194
						    max_height);
Line 1049... Line 1195...
1049
	bpp_sel = fb_helper->fb->bits_per_pixel;
1195
	mutex_unlock(&fb_helper->dev->mode_config.mutex);
1050
 
1196
 
1051
	count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
1197
	drm_modeset_lock_all(dev);
1052
						    max_height);
-