Subversion Repositories Kolibri OS

Rev

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

Rev 2160 Rev 3031
Line 29... Line 29...
29
 */
29
 */
30
#include 
30
#include 
31
#include 
31
#include 
32
#include 
32
#include 
33
#include 
33
#include 
-
 
34
#include 
34
#include "drmP.h"
35
#include 
35
#include "drm_crtc.h"
36
#include 
36
#include "drm_fb_helper.h"
37
#include 
37
#include "drm_crtc_helper.h"
38
#include 
Line 38... Line 39...
38
 
39
 
39
MODULE_AUTHOR("David Airlie, Jesse Barnes");
40
MODULE_AUTHOR("David Airlie, Jesse Barnes");
40
MODULE_DESCRIPTION("DRM KMS helper");
41
MODULE_DESCRIPTION("DRM KMS helper");
Line 85... Line 86...
85
 
86
 
86
static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
87
static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
87
{
88
{
Line -... Line 89...
-
 
89
	uint16_t *r_base, *g_base, *b_base;
-
 
90
 
-
 
91
	if (crtc->funcs->gamma_set == NULL)
88
	uint16_t *r_base, *g_base, *b_base;
92
		return;
89
 
93
 
90
	r_base = crtc->gamma_store;
94
	r_base = crtc->gamma_store;
Line 91... Line 95...
91
	g_base = r_base + crtc->gamma_size;
95
	g_base = r_base + crtc->gamma_size;
92
	b_base = g_base + crtc->gamma_size;
96
	b_base = g_base + crtc->gamma_size;
Line 93... Line -...
93
 
-
 
94
	crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
-
 
95
}
-
 
96
 
-
 
97
 
-
 
98
static void drm_fb_helper_on(struct fb_info *info)
-
 
99
{
-
 
100
	struct drm_fb_helper *fb_helper = info->par;
-
 
101
	struct drm_device *dev = fb_helper->dev;
-
 
102
	struct drm_crtc *crtc;
-
 
103
	struct drm_crtc_helper_funcs *crtc_funcs;
-
 
104
	struct drm_connector *connector;
-
 
105
	struct drm_encoder *encoder;
-
 
106
	int i, j;
-
 
107
 
-
 
108
	/*
-
 
109
	 * For each CRTC in this fb, turn the crtc on then,
-
 
110
	 * find all associated encoders and turn them on.
-
 
111
	 */
-
 
112
	mutex_lock(&dev->mode_config.mutex);
-
 
113
	for (i = 0; i < fb_helper->crtc_count; i++) {
-
 
114
		crtc = fb_helper->crtc_info[i].mode_set.crtc;
-
 
115
		crtc_funcs = crtc->helper_private;
-
 
116
 
-
 
117
		if (!crtc->enabled)
-
 
118
				continue;
-
 
119
 
-
 
120
			crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
-
 
121
 
-
 
122
		/* Walk the connectors & encoders on this fb turning them on */
-
 
123
		for (j = 0; j < fb_helper->connector_count; j++) {
-
 
124
			connector = fb_helper->connector_info[j]->connector;
-
 
125
			connector->dpms = DRM_MODE_DPMS_ON;
-
 
126
			drm_connector_property_set_value(connector,
-
 
127
							 dev->mode_config.dpms_property,
-
 
128
							 DRM_MODE_DPMS_ON);
-
 
129
		}
-
 
130
			/* Found a CRTC on this fb, now find encoders */
-
 
131
			list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-
 
132
				if (encoder->crtc == crtc) {
-
 
133
					struct drm_encoder_helper_funcs *encoder_funcs;
-
 
134
 
-
 
135
					encoder_funcs = encoder->helper_private;
-
 
136
					encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
-
 
Line 137... Line 97...
137
			}
97
 
138
		}
98
	crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size);
139
	}
99
}
140
	mutex_unlock(&dev->mode_config.mutex);
100
 
141
}
101
 
142
 
-
 
143
static void drm_fb_helper_off(struct fb_info *info, int dpms_mode)
102
 
