Subversion Repositories Kolibri OS

Rev

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

Rev 6935 Rev 6937
Line 51... Line 51...
51
 * track of a per-connector hpd interrupt.
51
 * track of a per-connector hpd interrupt.
52
 *
52
 *
53
 * This helper library can be used independently of the modeset helper library.
53
 * This helper library can be used independently of the modeset helper library.
54
 * Drivers can also overwrite different parts e.g. use their own hotplug
54
 * Drivers can also overwrite different parts e.g. use their own hotplug
55
 * handling code to avoid probing unrelated outputs.
55
 * handling code to avoid probing unrelated outputs.
-
 
56
 *
-
 
57
 * The probe helpers share the function table structures with other display
-
 
58
 * helper libraries. See struct &drm_connector_helper_funcs for the details.
56
 */
59
 */
Line 57... Line 60...
57
 
60
 
58
static bool drm_kms_helper_poll = true;
61
static bool drm_kms_helper_poll = true;
Line 124... Line 127...
124
	if (poll)
127
	if (poll)
125
		schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
128
		schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
126
}
129
}
127
EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked);
130
EXPORT_SYMBOL(drm_kms_helper_poll_enable_locked);
Line -... Line 131...
-
 
131
 
-
 
132
/**
-
 
133
 * drm_helper_probe_single_connector_modes - get complete set of display modes
-
 
134
 * @connector: connector to probe
-
 
135
 * @maxX: max width for modes
-
 
136
 * @maxY: max height for modes
-
 
137
 *
-
 
138
 * Based on the helper callbacks implemented by @connector in struct
-
 
139
 * &drm_connector_helper_funcs try to detect all valid modes.  Modes will first
-
 
140
 * be added to the connector's probed_modes list, then culled (based on validity
-
 
141
 * and the @maxX, @maxY parameters) and put into the normal modes list.
-
 
142
 *
-
 
143
 * Intended to be used as a generic implementation of the ->fill_modes()
-
 
144
 * @connector vfunc for drivers that use the CRTC helpers for output mode
-
 
145
 * filtering and detection.
-
 
146
 *
-
 
147
 * The basic procedure is as follows
-
 
148
 *
-
 
149
 * 1. All modes currently on the connector's modes list are marked as stale
-
 
150
 *
-
 
151
 * 2. New modes are added to the connector's probed_modes list with
-
 
152
 *    drm_mode_probed_add(). New modes start their life with status as OK.
-
 
153
 *    Modes are added from a single source using the following priority order.
-
 
154
 *
-
 
155
 *    - debugfs 'override_edid' (used for testing only)
-
 
156
 *    - firmware EDID (drm_load_edid_firmware())
-
 
157
 *    - connector helper ->get_modes() vfunc
-
 
158
 *    - if the connector status is connector_status_connected, standard
-
 
159
 *      VESA DMT modes up to 1024x768 are automatically added
-
 
160
 *      (drm_add_modes_noedid())
-
 
161
 *
-
 
162
 *    Finally modes specified via the kernel command line (video=...) are
-
 
163
 *    added in addition to what the earlier probes produced
-
 
164
 *    (drm_helper_probe_add_cmdline_mode()). These modes are generated
-
 
165
 *    using the VESA GTF/CVT formulas.
-
 
166
 *
-
 
167
 * 3. Modes are moved from the probed_modes list to the modes list. Potential
-
 
168
 *    duplicates are merged together (see drm_mode_connector_list_update()).
-
 
169
 *    After this step the probed_modes list will be empty again.
-
 
170
 *
-
 
171
 * 4. Any non-stale mode on the modes list then undergoes validation
-
 
172
 *
-
 
173
 *    - drm_mode_validate_basic() performs basic sanity checks
-
 
174
 *    - drm_mode_validate_size() filters out modes larger than @maxX and @maxY
-
 
175
 *      (if specified)
-
 
176
 *    - drm_mode_validate_flag() checks the modes againt basic connector
-
 
177
 *      capabilites (interlace_allowed,doublescan_allowed,stereo_allowed)
-
 
178
 *    - the optional connector ->mode_valid() helper can perform driver and/or
-
 
179
 *      hardware specific checks
-
 
180
 *
-
 
181
 * 5. Any mode whose status is not OK is pruned from the connector's modes list,
-
 
182
 *    accompanied by a debug message indicating the reason for the mode's
128
 
183
 *    rejection (see drm_mode_prune_invalid()).
-
 
184
 *
-
 
185
 * Returns:
-
 
186
 * The number of modes found on @connector.
129
 
187
 */