144
{
-
 
145
	struct drm_fb_helper *fb_helper = info->par;
103
static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
Line 146... Line 104...
146
	struct drm_device *dev = fb_helper->dev;
104
{
147
	struct drm_crtc *crtc;
105
	struct drm_fb_helper *fb_helper = info->par;
148
	struct drm_crtc_helper_funcs *crtc_funcs;
-
 
149
	struct drm_connector *connector;
106
	struct drm_device *dev = fb_helper->dev;
150
	struct drm_encoder *encoder;
107
	struct drm_crtc *crtc;
151
	int i, j;
108
	struct drm_connector *connector;
152
 
109
	int i, j;
153
	/*
-
 
Line 154... Line 110...
154
	 * For each CRTC in this fb, find all associated encoders
110
 
155
	 * and turn them off, then turn off the CRTC.
111
	/*
Line 156... Line 112...
156
	 */
112
	 * For each CRTC in this fb, turn the connectors on/off.
157
	mutex_lock(&dev->mode_config.mutex);
113
	 */
158
	for (i = 0; i < fb_helper->crtc_count; i++) {
114
	mutex_lock(&dev->mode_config.mutex);
159
		crtc = fb_helper->crtc_info[i].mode_set.crtc;
115
	for (i = 0; i < fb_helper->crtc_count; i++) {
160
		crtc_funcs = crtc->helper_private;
116
		crtc = fb_helper->crtc_info[i].mode_set.crtc;
161
 
117
 
162
		if (!crtc->enabled)
-
 
163
				continue;
-
 
164
 
-
 
165
		/* Walk the connectors on this fb and mark them off */
-
 
166
		for (j = 0; j < fb_helper->connector_count; j++) {
-
 
167
			connector = fb_helper->connector_info[j]->connector;
-
 
168
			connector->dpms = dpms_mode;
-
 
169
			drm_connector_property_set_value(connector,
-
 
170
							 dev->mode_config.dpms_property,
-
 
171
							 dpms_mode);
-
 
172
		}
118
		if (!crtc->enabled)
173
			/* Found a CRTC on this fb, now find encoders */
-
 
174
			list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
119
				continue;
175
				if (encoder->crtc == crtc) {
120
 
176
					struct drm_encoder_helper_funcs *encoder_funcs;
121
		/* Walk the connectors & encoders on this fb turning them on/off */
Line 177... Line 122...
177
 
122
		for (j = 0; j < fb_helper->connector_count; j++) {
178
					encoder_funcs = encoder->helper_private;
123
			connector = fb_helper->connector_info[j]->connector;
179
					encoder_funcs->dpms(encoder, dpms_mode);
124
			connector->funcs->dpms(connector, dpms_mode);
180
				}
125
			drm_connector_property_set_value(connector,
181
			}
126
				dev->mode_config.dpms_property, dpms_mode);
182
			    crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
127
		}
183
	}
128
	}
184
				mutex_unlock(&dev->mode_config.mutex);
129
				mutex_unlock(&dev->mode_config.mutex);
185
}
130
}
186
 
131
 
187
int drm_fb_helper_blank(int blank, struct fb_info *info)
132
int drm_fb_helper_blank(int blank, struct fb_info *info)
188
{
133
{
189
	switch (blank) {
134
	switch (blank) {
190
	/* Display: On; HSync: On, VSync: On */
135
	/* Display: On; HSync: On, VSync: On */
191
	case FB_BLANK_UNBLANK:
136
	case FB_BLANK_UNBLANK:
192
		drm_fb_helper_on(info);
137
		drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON);
193
		break;
138
		break;
194
	/* Display: Off; HSync: On, VSync: On */
139
	/* Display: Off; HSync: On, VSync: On */
195
	case FB_BLANK_NORMAL:
140
	case FB_BLANK_NORMAL:
196
		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
141
		drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
197
		break;
142
		break;
198
	/* Display: Off; HSync: Off, VSync: On */
143
	/* Display: Off; HSync: Off, VSync: On */
199
	case FB_BLANK_HSYNC_SUSPEND:
144
	case FB_BLANK_HSYNC_SUSPEND:
200
		drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY);
145
		drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY);
201
		break;
146
		break;
202
	/* Display: Off; HSync: On, VSync: Off */
147
	/* Display: Off; HSync: On, VSync: Off */
203
	case FB_BLANK_VSYNC_SUSPEND:
148
	case FB_BLANK_VSYNC_SUSPEND:
Line 217... Line 162...
217
	int i;
162
	int i;
Line 218... Line 163...
218
 
163
 
219
	for (i = 0; i < helper->connector_count; i++)
164
	for (i = 0; i < helper->connector_count; i++)
220
		kfree(helper->connector_info[i]);
165
		kfree(helper->connector_info[i]);
221
	kfree(helper->connector_info);
166
	kfree(helper->connector_info);
222
	for (i = 0; i < helper->crtc_count; i++)
167
	for (i = 0; i < helper->crtc_count; i++) {
-
 
168
		kfree(helper->crtc_info[i].mode_set.connectors);
-
 
169
		if (helper->crtc_info[i].mode_set.mode)
-
 
170
			drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode);
223
		kfree(helper->crtc_info[i].mode_set.connectors);
171
	}
224
	kfree(helper->crtc_info);
172
	kfree(helper->crtc_info);
Line 225... Line 173...
225
}
173
}
226
 
174
 
227
int drm_fb_helper_init(struct drm_device *dev,
175
int drm_fb_helper_init(struct drm_device *dev,
228
		       struct drm_fb_helper *fb_helper,
176
		       struct drm_fb_helper *fb_helper,
229
		       int crtc_count, int max_conn_count)
177
		       int crtc_count, int max_conn_count)
230
{
-
 
231
	struct drm_crtc *crtc;
178
{
Line 232... Line 179...
232
	int ret = 0;
179
	struct drm_crtc *crtc;
Line 233... Line 180...
233
	int i;
180
	int i;
Line 252... Line 199...
252
		fb_helper->crtc_info[i].mode_set.connectors =
199
		fb_helper->crtc_info[i].mode_set.connectors =
253
			kcalloc(max_conn_count,
200
			kcalloc(max_conn_count,
254
				sizeof(struct drm_connector *),
201
				sizeof(struct drm_connector *),
255
				GFP_KERNEL);
202
				GFP_KERNEL);
Line 256... Line 203...
256
 
203
 
257
		if (!fb_helper->crtc_info[i].mode_set.connectors) {
-
 
258
			ret = -ENOMEM;
204
		if (!fb_helper->crtc_info[i].mode_set.connectors)
259
			goto out_free;
-
 
260
		}
205
			goto out_free;
261
		fb_helper->crtc_info[i].mode_set.num_connectors = 0;
206
		fb_helper->crtc_info[i].mode_set.num_connectors = 0;
Line 262... Line 207...
262
	}
207
	}
263
 
208
 
264
	i = 0;
-
 
265
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
209
	i = 0;
266
		fb_helper->crtc_info[i].crtc_id = crtc->base.id;
210
	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
267
		fb_helper->crtc_info[i].mode_set.crtc = crtc;
211
		fb_helper->crtc_info[i].mode_set.crtc = crtc;
268
		i++;
-
 
-
 
212
		i++;
269
	}
213
	}
270
	fb_helper->conn_limit = max_conn_count;
214
 
271
	return 0;
215
	return 0;
272
out_free:
216
out_free:
273
	drm_fb_helper_crtc_free(fb_helper);
217
	drm_fb_helper_crtc_free(fb_helper);
Line 387... Line 331...
387
 
331
 
388
	if (var->pixclock != 0 || in_dbg_master())
332
	if (var->pixclock != 0 || in_dbg_master())
Line 389... Line 333...
389
		return -EINVAL;
333
		return -EINVAL;
-
 
334
 
-
 
335
	/* Need to resize the fb object !!! */
390
 