130
static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connector *connector,
188
int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
131
							      uint32_t maxX, uint32_t maxY, bool merge_type_bits)
189
					    uint32_t maxX, uint32_t maxY)
132
{
190
{
133
	struct drm_device *dev = connector->dev;
191
	struct drm_device *dev = connector->dev;
134
	struct drm_display_mode *mode;
192
	struct drm_display_mode *mode;
135
	const struct drm_connector_helper_funcs *connector_funcs =
193
	const struct drm_connector_helper_funcs *connector_funcs =
Line 141... Line 199...
141
 
199
 
Line 142... Line 200...
142
	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
200
	WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
143
 
201
 
144
	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
202
	DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
145
			connector->name);
203
			connector->name);
146
	/* set all modes to the unverified state */
204
	/* set all old modes to the stale state */
-
 
205
	list_for_each_entry(mode, &connector->modes, head)
-
 
206
		mode->status = MODE_STALE;
Line 147... Line 207...
147
	list_for_each_entry(mode, &connector->modes, head)
207
 
148
		mode->status = MODE_UNVERIFIED;
208
	old_status = connector->status;
149
 
209
 
150
	if (connector->force) {
210
	if (connector->force) {
151
		if (connector->force == DRM_FORCE_ON ||
211
		if (connector->force == DRM_FORCE_ON ||
152
		    connector->force == DRM_FORCE_ON_DIGITAL)
212
		    connector->force == DRM_FORCE_ON_DIGITAL)
153
			connector->status = connector_status_connected;
213
			connector->status = connector_status_connected;
154
		else
214
		else
155
			connector->status = connector_status_disconnected;
215
			connector->status = connector_status_disconnected;
156
		if (connector->funcs->force)
-
 
157
			connector->funcs->force(connector);
-
 
158
	} else {
216
		if (connector->funcs->force)
-
 
217
			connector->funcs->force(connector);
Line 159... Line 218...
159
		old_status = connector->status;
218
	} else {
160
 
219
		connector->status = connector->funcs->detect(connector, true);
161
		connector->status = connector->funcs->detect(connector, true);
220
	}
162
 
221
 
163
		/*
222
		/*
164
		 * Normally either the driver's hpd code or the poll loop should
223
		 * Normally either the driver's hpd code or the poll loop should
165
		 * pick up any changes and fire the hotplug event. But if
224
		 * pick up any changes and fire the hotplug event. But if
166
		 * userspace sneaks in a probe, we might miss a change. Hence
225
		 * userspace sneaks in a probe, we might miss a change. Hence
167
		 * check here, and if anything changed start the hotplug code.
226
		 * check here, and if anything changed start the hotplug code.
168
		 */
227
		 */
-
 
228
		if (old_status != connector->status) {
169
		if (old_status != connector->status) {
229
		DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
Line 170... Line 230...
170
			DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %d to %d\n",
230
				      connector->base.id,
171
				      connector->base.id,
231
				      connector->name,
172
				      connector->name,
232
			      drm_get_connector_status_name(old_status),
173
				      old_status, connector->status);
233
			      drm_get_connector_status_name(connector->status));
Line 181... Line 241...
181
			dev->mode_config.delayed_event = true;
241
			dev->mode_config.delayed_event = true;
182
			if (dev->mode_config.poll_enabled)
242
			if (dev->mode_config.poll_enabled)
183
				schedule_delayed_work(&dev->mode_config.output_poll_work,
243
				schedule_delayed_work(&dev->mode_config.output_poll_work,
184
						      0);
244
						      0);
185
		}
245
		}
186
	}
-
 
Line 187... Line 246...
187
 
246
 
188
	/* Re-enable polling in case the global poll config changed. */
247
	/* Re-enable polling in case the global poll config changed. */
189
	if (drm_kms_helper_poll != dev->mode_config.poll_running)
248
	if (drm_kms_helper_poll != dev->mode_config.poll_running)
Line 197... Line 256...
197
		drm_mode_connector_update_edid_property(connector, NULL);
256
		drm_mode_connector_update_edid_property(connector, NULL);
198
		verbose_prune = false;
257
		verbose_prune = false;
199
		goto prune;
258
		goto prune;
200
	}
259
	}
Line 201... Line -...
201
 
-
 
202
#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
-
 