336
	if (var->bits_per_pixel > fb->bits_per_pixel ||
391
	/* Need to resize the fb object !!! */
337
	    var->xres > fb->width || var->yres > fb->height ||
-
 
338
	    var->xres_virtual > fb->width || var->yres_virtual > fb->height) {
392
	if (var->bits_per_pixel > fb->bits_per_pixel || var->xres > fb->width || var->yres > fb->height) {
339
		DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb "
-
 
340
			  "request %dx%d-%d (virtual %dx%d) > %dx%d-%d\n",
393
		DRM_DEBUG("fb userspace requested width/height/bpp is greater than current fb "
341
			  var->xres, var->yres, var->bits_per_pixel,
394
			  "object %dx%d-%d > %dx%d-%d\n", var->xres, var->yres, var->bits_per_pixel,
342
			  var->xres_virtual, var->yres_virtual,
395
			  fb->width, fb->height, fb->bits_per_pixel);
343
			  fb->width, fb->height, fb->bits_per_pixel);
Line 396... Line 344...
396
		return -EINVAL;
344
		return -EINVAL;
Line 546... Line 494...
546
	sizes.surface_depth = 24;
494
	sizes.surface_depth = 24;
547
	sizes.surface_bpp = 32;
495
	sizes.surface_bpp = 32;
548
	sizes.fb_width = (unsigned)-1;
496
	sizes.fb_width = (unsigned)-1;
549
	sizes.fb_height = (unsigned)-1;
497
	sizes.fb_height = (unsigned)-1;
Line -... Line 498...
-
 
498
 
-
 
499
	/* if driver picks 8 or 16 by default use that
-
 
500
	   for both depth/bpp */
-
 
501
	if (preferred_bpp != sizes.surface_bpp) {
-
 
502
		sizes.surface_depth = sizes.surface_bpp = preferred_bpp;
-
 
503
	}
-
 
504
	/* first up get a count of crtcs now in use and new min/maxes width/heights */
-
 
505
	for (i = 0; i < fb_helper->connector_count; i++) {
-
 
506
		struct drm_fb_helper_connector *fb_helper_conn = fb_helper->connector_info[i];
-
 
507
		struct drm_cmdline_mode *cmdline_mode;
-
 
508
 
-
 
509
		cmdline_mode = &fb_helper_conn->cmdline_mode;
-
 
510
 
-
 
511
		if (cmdline_mode->bpp_specified) {
-
 
512
			switch (cmdline_mode->bpp) {
-
 
513
			case 8:
-
 
514
				sizes.surface_depth = sizes.surface_bpp = 8;
-
 
515
				break;
-
 
516
			case 15:
-
 
517
				sizes.surface_depth = 15;
-
 
518
				sizes.surface_bpp = 16;
-
 
519
				break;
-
 
520
			case 16:
-
 
521
				sizes.surface_depth = sizes.surface_bpp = 16;
-
 
522
				break;
-
 
523
			case 24:
-
 
524
				sizes.surface_depth = sizes.surface_bpp = 24;
-
 
525
				break;
550
 
526
			case 32:
551
    sizes.surface_depth = 24;
527
    sizes.surface_depth = 24;
-
 
528
    sizes.surface_bpp = 32;
-
 
529
				break;
-
 
530
			}
-
 
531
			break;
-
 
532
		}
Line 552... Line 533...
552
    sizes.surface_bpp = 32;
533
	}
553
 
534
 
554
	crtc_count = 0;
535
	crtc_count = 0;
555
	for (i = 0; i < fb_helper->crtc_count; i++) {
536
	for (i = 0; i < fb_helper->crtc_count; i++) {
Line 902... Line 883...
902
static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
883
static void drm_setup_crtcs(struct drm_fb_helper *fb_helper)
903
{
884
{
904
	struct drm_device *dev = fb_helper->dev;
885
	struct drm_device *dev = fb_helper->dev;
905
	struct drm_fb_helper_crtc **crtcs;
886
	struct drm_fb_helper_crtc **crtcs;
906
	struct drm_display_mode **modes;
887
	struct drm_display_mode **modes;
907
	struct drm_encoder *encoder;
-
 
908
	struct drm_mode_set *modeset;
888
	struct drm_mode_set *modeset;
909
	bool *enabled;
889
	bool *enabled;
910
	int width, height;
890
	int width, height;
911
	int i, ret;
891
	int i, ret;
Line 912... Line 892...
912
 
892
 
Line 913... Line 893...
913
	DRM_DEBUG_KMS("\n");
893
	DRM_DEBUG_KMS("\n");
914
 
894
 
Line 915... Line -...
915
	width = dev->mode_config.max_width;
-
 
916
	height = dev->mode_config.max_height;
-
 
917
 
-
 
918
	/* clean out all the encoder/crtc combos */
-
 
919
   list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
-
 
920
		encoder->crtc = NULL;
895
	width = dev->mode_config.max_width;
921
   }
896
	height = dev->mode_config.max_height;
922
 
897
 
923
	crtcs = kcalloc(dev->mode_config.num_connector,
898
	crtcs = kcalloc(dev->mode_config.num_connector,
924
			sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
899
			sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
Line 990... Line 965...
990
{
965
{
991
	struct drm_device *dev = fb_helper->dev;
966
	struct drm_device *dev = fb_helper->dev;
992
	int count = 0;
967
	int count = 0;
Line 993... Line 968...
993
 
968
 
994
	/* disable all the possible outputs/crtcs before entering KMS mode */
969
	/* disable all the possible outputs/crtcs before entering KMS mode */
Line 995... Line 970...
995
//   drm_helper_disable_unused_functions(fb_helper->dev);
970
	drm_helper_disable_unused_functions(fb_helper->dev);
Line 996... Line 971...
996
 
971
 
997
//   drm_fb_helper_parse_command_line(fb_helper);
972
//   drm_fb_helper_parse_command_line(fb_helper);