203
	count = drm_load_edid_firmware(connector);
-
 
204
	if (count == 0)
-
 
205
#endif
-
 
206
	{
260
 
207
		if (connector->override_edid) {
261
		if (connector->override_edid) {
Line 208... Line 262...
208
			struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
262
			struct edid *edid = (struct edid *) connector->edid_blob_ptr->data;
209
 
263
 
210
			count = drm_add_edid_modes(connector, edid);
264
			count = drm_add_edid_modes(connector, edid);
-
 
265
			drm_edid_to_eld(connector, edid);
-
 
266
	} else {
-
 
267
#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
-
 
268
		count = drm_load_edid_firmware(connector);
211
			drm_edid_to_eld(connector, edid);
269
		if (count == 0)
212
		} else
270
#endif
Line 213... Line 271...
213
			count = (*connector_funcs->get_modes)(connector);
271
			count = (*connector_funcs->get_modes)(connector);
214
	}
272
	}
215
 
273
 
216
	if (count == 0 && connector->status == connector_status_connected)
274
	if (count == 0 && connector->status == connector_status_connected)
217
		count = drm_add_modes_noedid(connector, 1024, 768);
275
		count = drm_add_modes_noedid(connector, 1024, 768);
Line 218... Line 276...
218
	count += drm_helper_probe_add_cmdline_mode(connector);
276
	count += drm_helper_probe_add_cmdline_mode(connector);
Line 219... Line 277...
219
	if (count == 0)
277
	if (count == 0)
220
		goto prune;
278
		goto prune;
221
 
279
 
222
	drm_mode_connector_list_update(connector, merge_type_bits);
280
	drm_mode_connector_list_update(connector);
Line 261... Line 319...
261
		drm_mode_debug_printmodeline(mode);
319
		drm_mode_debug_printmodeline(mode);
262
	}
320
	}
Line 263... Line 321...
263
 
321
 
264
	return count;
322
	return count;
265
}
-
 
266
 
-
 
267
/**
-
 
268
 * drm_helper_probe_single_connector_modes - get complete set of display modes
-
 
269
 * @connector: connector to probe
-
 
270
 * @maxX: max width for modes
-
 
271
 * @maxY: max height for modes
-
 
272
 *
-
 
273
 * Based on the helper callbacks implemented by @connector try to detect all
-
 
274
 * valid modes.  Modes will first be added to the connector's probed_modes list,
-
 
275
 * then culled (based on validity and the @maxX, @maxY parameters) and put into
-
 
276
 * the normal modes list.
-
 
277
 *
-
 
278
 * Intended to be use as a generic implementation of the ->fill_modes()
-
 
279
 * @connector vfunc for drivers that use the crtc helpers for output mode
-
 
280
 * filtering and detection.
-
 
281
 *
-
 
282
 * Returns:
-
 
283
 * The number of modes found on @connector.
-
 
284
 */
-
 
285
int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
-
 
286
					    uint32_t maxX, uint32_t maxY)
-
 
287
{
-
 
288
	return drm_helper_probe_single_connector_modes_merge_bits(connector, maxX, maxY, true);
-
 
289
}
323
}
Line 290... Line 324...
290
EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
324
EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
291
 
-
 
292
/**
-
 
293
 * drm_helper_probe_single_connector_modes_nomerge - get complete set of display modes
-
 
294
 * @connector: connector to probe
-
 
295
 * @maxX: max width for modes
-
 
296
 * @maxY: max height for modes
-
 
297
 *
-
 
298
 * This operates like drm_hehlper_probe_single_connector_modes except it
-
 
299
 * replaces the mode bits instead of merging them for preferred modes.
-
 
300
 */
-
 
301
int drm_helper_probe_single_connector_modes_nomerge(struct drm_connector *connector,
-
 
302
					    uint32_t maxX, uint32_t maxY)
-
 
303
{
-
 
304
	return drm_helper_probe_single_connector_modes_merge_bits(connector, maxX, maxY, false);
-
 
305
}
-
 
306
EXPORT_SYMBOL(drm_helper_probe_single_connector_modes_nomerge);
-
 
307
 
325
 
308
/**
326
/**
309
 * drm_kms_helper_hotplug_event - fire off KMS hotplug events
327
 * drm_kms_helper_hotplug_event - fire off KMS hotplug events
310
 * @dev: drm_device whose connector state changed
328
 * @dev: drm_device whose connector state changed
311
 *
329
 *