summaryrefslogtreecommitdiff
path: root/linux-core
diff options
context:
space:
mode:
Diffstat (limited to 'linux-core')
-rw-r--r--linux-core/drmP.h8
-rw-r--r--linux-core/drm_crtc.c745
-rw-r--r--linux-core/drm_crtc.h246
-rw-r--r--linux-core/drm_crtc_helper.c441
-rw-r--r--linux-core/drm_crtc_helper.h41
-rw-r--r--linux-core/drm_drv.c5
-rw-r--r--linux-core/drm_edid.c94
-rw-r--r--linux-core/drm_modes.c14
-rw-r--r--linux-core/drm_sysfs.c92
-rw-r--r--linux-core/dvo.h2
-rw-r--r--linux-core/dvo_ch7017.c4
-rw-r--r--linux-core/dvo_ch7xxx.c6
-rw-r--r--linux-core/dvo_ivch.c4
-rw-r--r--linux-core/dvo_sil164.c6
-rw-r--r--linux-core/dvo_tfp410.c8
-rw-r--r--linux-core/intel_crt.c115
-rw-r--r--linux-core/intel_display.c139
-rw-r--r--linux-core/intel_drv.h29
-rw-r--r--linux-core/intel_dvo.c135
-rw-r--r--linux-core/intel_fb.c34
-rw-r--r--linux-core/intel_lvds.c144
-rw-r--r--linux-core/intel_modes.c16
-rw-r--r--linux-core/intel_sdvo.c411
-rw-r--r--linux-core/intel_tv.c200
24 files changed, 1656 insertions, 1283 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 60ae018e..7c7e201a 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -743,7 +743,7 @@ struct drm_driver {
struct drm_set_version *sv);
/* FB routines, if present */
- int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output);
+ int (*fb_probe)(struct drm_device *dev, struct drm_crtc *crtc, struct drm_connector *connector);
int (*fb_remove)(struct drm_device *dev, struct drm_framebuffer *fb);
int (*fb_resize)(struct drm_device *dev, struct drm_crtc *crtc);
@@ -1317,9 +1317,9 @@ extern void drm_sysfs_destroy(void);
extern int drm_sysfs_device_add(struct drm_minor *minor);
extern void drm_sysfs_hotplug_event(struct drm_device *dev);
extern void drm_sysfs_device_remove(struct drm_minor *minor);
-extern char *drm_get_output_status_name(enum drm_output_status status);
-extern int drm_sysfs_output_add(struct drm_output *output);
-extern void drm_sysfs_output_remove(struct drm_output *output);
+extern char *drm_get_connector_status_name(enum drm_connector_status status);
+extern int drm_sysfs_connector_add(struct drm_connector *connector);
+extern void drm_sysfs_connector_remove(struct drm_connector *connector);
/*
* Basic memory manager support (drm_mm.c)
diff --git a/linux-core/drm_crtc.c b/linux-core/drm_crtc.c
index faf70df5..73c7f2a3 100644
--- a/linux-core/drm_crtc.c
+++ b/linux-core/drm_crtc.c
@@ -1,6 +1,7 @@
/*
* Copyright (c) 2006-2007 Intel Corporation
* Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
+ * Copyright (c) 2008 Red Hat Inc.
*
* DRM core CRTC related functions
*
@@ -59,43 +60,52 @@ char *drm_get_dpms_name(int val)
return "unknown";
}
-static struct drm_prop_enum_list drm_conn_enum_list[] =
-{ { ConnectorUnknown, "Unknown" },
- { ConnectorVGA, "VGA" },
- { ConnectorDVII, "DVI-I" },
- { ConnectorDVID, "DVI-D" },
- { ConnectorDVIA, "DVI-A" },
- { ConnectorComposite, "Composite" },
- { ConnectorSVIDEO, "SVIDEO" },
- { ConnectorLVDS, "LVDS" },
- { ConnectorComponent, "Component" },
- { Connector9PinDIN, "9-pin DIN" },
- { ConnectorDisplayPort, "DisplayPort" },
- { ConnectorHDMIA, "HDMI Type A" },
- { ConnectorHDMIB, "HDMI Type B" },
+static struct drm_prop_enum_list drm_connector_enum_list[] =
+{ { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
+ { DRM_MODE_CONNECTOR_VGA, "VGA" },
+ { DRM_MODE_CONNECTOR_DVII, "DVI-I" },
+ { DRM_MODE_CONNECTOR_DVID, "DVI-D" },
+ { DRM_MODE_CONNECTOR_DVIA, "DVI-A" },
+ { DRM_MODE_CONNECTOR_Composite, "Composite" },
+ { DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO" },
+ { DRM_MODE_CONNECTOR_LVDS, "LVDS" },
+ { DRM_MODE_CONNECTOR_Component, "Component" },
+ { DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN" },
+ { DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort" },
+ { DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A" },
+ { DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B" },
};
-static struct drm_prop_enum_list drm_output_enum_list[] =
-{ { DRM_MODE_OUTPUT_NONE, "None" },
- { DRM_MODE_OUTPUT_DAC, "DAC" },
- { DRM_MODE_OUTPUT_TMDS, "TMDS" },
- { DRM_MODE_OUTPUT_LVDS, "LVDS" },
- { DRM_MODE_OUTPUT_TVDAC, "TV" },
+static struct drm_prop_enum_list drm_encoder_enum_list[] =
+{ { DRM_MODE_ENCODER_NONE, "None" },
+ { DRM_MODE_ENCODER_DAC, "DAC" },
+ { DRM_MODE_ENCODER_TMDS, "TMDS" },
+ { DRM_MODE_ENCODER_LVDS, "LVDS" },
+ { DRM_MODE_ENCODER_TVDAC, "TV" },
};
-char *drm_get_output_name(struct drm_output *output)
+char *drm_get_encoder_name(struct drm_encoder *encoder)
{
static char buf[32];
- snprintf(buf, 32, "%s-%d", drm_output_enum_list[output->output_type].name,
- output->output_type_id);
+ snprintf(buf, 32, "%s-%d", drm_encoder_enum_list[encoder->encoder_type].name,
+ encoder->id);
return buf;
}
-char *drm_get_output_status_name(enum drm_output_status status)
+char *drm_get_connector_name(struct drm_connector *connector)
{
- if (status == output_status_connected)
+ static char buf[32];
+
+ snprintf(buf, 32, "%s-%d", drm_connector_enum_list[connector->connector_type].name,
+ connector->connector_type_id);
+ return buf;
+}
+
+char *drm_get_connector_status_name(enum drm_connector_status status)
+{
+ if (status == connector_status_connected)
return "connected";
- else if (status == output_status_disconnected)
+ else if (status == connector_status_disconnected)
return "disconnected";
else
return "unknown";
@@ -110,7 +120,7 @@ char *drm_get_output_status_name(enum drm_output_status status)
* Caller must hold DRM mode_config lock.
*
* Create a unique identifier based on @ptr in @dev's identifier space. Used
- * for tracking modes, CRTCs and outputs.
+ * for tracking modes, CRTCs and connectors.
*
* RETURNS:
* New unique (relative to other objects in @dev) integer identifier for the
@@ -276,190 +286,33 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
EXPORT_SYMBOL(drm_crtc_cleanup);
/**
- * drm_crtc_in_use - check if a given CRTC is in a mode_config
- * @crtc: CRTC to check
- *
- * LOCKING:
- * Caller must hold mode config lock.
- *
- * Walk @crtc's DRM device's mode_config and see if it's in use.
- *
- * RETURNS:
- * True if @crtc is part of the mode_config, false otherwise.
- */
-bool drm_crtc_in_use(struct drm_crtc *crtc)
-{
- struct drm_output *output;
- struct drm_device *dev = crtc->dev;
- /* FIXME: Locking around list access? */
- list_for_each_entry(output, &dev->mode_config.output_list, head)
- if (output->crtc == crtc)
- return true;
- return false;
-}
-EXPORT_SYMBOL(drm_crtc_in_use);
-
-/*
- * Detailed mode info for a standard 640x480@60Hz monitor
- */
-static struct drm_display_mode std_mode[] = {
- { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
- 752, 800, 0, 480, 490, 492, 525, 0,
- V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
-};
-
-/**
- * drm_crtc_probe_output_modes - get complete set of display modes
- * @dev: DRM device
- * @maxX: max width for modes
- * @maxY: max height for modes
- *
- * LOCKING:
- * Caller must hold mode config lock.
- *
- * Based on @dev's mode_config layout, scan all the outputs and try to detect
- * modes on them. Modes will first be added to the output's probed_modes
- * list, then culled (based on validity and the @maxX, @maxY parameters) and
- * put into the normal modes list.
- *
- * Intended to be used either at bootup time or when major configuration
- * changes have occurred.
- *
- * FIXME: take into account monitor limits
- */
-void drm_crtc_probe_single_output_modes(struct drm_output *output, int maxX, int maxY)
-{
- struct drm_device *dev = output->dev;
- struct drm_display_mode *mode, *t;
- int ret;
- //if (maxX == 0 || maxY == 0)
- // TODO
-
- /* set all modes to the unverified state */
- list_for_each_entry_safe(mode, t, &output->modes, head)
- mode->status = MODE_UNVERIFIED;
-
- output->status = (*output->funcs->detect)(output);
-
- if (output->status == output_status_disconnected) {
- DRM_DEBUG("%s is disconnected\n", drm_get_output_name(output));
- /* TODO set EDID to NULL */
- return;
- }
-
- ret = (*output->funcs->get_modes)(output);
-
- if (ret) {
- drm_mode_output_list_update(output);
- }
-
- if (maxX && maxY)
- drm_mode_validate_size(dev, &output->modes, maxX,
- maxY, 0);
- list_for_each_entry_safe(mode, t, &output->modes, head) {
- if (mode->status == MODE_OK)
- mode->status = (*output->funcs->mode_valid)(output,mode);
- }
-
-
- drm_mode_prune_invalid(dev, &output->modes, TRUE);
-
- if (list_empty(&output->modes)) {
- struct drm_display_mode *stdmode;
-
- DRM_DEBUG("No valid modes on %s\n", drm_get_output_name(output));
-
- /* Should we do this here ???
- * When no valid EDID modes are available we end up
- * here and bailed in the past, now we add a standard
- * 640x480@60Hz mode and carry on.
- */
- stdmode = drm_mode_duplicate(dev, &std_mode[0]);
- drm_mode_probed_add(output, stdmode);
- drm_mode_list_concat(&output->probed_modes,
- &output->modes);
-
- DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
- drm_get_output_name(output));
- }
-
- drm_mode_sort(&output->modes);
-
- DRM_DEBUG("Probed modes for %s\n", drm_get_output_name(output));
- list_for_each_entry_safe(mode, t, &output->modes, head) {
- mode->vrefresh = drm_mode_vrefresh(mode);
-
- drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
- drm_mode_debug_printmodeline(mode);
- }
-}
-
-void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
-{
- struct drm_output *output;
-
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- drm_crtc_probe_single_output_modes(output, maxX, maxY);
- }
-}
-EXPORT_SYMBOL(drm_crtc_probe_output_modes);
-
-
-/**
- * drm_disable_unused_functions - disable unused objects
- * @dev: DRM device
- *
- * LOCKING:
- * Caller must hold mode config lock.
- *
- * If an output or CRTC isn't part of @dev's mode_config, it can be disabled
- * by calling its dpms function, which should power it off.
- */
-void drm_disable_unused_functions(struct drm_device *dev)
-{
- struct drm_output *output;
- struct drm_crtc *crtc;
-
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- if (!output->crtc)
- (*output->funcs->dpms)(output, DPMSModeOff);
- }
-
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
- if (!crtc->enabled)
- crtc->funcs->dpms(crtc, DPMSModeOff);
- }
-}
-EXPORT_SYMBOL(drm_disable_unused_functions);
-
-/**
- * drm_mode_probed_add - add a mode to the specified output's probed mode list
- * @output: output the new mode
+ * drm_mode_probed_add - add a mode to the specified connector's probed mode list
+ * @connector: connector the new mode
* @mode: mode data
*
* LOCKING:
* Caller must hold mode config lock.
*
- * Add @mode to @output's mode list for later use.
+ * Add @mode to @connector's mode list for later use.
*/
-void drm_mode_probed_add(struct drm_output *output,
+void drm_mode_probed_add(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- list_add(&mode->head, &output->probed_modes);
+ list_add(&mode->head, &connector->probed_modes);
}
EXPORT_SYMBOL(drm_mode_probed_add);
/**
* drm_mode_remove - remove and free a mode
- * @output: output list to modify
+ * @connector: connector list to modify
* @mode: mode to remove
*
* LOCKING:
* Caller must hold mode config lock.
*
- * Remove @mode from @output's mode list, then free it.
+ * Remove @mode from @connector's mode list, then free it.
*/
-void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode)
+void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode)
{
list_del(&mode->head);
kfree(mode);
@@ -467,77 +320,104 @@ void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode)
EXPORT_SYMBOL(drm_mode_remove);
/**
- * drm_output_init - Init a preallocated output
+ * drm_connector_init - Init a preallocated connector
* @dev: DRM device
- * @output: the output to init
- * @funcs: callbacks for this output
- * @name: user visible name of the output
+ * @connector: the connector to init
+ * @funcs: callbacks for this connector
+ * @name: user visible name of the connector
*
* LOCKING:
* Caller must hold @dev's mode_config lock.
*
- * Initialises a preallocated output. Outputs should be
- * subclassed as part of driver output objects.
+ * Initialises a preallocated connector. Connectors should be
+ * subclassed as part of driver connector objects.
*/
-void drm_output_init(struct drm_device *dev,
- struct drm_output *output,
- const struct drm_output_funcs *funcs,
- int output_type)
+void drm_connector_init(struct drm_device *dev,
+ struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ int connector_type)
{
- output->dev = dev;
- output->funcs = funcs;
- output->id = drm_idr_get(dev, output);
- output->output_type = output_type;
- output->output_type_id = 1; /* TODO */
- INIT_LIST_HEAD(&output->user_modes);
- INIT_LIST_HEAD(&output->probed_modes);
- INIT_LIST_HEAD(&output->modes);
- /* randr_output? */
- /* output_set_monitor(output)? */
- /* check for output_ignored(output)? */
+ connector->dev = dev;
+ connector->funcs = funcs;
+ connector->id = drm_idr_get(dev, connector);
+ connector->connector_type = connector_type;
+ connector->connector_type_id = 1; /* TODO */
+ INIT_LIST_HEAD(&connector->user_modes);
+ INIT_LIST_HEAD(&connector->probed_modes);
+ INIT_LIST_HEAD(&connector->modes);
+ /* randr_connector? */
+ /* connector_set_monitor(connector)? */
+ /* check for connector_ignored(connector)? */
mutex_lock(&dev->mode_config.mutex);
- list_add_tail(&output->head, &dev->mode_config.output_list);
- dev->mode_config.num_output++;
+ list_add_tail(&connector->head, &dev->mode_config.connector_list);
+ dev->mode_config.num_connector++;
- drm_output_attach_property(output, dev->mode_config.edid_property, 0);
+ drm_connector_attach_property(connector, dev->mode_config.edid_property, 0);
- drm_output_attach_property(output, dev->mode_config.dpms_property, 0);
+ drm_connector_attach_property(connector, dev->mode_config.dpms_property, 0);
mutex_unlock(&dev->mode_config.mutex);
}
-EXPORT_SYMBOL(drm_output_init);
+EXPORT_SYMBOL(drm_connector_init);
/**
- * drm_output_cleanup - cleans up an initialised output
- * @output: output to cleanup
+ * drm_connector_cleanup - cleans up an initialised connector
+ * @connector: connector to cleanup
*
* LOCKING:
* Caller must hold @dev's mode_config lock.
*
- * Cleans up the output but doesn't free the object.
+ * Cleans up the connector but doesn't free the object.
*/
-void drm_output_cleanup(struct drm_output *output)
+void drm_connector_cleanup(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_display_mode *mode, *t;
- list_for_each_entry_safe(mode, t, &output->probed_modes, head)
- drm_mode_remove(output, mode);
+ list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
+ drm_mode_remove(connector, mode);
- list_for_each_entry_safe(mode, t, &output->modes, head)
- drm_mode_remove(output, mode);
+ list_for_each_entry_safe(mode, t, &connector->modes, head)
+ drm_mode_remove(connector, mode);
- list_for_each_entry_safe(mode, t, &output->user_modes, head)
- drm_mode_remove(output, mode);
+ list_for_each_entry_safe(mode, t, &connector->user_modes, head)
+ drm_mode_remove(connector, mode);
mutex_lock(&dev->mode_config.mutex);
- drm_idr_put(dev, output->id);
- list_del(&output->head);
+ drm_idr_put(dev, connector->id);
+ list_del(&connector->head);
mutex_unlock(&dev->mode_config.mutex);
}
-EXPORT_SYMBOL(drm_output_cleanup);
+EXPORT_SYMBOL(drm_connector_cleanup);
+void drm_encoder_init(struct drm_device *dev,
+ struct drm_encoder *encoder,
+ const struct drm_encoder_funcs *funcs,
+ int encoder_type)
+{
+ encoder->dev = dev;
+ encoder->id = drm_idr_get(dev, encoder);
+ encoder->encoder_type = encoder_type;
+ encoder->funcs = funcs;
+
+ mutex_lock(&dev->mode_config.mutex);
+ list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
+ dev->mode_config.num_encoder++;
+
+ mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_encoder_init);
+
+void drm_encoder_cleanup(struct drm_encoder *encoder)
+{
+ struct drm_device *dev = encoder->dev;
+ mutex_lock(&dev->mode_config.mutex);
+ drm_idr_put(dev, encoder->id);
+ list_del(&encoder->head);
+ mutex_unlock(&dev->mode_config.mutex);
+}
+EXPORT_SYMBOL(drm_encoder_cleanup);
/**
* drm_mode_create - create a new display mode
@@ -582,12 +462,12 @@ void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode)
}
EXPORT_SYMBOL(drm_mode_destroy);
-static int drm_mode_create_standard_output_properties(struct drm_device *dev)
+static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
{
int i;
/*
- * Standard properties (apply to all outputs)
+ * Standard properties (apply to all connectors)
*/
dev->mode_config.edid_property =
drm_property_create(dev, DRM_MODE_PROP_BLOB | DRM_MODE_PROP_IMMUTABLE,
@@ -599,29 +479,17 @@ static int drm_mode_create_standard_output_properties(struct drm_device *dev)
for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++)
drm_property_add_enum(dev->mode_config.dpms_property, i, drm_dpms_enum_list[i].type, drm_dpms_enum_list[i].name);
- dev->mode_config.connector_type_property =
- drm_property_create(dev, DRM_MODE_PROP_ENUM | DRM_MODE_PROP_IMMUTABLE,
- "Connector Type", ARRAY_SIZE(drm_conn_enum_list));
- for (i = 0; i < ARRAY_SIZE(drm_conn_enum_list); i++)
- drm_property_add_enum(dev->mode_config.connector_type_property, i, drm_conn_enum_list[i].type, drm_conn_enum_list[i].name);
-
- dev->mode_config.connector_num_property =
- drm_property_create(dev, DRM_MODE_PROP_RANGE | DRM_MODE_PROP_IMMUTABLE,
- "Connector ID", 2);
- dev->mode_config.connector_num_property->values[0] = 0;
- dev->mode_config.connector_num_property->values[1] = 20;
-
return 0;
}
/**
- * drm_create_tv_properties - create TV specific output properties
+ * drm_create_tv_properties - create TV specific connector properties
* @dev: DRM device
* @num_modes: number of different TV formats (modes) supported
* @modes: array of pointers to strings containing name of each format
*
* Called by a driver's TV initialization routine, this function creates
- * the TV specific output properties for a given device. Caller is
+ * the TV specific connector properties for a given device. Caller is
* responsible for allocating a list of format names and passing them to
* this routine.
*/
@@ -681,17 +549,19 @@ void drm_mode_config_init(struct drm_device *dev)
mutex_init(&dev->mode_config.mutex);
INIT_LIST_HEAD(&dev->mode_config.fb_list);
INIT_LIST_HEAD(&dev->mode_config.crtc_list);
- INIT_LIST_HEAD(&dev->mode_config.output_list);
+ INIT_LIST_HEAD(&dev->mode_config.connector_list);
+ INIT_LIST_HEAD(&dev->mode_config.encoder_list);
INIT_LIST_HEAD(&dev->mode_config.property_list);
INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
idr_init(&dev->mode_config.crtc_idr);
- drm_mode_create_standard_output_properties(dev);
+ drm_mode_create_standard_connector_properties(dev);
/* Just to be sure */
dev->mode_config.num_fb = 0;
- dev->mode_config.num_output = 0;
+ dev->mode_config.num_connector = 0;
dev->mode_config.num_crtc = 0;
+ dev->mode_config.num_encoder = 0;
dev->mode_config.hotplug_counter = 0;
}
EXPORT_SYMBOL(drm_mode_config_init);
@@ -750,21 +620,26 @@ out_err:
* LOCKING:
* Caller must hold mode config lock.
*
- * Free up all the outputs and CRTCs associated with this DRM device, then
+ * Free up all the connectors and CRTCs associated with this DRM device, then
* free up the framebuffers and associated buffer objects.
*
* FIXME: cleanup any dangling user buffer objects too
*/
void drm_mode_config_cleanup(struct drm_device *dev)
{
- struct drm_output *output, *ot;
+ struct drm_connector *connector, *ot;
struct drm_crtc *crtc, *ct;
+ struct drm_encoder *encoder, *enct;
struct drm_framebuffer *fb, *fbt;
struct drm_property *property, *pt;
- list_for_each_entry_safe(output, ot, &dev->mode_config.output_list, head) {
- drm_sysfs_output_remove(output);
- output->funcs->destroy(output);
+ list_for_each_entry_safe(encoder, enct, &dev->mode_config.encoder_list, head) {
+ encoder->funcs->destroy(encoder);
+ }
+
+ list_for_each_entry_safe(connector, ot, &dev->mode_config.connector_list, head) {
+ drm_sysfs_connector_remove(connector);
+ connector->funcs->destroy(connector);
}
list_for_each_entry_safe(property, pt, &dev->mode_config.property_list, head) {
@@ -871,7 +746,7 @@ void drm_crtc_convert_umode(struct drm_display_mode *out, struct drm_mode_modein
* Takes mode config lock.
*
* Construct a set of configuration description structures and return
- * them to the user, including CRTC, output and framebuffer configuration.
+ * them to the user, including CRTC, connector and framebuffer configuration.
*
* Called by the user via ioctl.
*
@@ -884,16 +759,19 @@ int drm_mode_getresources(struct drm_device *dev,
struct drm_mode_card_res *card_res = data;
struct list_head *lh;
struct drm_framebuffer *fb;
- struct drm_output *output;
+ struct drm_connector *connector;
struct drm_crtc *crtc;
+ struct drm_encoder *encoder;
int ret = 0;
- int output_count = 0;
+ int connector_count = 0;
int crtc_count = 0;
int fb_count = 0;
+ int encoder_count = 0;
int copied = 0;
uint32_t __user *fb_id;
uint32_t __user *crtc_id;
- uint32_t __user *output_id;
+ uint32_t __user *connector_id;
+ uint32_t __user *encoder_id;
mutex_lock(&dev->mode_config.mutex);
@@ -903,8 +781,11 @@ int drm_mode_getresources(struct drm_device *dev,
list_for_each(lh, &dev->mode_config.crtc_list)
crtc_count++;
- list_for_each(lh, &dev->mode_config.output_list)
- output_count++;
+ list_for_each(lh, &dev->mode_config.connector_list)
+ connector_count++;
+
+ list_for_each(lh, &dev->mode_config.encoder_list)
+ encoder_count++;
card_res->max_height = dev->mode_config.max_height;
card_res->min_height = dev->mode_config.min_height;
@@ -942,24 +823,40 @@ int drm_mode_getresources(struct drm_device *dev,
card_res->count_crtcs = crtc_count;
- /* Outputs */
- if (card_res->count_outputs >= output_count) {
+ /* Connectors */
+ if (card_res->count_connectors >= connector_count) {
copied = 0;
- output_id = (uint32_t *)(unsigned long)card_res->output_id_ptr;
- list_for_each_entry(output, &dev->mode_config.output_list,
+ connector_id = (uint32_t *)(unsigned long)card_res->connector_id_ptr;
+ list_for_each_entry(connector, &dev->mode_config.connector_list,
head) {
- DRM_DEBUG("OUTPUT ID is %d\n", output->id);
- if (put_user(output->id, output_id + copied)) {
+ DRM_DEBUG("CONNECTOR ID is %d\n", connector->id);
+ if (put_user(connector->id, connector_id + copied)) {
ret = -EFAULT;
goto out;
}
copied++;
}
}
- card_res->count_outputs = output_count;
+ card_res->count_connectors = connector_count;
+
+ /* Encoders */
+ if (card_res->count_encoders >= encoder_count) {
+ copied = 0;
+ encoder_id = (uint32_t *)(unsigned long)card_res->encoder_id_ptr;
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list,
+ head) {
+ DRM_DEBUG("ENCODER ID is %d\n", encoder->id);
+ if (put_user(encoder->id, encoder_id + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
+ }
+ }
+ card_res->count_encoders = encoder_count;
- DRM_DEBUG("Counted %d %d\n", card_res->count_crtcs,
- card_res->count_outputs);
+ DRM_DEBUG("Counted %d %d %d\n", card_res->count_crtcs,
+ card_res->count_connectors, card_res->count_encoders);
out:
mutex_unlock(&dev->mode_config.mutex);
@@ -988,8 +885,6 @@ int drm_mode_getcrtc(struct drm_device *dev,
{
struct drm_mode_crtc *crtc_resp = data;
struct drm_crtc *crtc;
- struct drm_output *output;
- int ocount;
int ret = 0;
mutex_lock(&dev->mode_config.mutex);
@@ -1007,16 +902,11 @@ int drm_mode_getcrtc(struct drm_device *dev,
else
crtc_resp->fb_id = 0;
- crtc_resp->outputs = 0;
+ crtc_resp->connectors = 0;
if (crtc->enabled) {
drm_crtc_convert_to_umode(&crtc_resp->mode, &crtc->mode);
crtc_resp->mode_valid = 1;
- ocount = 0;
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- if (output->crtc == crtc)
- crtc_resp->outputs |= 1 << (ocount++);
- }
} else {
crtc_resp->mode_valid = 0;
@@ -1028,7 +918,7 @@ out:
}
/**
- * drm_mode_getoutput - get output configuration
+ * drm_mode_getconnector - get connector configuration
* @inode: inode from the ioctl
* @filp: file * from the ioctl
* @cmd: cmd from ioctl
@@ -1037,21 +927,22 @@ out:
* LOCKING:
* Caller? (FIXME)
*
- * Construct a output configuration structure to return to the user.
+ * Construct a connector configuration structure to return to the user.
*
* Called by the user via ioctl.
*
* RETURNS:
* Zero on success, errno on failure.
*/
-int drm_mode_getoutput(struct drm_device *dev,
+int drm_mode_getconnector(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_get_output *out_resp = data;
- struct drm_output *output;
+ struct drm_mode_get_connector *out_resp = data;
+ struct drm_connector *connector;
struct drm_display_mode *mode;
int mode_count = 0;
int props_count = 0;
+ int encoders_count = 0;
int ret = 0;
int copied = 0;
int i;
@@ -1059,49 +950,53 @@ int drm_mode_getoutput(struct drm_device *dev,
struct drm_mode_modeinfo __user *mode_ptr;
uint32_t __user *prop_ptr;
uint64_t __user *prop_values;
+ uint32_t __user *encoder_ptr;
memset(&u_mode, 0, sizeof(struct drm_mode_modeinfo));
- DRM_DEBUG("output id %d:\n", out_resp->output);
+ DRM_DEBUG("connector id %d:\n", out_resp->connector);
mutex_lock(&dev->mode_config.mutex);
- output= idr_find(&dev->mode_config.crtc_idr, out_resp->output);
- if (!output || (output->id != out_resp->output)) {
+ connector= idr_find(&dev->mode_config.crtc_idr, out_resp->connector);
+ if (!connector || (connector->id != out_resp->connector)) {
ret = -EINVAL;
goto out;
}
- list_for_each_entry(mode, &output->modes, head)
+ list_for_each_entry(mode, &connector->modes, head)
mode_count++;
- for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
- if (output->property_ids[i] != 0) {
+ for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
+ if (connector->property_ids[i] != 0) {
props_count++;
}
}
+ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+ if (connector->encoder_ids[i] != 0) {
+ encoders_count++;
+ }
+ }
+
if (out_resp->count_modes == 0) {
- drm_crtc_probe_single_output_modes(output, dev->mode_config.max_width, dev->mode_config.max_height);
+ connector->funcs->fill_modes(connector, dev->mode_config.max_width, dev->mode_config.max_height);
}
- out_resp->output_type = output->output_type;
- out_resp->output_type_id = output->output_type_id;
- out_resp->mm_width = output->display_info.width_mm;
- out_resp->mm_height = output->display_info.height_mm;
- out_resp->subpixel = output->display_info.subpixel_order;
- out_resp->connection = output->status;
- if (output->crtc)
- out_resp->crtc = output->crtc->id;
+ out_resp->connector_type = connector->connector_type;
+ out_resp->connector_type_id = connector->connector_type_id;
+ out_resp->mm_width = connector->display_info.width_mm;
+ out_resp->mm_height = connector->display_info.height_mm;
+ out_resp->subpixel = connector->display_info.subpixel_order;
+ out_resp->connection = connector->status;
+ if (connector->encoder)
+ out_resp->encoder = connector->encoder->id;
else
- out_resp->crtc = 0;
-
- out_resp->crtcs = output->possible_crtcs;
- out_resp->clones = output->possible_clones;
+ out_resp->encoder = 0;
if ((out_resp->count_modes >= mode_count) && mode_count) {
copied = 0;
mode_ptr = (struct drm_mode_modeinfo *)(unsigned long)out_resp->modes_ptr;
- list_for_each_entry(mode, &output->modes, head) {
+ list_for_each_entry(mode, &connector->modes, head) {
drm_crtc_convert_to_umode(&u_mode, mode);
if (copy_to_user(mode_ptr + copied,
&u_mode, sizeof(u_mode))) {
@@ -1118,14 +1013,14 @@ int drm_mode_getoutput(struct drm_device *dev,
copied = 0;
prop_ptr = (uint32_t *)(unsigned long)(out_resp->props_ptr);
prop_values = (uint64_t *)(unsigned long)(out_resp->prop_values_ptr);
- for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
- if (output->property_ids[i] != 0) {
- if (put_user(output->property_ids[i], prop_ptr + copied)) {
+ for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
+ if (connector->property_ids[i] != 0) {
+ if (put_user(connector->property_ids[i], prop_ptr + copied)) {
ret = -EFAULT;
goto out;
}
- if (put_user(output->property_values[i], prop_values + copied)) {
+ if (put_user(connector->property_values[i], prop_values + copied)) {
ret = -EFAULT;
goto out;
}
@@ -1135,6 +1030,50 @@ int drm_mode_getoutput(struct drm_device *dev,
}
out_resp->count_props = props_count;
+ if ((out_resp->count_encoders >= encoders_count) && encoders_count) {
+ copied = 0;
+ encoder_ptr = (uint32_t *)(unsigned long)(out_resp->encoders_ptr);
+ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+ if (connector->encoder_ids[i] != 0) {
+ if (put_user(connector->encoder_ids[i], encoder_ptr + copied)) {
+ ret = -EFAULT;
+ goto out;
+ }
+ copied++;
+ }
+ }
+ }
+ out_resp->count_encoders = encoders_count;
+
+out:
+ mutex_unlock(&dev->mode_config.mutex);
+ return ret;
+}
+
+int drm_mode_getencoder(struct drm_device *dev,
+ void *data, struct drm_file *file_priv)
+{
+ struct drm_mode_get_encoder *enc_resp = data;
+ struct drm_encoder *encoder;
+ int ret = 0;
+
+ mutex_lock(&dev->mode_config.mutex);
+ encoder = idr_find(&dev->mode_config.crtc_idr, enc_resp->encoder_id);
+ if (!encoder || (encoder->id != enc_resp->encoder_id)) {
+ DRM_DEBUG("Unknown encoder ID %d\n", enc_resp->encoder_id);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ if (encoder->crtc)
+ enc_resp->crtc = encoder->crtc->id;
+ else
+ enc_resp->crtc = 0;
+ enc_resp->encoder_type = encoder->encoder_type;
+ enc_resp->encoder_id = encoder->id;
+ enc_resp->crtcs = encoder->possible_crtcs;
+ enc_resp->clones = encoder->possible_clones;
+
out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
@@ -1162,11 +1101,11 @@ int drm_mode_setcrtc(struct drm_device *dev,
{
struct drm_mode_crtc *crtc_req = data;
struct drm_crtc *crtc, *crtcfb;
- struct drm_output **output_set = NULL, *output;
+ struct drm_connector **connector_set = NULL, *connector;
struct drm_framebuffer *fb = NULL;
struct drm_display_mode *mode = NULL;
struct drm_mode_set set;
- uint32_t __user *set_outputs_ptr;
+ uint32_t __user *set_connectors_ptr;
int ret = 0;
int i;
@@ -1202,43 +1141,43 @@ int drm_mode_setcrtc(struct drm_device *dev,
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
}
- if (crtc_req->count_outputs == 0 && mode) {
- DRM_DEBUG("Count outputs is 0 but mode set\n");
+ if (crtc_req->count_connectors == 0 && mode) {
+ DRM_DEBUG("Count connectors is 0 but mode set\n");
ret = -EINVAL;
goto out;
}
- if (crtc_req->count_outputs > 0 && !mode && !fb) {
- DRM_DEBUG("Count outputs is %d but no mode or fb set\n", crtc_req->count_outputs);
+ if (crtc_req->count_connectors > 0 && !mode && !fb) {
+ DRM_DEBUG("Count connectors is %d but no mode or fb set\n", crtc_req->count_connectors);
ret = -EINVAL;
goto out;
}
- if (crtc_req->count_outputs > 0) {
+ if (crtc_req->count_connectors > 0) {
u32 out_id;
- /* Maybe we should check that count_outputs is a sensible value. */
- output_set = kmalloc(crtc_req->count_outputs *
- sizeof(struct drm_output *), GFP_KERNEL);
- if (!output_set) {
+ /* Maybe we should check that count_connectors is a sensible value. */
+ connector_set = kmalloc(crtc_req->count_connectors *
+ sizeof(struct drm_connector *), GFP_KERNEL);
+ if (!connector_set) {
ret = -ENOMEM;
goto out;
}
- for (i = 0; i < crtc_req->count_outputs; i++) {
- set_outputs_ptr = (uint32_t *)(unsigned long)crtc_req->set_outputs_ptr;
- if (get_user(out_id, &set_outputs_ptr[i])) {
+ for (i = 0; i < crtc_req->count_connectors; i++) {
+ set_connectors_ptr = (uint32_t *)(unsigned long)crtc_req->set_connectors_ptr;
+ if (get_user(out_id, &set_connectors_ptr[i])) {
ret = -EFAULT;
goto out;
}
- output = idr_find(&dev->mode_config.crtc_idr, out_id);
- if (!output || (out_id != output->id)) {
- DRM_DEBUG("Output id %d unknown\n", out_id);
+ connector = idr_find(&dev->mode_config.crtc_idr, out_id);
+ if (!connector || (out_id != connector->id)) {
+ DRM_DEBUG("Connector id %d unknown\n", out_id);
ret = -EINVAL;
goto out;
}
- output_set[i] = output;
+ connector_set[i] = connector;
}
}
@@ -1246,13 +1185,13 @@ int drm_mode_setcrtc(struct drm_device *dev,
set.x = crtc_req->x;
set.y = crtc_req->y;
set.mode = mode;
- set.outputs = output_set;
- set.num_outputs = crtc_req->count_outputs;
+ set.connectors = connector_set;
+ set.num_connectors = crtc_req->count_connectors;
set.fb =fb;
ret = crtc->funcs->set_config(&set);
out:
- kfree(output_set);
+ kfree(connector_set);
mutex_unlock(&dev->mode_config.mutex);
return ret;
}
@@ -1523,29 +1462,31 @@ void drm_fb_release(struct file *filp)
*/
static int drm_mode_attachmode(struct drm_device *dev,
- struct drm_output *output,
+ struct drm_connector *connector,
struct drm_display_mode *mode)
{
int ret = 0;
- list_add_tail(&mode->head, &output->user_modes);
+ list_add_tail(&mode->head, &connector->user_modes);
return ret;
}
int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
struct drm_display_mode *mode)
{
- struct drm_output *output;
+ struct drm_connector *connector;
int ret = 0;
struct drm_display_mode *dup_mode;
int need_dup = 0;
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- if (output->crtc == crtc) {
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder)
+ break;
+ if (connector->encoder->crtc == crtc) {
if (need_dup)
dup_mode = drm_mode_duplicate(dev, mode);
else
dup_mode = mode;
- ret = drm_mode_attachmode(dev, output, dup_mode);
+ ret = drm_mode_attachmode(dev, connector, dup_mode);
if (ret)
return ret;
need_dup = 1;
@@ -1556,14 +1497,14 @@ int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
EXPORT_SYMBOL(drm_mode_attachmode_crtc);
static int drm_mode_detachmode(struct drm_device *dev,
- struct drm_output *output,
+ struct drm_connector *connector,
struct drm_display_mode *mode)
{
int found = 0;
int ret = 0;
struct drm_display_mode *match_mode, *t;
- list_for_each_entry_safe(match_mode, t, &output->user_modes, head) {
+ list_for_each_entry_safe(match_mode, t, &connector->user_modes, head) {
if (drm_mode_equal(match_mode, mode)) {
list_del(&match_mode->head);
drm_mode_destroy(dev, match_mode);
@@ -1580,23 +1521,23 @@ static int drm_mode_detachmode(struct drm_device *dev,
int drm_mode_detachmode_crtc(struct drm_device *dev, struct drm_display_mode *mode)
{
- struct drm_output *output;
+ struct drm_connector *connector;
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- drm_mode_detachmode(dev, output, mode);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ drm_mode_detachmode(dev, connector, mode);
}
return 0;
}
EXPORT_SYMBOL(drm_mode_detachmode_crtc);
/**
- * drm_fb_attachmode - Attach a user mode to an output
+ * drm_fb_attachmode - Attach a user mode to an connector
* @inode: inode from the ioctl
* @filp: file * from the ioctl
* @cmd: cmd from ioctl
* @arg: arg from ioctl
*
- * This attaches a user specified mode to an output.
+ * This attaches a user specified mode to an connector.
* Called by the user via ioctl.
*
* RETURNS:
@@ -1606,15 +1547,15 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_mode_mode_cmd *mode_cmd = data;
- struct drm_output *output;
+ struct drm_connector *connector;
struct drm_display_mode *mode;
struct drm_mode_modeinfo *umode = &mode_cmd->mode;
int ret = 0;
mutex_lock(&dev->mode_config.mutex);
- output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
- if (!output || (output->id != mode_cmd->output_id)) {
+ connector = idr_find(&dev->mode_config.crtc_idr, mode_cmd->connector_id);
+ if (!connector || (connector->id != mode_cmd->connector_id)) {
ret = -EINVAL;
goto out;
}
@@ -1627,7 +1568,7 @@ int drm_mode_attachmode_ioctl(struct drm_device *dev,
drm_crtc_convert_umode(mode, umode);
- ret = drm_mode_attachmode(dev, output, mode);
+ ret = drm_mode_attachmode(dev, connector, mode);
out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
@@ -1635,7 +1576,7 @@ out:
/**
- * drm_fb_detachmode - Detach a user specified mode from an output
+ * drm_fb_detachmode - Detach a user specified mode from an connector
* @inode: inode from the ioctl
* @filp: file * from the ioctl
* @cmd: cmd from ioctl
@@ -1650,21 +1591,21 @@ int drm_mode_detachmode_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
struct drm_mode_mode_cmd *mode_cmd = data;
- struct drm_output *output;
+ struct drm_connector *connector;
struct drm_display_mode mode;
struct drm_mode_modeinfo *umode = &mode_cmd->mode;
int ret = 0;
mutex_lock(&dev->mode_config.mutex);
- output = idr_find(&dev->mode_config.crtc_idr, mode_cmd->output_id);
- if (!output || (output->id != mode_cmd->output_id)) {
+ connector = idr_find(&dev->mode_config.crtc_idr, mode_cmd->connector_id);
+ if (!connector || (connector->id != mode_cmd->connector_id)) {
ret = -EINVAL;
goto out;
}
drm_crtc_convert_umode(&mode, umode);
- ret = drm_mode_detachmode(dev, output, &mode);
+ ret = drm_mode_detachmode(dev, connector, &mode);
out:
mutex_unlock(&dev->mode_config.mutex);
return ret;
@@ -1750,60 +1691,60 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property)
}
EXPORT_SYMBOL(drm_property_destroy);
-int drm_output_attach_property(struct drm_output *output,
+int drm_connector_attach_property(struct drm_connector *connector,
struct drm_property *property, uint64_t init_val)
{
int i;
- for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
- if (output->property_ids[i] == 0) {
- output->property_ids[i] = property->id;
- output->property_values[i] = init_val;
+ for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
+ if (connector->property_ids[i] == 0) {
+ connector->property_ids[i] = property->id;
+ connector->property_values[i] = init_val;
break;
}
}
- if (i == DRM_OUTPUT_MAX_PROPERTY)
+ if (i == DRM_CONNECTOR_MAX_PROPERTY)
return -EINVAL;
return 0;
}
-EXPORT_SYMBOL(drm_output_attach_property);
+EXPORT_SYMBOL(drm_connector_attach_property);
-int drm_output_property_set_value(struct drm_output *output,
+int drm_connector_property_set_value(struct drm_connector *connector,
struct drm_property *property, uint64_t value)
{
int i;
- for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
- if (output->property_ids[i] == property->id) {
- output->property_values[i] = value;
+ for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
+ if (connector->property_ids[i] == property->id) {
+ connector->property_values[i] = value;
break;
}
}
- if (i == DRM_OUTPUT_MAX_PROPERTY)
+ if (i == DRM_CONNECTOR_MAX_PROPERTY)
return -EINVAL;
return 0;
}
-EXPORT_SYMBOL(drm_output_property_set_value);
+EXPORT_SYMBOL(drm_connector_property_set_value);
-int drm_output_property_get_value(struct drm_output *output,
+int drm_connector_property_get_value(struct drm_connector *connector,
struct drm_property *property, uint64_t *val)
{
int i;
- for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
- if (output->property_ids[i] == property->id) {
- *val = output->property_values[i];
+ for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
+ if (connector->property_ids[i] == property->id) {
+ *val = connector->property_values[i];
break;
}
}
- if (i == DRM_OUTPUT_MAX_PROPERTY)
+ if (i == DRM_CONNECTOR_MAX_PROPERTY)
return -EINVAL;
return 0;
}
-EXPORT_SYMBOL(drm_output_property_get_value);
+EXPORT_SYMBOL(drm_connector_property_get_value);
int drm_mode_getproperty_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
@@ -1965,41 +1906,41 @@ done:
return ret;
}
-int drm_mode_output_update_edid_property(struct drm_output *output, struct edid *edid)
+int drm_mode_connector_update_edid_property(struct drm_connector *connector, struct edid *edid)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
int ret = 0;
- if (output->edid_blob_ptr)
- drm_property_destroy_blob(dev, output->edid_blob_ptr);
+ if (connector->edid_blob_ptr)
+ drm_property_destroy_blob(dev, connector->edid_blob_ptr);
- output->edid_blob_ptr = drm_property_create_blob(output->dev, 128, edid);
+ connector->edid_blob_ptr = drm_property_create_blob(connector->dev, 128, edid);
- ret = drm_output_property_set_value(output, dev->mode_config.edid_property, output->edid_blob_ptr->id);
+ ret = drm_connector_property_set_value(connector, dev->mode_config.edid_property, connector->edid_blob_ptr->id);
return ret;
}
-EXPORT_SYMBOL(drm_mode_output_update_edid_property);
+EXPORT_SYMBOL(drm_mode_connector_update_edid_property);
-int drm_mode_output_property_set_ioctl(struct drm_device *dev,
+int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv)
{
- struct drm_mode_output_set_property *out_resp = data;
+ struct drm_mode_connector_set_property *out_resp = data;
struct drm_property *property;
- struct drm_output *output;
+ struct drm_connector *connector;
int ret = -EINVAL;
int i;
mutex_lock(&dev->mode_config.mutex);
- output = idr_find(&dev->mode_config.crtc_idr, out_resp->output_id);
- if (!output || (output->id != out_resp->output_id)) {
+ connector = idr_find(&dev->mode_config.crtc_idr, out_resp->connector_id);
+ if (!connector || (connector->id != out_resp->connector_id)) {
goto out;
}
- for (i = 0; i < DRM_OUTPUT_MAX_PROPERTY; i++) {
- if (output->property_ids[i] == out_resp->prop_id)
+ for (i = 0; i < DRM_CONNECTOR_MAX_PROPERTY; i++) {
+ if (connector->property_ids[i] == out_resp->prop_id)
break;
}
- if (i == DRM_OUTPUT_MAX_PROPERTY) {
+ if (i == DRM_CONNECTOR_MAX_PROPERTY) {
goto out;
}
@@ -2030,8 +1971,8 @@ int drm_mode_output_property_set_ioctl(struct drm_device *dev,
}
}
- if (output->funcs->set_property)
- ret = output->funcs->set_property(output, property, out_resp->value);
+ if (connector->funcs->set_property)
+ ret = connector->funcs->set_property(connector, property, out_resp->value);
out:
mutex_unlock(&dev->mode_config.mutex);
@@ -2099,3 +2040,33 @@ out:
return ret;
}
+
+int drm_mode_connector_attach_encoder(struct drm_connector *connector,
+ struct drm_encoder *encoder)
+{
+ int i;
+
+ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+ if (connector->encoder_ids[i] == 0) {
+ connector->encoder_ids[i] = encoder->id;
+ return 0;
+ }
+ }
+ return -ENOMEM;
+}
+EXPORT_SYMBOL(drm_mode_connector_attach_encoder);
+
+void drm_mode_connector_detach_encoder(struct drm_connector *connector,
+ struct drm_encoder *encoder)
+{
+ int i;
+ for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
+ if (connector->encoder_ids[i] == encoder->id) {
+ connector->encoder_ids[i] = 0;
+ if (connector->encoder == encoder)
+ connector->encoder = NULL;
+ break;
+ }
+ }
+}
+EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
diff --git a/linux-core/drm_crtc.h b/linux-core/drm_crtc.h
index b769eb7a..390ab2d3 100644
--- a/linux-core/drm_crtc.h
+++ b/linux-core/drm_crtc.h
@@ -17,10 +17,10 @@ struct drm_device;
struct drm_mode_set;
/*
- * Note on terminology: here, for brevity and convenience, we refer to output
- * control chips as 'CRTCs'. They can control any type of output, VGA, LVDS,
+ * Note on terminology: here, for brevity and convenience, we refer to connector
+ * control chips as 'CRTCs'. They can control any type of connector, VGA, LVDS,
* DVI, etc. And 'screen' refers to the whole of the visible display, which
- * may span multiple monitors (and therefore multiple CRTC and output
+ * may span multiple monitors (and therefore multiple CRTC and connector
* structures).
*/
@@ -80,7 +80,7 @@ struct drm_display_mode {
struct list_head head;
char name[DRM_DISPLAY_MODE_LEN];
int mode_id;
- int output_count;
+ int connector_count;
enum drm_mode_status status;
int type;
@@ -149,24 +149,24 @@ struct drm_display_mode {
#define DPMSModeSuspend 2
#define DPMSModeOff 3
-#define ConnectorUnknown 0
-#define ConnectorVGA 1
-#define ConnectorDVII 2
-#define ConnectorDVID 3
-#define ConnectorDVIA 4
-#define ConnectorComposite 5
-#define ConnectorSVIDEO 6
-#define ConnectorLVDS 7
-#define ConnectorComponent 8
-#define Connector9PinDIN 9
-#define ConnectorDisplayPort 10
-#define ConnectorHDMIA 11
-#define ConnectorHDMIB 12
-
-enum drm_output_status {
- output_status_connected = 1,
- output_status_disconnected = 2,
- output_status_unknown = 3,
+#define DRM_MODE_CONNECTOR_Unknown 0
+#define DRM_MODE_CONNECTOR_VGA 1
+#define DRM_MODE_CONNECTOR_DVII 2
+#define DRM_MODE_CONNECTOR_DVID 3
+#define DRM_MODE_CONNECTOR_DVIA 4
+#define DRM_MODE_CONNECTOR_Composite 5
+#define DRM_MODE_CONNECTOR_SVIDEO 6
+#define DRM_MODE_CONNECTOR_LVDS 7
+#define DRM_MODE_CONNECTOR_Component 8
+#define DRM_MODE_CONNECTOR_9PinDIN 9
+#define DRM_MODE_CONNECTOR_DisplayPort 10
+#define DRM_MODE_CONNECTOR_HDMIA 11
+#define DRM_MODE_CONNECTOR_HDMIB 12
+
+enum drm_connector_status {
+ connector_status_connected = 1,
+ connector_status_disconnected = 2,
+ connector_status_unknown = 3,
};
enum subpixel_order {
@@ -276,7 +276,8 @@ struct drm_property {
};
struct drm_crtc;
-struct drm_output;
+struct drm_connector;
+struct drm_encoder;
/**
* drm_crtc_funcs - control CRTCs for a given device
@@ -294,21 +295,15 @@ struct drm_output;
* @destroy: deinit and free object.
*
* The drm_crtc_funcs structure is the central CRTC management structure
- * in the DRM. Each CRTC controls one or more outputs (note that the name
+ * in the DRM. Each CRTC controls one or more connectors (note that the name
* CRTC is simply historical, a CRTC may control LVDS, VGA, DVI, TV out, etc.
- * outputs, not just CRTs).
+ * connectors, not just CRTs).
*
* Each driver is responsible for filling out this structure at startup time,
* in addition to providing other modesetting features, like i2c and DDC
* bus accessors.
*/
struct drm_crtc_funcs {
- /*
- * Control power levels on the CRTC. If the mode passed in is
- * unsupported, the provider must use the next lowest power level.
- */
- void (*dpms)(struct drm_crtc *crtc, int mode);
-
/* Save CRTC state */
void (*save)(struct drm_crtc *crtc); /* suspend? */
/* Restore CRTC state */
@@ -338,7 +333,7 @@ struct drm_crtc_funcs {
* @desired_y: desired y for desired_mode
* @funcs: CRTC control functions
*
- * Each CRTC may have one or more outputs associated with it. This structure
+ * Each CRTC may have one or more connectors associated with it. This structure
* allows the CRTC to be controlled.
*/
struct drm_crtc {
@@ -347,7 +342,7 @@ struct drm_crtc {
int id; /* idr assigned */
- /* framebuffer the output is currently bound to */
+ /* framebuffer the connector is currently bound to */
struct drm_framebuffer *fb;
bool enabled;
@@ -364,96 +359,113 @@ struct drm_crtc {
};
/**
- * drm_output_funcs - control outputs on a given device
- * @init: setup this output
+ * drm_connector_funcs - control connectors on a given device
* @dpms: set power state (see drm_crtc_funcs above)
- * @save: save output state
- * @restore: restore output state
- * @mode_valid: is this mode valid on the given output?
- * @mode_fixup: try to fixup proposed mode for this output
+ * @save: save connector state
+ * @restore: restore connector state
+ * @mode_valid: is this mode valid on the given connector?
+ * @mode_fixup: try to fixup proposed mode for this connector
* @mode_set: set this mode
- * @detect: is this output active?
- * @get_modes: get mode list for this output
- * @set_property: property for this output may need update
+ * @detect: is this connector active?
+ * @get_modes: get mode list for this connector
+ * @set_property: property for this connector may need update
* @destroy: make object go away
*
- * Each CRTC may have one or more outputs attached to it. The functions
- * below allow the core DRM code to control outputs, enumerate available modes,
+ * Each CRTC may have one or more connectors attached to it. The functions
+ * below allow the core DRM code to control connectors, enumerate available modes,
* etc.
*/
-struct drm_output_funcs {
- void (*init)(struct drm_output *output);
- void (*dpms)(struct drm_output *output, int mode);
- void (*save)(struct drm_output *output);
- void (*restore)(struct drm_output *output);
- enum drm_output_status (*detect)(struct drm_output *output);
- int (*get_modes)(struct drm_output *output);
- bool (*set_property)(struct drm_output *output, struct drm_property *property,
+struct drm_connector_funcs {
+ void (*dpms)(struct drm_connector *connector, int mode);
+ void (*save)(struct drm_connector *connector);
+ void (*restore)(struct drm_connector *connector);
+ enum drm_connector_status (*detect)(struct drm_connector *connector);
+ void (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
+ bool (*set_property)(struct drm_connector *connector, struct drm_property *property,
uint64_t val);
- void (*destroy)(struct drm_output *output);
- int (*mode_valid)(struct drm_output *output,
- struct drm_display_mode *mode);
+ void (*destroy)(struct drm_connector *connector);
+};
+
+struct drm_encoder_funcs {
+ void (*destroy)(struct drm_encoder *encoder);
+};
+
+#define DRM_CONNECTOR_MAX_UMODES 16
+#define DRM_CONNECTOR_MAX_PROPERTY 16
+#define DRM_CONNECTOR_LEN 32
+#define DRM_CONNECTOR_MAX_ENCODER 2
+
+/**
+ * drm_encoder - central DRM encoder structure
+ */
+struct drm_encoder {
+ struct drm_device *dev;
+ struct list_head head;
+
+ int id;
+ int encoder_type;
+ uint32_t possible_crtcs;
+ uint32_t possible_clones;
+ struct drm_crtc *crtc;
+ const struct drm_encoder_funcs *funcs;
+ void *helper_private;
};
-#define DRM_OUTPUT_MAX_UMODES 16
-#define DRM_OUTPUT_MAX_PROPERTY 16
-#define DRM_OUTPUT_LEN 32
/**
- * drm_output - central DRM output control structure
- * @crtc: CRTC this output is currently connected to, NULL if none
- * @possible_crtcs: bitmap of CRTCS this output could be attached to
- * @possible_clones: bitmap of possible outputs this output could clone
- * @interlace_allowed: can this output handle interlaced modes?
- * @doublescan_allowed: can this output handle doublescan?
- * @available_modes: modes available on this output (from get_modes() + user)
- * @initial_x: initial x position for this output
- * @initial_y: initial y position for this output
- * @status: output connected?
- * @funcs: output control functions
+ * drm_connector - central DRM connector control structure
+ * @crtc: CRTC this connector is currently connected to, NULL if none
+ * @interlace_allowed: can this connector handle interlaced modes?
+ * @doublescan_allowed: can this connector handle doublescan?
+ * @available_modes: modes available on this connector (from get_modes() + user)
+ * @initial_x: initial x position for this connector
+ * @initial_y: initial y position for this connector
+ * @status: connector connected?
+ * @funcs: connector control functions
*
- * Each output may be connected to one or more CRTCs, or may be clonable by
- * another output if they can share a CRTC. Each output also has a specific
+ * Each connector may be connected to one or more CRTCs, or may be clonable by
+ * another connector if they can share a CRTC. Each connector also has a specific
* position in the broader display (referred to as a 'screen' though it could
* span multiple monitors).
*/
-struct drm_output {
+struct drm_connector {
struct drm_device *dev;
struct device kdev;
struct device_attribute *attr;
struct list_head head;
- struct drm_crtc *crtc;
int id; /* idr assigned */
- int output_type;
- int output_type_id;
- unsigned long possible_crtcs;
- unsigned long possible_clones;
+ int connector_type;
+ int connector_type_id;
bool interlace_allowed;
bool doublescan_allowed;
- struct list_head modes; /* list of modes on this output */
+ struct list_head modes; /* list of modes on this connector */
int initial_x, initial_y;
- enum drm_output_status status;
+ enum drm_connector_status status;
/* these are modes added by probing with DDC or the BIOS */
struct list_head probed_modes;
struct drm_display_info display_info;
- const struct drm_output_funcs *funcs;
+ const struct drm_connector_funcs *funcs;
struct list_head user_modes;
struct drm_property_blob *edid_blob_ptr;
- u32 property_ids[DRM_OUTPUT_MAX_PROPERTY];
- uint64_t property_values[DRM_OUTPUT_MAX_PROPERTY];
+ u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY];
+ uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY];
void *helper_private;
+
+ uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
+ uint32_t force_encoder_id;
+ struct drm_encoder *encoder; /* currently active encoder */
};
/**
* struct drm_mode_set
*
- * Represents a single crtc the outputs that it drives with what mode
+ * Represents a single crtc the connectors that it drives with what mode
* and from which framebuffer it scans out from.
*
* This is used to set modes.
@@ -467,8 +479,8 @@ struct drm_mode_set
uint32_t x;
uint32_t y;
- struct drm_output **outputs;
- size_t num_outputs;
+ struct drm_connector **connectors;
+ size_t num_connectors;
};
/**
@@ -478,7 +490,7 @@ struct drm_mode_set
* Currently only a resize hook is available. DRM will call back into the
* driver with a new screen width and height. If the driver can't support
* the proposed size, it can return false. Otherwise it should adjust
- * the CRTC<->output mappings as needed and update its view of the screen.
+ * the CRTC<->connector mappings as needed and update its view of the screen.
*/
struct drm_mode_config_funcs {
bool (*resize_fb)(struct drm_device *dev, struct drm_framebuffer *fb);
@@ -490,12 +502,14 @@ struct drm_mode_config_funcs {
*/
struct drm_mode_config {
struct mutex mutex; /* protects configuration and IDR */
- struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, output, modes - just makes life easier */
+ struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */
/* this is limited to one for now */
int num_fb;
struct list_head fb_list;
- int num_output;
- struct list_head output_list;
+ int num_connector;
+ struct list_head connector_list;
+ int num_encoder;
+ struct list_head encoder_list;
int num_crtc;
struct list_head crtc_list;
@@ -511,8 +525,6 @@ struct drm_mode_config {
struct list_head property_blob_list;
struct drm_property *edid_property;
struct drm_property *dpms_property;
- struct drm_property *connector_type_property;
- struct drm_property *connector_num_property;
/* TV properties */
struct drm_property *tv_mode_property;
@@ -531,22 +543,29 @@ extern void drm_crtc_init(struct drm_device *dev,
const struct drm_crtc_funcs *funcs);
extern void drm_crtc_cleanup(struct drm_crtc *crtc);
-void drm_output_init(struct drm_device *dev,
- struct drm_output *output,
- const struct drm_output_funcs *funcs,
- int output_type);
+extern void drm_connector_init(struct drm_device *dev,
+ struct drm_connector *connector,
+ const struct drm_connector_funcs *funcs,
+ int connector_type);
+
+extern void drm_connector_cleanup(struct drm_connector *connector);
-void drm_output_cleanup(struct drm_output *output);
+extern void drm_encoder_init(struct drm_device *dev,
+ struct drm_encoder *encoder,
+ const struct drm_encoder_funcs *funcs,
+ int encoder_type);
-extern char *drm_get_output_name(struct drm_output *output);
+extern void drm_encoder_cleanup(struct drm_encoder *encoder);
+
+extern char *drm_get_connector_name(struct drm_connector *connector);
extern char *drm_get_dpms_name(int val);
extern void drm_fb_release(struct file *filp);
-extern struct edid *drm_get_edid(struct drm_output *output,
+extern struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter);
-extern int drm_add_edid_modes(struct drm_output *output, struct edid *edid);
-extern void drm_mode_probed_add(struct drm_output *output, struct drm_display_mode *mode);
-extern void drm_mode_remove(struct drm_output *output, struct drm_display_mode *mode);
+extern int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid);
+extern void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode);
+extern void drm_mode_remove(struct drm_connector *connector, struct drm_display_mode *mode);
extern struct drm_display_mode *drm_mode_duplicate(struct drm_device *dev,
struct drm_display_mode *mode);
extern void drm_mode_debug_printmodeline(struct drm_display_mode *mode);
@@ -554,7 +573,6 @@ extern void drm_mode_config_init(struct drm_device *dev);
extern void drm_mode_config_cleanup(struct drm_device *dev);
extern void drm_mode_set_name(struct drm_display_mode *mode);
extern bool drm_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2);
-extern void drm_disable_unused_functions(struct drm_device *dev);
/* for us by fb module */
extern int drm_mode_attachmode_crtc(struct drm_device *dev,
@@ -575,13 +593,13 @@ extern void drm_mode_sort(struct list_head *mode_list);
extern int drm_mode_vrefresh(struct drm_display_mode *mode);
extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
int adjust_flags);
-extern void drm_mode_output_list_update(struct drm_output *output);
-extern int drm_mode_output_update_edid_property(struct drm_output *output,
+extern void drm_mode_connector_list_update(struct drm_connector *connector);
+extern int drm_mode_connector_update_edid_property(struct drm_connector *connector,
struct edid *edid);
-extern int drm_output_property_set_value(struct drm_output *output,
+extern int drm_connector_property_set_value(struct drm_connector *connector,
struct drm_property *property,
uint64_t value);
-extern int drm_output_property_get_value(struct drm_output *output,
+extern int drm_connector_property_get_value(struct drm_connector *connector,
struct drm_property *property,
uint64_t *value);
extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
@@ -591,10 +609,10 @@ extern struct drm_framebuffer *drm_framebuffer_create(struct drm_device *dev);
extern void drm_framebuffer_destroy(struct drm_framebuffer *fb);
extern int drmfb_probe(struct drm_device *dev, struct drm_crtc *crtc);
extern int drmfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
-extern void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY);
+extern void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY);
extern bool drm_crtc_in_use(struct drm_crtc *crtc);
-extern int drm_output_attach_property(struct drm_output *output,
+extern int drm_connector_attach_property(struct drm_connector *connector,
struct drm_property *property, uint64_t init_val);
extern struct drm_property *drm_property_create(struct drm_device *dev, int flags,
const char *name, int num_values);
@@ -603,6 +621,12 @@ extern int drm_property_add_enum(struct drm_property *property, int index,
uint64_t value, const char *name);
extern bool drm_create_tv_properties(struct drm_device *dev, int num_formats,
char *formats[]);
+extern char *drm_get_encoder_name(struct drm_encoder *encoder);
+
+extern int drm_mode_connector_attach_encoder(struct drm_connector *connector,
+ struct drm_encoder *encoder);
+extern void drm_mode_connector_detach_encoder(struct drm_connector *connector,
+ struct drm_encoder *encoder);
/* IOCTLs */
extern int drm_mode_getresources(struct drm_device *dev,
@@ -610,7 +634,7 @@ extern int drm_mode_getresources(struct drm_device *dev,
extern int drm_mode_getcrtc(struct drm_device *dev,
void *data, struct drm_file *file_priv);
-extern int drm_mode_getoutput(struct drm_device *dev,
+extern int drm_mode_getconnector(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern int drm_mode_setcrtc(struct drm_device *dev,
void *data, struct drm_file *file_priv);
@@ -635,11 +659,13 @@ extern int drm_mode_getproperty_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern int drm_mode_getblob_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
-extern int drm_mode_output_property_set_ioctl(struct drm_device *dev,
+extern int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern int drm_mode_hotplug_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern int drm_mode_replacefb(struct drm_device *dev,
void *data, struct drm_file *file_priv);
+int drm_mode_getencoder(struct drm_device *dev,
+ void *data, struct drm_file *file_priv);
#endif /* __DRM_CRTC_H__ */
diff --git a/linux-core/drm_crtc_helper.c b/linux-core/drm_crtc_helper.c
index f776dbed..2ceaa860 100644
--- a/linux-core/drm_crtc_helper.c
+++ b/linux-core/drm_crtc_helper.c
@@ -34,9 +34,168 @@
#include "drm_crtc.h"
#include "drm_crtc_helper.h"
+/*
+ * Detailed mode info for a standard 640x480@60Hz monitor
+ */
+static struct drm_display_mode std_mode[] = {
+ { DRM_MODE("640x480", DRM_MODE_TYPE_DEFAULT, 25200, 640, 656,
+ 752, 800, 0, 480, 490, 492, 525, 0,
+ V_NHSYNC | V_NVSYNC) }, /* 640x480@60Hz */
+};
/**
- * drm_pick_crtcs - pick crtcs for output devices
+ * drm_helper_probe_connector_modes - get complete set of display modes
+ * @dev: DRM device
+ * @maxX: max width for modes
+ * @maxY: max height for modes
+ *
+ * LOCKING:
+ * Caller must hold mode config lock.
+ *
+ * Based on @dev's mode_config layout, scan all the connectors and try to detect
+ * modes on them. Modes will first be added to the connector's probed_modes
+ * list, then culled (based on validity and the @maxX, @maxY parameters) and
+ * put into the normal modes list.
+ *
+ * Intended to be used either at bootup time or when major configuration
+ * changes have occurred.
+ *
+ * FIXME: take into account monitor limits
+ */
+void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_display_mode *mode, *t;
+ struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
+ int ret;
+
+ /* set all modes to the unverified state */
+ list_for_each_entry_safe(mode, t, &connector->modes, head)
+ mode->status = MODE_UNVERIFIED;
+
+ connector->status = (*connector->funcs->detect)(connector);
+
+ if (connector->status == connector_status_disconnected) {
+ DRM_DEBUG("%s is disconnected\n", drm_get_connector_name(connector));
+ /* TODO set EDID to NULL */
+ return;
+ }
+
+ ret = (*connector_funcs->get_modes)(connector);
+
+ if (ret) {
+ drm_mode_connector_list_update(connector);
+ }
+
+ if (maxX && maxY)
+ drm_mode_validate_size(dev, &connector->modes, maxX,
+ maxY, 0);
+ list_for_each_entry_safe(mode, t, &connector->modes, head) {
+ if (mode->status == MODE_OK)
+ mode->status = (*connector_funcs->mode_valid)(connector,mode);
+ }
+
+
+ drm_mode_prune_invalid(dev, &connector->modes, TRUE);
+
+ if (list_empty(&connector->modes)) {
+ struct drm_display_mode *stdmode;
+
+ DRM_DEBUG("No valid modes on %s\n", drm_get_connector_name(connector));
+
+ /* Should we do this here ???
+ * When no valid EDID modes are available we end up
+ * here and bailed in the past, now we add a standard
+ * 640x480@60Hz mode and carry on.
+ */
+ stdmode = drm_mode_duplicate(dev, &std_mode[0]);
+ drm_mode_probed_add(connector, stdmode);
+ drm_mode_list_concat(&connector->probed_modes,
+ &connector->modes);
+
+ DRM_DEBUG("Adding standard 640x480 @ 60Hz to %s\n",
+ drm_get_connector_name(connector));
+ }
+
+ drm_mode_sort(&connector->modes);
+
+ DRM_DEBUG("Probed modes for %s\n", drm_get_connector_name(connector));
+ list_for_each_entry_safe(mode, t, &connector->modes, head) {
+ mode->vrefresh = drm_mode_vrefresh(mode);
+
+ drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+ drm_mode_debug_printmodeline(mode);
+ }
+}
+EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
+
+void drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX, uint32_t maxY)
+{
+ struct drm_connector *connector;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ drm_helper_probe_single_connector_modes(connector, maxX, maxY);
+ }
+}
+EXPORT_SYMBOL(drm_helper_probe_connector_modes);
+
+
+/**
+ * drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
+ * @crtc: CRTC to check
+ *
+ * LOCKING:
+ * Caller must hold mode config lock.
+ *
+ * Walk @crtc's DRM device's mode_config and see if it's in use.
+ *
+ * RETURNS:
+ * True if @crtc is part of the mode_config, false otherwise.
+ */
+bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
+{
+ struct drm_encoder *encoder;
+ struct drm_device *dev = crtc->dev;
+ /* FIXME: Locking around list access? */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
+ if (encoder->crtc == crtc)
+ return true;
+ return false;
+}
+EXPORT_SYMBOL(drm_helper_crtc_in_use);
+
+/**
+ * drm_disable_unused_functions - disable unused objects
+ * @dev: DRM device
+ *
+ * LOCKING:
+ * Caller must hold mode config lock.
+ *
+ * If an connector or CRTC isn't part of @dev's mode_config, it can be disabled
+ * by calling its dpms function, which should power it off.
+ */
+void drm_helper_disable_unused_functions(struct drm_device *dev)
+{
+ struct drm_encoder *encoder;
+ struct drm_encoder_helper_funcs *encoder_funcs;
+ struct drm_crtc *crtc;
+
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ encoder_funcs = encoder->helper_private;
+ if (!encoder->crtc)
+ (*encoder_funcs->dpms)(encoder, DPMSModeOff);
+ }
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ if (!crtc->enabled)
+ crtc_funcs->dpms(crtc, DPMSModeOff);
+ }
+}
+EXPORT_SYMBOL(drm_helper_disable_unused_functions);
+
+/**
+ * drm_pick_crtcs - pick crtcs for connector devices
* @dev: DRM device
*
* LOCKING:
@@ -45,36 +204,44 @@
static void drm_pick_crtcs (struct drm_device *dev)
{
int c, o, assigned;
- struct drm_output *output, *output_equal;
+ struct drm_connector *connector, *connector_equal;
+ struct drm_encoder *encoder, *encoder_equal;
struct drm_crtc *crtc;
struct drm_display_mode *des_mode = NULL, *modes, *modes_equal;
+ struct drm_connector_helper_funcs *connector_funcs;
int found;
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- output->crtc = NULL;
-
- /* Don't hook up outputs that are disconnected ??
+ /* clean out all the encoder/crtc combos */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
+ encoder->crtc = NULL;
+ }
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ connector_funcs = connector->helper_private;
+ connector->encoder = NULL;
+
+ /* Don't hook up connectors that are disconnected ??
*
* This is debateable. Do we want fixed /dev/fbX or
* dynamic on hotplug (need mode code for that though) ?
*
- * If we don't hook up outputs now, then we only create
- * /dev/fbX for the output that's enabled, that's good as
- * the users console will be on that output.
+ * If we don't hook up connectors now, then we only create
+ * /dev/fbX for the connector that's enabled, that's good as
+ * the users console will be on that connector.
*
- * If we do hook up outputs that are disconnected now, then
+ * If we do hook up connectors that are disconnected now, then
* the user may end up having to muck about with the fbcon
- * map flags to assign his console to the enabled output. Ugh.
+ * map flags to assign his console to the enabled connector. Ugh.
*/
- if (output->status != output_status_connected)
+ if (connector->status != connector_status_connected)
continue;
- if (list_empty(&output->modes))
+ if (list_empty(&connector->modes))
continue;
des_mode = NULL;
found = 0;
- list_for_each_entry(des_mode, &output->modes, head) {
+ list_for_each_entry(des_mode, &connector->modes, head) {
if (des_mode->type & DRM_MODE_TYPE_PREFERRED) {
found = 1;
break;
@@ -84,25 +251,31 @@ static void drm_pick_crtcs (struct drm_device *dev)
/* No preferred mode, let's just select the first available */
if (!found) {
des_mode = NULL;
- list_for_each_entry(des_mode, &output->modes, head) {
+ list_for_each_entry(des_mode, &connector->modes, head) {
break;
}
}
+ encoder = connector_funcs->best_encoder(connector);
+ if (!encoder)
+ continue;
+
+ connector->encoder = encoder;
+
c = -1;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
assigned = 0;
c++;
- if ((output->possible_crtcs & (1 << c)) == 0)
+ if ((encoder->possible_crtcs & (1 << c)) == 0)
continue;
- list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
- if (output->id == output_equal->id)
+ list_for_each_entry(encoder_equal, &dev->mode_config.encoder_list, head) {
+ if (encoder->id == encoder_equal->id)
continue;
/* Find out if crtc has been assigned before */
- if (output_equal->crtc == crtc)
+ if (encoder_equal->crtc == crtc)
assigned = 1;
}
@@ -112,16 +285,21 @@ static void drm_pick_crtcs (struct drm_device *dev)
#endif
o = -1;
- list_for_each_entry(output_equal, &dev->mode_config.output_list, head) {
+ list_for_each_entry(connector_equal, &dev->mode_config.connector_list, head) {
o++;
- if (output->id == output_equal->id)
+ if (connector->id == connector_equal->id)
+ continue;
+
+ encoder_equal = connector_equal->encoder;
+
+ if (!encoder_equal)
continue;
- list_for_each_entry(modes, &output->modes, head) {
- list_for_each_entry(modes_equal, &output_equal->modes, head) {
+ list_for_each_entry(modes, &connector->modes, head) {
+ list_for_each_entry(modes_equal, &connector_equal->modes, head) {
if (drm_mode_equal (modes, modes_equal)) {
- if ((output->possible_clones & output_equal->possible_clones) && (output_equal->crtc == crtc)) {
- printk("Cloning %s (0x%lx) to %s (0x%lx)\n",drm_get_output_name(output),output->possible_clones,drm_get_output_name(output_equal),output_equal->possible_clones);
+ if ((encoder->possible_clones & encoder_equal->possible_clones) && (connector_equal->encoder->crtc == crtc)) {
+ printk("Cloning %s (0x%lx) to %s (0x%lx)\n",drm_get_connector_name(connector),encoder->possible_clones,drm_get_connector_name(connector_equal),encoder_equal->possible_clones);
des_mode = modes;
assigned = 0;
goto clone;
@@ -137,10 +315,10 @@ clone:
continue;
/* Found a CRTC to attach to, do it ! */
- output->crtc = crtc;
- output->crtc->desired_mode = des_mode;
- output->initial_x = 0;
- output->initial_y = 0;
+ encoder->crtc = crtc;
+ encoder->crtc->desired_mode = des_mode;
+ connector->initial_x = 0;
+ connector->initial_y = 0;
DRM_DEBUG("Desired mode for CRTC %d is 0x%x:%s\n",c,des_mode->mode_id, des_mode->name);
break;
}
@@ -158,7 +336,7 @@ EXPORT_SYMBOL(drm_pick_crtcs);
* LOCKING:
* Caller must hold mode config lock.
*
- * Try to set @mode on @crtc. Give @crtc and its associated outputs a chance
+ * Try to set @mode on @crtc. Give @crtc and its associated connectors a chance
* to fixup or reject the mode prior to trying to set it.
*
* RETURNS:
@@ -170,14 +348,14 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo
struct drm_device *dev = crtc->dev;
struct drm_display_mode *adjusted_mode, saved_mode;
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
- struct drm_output_helper_funcs *output_funcs;
+ struct drm_encoder_helper_funcs *encoder_funcs;
int saved_x, saved_y;
- struct drm_output *output;
+ struct drm_encoder *encoder;
bool ret = true;
adjusted_mode = drm_mode_duplicate(dev, mode);
- crtc->enabled = drm_crtc_in_use(crtc);
+ crtc->enabled = drm_helper_crtc_in_use(crtc);
if (!crtc->enabled)
return true;
@@ -200,16 +378,16 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo
}
}
- /* Pass our mode to the outputs and the CRTC to give them a chance to
- * adjust it according to limitations or output properties, and also
+ /* Pass our mode to the connectors and the CRTC to give them a chance to
+ * adjust it according to limitations or connector properties, and also
* a chance to reject the mode entirely.
*/
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (output->crtc != crtc)
+ if (encoder->crtc != crtc)
continue;
- output_funcs = output->helper_private;
- if (!(ret = output_funcs->mode_fixup(output, mode, adjusted_mode))) {
+ encoder_funcs = encoder->helper_private;
+ if (!(ret = encoder_funcs->mode_fixup(encoder, mode, adjusted_mode))) {
goto done;
}
}
@@ -218,48 +396,44 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo
goto done;
}
- /* Prepare the outputs and CRTCs before setting the mode. */
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
+ /* Prepare the encoders and CRTCs before setting the mode. */
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (output->crtc != crtc)
+ if (encoder->crtc != crtc)
continue;
- output_funcs = output->helper_private;
- /* Disable the output as the first thing we do. */
- output_funcs->prepare(output);
+ encoder_funcs = encoder->helper_private;
+ /* Disable the encoders as the first thing we do. */
+ encoder_funcs->prepare(encoder);
}
crtc_funcs->prepare(crtc);
- /* Set up the DPLL and any output state that needs to adjust or depend
+ /* Set up the DPLL and any encoders state that needs to adjust or depend
* on the DPLL.
*/
crtc_funcs->mode_set(crtc, mode, adjusted_mode, x, y);
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (output->crtc != crtc)
+ if (encoder->crtc != crtc)
continue;
- DRM_INFO("%s: set mode %s %x\n", drm_get_output_name(output), mode->name, mode->mode_id);
- output_funcs = output->helper_private;
- output_funcs->mode_set(output, mode, adjusted_mode);
+ DRM_INFO("%s: set mode %s %x\n", drm_get_encoder_name(encoder), mode->name, mode->mode_id);
+ encoder_funcs = encoder->helper_private;
+ encoder_funcs->mode_set(encoder, mode, adjusted_mode);
}
- /* Now, enable the clocks, plane, pipe, and outputs that we set up. */
+ /* Now, enable the clocks, plane, pipe, and connectors that we set up. */
crtc_funcs->commit(crtc);
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
- if (output->crtc != crtc)
+ if (encoder->crtc != crtc)
continue;
- output_funcs = output->helper_private;
- output_funcs->commit(output);
+ encoder_funcs = encoder->helper_private;
+ encoder_funcs->commit(encoder);
-#if 0 // TODO def RANDR_12_INTERFACE
- if (output->randr_output)
- RRPostPendingProperties (output->randr_output);
-#endif
}
/* XXX free adjustedmode */
@@ -285,7 +459,7 @@ EXPORT_SYMBOL(drm_crtc_helper_set_mode);
* @crtc: CRTC to setup
* @crtc_info: user provided configuration
* @new_mode: new mode to set
- * @output_set: set of outputs for the new config
+ * @connector_set: set of connectors for the new config
* @fb: new framebuffer
*
* LOCKING:
@@ -301,12 +475,14 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
{
struct drm_device *dev;
struct drm_crtc **save_crtcs, *new_crtc;
+ struct drm_encoder **save_encoders, *new_encoder;
bool save_enabled;
bool changed = false;
bool flip_or_move = false;
- struct drm_output *output;
- int count = 0, ro;
+ struct drm_connector *connector;
+ int count = 0, ro, fail = 0;
struct drm_crtc_helper_funcs *crtc_funcs;
+ int ret = 0;
DRM_DEBUG("\n");
@@ -321,17 +497,23 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
crtc_funcs = set->crtc->helper_private;
- DRM_DEBUG("crtc: %p fb: %p outputs: %p num_outputs: %i (x, y) (%i, %i)\n", set->crtc, set->fb, set->outputs, set->num_outputs, set->x, set->y);
+ DRM_DEBUG("crtc: %p fb: %p connectors: %p num_connectors: %i (x, y) (%i, %i)\n", set->crtc, set->fb, set->connectors, set->num_connectors, set->x, set->y);
dev = set->crtc->dev;
/* save previous config */
save_enabled = set->crtc->enabled;
- /* this is meant to be num_output not num_crtc */
- save_crtcs = kzalloc(dev->mode_config.num_output * sizeof(struct drm_crtc *), GFP_KERNEL);
+ /* this is meant to be num_connector not num_crtc */
+ save_crtcs = kzalloc(dev->mode_config.num_connector * sizeof(struct drm_crtc *), GFP_KERNEL);
if (!save_crtcs)
return -ENOMEM;
+ save_encoders = kzalloc(dev->mode_config.num_connector * sizeof(struct drm_encoders *), GFP_KERNEL);
+ if (!save_encoders) {
+ kfree(save_crtcs);
+ return -ENOMEM;
+ }
+
/* We should be able to check here if the fb has the same properties
* and then just flip_or_move it */
if (set->crtc->fb != set->fb)
@@ -347,21 +529,53 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
changed = true;
}
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- save_crtcs[count++] = output->crtc;
+ /* a) traverse passed in connector list and get encoders for them */
+ count = 0;
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ struct drm_connector_helper_funcs *connector_funcs = connector->helper_private;
+ save_encoders[count++] = connector->encoder;
+ new_encoder = NULL;
+ for (ro = 0; ro < set->num_connectors; ro++) {
+ if (set->connectors[ro] == connector) {
+ new_encoder = connector_funcs->best_encoder(connector);
+ /* if we can't get an encoder for a connector
+ we are setting now - then fail */
+ if (new_encoder == NULL)
+ /* don't break so fail path works correct */
+ fail = 1;
+ break;
+ }
+ }
+
+ if (new_encoder != connector->encoder) {
+ changed = true;
+ connector->encoder = new_encoder;
+ }
+ }
+
+ if (fail) {
+ ret = -EINVAL;
+ goto fail_no_encoder;
+ }
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (!connector->encoder)
+ continue;
+
+ save_crtcs[count++] = connector->encoder->crtc;
- if (output->crtc == set->crtc)
+ if (connector->encoder->crtc == set->crtc)
new_crtc = NULL;
else
- new_crtc = output->crtc;
+ new_crtc = connector->encoder->crtc;
- for (ro = 0; ro < set->num_outputs; ro++) {
- if (set->outputs[ro] == output)
+ for (ro = 0; ro < set->num_connectors; ro++) {
+ if (set->connectors[ro] == connector)
new_crtc = set->crtc;
}
- if (new_crtc != output->crtc) {
+ if (new_crtc != connector->encoder->crtc) {
changed = true;
- output->crtc = new_crtc;
+ connector->encoder->crtc = new_crtc;
}
}
@@ -376,40 +590,53 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
DRM_DEBUG("attempting to set mode from userspace\n");
drm_mode_debug_printmodeline(set->mode);
if (!drm_crtc_helper_set_mode(set->crtc, set->mode, set->x,
- set->y)) {
- set->crtc->enabled = save_enabled;
- count = 0;
- list_for_each_entry(output, &dev->mode_config.output_list, head)
- output->crtc = save_crtcs[count++];
- kfree(save_crtcs);
- return -EINVAL;
+ set->y)) {
+ ret = -EINVAL;
+ goto fail_set_mode;
}
/* TODO are these needed? */
set->crtc->desired_x = set->x;
set->crtc->desired_y = set->y;
set->crtc->desired_mode = set->mode;
}
- drm_disable_unused_functions(dev);
+ drm_helper_disable_unused_functions(dev);
} else if (flip_or_move) {
if (set->crtc->fb != set->fb)
set->crtc->fb = set->fb;
crtc_funcs->mode_set_base(set->crtc, set->x, set->y);
}
+ kfree(save_encoders);
kfree(save_crtcs);
return 0;
+
+fail_set_mode:
+ set->crtc->enabled = save_enabled;
+ count = 0;
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head)
+ connector->encoder->crtc = save_crtcs[count++];
+fail_no_encoder:
+ kfree(save_crtcs);
+ count = 0;
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ connector->encoder = save_encoders[count++];
+ }
+ kfree(save_encoders);
+ return ret;
+
+
}
EXPORT_SYMBOL(drm_crtc_helper_set_config);
/**
- * drm_initial_config - setup a sane initial output configuration
+ * drm_initial_config - setup a sane initial connector configuration
* @dev: DRM device
* @can_grow: this configuration is growable
*
* LOCKING:
* Called at init time, must take mode config lock.
*
- * Scan the CRTCs and outputs and try to put together an initial setup.
+ * Scan the CRTCs and connectors and try to put together an initial setup.
* At the moment, this is a cloned configuration across all heads with
* a new framebuffer object as the backing store.
*
@@ -418,35 +645,36 @@ EXPORT_SYMBOL(drm_crtc_helper_set_config);
*/
bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
{
- struct drm_output *output;
+ struct drm_connector *connector;
int ret = false;
mutex_lock(&dev->mode_config.mutex);
- drm_crtc_probe_output_modes(dev, 2048, 2048);
+ drm_helper_probe_connector_modes(dev, 2048, 2048);
drm_pick_crtcs(dev);
- /* This is a little screwy, as we've already walked the outputs
+ /* This is a little screwy, as we've already walked the connectors
* above, but it's a little bit of magic too. There's the potential
* for things not to get setup above if an existing device gets
- * re-assigned thus confusing the hardware. By walking the outputs
+ * re-assigned thus confusing the hardware. By walking the connectors
* this fixes up their crtc's.
*/
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- /* can't setup the output if there's no assigned mode */
- if (!output->crtc || !output->crtc->desired_mode)
+ struct drm_crtc *crtc = connector->encoder->crtc;
+ /* can't setup the connector if there's no assigned mode */
+ if (!crtc || !crtc->desired_mode)
continue;
- dev->driver->fb_probe(dev, output->crtc, output);
+ dev->driver->fb_probe(dev, crtc, connector);
/* and needs an attached fb */
- if (output->crtc->fb)
- drm_crtc_helper_set_mode(output->crtc, output->crtc->desired_mode, 0, 0);
+ if (crtc->fb)
+ drm_crtc_helper_set_mode(crtc, crtc->desired_mode, 0, 0);
}
- drm_disable_unused_functions(dev);
+ drm_helper_disable_unused_functions(dev);
mutex_unlock(&dev->mode_config.mutex);
return ret;
@@ -456,7 +684,7 @@ EXPORT_SYMBOL(drm_helper_initial_config);
/**
* drm_hotplug_stage_two
* @dev DRM device
- * @output hotpluged output
+ * @connector hotpluged connector
*
* LOCKING.
* Caller must hold mode config lock, function might grab struct lock.
@@ -466,7 +694,7 @@ EXPORT_SYMBOL(drm_helper_initial_config);
* RETURNS:
* Zero on success, errno on failure.
*/
-int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_output *output,
+int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *connector,
bool connected)
{
int has_config = 0;
@@ -479,37 +707,38 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_output *outp
return 0;
}
- if (output->crtc && output->crtc->desired_mode) {
- DRM_DEBUG("drm thinks that the output already has a config\n");
+ if (connector->encoder->crtc && connector->encoder->crtc->desired_mode) {
+ DRM_DEBUG("drm thinks that the connector already has a config\n");
has_config = 1;
}
- drm_crtc_probe_output_modes(dev, 2048, 2048);
+ drm_helper_probe_connector_modes(dev, 2048, 2048);
if (!has_config)
drm_pick_crtcs(dev);
- if (!output->crtc || !output->crtc->desired_mode) {
- DRM_DEBUG("could not find a desired mode or crtc for output\n");
+ if (!connector->encoder->crtc || !connector->encoder->crtc->desired_mode) {
+ DRM_DEBUG("could not find a desired mode or crtc for connector\n");
return 1;
}
/* We should really check if there is a fb using this crtc */
if (!has_config)
- dev->driver->fb_probe(dev, output->crtc, output);
+ dev->driver->fb_probe(dev, connector->encoder->crtc, connector);
else {
- dev->driver->fb_resize(dev, output->crtc);
+ dev->driver->fb_resize(dev, connector->encoder->crtc);
#if 0
- if (!drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0))
+ if (!drm_crtc_set_mode(connector->encoder->crtc, connector->encoder->crtc->desired_mode, 0, 0))
DRM_ERROR("failed to set mode after hotplug\n");
#endif
}
drm_sysfs_hotplug_event(dev);
- drm_disable_unused_functions(dev);
+ drm_helper_disable_unused_functions(dev);
return 0;
}
EXPORT_SYMBOL(drm_helper_hotplug_stage_two);
+
diff --git a/linux-core/drm_crtc_helper.h b/linux-core/drm_crtc_helper.h
index f56b97c6..3a3a4d4f 100644
--- a/linux-core/drm_crtc_helper.h
+++ b/linux-core/drm_crtc_helper.h
@@ -21,6 +21,11 @@
#include <linux/fb.h>
struct drm_crtc_helper_funcs {
+ /*
+ * Control power levels on the CRTC. If the mode passed in is
+ * unsupported, the provider must use the next lowest power level.
+ */
+ void (*dpms)(struct drm_crtc *crtc, int mode);
void (*prepare)(struct drm_crtc *crtc);
void (*commit)(struct drm_crtc *crtc);
@@ -36,32 +41,50 @@ struct drm_crtc_helper_funcs {
void (*mode_set_base)(struct drm_crtc *crtc, int x, int y);
};
-struct drm_output_helper_funcs {
- bool (*mode_fixup)(struct drm_output *output,
+struct drm_encoder_helper_funcs {
+ void (*dpms)(struct drm_encoder *encoder, int mode);
+ void (*save)(struct drm_encoder *encoder);
+ void (*restore)(struct drm_encoder *encoder);
+
+ bool (*mode_fixup)(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
- void (*prepare)(struct drm_output *output);
- void (*commit)(struct drm_output *output);
- void (*mode_set)(struct drm_output *output,
+ void (*prepare)(struct drm_encoder *encoder);
+ void (*commit)(struct drm_encoder *encoder);
+ void (*mode_set)(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
};
-extern int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_output *output,
+struct drm_connector_helper_funcs {
+ int (*get_modes)(struct drm_connector *connector);
+ int (*mode_valid)(struct drm_connector *connector,
+ struct drm_display_mode *mode);
+ struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
+};
+
+extern void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
+extern void drm_helper_disable_unused_functions(struct drm_device *dev);
+extern int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *connector,
bool connected);
extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow);
extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mode,
int x, int y);
-
+extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);
static inline void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_crtc_helper_funcs *funcs)
{
crtc->helper_private = (void *)funcs;
}
-static inline void drm_output_helper_add(struct drm_output *output, const struct drm_output_helper_funcs *funcs)
+static inline void drm_encoder_helper_add(struct drm_encoder *encoder, const struct drm_encoder_helper_funcs *funcs)
+{
+ encoder->helper_private = (void *)funcs;
+}
+
+static inline void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs)
{
- output->helper_private = (void *)funcs;
+ connector->helper_private = (void *)funcs;
}
diff --git a/linux-core/drm_drv.c b/linux-core/drm_drv.c
index d96b14b6..5a16fe8d 100644
--- a/linux-core/drm_drv.c
+++ b/linux-core/drm_drv.c
@@ -126,14 +126,14 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETOUTPUT, drm_mode_getoutput, DRM_MASTER|DRM_CONTROL_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW),
- DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_output_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW),
@@ -142,6 +142,7 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_WAIT_HOTPLUG, drm_wait_hotplug, 0),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_REPLACEFB, drm_mode_replacefb, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
+ DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_ROOT_ONLY|DRM_CONTROL_ALLOW),
DRM_IOCTL_DEF(DRM_IOCTL_MM_INIT, drm_mm_init_ioctl,
DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
diff --git a/linux-core/drm_edid.c b/linux-core/drm_edid.c
index e033abdf..69906ed9 100644
--- a/linux-core/drm_edid.c
+++ b/linux-core/drm_edid.c
@@ -211,9 +211,9 @@ static struct drm_display_mode edid_est_modes[] = {
* Each EDID block contains a bitmap of the supported "established modes" list
* (defined above). Tease them out and add them to the global modes list.
*/
-static int add_established_modes(struct drm_output *output, struct edid *edid)
+static int add_established_modes(struct drm_connector *connector, struct edid *edid)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
unsigned long est_bits = edid->established_timings.t1 |
(edid->established_timings.t2 << 8) |
((edid->established_timings.mfg_rsvd & 0x80) << 9);
@@ -224,7 +224,7 @@ static int add_established_modes(struct drm_output *output, struct edid *edid)
struct drm_display_mode *newmode;
newmode = drm_mode_duplicate(dev, &edid_est_modes[i]);
if (newmode) {
- drm_mode_probed_add(output, newmode);
+ drm_mode_probed_add(connector, newmode);
modes++;
}
}
@@ -239,9 +239,9 @@ static int add_established_modes(struct drm_output *output, struct edid *edid)
* Standard modes can be calculated using the CVT standard. Grab them from
* @edid, calculate them, and add them to the list.
*/
-static int add_standard_modes(struct drm_output *output, struct edid *edid)
+static int add_standard_modes(struct drm_connector *connector, struct edid *edid)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
int i, modes = 0;
for (i = 0; i < EDID_STD_TIMINGS; i++) {
@@ -254,7 +254,7 @@ static int add_standard_modes(struct drm_output *output, struct edid *edid)
newmode = drm_mode_std(dev, &edid->standard_timings[i]);
if (newmode) {
- drm_mode_probed_add(output, newmode);
+ drm_mode_probed_add(connector, newmode);
modes++;
}
}
@@ -269,9 +269,9 @@ static int add_standard_modes(struct drm_output *output, struct edid *edid)
* Some of the detailed timing sections may contain mode information. Grab
* it and add it to the list.
*/
-static int add_detailed_info(struct drm_output *output, struct edid *edid)
+static int add_detailed_info(struct drm_connector *connector, struct edid *edid)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
int i, j, modes = 0;
for (i = 0; i < EDID_DETAILED_TIMINGS; i++) {
@@ -290,11 +290,11 @@ static int add_detailed_info(struct drm_output *output, struct edid *edid)
if (newmode) {
if (i == 0 && edid->preferred_timing)
newmode->type |= DRM_MODE_TYPE_PREFERRED;
- drm_mode_probed_add(output, newmode);
+ drm_mode_probed_add(connector, newmode);
- /* Use first one for output's preferred mode */
- if (!output->display_info.preferred_mode)
- output->display_info.preferred_mode =
+ /* Use first one for connector's preferred mode */
+ if (!connector->display_info.preferred_mode)
+ connector->display_info.preferred_mode =
newmode;
modes++;
}
@@ -323,7 +323,7 @@ static int add_detailed_info(struct drm_output *output, struct edid *edid)
std = &data->data.timings[j];
newmode = drm_mode_std(dev, std);
if (newmode) {
- drm_mode_probed_add(output, newmode);
+ drm_mode_probed_add(connector, newmode);
modes++;
}
}
@@ -440,32 +440,32 @@ static unsigned char *drm_ddc_read(struct i2c_adapter *adapter)
/**
* drm_get_edid - get EDID data, if available
- * @output: output we're probing
+ * @connector: connector we're probing
* @adapter: i2c adapter to use for DDC
*
- * Poke the given output's i2c channel to grab EDID data if possible.
+ * Poke the given connector's i2c channel to grab EDID data if possible.
*
* Return edid data or NULL if we couldn't find any.
*/
-struct edid *drm_get_edid(struct drm_output *output,
+struct edid *drm_get_edid(struct drm_connector *connector,
struct i2c_adapter *adapter)
{
struct edid *edid;
edid = (struct edid *)drm_ddc_read(adapter);
if (!edid) {
- dev_warn(&output->dev->pdev->dev, "%s: no EDID data\n",
- drm_get_output_name(output));
+ dev_warn(&connector->dev->pdev->dev, "%s: no EDID data\n",
+ drm_get_connector_name(connector));
return NULL;
}
if (!edid_valid(edid)) {
- dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n",
- drm_get_output_name(output));
+ dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
+ drm_get_connector_name(connector));
kfree(edid);
return NULL;
}
- output->display_info.raw_edid = (char *)edid;
+ connector->display_info.raw_edid = (char *)edid;
return edid;
}
@@ -473,14 +473,14 @@ EXPORT_SYMBOL(drm_get_edid);
/**
* drm_add_edid_modes - add modes from EDID data, if available
- * @output: output we're probing
+ * @connector: connector we're probing
* @edid: edid data
*
- * Add the specified modes to the output's mode list.
+ * Add the specified modes to the connector's mode list.
*
* Return number of modes added or 0 if we couldn't find any.
*/
-int drm_add_edid_modes(struct drm_output *output, struct edid *edid)
+int drm_add_edid_modes(struct drm_connector *connector, struct edid *edid)
{
int num_modes = 0;
@@ -488,31 +488,31 @@ int drm_add_edid_modes(struct drm_output *output, struct edid *edid)
return 0;
}
if (!edid_valid(edid)) {
- dev_warn(&output->dev->pdev->dev, "%s: EDID invalid.\n",
- drm_get_output_name(output));
+ dev_warn(&connector->dev->pdev->dev, "%s: EDID invalid.\n",
+ drm_get_connector_name(connector));
return 0;
}
- num_modes += add_established_modes(output, edid);
- num_modes += add_standard_modes(output, edid);
- num_modes += add_detailed_info(output, edid);
-
- output->display_info.serration_vsync = edid->serration_vsync;
- output->display_info.sync_on_green = edid->sync_on_green;
- output->display_info.composite_sync = edid->composite_sync;
- output->display_info.separate_syncs = edid->separate_syncs;
- output->display_info.blank_to_black = edid->blank_to_black;
- output->display_info.video_level = edid->video_level;
- output->display_info.digital = edid->digital;
- output->display_info.width_mm = edid->width_cm * 10;
- output->display_info.height_mm = edid->height_cm * 10;
- output->display_info.gamma = edid->gamma;
- output->display_info.gtf_supported = edid->default_gtf;
- output->display_info.standard_color = edid->standard_color;
- output->display_info.display_type = edid->display_type;
- output->display_info.active_off_supported = edid->pm_active_off;
- output->display_info.suspend_supported = edid->pm_suspend;
- output->display_info.standby_supported = edid->pm_standby;
- output->display_info.gamma = edid->gamma;
+ num_modes += add_established_modes(connector, edid);
+ num_modes += add_standard_modes(connector, edid);
+ num_modes += add_detailed_info(connector, edid);
+
+ connector->display_info.serration_vsync = edid->serration_vsync;
+ connector->display_info.sync_on_green = edid->sync_on_green;
+ connector->display_info.composite_sync = edid->composite_sync;
+ connector->display_info.separate_syncs = edid->separate_syncs;
+ connector->display_info.blank_to_black = edid->blank_to_black;
+ connector->display_info.video_level = edid->video_level;
+ connector->display_info.digital = edid->digital;
+ connector->display_info.width_mm = edid->width_cm * 10;
+ connector->display_info.height_mm = edid->height_cm * 10;
+ connector->display_info.gamma = edid->gamma;
+ connector->display_info.gtf_supported = edid->default_gtf;
+ connector->display_info.standard_color = edid->standard_color;
+ connector->display_info.display_type = edid->display_type;
+ connector->display_info.active_off_supported = edid->pm_active_off;
+ connector->display_info.suspend_supported = edid->pm_suspend;
+ connector->display_info.standby_supported = edid->pm_standby;
+ connector->display_info.gamma = edid->gamma;
return num_modes;
}
diff --git a/linux-core/drm_modes.c b/linux-core/drm_modes.c
index 897777d0..26b96e73 100644
--- a/linux-core/drm_modes.c
+++ b/linux-core/drm_modes.c
@@ -521,27 +521,27 @@ void drm_mode_sort(struct list_head *mode_list)
/**
- * drm_mode_output_list_update - update the mode list for the output
- * @output: the output to update
+ * drm_mode_connector_list_update - update the mode list for the connector
+ * @connector: the connector to update
*
* LOCKING:
* Caller must hold a lock protecting @mode_list.
*
- * This moves the modes from the @output probed_modes list
+ * This moves the modes from the @connector probed_modes list
* to the actual mode list. It compares the probed mode against the current
* list and only adds different modes. All modes unverified after this point
* will be removed by the prune invalid modes.
*/
-void drm_mode_output_list_update(struct drm_output *output)
+void drm_mode_connector_list_update(struct drm_connector *connector)
{
struct drm_display_mode *mode;
struct drm_display_mode *pmode, *pt;
int found_it;
- list_for_each_entry_safe(pmode, pt, &output->probed_modes,
+ list_for_each_entry_safe(pmode, pt, &connector->probed_modes,
head) {
found_it = 0;
/* go through current modes checking for the new probed mode */
- list_for_each_entry(mode, &output->modes, head) {
+ list_for_each_entry(mode, &connector->modes, head) {
if (drm_mode_equal(pmode, mode)) {
found_it = 1;
/* if equal delete the probed mode */
@@ -553,7 +553,7 @@ void drm_mode_output_list_update(struct drm_output *output)
}
if (!found_it) {
- list_move_tail(&pmode->head, &output->modes);
+ list_move_tail(&pmode->head, &connector->modes);
}
}
}
diff --git a/linux-core/drm_sysfs.c b/linux-core/drm_sysfs.c
index 8691d156..01a3c047 100644
--- a/linux-core/drm_sysfs.c
+++ b/linux-core/drm_sysfs.c
@@ -147,27 +147,27 @@ static void drm_sysfs_device_release(struct device *dev)
}
/*
- * Output properties
+ * Connector properties
*/
static ssize_t status_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
- struct drm_output *output = container_of(device, struct drm_output, kdev);
+ struct drm_connector *connector = container_of(device, struct drm_connector, kdev);
return snprintf(buf, PAGE_SIZE, "%s",
- drm_get_output_status_name(output->funcs->detect(output)));
+ drm_get_connector_status_name(connector->funcs->detect(connector)));
}
static ssize_t dpms_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
- struct drm_output *output = container_of(device, struct drm_output, kdev);
- struct drm_device *dev = output->dev;
+ struct drm_connector *connector = container_of(device, struct drm_connector, kdev);
+ struct drm_device *dev = connector->dev;
uint64_t dpms_status;
int ret;
- ret = drm_output_property_get_value(output,
+ ret = drm_connector_property_get_value(connector,
dev->mode_config.dpms_property,
&dpms_status);
if (ret)
@@ -179,17 +179,17 @@ static ssize_t dpms_show(struct device *device,
static ssize_t edid_show(struct kobject *kobj, struct bin_attribute *attr,
char *buf, loff_t off, size_t count)
{
- struct device *output_dev = container_of(kobj, struct device, kobj);
- struct drm_output *output = container_of(output_dev, struct drm_output,
+ struct device *connector_dev = container_of(kobj, struct device, kobj);
+ struct drm_connector *connector = container_of(connector_dev, struct drm_connector,
kdev);
unsigned char *edid;
size_t size;
- if (!output->edid_blob_ptr)
+ if (!connector->edid_blob_ptr)
return 0;
- edid = output->edid_blob_ptr->data;
- size = output->edid_blob_ptr->length;
+ edid = connector->edid_blob_ptr->data;
+ size = connector->edid_blob_ptr->length;
if (!edid)
return 0;
@@ -207,11 +207,11 @@ static ssize_t modes_show(struct device *device,
struct device_attribute *attr,
char *buf)
{
- struct drm_output *output = container_of(device, struct drm_output, kdev);
+ struct drm_connector *connector = container_of(device, struct drm_connector, kdev);
struct drm_display_mode *mode;
int written = 0;
- list_for_each_entry(mode, &output->modes, head) {
+ list_for_each_entry(mode, &connector->modes, head) {
written += snprintf(buf + written, PAGE_SIZE - written, "%s\n",
mode->name);
}
@@ -219,7 +219,7 @@ static ssize_t modes_show(struct device *device,
return written;
}
-static struct device_attribute output_attrs[] = {
+static struct device_attribute connector_attrs[] = {
__ATTR_RO(status),
__ATTR_RO(dpms),
__ATTR_RO(modes),
@@ -232,48 +232,48 @@ static struct bin_attribute edid_attr = {
};
/**
- * drm_sysfs_output_add - add an output to sysfs
- * @output: output to add
+ * drm_sysfs_connector_add - add an connector to sysfs
+ * @connector: connector to add
*
- * Create an output device in sysfs, along with its associated output
+ * Create an connector device in sysfs, along with its associated connector
* properties (so far, connection status, dpms, mode list & edid) and
- * generate a hotplug event so userspace knows there's a new output
+ * generate a hotplug event so userspace knows there's a new connector
* available.
*/
-int drm_sysfs_output_add(struct drm_output *output)
+int drm_sysfs_connector_add(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
int ret = 0, i, j;
- if (device_is_registered(&output->kdev))
+ if (device_is_registered(&connector->kdev))
return 0;
- output->kdev.parent = &dev->primary->kdev;
- output->kdev.class = drm_class;
- output->kdev.release = drm_sysfs_device_release;
+ connector->kdev.parent = &dev->primary->kdev;
+ connector->kdev.class = drm_class;
+ connector->kdev.release = drm_sysfs_device_release;
- DRM_DEBUG("adding \"%s\" to sysfs\n", drm_get_output_name(output));
+ DRM_DEBUG("adding \"%s\" to sysfs\n", drm_get_connector_name(connector));
- snprintf(output->kdev.bus_id, BUS_ID_SIZE, "card%d-%s",
- dev->primary->index, drm_get_output_name(output));
- ret = device_register(&output->kdev);
+ snprintf(connector->kdev.bus_id, BUS_ID_SIZE, "card%d-%s",
+ dev->primary->index, drm_get_connector_name(connector));
+ ret = device_register(&connector->kdev);
if (ret) {
- DRM_ERROR("failed to register output device: %d\n", ret);
+ DRM_ERROR("failed to register connector device: %d\n", ret);
goto out;
}
- for (i = 0; i < ARRAY_SIZE(output_attrs); i++) {
- ret = device_create_file(&output->kdev, &output_attrs[i]);
+ for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) {
+ ret = device_create_file(&connector->kdev, &connector_attrs[i]);
if (ret)
goto err_out_files;
}
- ret = sysfs_create_bin_file(&output->kdev.kobj, &edid_attr);
+ ret = sysfs_create_bin_file(&connector->kdev.kobj, &edid_attr);
if (ret)
goto err_out_files;
- /* Let userspace know we have a new output */
+ /* Let userspace know we have a new connector */
drm_sysfs_hotplug_event(dev);
return 0;
@@ -281,33 +281,33 @@ int drm_sysfs_output_add(struct drm_output *output)
err_out_files:
if (i > 0)
for (j = 0; j < i; j++)
- device_remove_file(&output->kdev, &output_attrs[i]);
- device_unregister(&output->kdev);
+ device_remove_file(&connector->kdev, &connector_attrs[i]);
+ device_unregister(&connector->kdev);
out:
return ret;
}
-EXPORT_SYMBOL(drm_sysfs_output_add);
+EXPORT_SYMBOL(drm_sysfs_connector_add);
/**
- * drm_sysfs_output_remove - remove an output device from sysfs
- * @output: output to remove
+ * drm_sysfs_connector_remove - remove an connector device from sysfs
+ * @connector: connector to remove
*
- * Remove @output and its associated attributes from sysfs. Note that
+ * Remove @connector and its associated attributes from sysfs. Note that
* the device model core will take care of sending the "remove" uevent
* at this time, so we don't need to do it.
*/
-void drm_sysfs_output_remove(struct drm_output *output)
+void drm_sysfs_connector_remove(struct drm_connector *connector)
{
int i;
- DRM_DEBUG("removing \"%s\" from sysfs\n", drm_get_output_name(output));
- for (i = 0; i < ARRAY_SIZE(output_attrs); i++)
- device_remove_file(&output->kdev, &output_attrs[i]);
- sysfs_remove_bin_file(&output->kdev.kobj, &edid_attr);
- device_unregister(&output->kdev);
+ DRM_DEBUG("removing \"%s\" from sysfs\n", drm_get_connector_name(connector));
+ for (i = 0; i < ARRAY_SIZE(connector_attrs); i++)
+ device_remove_file(&connector->kdev, &connector_attrs[i]);
+ sysfs_remove_bin_file(&connector->kdev.kobj, &edid_attr);
+ device_unregister(&connector->kdev);
}
-EXPORT_SYMBOL(drm_sysfs_output_remove);
+EXPORT_SYMBOL(drm_sysfs_connector_remove);
/**
* drm_sysfs_hotplug_event - generate a DRM uevent
diff --git a/linux-core/dvo.h b/linux-core/dvo.h
index c6c1dbdb..b122ea1f 100644
--- a/linux-core/dvo.h
+++ b/linux-core/dvo.h
@@ -126,7 +126,7 @@ struct intel_dvo_dev_ops {
/*
* Probe for a connected output, and return detect_status.
*/
- enum drm_output_status (*detect)(struct intel_dvo_device *dvo);
+ enum drm_connector_status (*detect)(struct intel_dvo_device *dvo);
/**
* Query the device for the modes it provides.
diff --git a/linux-core/dvo_ch7017.c b/linux-core/dvo_ch7017.c
index 8349da1b..194a7af1 100644
--- a/linux-core/dvo_ch7017.c
+++ b/linux-core/dvo_ch7017.c
@@ -258,9 +258,9 @@ fail:
return false;
}
-static enum drm_output_status ch7017_detect(struct intel_dvo_device *dvo)
+static enum drm_connector_status ch7017_detect(struct intel_dvo_device *dvo)
{
- return output_status_unknown;
+ return connector_status_unknown;
}
static enum drm_mode_status ch7017_mode_valid(struct intel_dvo_device *dvo,
diff --git a/linux-core/dvo_ch7xxx.c b/linux-core/dvo_ch7xxx.c
index 69827a7d..18922556 100644
--- a/linux-core/dvo_ch7xxx.c
+++ b/linux-core/dvo_ch7xxx.c
@@ -230,7 +230,7 @@ out:
return false;
}
-static enum drm_output_status ch7xxx_detect(struct intel_dvo_device *dvo)
+static enum drm_connector_status ch7xxx_detect(struct intel_dvo_device *dvo)
{
uint8_t cdet, orig_pm, pm;
@@ -247,8 +247,8 @@ static enum drm_output_status ch7xxx_detect(struct intel_dvo_device *dvo)
ch7xxx_writeb(dvo, CH7xxx_PM, orig_pm);
if (cdet & CH7xxx_CDET_DVI)
- return output_status_connected;
- return output_status_disconnected;
+ return connector_status_connected;
+ return connector_status_disconnected;
}
static enum drm_mode_status ch7xxx_mode_valid(struct intel_dvo_device *dvo,
diff --git a/linux-core/dvo_ivch.c b/linux-core/dvo_ivch.c
index 9209dd02..7ba00b34 100644
--- a/linux-core/dvo_ivch.c
+++ b/linux-core/dvo_ivch.c
@@ -297,9 +297,9 @@ out:
return false;
}
-static enum drm_output_status ivch_detect(struct intel_dvo_device *dvo)
+static enum drm_connector_status ivch_detect(struct intel_dvo_device *dvo)
{
- return output_status_connected;
+ return connector_status_connected;
}
static enum drm_mode_status ivch_mode_valid(struct intel_dvo_device *dvo,
diff --git a/linux-core/dvo_sil164.c b/linux-core/dvo_sil164.c
index 0cee59b1..d0fa4913 100644
--- a/linux-core/dvo_sil164.c
+++ b/linux-core/dvo_sil164.c
@@ -180,16 +180,16 @@ out:
return false;
}
-static enum drm_output_status sil164_detect(struct intel_dvo_device *dvo)
+static enum drm_connector_status sil164_detect(struct intel_dvo_device *dvo)
{
uint8_t reg9;
sil164_readb(dvo, SIL164_REG9, &reg9);
if (reg9 & SIL164_9_HTPLG)
- return output_status_connected;
+ return connector_status_connected;
else
- return output_status_disconnected;
+ return connector_status_disconnected;
}
static enum drm_mode_status sil164_mode_valid(struct intel_dvo_device *dvo,
diff --git a/linux-core/dvo_tfp410.c b/linux-core/dvo_tfp410.c
index 64448509..c1d1aa96 100644
--- a/linux-core/dvo_tfp410.c
+++ b/linux-core/dvo_tfp410.c
@@ -207,16 +207,16 @@ out:
return false;
}
-static enum drm_output_status tfp410_detect(struct intel_dvo_device *dvo)
+static enum drm_connector_status tfp410_detect(struct intel_dvo_device *dvo)
{
- enum drm_output_status ret = output_status_disconnected;
+ enum drm_connector_status ret = connector_status_disconnected;
uint8_t ctl2;
if (tfp410_readb(dvo, TFP410_CTL_2, &ctl2)) {
if (ctl2 & TFP410_CTL_2_HTPLG)
- ret = output_status_connected;
+ ret = connector_status_connected;
else
- ret = output_status_disconnected;
+ ret = connector_status_disconnected;
}
return ret;
diff --git a/linux-core/intel_crt.c b/linux-core/intel_crt.c
index 584dea21..bf7c449e 100644
--- a/linux-core/intel_crt.c
+++ b/linux-core/intel_crt.c
@@ -33,9 +33,9 @@
#include "i915_drm.h"
#include "i915_drv.h"
-static void intel_crt_dpms(struct drm_output *output, int mode)
+static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 temp;
@@ -61,17 +61,17 @@ static void intel_crt_dpms(struct drm_output *output, int mode)
I915_WRITE(ADPA, temp);
}
-static void intel_crt_save(struct drm_output *output)
+static void intel_crt_save(struct drm_connector *connector)
{
}
-static void intel_crt_restore(struct drm_output *output)
+static void intel_crt_restore(struct drm_connector *connector)
{
}
-static int intel_crt_mode_valid(struct drm_output *output,
+static int intel_crt_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
if (mode->flags & V_DBLSCAN)
@@ -83,19 +83,20 @@ static int intel_crt_mode_valid(struct drm_output *output,
return MODE_OK;
}
-static bool intel_crt_mode_fixup(struct drm_output *output,
+static bool intel_crt_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
return true;
}
-static void intel_crt_mode_set(struct drm_output *output,
+static void intel_crt_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = output->dev;
- struct drm_crtc *crtc = output->crtc;
+
+ struct drm_device *dev = encoder->dev;
+ struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
struct drm_i915_private *dev_priv = dev->dev_private;
int dpll_md_reg;
@@ -138,9 +139,9 @@ static void intel_crt_mode_set(struct drm_output *output,
* \return TRUE if CRT is connected.
* \return FALSE if CRT is disconnected.
*/
-static bool intel_crt_detect_hotplug(struct drm_output *output)
+static bool intel_crt_detect_hotplug(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 temp;
@@ -164,57 +165,58 @@ static bool intel_crt_detect_hotplug(struct drm_output *output)
return false;
}
-static bool intel_crt_detect_ddc(struct drm_output *output)
+static bool intel_crt_detect_ddc(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
/* CRT should always be at 0, but check anyway */
if (intel_output->type != INTEL_OUTPUT_ANALOG)
return false;
- return intel_ddc_probe(output);
+ return intel_ddc_probe(intel_output);
}
-static enum drm_output_status intel_crt_detect(struct drm_output *output)
+static enum drm_connector_status intel_crt_detect(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
if (IS_I9XX(dev) && !IS_I915G(dev) && !IS_I915GM(dev)) {
- if (intel_crt_detect_hotplug(output))
- return output_status_connected;
+ if (intel_crt_detect_hotplug(connector))
+ return connector_status_connected;
else
- return output_status_disconnected;
+ return connector_status_disconnected;
}
- if (intel_crt_detect_ddc(output))
- return output_status_connected;
+ if (intel_crt_detect_ddc(connector))
+ return connector_status_connected;
/* TODO use load detect */
- return output_status_unknown;
+ return connector_status_unknown;
}
-static void intel_crt_destroy(struct drm_output *output)
+static void intel_crt_destroy(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
intel_i2c_destroy(intel_output->ddc_bus);
- drm_output_cleanup(output);
- kfree(output);
+ drm_connector_cleanup(connector);
+ kfree(connector);
}
-static int intel_crt_get_modes(struct drm_output *output)
+static int intel_crt_get_modes(struct drm_connector *connector)
{
- return intel_ddc_get_modes(output);
+ struct intel_output *intel_output = to_intel_output(connector);
+ return intel_ddc_get_modes(intel_output);
}
-static bool intel_crt_set_property(struct drm_output *output,
+static bool intel_crt_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t value)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
- if (property == dev->mode_config.dpms_property)
- intel_crt_dpms(output, (uint32_t)(value & 0xf));
+ if (property == dev->mode_config.dpms_property && connector->encoder)
+ intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf));
return true;
}
@@ -223,52 +225,71 @@ static bool intel_crt_set_property(struct drm_output *output,
* Routines for controlling stuff on the analog port
*/
-static const struct drm_output_helper_funcs intel_crt_helper_funcs = {
+static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = {
+ .dpms = intel_crt_dpms,
.mode_fixup = intel_crt_mode_fixup,
- .prepare = intel_output_prepare,
- .commit = intel_output_commit,
+ .prepare = intel_encoder_prepare,
+ .commit = intel_encoder_commit,
.mode_set = intel_crt_mode_set,
};
-static const struct drm_output_funcs intel_crt_output_funcs = {
- .dpms = intel_crt_dpms,
+static const struct drm_connector_funcs intel_crt_connector_funcs = {
.save = intel_crt_save,
.restore = intel_crt_restore,
.detect = intel_crt_detect,
- .get_modes = intel_crt_get_modes,
+ .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = intel_crt_destroy,
.set_property = intel_crt_set_property,
+};
+
+static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
.mode_valid = intel_crt_mode_valid,
+ .get_modes = intel_crt_get_modes,
+ .best_encoder = intel_best_encoder,
+};
+void intel_crt_enc_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs intel_crt_enc_funcs = {
+ .destroy = intel_crt_enc_destroy,
};
void intel_crt_init(struct drm_device *dev)
{
- struct drm_output *output;
+ struct drm_connector *connector;
struct intel_output *intel_output;
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output)
return;
- output = &intel_output->base;
- drm_output_init(dev, &intel_output->base, &intel_crt_output_funcs, DRM_MODE_OUTPUT_DAC);
+ connector = &intel_output->base;
+ drm_connector_init(dev, &intel_output->base, &intel_crt_connector_funcs, DRM_MODE_CONNECTOR_VGA);
+
+ drm_encoder_init(dev, &intel_output->enc, &intel_crt_enc_funcs, DRM_MODE_ENCODER_DAC);
+
+ drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
/* Set up the DDC bus. */
intel_output->ddc_bus = intel_i2c_create(dev, GPIOA, "CRTDDC_A");
if (!intel_output->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n");
- intel_crt_destroy(output);
+ intel_crt_destroy(connector);
return;
}
intel_output->type = INTEL_OUTPUT_ANALOG;
- output->interlace_allowed = 0;
- output->doublescan_allowed = 0;
+ connector->interlace_allowed = 0;
+ connector->doublescan_allowed = 0;
+
+ drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
+ drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);
+
+ drm_sysfs_connector_add(connector);
- drm_output_helper_add(output, &intel_crt_helper_funcs);
- drm_sysfs_output_add(output);
- drm_output_attach_property(output, dev->mode_config.connector_type_property, ConnectorVGA);
}
diff --git a/linux-core/intel_display.c b/linux-core/intel_display.c
index abcf5f5e..e23b3973 100644
--- a/linux-core/intel_display.c
+++ b/linux-core/intel_display.c
@@ -225,10 +225,10 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
{
struct drm_device *dev = crtc->dev;
struct drm_mode_config *mode_config = &dev->mode_config;
- struct drm_output *l_entry;
+ struct drm_connector *l_entry;
- list_for_each_entry(l_entry, &mode_config->output_list, head) {
- if (l_entry->crtc == crtc) {
+ list_for_each_entry(l_entry, &mode_config->connector_list, head) {
+ if (l_entry->encoder->crtc == crtc) {
struct intel_output *intel_output = to_intel_output(l_entry);
if (intel_output->type == type)
return true;
@@ -240,7 +240,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
#define INTELPllInvalid(s) { /* ErrorF (s) */; return false; }
/**
* Returns whether the given set of divisors are valid for a given refclk with
- * the given outputs.
+ * the given connectors.
*/
static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
@@ -264,7 +264,7 @@ static bool intel_PLL_is_valid(struct drm_crtc *crtc, intel_clock_t *clock)
if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
INTELPllInvalid ("vco out of range\n");
/* XXX: We may need to be checking "Dot clock" depending on the multiplier,
- * output, etc., rather than just a single range.
+ * connector, etc., rather than just a single range.
*/
if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
INTELPllInvalid ("dot out of range\n");
@@ -575,24 +575,28 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode)
static void intel_crtc_prepare (struct drm_crtc *crtc)
{
- crtc->funcs->dpms(crtc, DPMSModeOff);
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DPMSModeOff);
}
static void intel_crtc_commit (struct drm_crtc *crtc)
{
- crtc->funcs->dpms(crtc, DPMSModeOn);
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DPMSModeOn);
}
-void intel_output_prepare (struct drm_output *output)
+void intel_encoder_prepare (struct drm_encoder *encoder)
{
+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
/* lvds has its own version of prepare see intel_lvds_prepare */
- output->funcs->dpms(output, DPMSModeOff);
+ encoder_funcs->dpms(encoder, DPMSModeOff);
}
-void intel_output_commit (struct drm_output *output)
+void intel_encoder_commit (struct drm_encoder *encoder)
{
+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
/* lvds has its own version of commit see intel_lvds_commit */
- output->funcs->dpms(output, DPMSModeOn);
+ encoder_funcs->dpms(encoder, DPMSModeOn);
}
static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
@@ -716,12 +720,12 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
bool ok, is_sdvo = false, is_dvo = false;
bool is_crt = false, is_lvds = false, is_tv = false;
struct drm_mode_config *mode_config = &dev->mode_config;
- struct drm_output *output;
+ struct drm_connector *connector;
- list_for_each_entry(output, &mode_config->output_list, head) {
- struct intel_output *intel_output = to_intel_output(output);
+ list_for_each_entry(connector, &mode_config->connector_list, head) {
+ struct intel_output *intel_output = to_intel_output(connector);
- if (output->crtc != crtc)
+ if (!connector->encoder || connector->encoder->crtc != crtc)
continue;
switch (intel_output->type) {
@@ -1082,38 +1086,40 @@ static struct drm_display_mode load_detect_mode = {
704, 832, 0, 480, 489, 491, 520, 0, V_NHSYNC | V_NVSYNC),
};
-struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output,
+struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
struct drm_display_mode *mode,
int *dpms_mode)
{
- struct drm_device *dev = output->dev;
- struct intel_output *intel_output = to_intel_output(output);
struct intel_crtc *intel_crtc;
struct drm_crtc *possible_crtc;
struct drm_crtc *supported_crtc =NULL;
+ struct drm_encoder *encoder = &intel_output->enc;
struct drm_crtc *crtc = NULL;
- struct drm_output_helper_funcs *output_funcs;
+ struct drm_device *dev = encoder->dev;
+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+ struct drm_crtc_helper_funcs *crtc_funcs;
int i = -1;
/*
* Algorithm gets a little messy:
- * - if the output already has an assigned crtc, use it (but make
+ * - if the connector already has an assigned crtc, use it (but make
* sure it's on first)
- * - try to find the first unused crtc that can drive this output,
+ * - try to find the first unused crtc that can drive this connector,
* and use that if we find one
* - if there are no unused crtcs available, try to use the first
- * one we found that supports the output
+ * one we found that supports the connector
*/
- /* See if we already have a CRTC for this output */
- if (output->crtc) {
- crtc = output->crtc;
- /* Make sure the crtc and output are running */
+ /* See if we already have a CRTC for this connector */
+ if (encoder->crtc) {
+ crtc = encoder->crtc;
+ /* Make sure the crtc and connector are running */
intel_crtc = to_intel_crtc(crtc);
*dpms_mode = intel_crtc->dpms_mode;
if (intel_crtc->dpms_mode != DPMSModeOn) {
- crtc->funcs->dpms(crtc, DPMSModeOn);
- output->funcs->dpms(output, DPMSModeOn);
+ crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DPMSModeOn);
+ encoder_funcs->dpms(encoder, DPMSModeOn);
}
return crtc;
}
@@ -1121,7 +1127,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output,
/* Find an unused one (if possible) */
list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) {
i++;
- if (!(output->possible_crtcs & (1 << i)))
+ if (!(encoder->possible_crtcs & (1 << i)))
continue;
if (!possible_crtc->enabled) {
crtc = possible_crtc;
@@ -1133,7 +1139,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output,
/*
* If we didn't find an unused CRTC, use the first available one
- * that can drive this output.
+ * that can drive this connector.
*/
if (!crtc) {
crtc = supported_crtc;
@@ -1141,7 +1147,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output,
return NULL;
}
- output->crtc = crtc;
+ encoder->crtc = crtc;
intel_output->load_detect_temp = TRUE;
intel_crtc = to_intel_crtc(crtc);
@@ -1152,38 +1158,41 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output,
mode = &load_detect_mode;
drm_crtc_helper_set_mode(crtc, mode, 0, 0);
} else {
- if (intel_crtc->dpms_mode != DPMSModeOn)
- crtc->funcs->dpms(crtc, DPMSModeOn);
+ if (intel_crtc->dpms_mode != DPMSModeOn) {
+ crtc_funcs = crtc->helper_private;
+ crtc_funcs->dpms(crtc, DPMSModeOn);
+ }
- output_funcs = output->helper_private;
- /* Add this output to the crtc */
- output_funcs->mode_set(output, &crtc->mode, &crtc->mode);
- output_funcs->commit(output);
+ /* Add this connector to the crtc */
+ encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode);
+ encoder_funcs->commit(encoder);
}
- /* let the output get through one full cycle before testing */
+ /* let the connector get through one full cycle before testing */
intel_wait_for_vblank(dev);
return crtc;
}
-void intel_release_load_detect_pipe(struct drm_output *output, int dpms_mode)
+void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
{
- struct drm_device *dev = output->dev;
- struct intel_output *intel_output = to_intel_output(output);
- struct drm_crtc *crtc = output->crtc;
+ struct drm_encoder *encoder = &intel_output->enc;
+ struct drm_device *dev = encoder->dev;
+ struct drm_crtc *crtc = encoder->crtc;
+ struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
if (intel_output->load_detect_temp) {
- output->crtc = NULL;
+ encoder->crtc = NULL;
intel_output->load_detect_temp = FALSE;
- crtc->enabled = drm_crtc_in_use(crtc);
- drm_disable_unused_functions(dev);
+ crtc->enabled = drm_helper_crtc_in_use(crtc);
+ drm_helper_disable_unused_functions(dev);
}
/* Switch crtc and output back off if necessary */
if (crtc->enabled && dpms_mode != DPMSModeOn) {
- if (output->crtc == crtc)
- output->funcs->dpms(output, dpms_mode);
- crtc->funcs->dpms(crtc, dpms_mode);
+ if (encoder->crtc == crtc)
+ encoder_funcs->dpms(encoder, dpms_mode);
+ crtc_funcs->dpms(crtc, dpms_mode);
}
}
@@ -1257,7 +1266,7 @@ static int intel_crtc_clock_get(struct drm_device *dev, struct drm_crtc *crtc)
}
/* XXX: It would be nice to validate the clocks, but we can't reuse
- * i830PllIsValid() because it relies on the xf86_config output
+ * i830PllIsValid() because it relies on the xf86_config connector
* configuration being accurate, which it isn't necessarily.
*/
@@ -1306,6 +1315,7 @@ static void intel_crtc_destroy(struct drm_crtc *crtc)
}
static const struct drm_crtc_helper_funcs intel_helper_funcs = {
+ .dpms = intel_crtc_dpms,
.mode_fixup = intel_crtc_mode_fixup,
.mode_set = intel_crtc_mode_set,
.mode_set_base = intel_pipe_set_base,
@@ -1314,7 +1324,6 @@ static const struct drm_crtc_helper_funcs intel_helper_funcs = {
};
static const struct drm_crtc_funcs intel_crtc_funcs = {
- .dpms = intel_crtc_dpms,
.cursor_set = intel_crtc_cursor_set,
.cursor_move = intel_crtc_cursor_move,
.gamma_set = intel_crtc_gamma_set,
@@ -1358,14 +1367,14 @@ struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
return crtc;
}
-int intel_output_clones(struct drm_device *dev, int type_mask)
+int intel_connector_clones(struct drm_device *dev, int type_mask)
{
int index_mask = 0;
- struct drm_output *output;
+ struct drm_connector *connector;
int entry = 0;
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- struct intel_output *intel_output = to_intel_output(output);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ struct intel_output *intel_output = to_intel_output(connector);
if (type_mask & (1 << intel_output->type))
index_mask |= (1 << entry);
entry++;
@@ -1376,7 +1385,7 @@ int intel_output_clones(struct drm_device *dev, int type_mask)
static void intel_setup_outputs(struct drm_device *dev)
{
- struct drm_output *output;
+ struct drm_connector *connector;
intel_crt_init(dev);
@@ -1393,8 +1402,9 @@ static void intel_setup_outputs(struct drm_device *dev)
if (IS_I9XX(dev) && !IS_I915G(dev))
intel_tv_init(dev);
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- struct intel_output *intel_output = to_intel_output(output);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ struct intel_output *intel_output = to_intel_output(connector);
+ struct drm_encoder *encoder = &intel_output->enc;
int crtc_mask = 0, clone_mask = 0;
/* valid crtcs */
@@ -1424,8 +1434,8 @@ static void intel_setup_outputs(struct drm_device *dev)
clone_mask = (1 << INTEL_OUTPUT_TVOUT);
break;
}
- output->possible_crtcs = crtc_mask;
- output->possible_clones = intel_output_clones(dev, clone_mask);
+ encoder->possible_crtcs = crtc_mask;
+ encoder->possible_clones = intel_connector_clones(dev, clone_mask);
}
}
@@ -1479,3 +1489,14 @@ void intel_modeset_cleanup(struct drm_device *dev)
{
drm_mode_config_cleanup(dev);
}
+
+
+/* current intel driver doesn't take advantage of encoders
+ always give back the encoder for the connector
+*/
+struct drm_encoder *intel_best_encoder(struct drm_connector *connector)
+{
+ struct intel_output *intel_output = to_intel_output(connector);
+
+ return &intel_output->enc;
+}
diff --git a/linux-core/intel_drv.h b/linux-core/intel_drv.h
index 82d2d703..24287e37 100644
--- a/linux-core/intel_drv.h
+++ b/linux-core/intel_drv.h
@@ -47,7 +47,9 @@ struct intel_i2c_chan {
};
struct intel_output {
- struct drm_output base;
+ struct drm_connector base;
+
+ struct drm_encoder enc;
int type;
struct intel_i2c_chan *i2c_bus; /* for control functions */
struct intel_i2c_chan *ddc_bus; /* for DDC only stuff */
@@ -66,12 +68,13 @@ struct intel_crtc {
#define to_intel_crtc(x) container_of(x, struct intel_crtc, base)
#define to_intel_output(x) container_of(x, struct intel_output, base)
+#define enc_to_intel_output(x) container_of(x, struct intel_output, enc)
struct intel_i2c_chan *intel_i2c_create(struct drm_device *dev, const u32 reg,
const char *name);
void intel_i2c_destroy(struct intel_i2c_chan *chan);
-int intel_ddc_get_modes(struct drm_output *output);
-extern bool intel_ddc_probe(struct drm_output *output);
+int intel_ddc_get_modes(struct intel_output *intel_output);
+extern bool intel_ddc_probe(struct intel_output *intel_output);
extern void intel_crt_init(struct drm_device *dev);
extern void intel_sdvo_init(struct drm_device *dev, int output_device);
@@ -80,23 +83,25 @@ extern void intel_tv_init(struct drm_device *dev);
extern void intel_lvds_init(struct drm_device *dev);
extern void intel_crtc_load_lut(struct drm_crtc *crtc);
-extern void intel_output_prepare (struct drm_output *output);
-extern void intel_output_commit (struct drm_output *output);
+extern void intel_encoder_prepare (struct drm_encoder *encoder);
+extern void intel_encoder_commit (struct drm_encoder *encoder);
+
+extern struct drm_encoder *intel_best_encoder(struct drm_connector *connector);
+
extern struct drm_display_mode *intel_crtc_mode_get(struct drm_device *dev,
struct drm_crtc *crtc);
extern void intel_wait_for_vblank(struct drm_device *dev);
extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
-extern struct drm_crtc *intel_get_load_detect_pipe(struct drm_output *output,
+extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_output *intel_output,
struct drm_display_mode *mode,
int *dpms_mode);
-extern void intel_release_load_detect_pipe(struct drm_output *output,
+extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
int dpms_mode);
-extern struct drm_output* intel_sdvo_find(struct drm_device *dev, int sdvoB);
-extern int intel_sdvo_supports_hotplug(struct drm_output *output);
-extern void intel_sdvo_set_hotplug(struct drm_output *output, int enable);
-
-extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output);
+extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
+extern int intel_sdvo_supports_hotplug(struct drm_connector *connector);
+extern void intel_sdvo_set_hotplug(struct drm_connector *connector, int enable);
+extern int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_connector *connector);
extern int intelfb_remove(struct drm_device *dev, struct drm_framebuffer *fb);
extern int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc);
diff --git a/linux-core/intel_dvo.c b/linux-core/intel_dvo.c
index d9f39af6..b061b1c5 100644
--- a/linux-core/intel_dvo.c
+++ b/linux-core/intel_dvo.c
@@ -85,10 +85,10 @@ struct intel_dvo_device intel_dvo_devices[] = {
}
};
-static void intel_dvo_dpms(struct drm_output *output, int mode)
+static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
{
- struct drm_i915_private *dev_priv = output->dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct drm_i915_private *dev_priv = encoder->dev->dev_private;
+ struct intel_output *intel_output = enc_to_intel_output(encoder);
struct intel_dvo_device *dvo = intel_output->dev_priv;
u32 dvo_reg = dvo->dvo_reg;
u32 temp = I915_READ(dvo_reg);
@@ -104,10 +104,10 @@ static void intel_dvo_dpms(struct drm_output *output, int mode)
}
}
-static void intel_dvo_save(struct drm_output *output)
+static void intel_dvo_save(struct drm_connector *connector)
{
- struct drm_i915_private *dev_priv = output->dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct drm_i915_private *dev_priv = connector->dev->dev_private;
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_dvo_device *dvo = intel_output->dev_priv;
/* Each output should probably just save the registers it touches,
@@ -120,10 +120,10 @@ static void intel_dvo_save(struct drm_output *output)
dvo->dev_ops->save(dvo);
}
-static void intel_dvo_restore(struct drm_output *output)
+static void intel_dvo_restore(struct drm_connector *connector)
{
- struct drm_i915_private *dev_priv = output->dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct drm_i915_private *dev_priv = connector->dev->dev_private;
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_dvo_device *dvo = intel_output->dev_priv;
dvo->dev_ops->restore(dvo);
@@ -133,10 +133,10 @@ static void intel_dvo_restore(struct drm_output *output)
I915_WRITE(DVOC, dev_priv->saveDVOC);
}
-static int intel_dvo_mode_valid(struct drm_output *output,
+static int intel_dvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_dvo_device *dvo = intel_output->dev_priv;
if (mode->flags & V_DBLSCAN)
@@ -154,11 +154,11 @@ static int intel_dvo_mode_valid(struct drm_output *output,
return dvo->dev_ops->mode_valid(dvo, mode);
}
-static bool intel_dvo_mode_fixup(struct drm_output *output,
+static bool intel_dvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = enc_to_intel_output(encoder);
struct intel_dvo_device *dvo = intel_output->dev_priv;
/* If we have timings from the BIOS for the panel, put them in
@@ -187,14 +187,14 @@ static bool intel_dvo_mode_fixup(struct drm_output *output,
return true;
}
-static void intel_dvo_mode_set(struct drm_output *output,
+static void intel_dvo_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc);
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+ struct intel_output *intel_output = enc_to_intel_output(encoder);
struct intel_dvo_device *dvo = intel_output->dev_priv;
int pipe = intel_crtc->pipe;
u32 dvo_val;
@@ -247,17 +247,17 @@ static void intel_dvo_mode_set(struct drm_output *output,
*
* Unimplemented.
*/
-static enum drm_output_status intel_dvo_detect(struct drm_output *output)
+static enum drm_connector_status intel_dvo_detect(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_dvo_device *dvo = intel_output->dev_priv;
return dvo->dev_ops->detect(dvo);
}
-static int intel_dvo_get_modes(struct drm_output *output)
+static int intel_dvo_get_modes(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_dvo_device *dvo = intel_output->dev_priv;
/* We should probably have an i2c driver get_modes function for those
@@ -265,8 +265,8 @@ static int intel_dvo_get_modes(struct drm_output *output)
* (TV-out, for example), but for now with just TMDS and LVDS,
* that's not the case.
*/
- intel_ddc_get_modes(output);
- if (!list_empty(&output->probed_modes))
+ intel_ddc_get_modes(intel_output);
+ if (!list_empty(&connector->probed_modes))
return 1;
#if 0
@@ -280,18 +280,18 @@ static int intel_dvo_get_modes(struct drm_output *output)
if (dvo->panel_fixed_mode != NULL) {
struct drm_display_mode *mode;
- mode = drm_mode_duplicate(output->dev, dvo->panel_fixed_mode);
+ mode = drm_mode_duplicate(connector->dev, dvo->panel_fixed_mode);
if (mode) {
- drm_mode_probed_add(output, mode);
+ drm_mode_probed_add(connector, mode);
return 1;
}
}
return 0;
}
-static void intel_dvo_destroy (struct drm_output *output)
+static void intel_dvo_destroy (struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_dvo_device *dvo = intel_output->dev_priv;
if (dvo) {
@@ -306,16 +306,16 @@ static void intel_dvo_destroy (struct drm_output *output)
intel_i2c_destroy(intel_output->i2c_bus);
if (intel_output->ddc_bus)
intel_i2c_destroy(intel_output->ddc_bus);
- drm_output_cleanup(output);
- kfree(output);
+ drm_connector_cleanup(connector);
+ kfree(intel_output);
}
#ifdef RANDR_GET_CRTC_INTERFACE
-static struct drm_crtc *intel_dvo_get_crtc(struct drm_output *output)
+static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_dvo_device *dvo = intel_output->dev_priv;
int pipe = !!(I915_READ(dvo->dvo_reg) & SDVO_PIPE_B_SELECT);
@@ -323,23 +323,38 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_output *output)
}
#endif
-static const struct drm_output_helper_funcs intel_dvo_helper_funcs = {
+static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
+ .dpms = intel_dvo_dpms,
.mode_fixup = intel_dvo_mode_fixup,
- .prepare = intel_output_prepare,
+ .prepare = intel_encoder_prepare,
.mode_set = intel_dvo_mode_set,
- .commit = intel_output_commit,
+ .commit = intel_encoder_commit,
};
-static const struct drm_output_funcs intel_dvo_output_funcs = {
- .dpms = intel_dvo_dpms,
+static const struct drm_connector_funcs intel_dvo_connector_funcs = {
.save = intel_dvo_save,
.restore = intel_dvo_restore,
.detect = intel_dvo_detect,
- .get_modes = intel_dvo_get_modes,
.destroy = intel_dvo_destroy,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+};
+
+static const struct drm_connector_helper_funcs intel_dvo_connector_helper_funcs = {
.mode_valid = intel_dvo_mode_valid,
+ .get_modes = intel_dvo_get_modes,
+ .best_encoder = intel_best_encoder,
};
+void intel_dvo_enc_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs intel_dvo_enc_funcs = {
+ .destroy = intel_dvo_enc_destroy,
+};
+
+
/**
* Attempts to get a fixed panel timing for LVDS (currently only the i830).
*
@@ -347,11 +362,11 @@ static const struct drm_output_funcs intel_dvo_output_funcs = {
* chip being on DVOB/C and having multiple pipes.
*/
static struct drm_display_mode *
-intel_dvo_get_current_mode (struct drm_output *output)
+intel_dvo_get_current_mode (struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_dvo_device *dvo = intel_output->dev_priv;
uint32_t dvo_reg = dvo->dvo_reg;
uint32_t dvo_val = I915_READ(dvo_reg);
@@ -388,8 +403,7 @@ void intel_dvo_init(struct drm_device *dev)
int ret = 0;
int i;
int gpio_inited = 0;
- int connector = ConnectorUnknown;
-
+ int encoder_type = DRM_MODE_ENCODER_NONE;
intel_output = kzalloc (sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output)
return;
@@ -401,7 +415,7 @@ void intel_dvo_init(struct drm_device *dev)
/* Now, try to find a controller */
for (i = 0; i < ARRAY_SIZE(intel_dvo_devices); i++) {
- struct drm_output *output = &intel_output->base;
+ struct drm_connector *connector = &intel_output->base;
int gpio;
dvo = &intel_dvo_devices[i];
@@ -442,25 +456,31 @@ void intel_dvo_init(struct drm_device *dev)
intel_output->type = INTEL_OUTPUT_DVO;
switch (dvo->type) {
case INTEL_DVO_CHIP_TMDS:
- connector = ConnectorDVID;
- drm_output_init(dev, output, &intel_dvo_output_funcs,
- DRM_MODE_OUTPUT_TMDS);
+ // connector = DRM_MODE_CONNECTOR_DVID;
+ drm_connector_init(dev, connector, &intel_dvo_connector_funcs,
+ DRM_MODE_CONNECTOR_DVII);
+ encoder_type = DRM_MODE_ENCODER_TMDS;
break;
case INTEL_DVO_CHIP_LVDS:
- connector = ConnectorLVDS;
- drm_output_init(dev, output, &intel_dvo_output_funcs,
- DRM_MODE_OUTPUT_LVDS);
+ // connector = DRM_MODE_CONNECTOR_LVDS;
+ drm_connector_init(dev, connector, &intel_dvo_connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+ encoder_type = DRM_MODE_ENCODER_LVDS;
break;
}
- drm_output_helper_add(output, &intel_dvo_helper_funcs);
- output->display_info.subpixel_order = SubPixelHorizontalRGB;
- output->interlace_allowed = false;
- output->doublescan_allowed = false;
+ drm_connector_helper_add(connector, &intel_dvo_connector_helper_funcs);
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = false;
+ connector->doublescan_allowed = false;
intel_output->dev_priv = dvo;
intel_output->i2c_bus = i2cbus;
+ drm_encoder_init(dev, &intel_output->enc, &intel_dvo_enc_funcs, encoder_type);
+ drm_encoder_helper_add(&intel_output->enc, &intel_dvo_helper_funcs);
+
+ drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
if (dvo->type == INTEL_DVO_CHIP_LVDS) {
/* For our LVDS chipsets, we should hopefully be able
* to dig the fixed panel mode out of the BIOS data.
@@ -469,14 +489,11 @@ void intel_dvo_init(struct drm_device *dev)
* headers, likely), so for now, just get the current
* mode being output through DVO.
*/
- dvo->panel_fixed_mode = intel_dvo_get_current_mode(output);
+ dvo->panel_fixed_mode = intel_dvo_get_current_mode(connector);
dvo->panel_wants_dither = true;
}
- drm_sysfs_output_add(output);
- drm_output_attach_property(output,
- dev->mode_config.connector_type_property,
- connector);
+ drm_sysfs_connector_add(connector);
return;
}
diff --git a/linux-core/intel_fb.c b/linux-core/intel_fb.c
index 05fc3b29..138d189e 100644
--- a/linux-core/intel_fb.c
+++ b/linux-core/intel_fb.c
@@ -53,7 +53,7 @@ struct intelfb_par {
*/
struct drm_display_mode *our_mode;
struct drm_mode_set set;
- struct drm_output *hack;
+ struct drm_connector *hack;
};
/*
static int
@@ -114,7 +114,7 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
struct intelfb_par *par = info->par;
/*struct drm_device *dev = par->dev;*/
struct drm_framebuffer *fb = par->set.fb;
- /*struct drm_output *output;*/
+ /*struct drm_connector *connector;*/
int depth/*, found = 0*/;
if (!var->pixclock)
@@ -195,17 +195,17 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
}
#if 0
- /* Here we walk the output mode list and look for modes. If we haven't
+ /* Here we walk the connector mode list and look for modes. If we haven't
* got it, then bail. Not very nice, so this is disabled.
* In the set_par code, we create our mode based on the incoming
* parameters. Nicer, but may not be desired by some.
*/
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- if (output->crtc == par->crtc)
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (connector->crtc == par->crtc)
break;
}
- list_for_each_entry(drm_mode, &output->modes, head) {
+ list_for_each_entry(drm_mode, &connector->modes, head) {
if (drm_mode->hdisplay == var->xres &&
drm_mode->vdisplay == var->yres &&
(((PICOS2KHZ(var->pixclock))/1000) >= ((drm_mode->clock/1000)-1)) &&
@@ -230,7 +230,7 @@ static int intelfb_set_par(struct fb_info *info)
struct drm_framebuffer *fb = par->set.fb;
struct drm_device *dev = par->dev;
struct drm_display_mode *drm_mode, *search_mode;
- struct drm_output *output = NULL;
+ struct drm_connector *connector = NULL;
struct fb_var_screeninfo *var = &info->var;
int found = 0;
@@ -276,20 +276,20 @@ static int intelfb_set_par(struct fb_info *info)
drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);
found = 0;
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- if (output->crtc == par->set.crtc){
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (connector->encoder->crtc == par->set.crtc){
found = 1;
break;
}
}
- /* no output bound, bail */
+ /* no connector bound, bail */
if (!found)
return -EINVAL;
found = 0;
drm_mode_debug_printmodeline(drm_mode);
- list_for_each_entry(search_mode, &output->modes, head) {
+ list_for_each_entry(search_mode, &connector->modes, head) {
drm_mode_debug_printmodeline(search_mode);
if (drm_mode_equal(drm_mode, search_mode)) {
drm_mode_destroy(dev, drm_mode);
@@ -299,7 +299,7 @@ static int intelfb_set_par(struct fb_info *info)
}
}
- /* If we didn't find a matching mode that exists on our output,
+ /* If we didn't find a matching mode that exists on our connector,
* create a new attachment for the incoming user specified mode
*/
if (!found) {
@@ -566,7 +566,7 @@ int intelfb_resize(struct drm_device *dev, struct drm_crtc *crtc)
}
EXPORT_SYMBOL(intelfb_resize);
-int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_output *output)
+int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_connector *connector)
{
struct fb_info *info;
struct intelfb_par *par;
@@ -581,7 +581,7 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_outp
return -EINVAL;
}
- if (!output)
+ if (!connector)
return -EINVAL;
fb = drm_framebuffer_create(dev);
@@ -627,9 +627,9 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc, struct drm_outp
par->dev = dev;
par->set.crtc = crtc;
par->set.fb = fb;
- par->hack = output;
- par->set.outputs = &par->hack;
- par->set.num_outputs = 1;
+ par->hack = connector;
+ par->set.connectors = &par->hack;
+ par->set.num_connectors = 1;
info->fbops = &intelfb_ops;
diff --git a/linux-core/intel_lvds.c b/linux-core/intel_lvds.c
index 6781a47c..f2fe4612 100644
--- a/linux-core/intel_lvds.c
+++ b/linux-core/intel_lvds.c
@@ -89,9 +89,9 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on)
}
}
-static void intel_lvds_dpms(struct drm_output *output, int mode)
+static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
if (mode == DPMSModeOn)
intel_lvds_set_power(dev, true);
@@ -101,9 +101,9 @@ static void intel_lvds_dpms(struct drm_output *output, int mode)
/* XXX: We never power down the LVDS pairs. */
}
-static void intel_lvds_save(struct drm_output *output)
+static void intel_lvds_save(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->savePP_ON = I915_READ(PP_ON_DELAYS);
@@ -122,9 +122,9 @@ static void intel_lvds_save(struct drm_output *output)
intel_lvds_get_max_backlight(dev);
}
-static void intel_lvds_restore(struct drm_output *output)
+static void intel_lvds_restore(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
@@ -138,10 +138,10 @@ static void intel_lvds_restore(struct drm_output *output)
intel_lvds_set_power(dev, false);
}
-static int intel_lvds_mode_valid(struct drm_output *output,
+static int intel_lvds_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
struct drm_display_mode *fixed_mode = dev_priv->panel_fixed_mode;
@@ -155,14 +155,14 @@ static int intel_lvds_mode_valid(struct drm_output *output,
return MODE_OK;
}
-static bool intel_lvds_mode_fixup(struct drm_output *output,
+static bool intel_lvds_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc);
- struct drm_output *tmp_output;
+ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
+ struct drm_encoder *tmp_encoder;
/* Should never happen!! */
if (!IS_I965G(dev) && intel_crtc->pipe == 0) {
@@ -171,10 +171,10 @@ static bool intel_lvds_mode_fixup(struct drm_output *output,
}
/* Should never happen!! */
- list_for_each_entry(tmp_output, &dev->mode_config.output_list, head) {
- if (tmp_output != output && tmp_output->crtc == output->crtc) {
+ list_for_each_entry(tmp_encoder, &dev->mode_config.encoder_list, head) {
+ if (tmp_encoder != encoder && tmp_encoder->crtc == encoder->crtc) {
printk(KERN_ERR "Can't enable LVDS and another "
- "output on the same pipe\n");
+ "encoder on the same pipe\n");
return false;
}
}
@@ -211,9 +211,9 @@ static bool intel_lvds_mode_fixup(struct drm_output *output,
return true;
}
-static void intel_lvds_prepare(struct drm_output *output)
+static void intel_lvds_prepare(struct drm_encoder *encoder)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
@@ -223,9 +223,9 @@ static void intel_lvds_prepare(struct drm_output *output)
intel_lvds_set_power(dev, false);
}
-static void intel_lvds_commit( struct drm_output *output)
+static void intel_lvds_commit( struct drm_encoder *encoder)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
if (dev_priv->backlight_duty_cycle == 0)
@@ -235,13 +235,13 @@ static void intel_lvds_commit( struct drm_output *output)
intel_lvds_set_power(dev, true);
}
-static void intel_lvds_mode_set(struct drm_output *output,
+static void intel_lvds_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_crtc *intel_crtc = to_intel_crtc(output->crtc);
+ struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
u32 pfit_control;
/*
@@ -276,24 +276,25 @@ static void intel_lvds_mode_set(struct drm_output *output,
/**
* Detect the LVDS connection.
*
- * This always returns OUTPUT_STATUS_CONNECTED. This output should only have
+ * This always returns CONNECTOR_STATUS_CONNECTED. This connector should only have
* been set up if the LVDS was actually connected anyway.
*/
-static enum drm_output_status intel_lvds_detect(struct drm_output *output)
+static enum drm_connector_status intel_lvds_detect(struct drm_connector *connector)
{
- return output_status_connected;
+ return connector_status_connected;
}
/**
* Return the list of DDC modes if available, or the BIOS fixed mode otherwise.
*/
-static int intel_lvds_get_modes(struct drm_output *output)
+static int intel_lvds_get_modes(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
+ struct intel_output *intel_output = to_intel_output(connector);
struct drm_i915_private *dev_priv = dev->dev_private;
int ret = 0;
- ret = intel_ddc_get_modes(output);
+ ret = intel_ddc_get_modes(intel_output);
if (ret)
return ret;
@@ -302,15 +303,15 @@ static int intel_lvds_get_modes(struct drm_output *output)
* Set wide sync ranges so we get all modes
* handed to valid_mode for checking
*/
- output->display_info.min_vfreq = 0;
- output->display_info.max_vfreq = 200;
- output->display_info.min_hfreq = 0;
- output->display_info.max_hfreq = 200;
+ connector->display_info.min_vfreq = 0;
+ connector->display_info.max_vfreq = 200;
+ connector->display_info.min_hfreq = 0;
+ connector->display_info.max_hfreq = 200;
if (dev_priv->panel_fixed_mode != NULL) {
struct drm_display_mode *mode =
drm_mode_duplicate(dev, dev_priv->panel_fixed_mode);
- drm_mode_probed_add(output, mode);
+ drm_mode_probed_add(connector, mode);
return 1;
}
@@ -319,49 +320,67 @@ static int intel_lvds_get_modes(struct drm_output *output)
/**
* intel_lvds_destroy - unregister and free LVDS structures
- * @output: output to free
+ * @connector: connector to free
*
- * Unregister the DDC bus for this output then free the driver private
+ * Unregister the DDC bus for this connector then free the driver private
* structure.
*/
-static void intel_lvds_destroy(struct drm_output *output)
+static void intel_lvds_destroy(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
intel_i2c_destroy(intel_output->ddc_bus);
- drm_output_cleanup(output);
- kfree(output);
+ drm_connector_cleanup(connector);
+ kfree(connector);
}
-static const struct drm_output_helper_funcs intel_lvds_helper_funcs = {
+static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
+ .dpms = intel_lvds_dpms,
.mode_fixup = intel_lvds_mode_fixup,
.prepare = intel_lvds_prepare,
.mode_set = intel_lvds_mode_set,
.commit = intel_lvds_commit,
};
-static const struct drm_output_funcs intel_lvds_output_funcs = {
- .dpms = intel_lvds_dpms,
+static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
+ .get_modes = intel_lvds_get_modes,
+ .mode_valid = intel_lvds_mode_valid,
+ .best_encoder = intel_best_encoder,
+};
+
+static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.save = intel_lvds_save,
.restore = intel_lvds_restore,
.detect = intel_lvds_detect,
- .get_modes = intel_lvds_get_modes,
+ .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = intel_lvds_destroy,
- .mode_valid = intel_lvds_mode_valid,
};
+
+static void intel_lvds_enc_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
+ .destroy = intel_lvds_enc_destroy,
+};
+
+
+
/**
- * intel_lvds_init - setup LVDS outputs on this device
+ * intel_lvds_init - setup LVDS connectors on this device
* @dev: drm device
*
- * Create the output, register the LVDS DDC bus, and try to figure out what
+ * Create the connector, register the LVDS DDC bus, and try to figure out what
* modes we can display on the LVDS panel (if present).
*/
void intel_lvds_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
struct intel_output *intel_output;
- struct drm_output *output;
+ struct drm_connector *connector;
+ struct drm_encoder *encoder;
struct drm_display_mode *scan; /* *modes, *bios_mode; */
struct drm_crtc *crtc;
u32 lvds;
@@ -372,16 +391,22 @@ void intel_lvds_init(struct drm_device *dev)
return;
}
- output = &intel_output->base;
- drm_output_init(dev, &intel_output->base, &intel_lvds_output_funcs,
- DRM_MODE_OUTPUT_LVDS);
+ connector = &intel_output->base;
+ encoder = &intel_output->enc;
+ drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
+ DRM_MODE_CONNECTOR_LVDS);
+
+ drm_encoder_init(dev, &intel_output->enc, &intel_lvds_enc_funcs,
+ DRM_MODE_ENCODER_LVDS);
+ drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
intel_output->type = INTEL_OUTPUT_LVDS;
- drm_output_helper_add(output, &intel_lvds_helper_funcs);
- output->display_info.subpixel_order = SubPixelHorizontalRGB;
- output->interlace_allowed = FALSE;
- output->doublescan_allowed = FALSE;
+ drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
+ drm_connector_helper_add(connector, &intel_lvds_connector_helper_funcs);
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ connector->interlace_allowed = FALSE;
+ connector->doublescan_allowed = FALSE;
/*
@@ -399,7 +424,7 @@ void intel_lvds_init(struct drm_device *dev)
if (!intel_output->ddc_bus) {
dev_printk(KERN_ERR, &dev->pdev->dev, "DDC bus registration "
"failed.\n");
- intel_lvds_destroy(output);
+ intel_lvds_destroy(connector);
return;
}
@@ -407,9 +432,9 @@ void intel_lvds_init(struct drm_device *dev)
* Attempt to get the fixed panel mode from DDC. Assume that the
* preferred mode is the right one.
*/
- intel_ddc_get_modes(output);
+ intel_ddc_get_modes(intel_output);
- list_for_each_entry(scan, &output->probed_modes, head) {
+ list_for_each_entry(scan, &connector->probed_modes, head) {
if (scan->type & DRM_MODE_TYPE_PREFERRED) {
dev_priv->panel_fixed_mode =
drm_mode_duplicate(dev, scan);
@@ -481,11 +506,10 @@ void intel_lvds_init(struct drm_device *dev)
#endif
out:
- drm_sysfs_output_add(output);
- drm_output_attach_property(output, dev->mode_config.connector_type_property, ConnectorLVDS);
+ drm_sysfs_connector_add(connector);
return;
failed:
DRM_DEBUG("No LVDS modes found, disabling.\n");
- intel_lvds_destroy(output);
+ intel_lvds_destroy(connector);
}
diff --git a/linux-core/intel_modes.c b/linux-core/intel_modes.c
index 8e9a506a..79be3575 100644
--- a/linux-core/intel_modes.c
+++ b/linux-core/intel_modes.c
@@ -13,9 +13,8 @@
* intel_ddc_probe
*
*/
-bool intel_ddc_probe(struct drm_output *output)
+bool intel_ddc_probe(struct intel_output *intel_output)
{
- struct intel_output *intel_output = to_intel_output(output);
u8 out_buf[] = { 0x0, 0x0};
u8 buf[2];
int ret;
@@ -43,20 +42,19 @@ bool intel_ddc_probe(struct drm_output *output)
/**
* intel_ddc_get_modes - get modelist from monitor
- * @output: DRM output device to use
+ * @connector: DRM connector device to use
*
- * Fetch the EDID information from @output using the DDC bus.
+ * Fetch the EDID information from @connector using the DDC bus.
*/
-int intel_ddc_get_modes(struct drm_output *output)
+int intel_ddc_get_modes(struct intel_output *intel_output)
{
- struct intel_output *intel_output = to_intel_output(output);
struct edid *edid;
int ret = 0;
- edid = drm_get_edid(output, &intel_output->ddc_bus->adapter);
+ edid = drm_get_edid(&intel_output->base, &intel_output->ddc_bus->adapter);
if (edid) {
- drm_mode_output_update_edid_property(output, edid);
- ret = drm_add_edid_modes(output, edid);
+ drm_mode_connector_update_edid_property(&intel_output->base, edid);
+ ret = drm_add_edid_modes(&intel_output->base, edid);
kfree(edid);
}
return ret;
diff --git a/linux-core/intel_sdvo.c b/linux-core/intel_sdvo.c
index f4b1c6ef..9ae0d567 100644
--- a/linux-core/intel_sdvo.c
+++ b/linux-core/intel_sdvo.c
@@ -60,11 +60,10 @@ struct intel_sdvo_priv {
* SDVOB and SDVOC to work around apparent hardware issues (according to
* comments in the BIOS).
*/
-void intel_sdvo_write_sdvox(struct drm_output *output, u32 val)
+void intel_sdvo_write_sdvox(struct intel_output *intel_output, u32 val)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = intel_output->base.dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
u32 bval = val, cval = val;
int i;
@@ -88,10 +87,9 @@ void intel_sdvo_write_sdvox(struct drm_output *output, u32 val)
}
}
-static bool intel_sdvo_read_byte(struct drm_output *output, u8 addr,
+static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr,
u8 *ch)
{
- struct intel_output *intel_output = to_intel_output(output);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
u8 out_buf[2];
u8 buf[2];
@@ -126,10 +124,9 @@ static bool intel_sdvo_read_byte(struct drm_output *output, u8 addr,
return false;
}
-static bool intel_sdvo_write_byte(struct drm_output *output, int addr,
+static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr,
u8 ch)
{
- struct intel_output *intel_output = to_intel_output(output);
u8 out_buf[2];
struct i2c_msg msgs[] = {
{
@@ -198,10 +195,9 @@ const static struct _sdvo_cmd_name {
#define SDVO_NAME(dev_priv) ((dev_priv)->output_device == SDVOB ? "SDVOB" : "SDVOC")
#define SDVO_PRIV(output) ((struct intel_sdvo_priv *) (output)->dev_priv)
-static void intel_sdvo_write_cmd(struct drm_output *output, u8 cmd,
+static void intel_sdvo_write_cmd(struct intel_output *intel_output, u8 cmd,
void *args, int args_len)
{
- struct intel_output *intel_output = to_intel_output(output);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
int i;
@@ -223,10 +219,10 @@ static void intel_sdvo_write_cmd(struct drm_output *output, u8 cmd,
}
for (i = 0; i < args_len; i++) {
- intel_sdvo_write_byte(output, SDVO_I2C_ARG_0 - i, ((u8*)args)[i]);
+ intel_sdvo_write_byte(intel_output, SDVO_I2C_ARG_0 - i, ((u8*)args)[i]);
}
- intel_sdvo_write_byte(output, SDVO_I2C_OPCODE, cmd);
+ intel_sdvo_write_byte(intel_output, SDVO_I2C_OPCODE, cmd);
}
static const char *cmd_status_names[] = {
@@ -239,10 +235,9 @@ static const char *cmd_status_names[] = {
"Scaling not supported"
};
-static u8 intel_sdvo_read_response(struct drm_output *output, void *response,
+static u8 intel_sdvo_read_response(struct intel_output *intel_output, void *response,
int response_len)
{
- struct intel_output *intel_output = to_intel_output(output);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
int i;
u8 status;
@@ -251,12 +246,12 @@ static u8 intel_sdvo_read_response(struct drm_output *output, void *response,
while (retry--) {
/* Read the command response */
for (i = 0; i < response_len; i++) {
- intel_sdvo_read_byte(output, SDVO_I2C_RETURN_0 + i,
+ intel_sdvo_read_byte(intel_output, SDVO_I2C_RETURN_0 + i,
&((u8 *)response)[i]);
}
/* read the return status */
- intel_sdvo_read_byte(output, SDVO_I2C_CMD_STATUS, &status);
+ intel_sdvo_read_byte(intel_output, SDVO_I2C_CMD_STATUS, &status);
if (1) {
DRM_DEBUG("%s: R: ", SDVO_NAME(sdvo_priv));
@@ -295,12 +290,12 @@ int intel_sdvo_get_pixel_multiplier(struct drm_display_mode *mode)
* SDVO chips which defeats the purpose of doing a bus switch in the first
* place.
*/
-void intel_sdvo_set_control_bus_switch(struct drm_output *output, u8 target)
+void intel_sdvo_set_control_bus_switch(struct intel_output *intel_output, u8 target)
{
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CONTROL_BUS_SWITCH, &target, 1);
}
-static bool intel_sdvo_set_target_input(struct drm_output *output, bool target_0, bool target_1)
+static bool intel_sdvo_set_target_input(struct intel_output *intel_output, bool target_0, bool target_1)
{
struct intel_sdvo_set_target_input_args targets = {0};
u8 status;
@@ -311,10 +306,10 @@ static bool intel_sdvo_set_target_input(struct drm_output *output, bool target_0
if (target_1)
targets.target_1 = 1;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_INPUT, &targets,
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_INPUT, &targets,
sizeof(targets));
- status = intel_sdvo_read_response(output, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
@@ -325,13 +320,13 @@ static bool intel_sdvo_set_target_input(struct drm_output *output, bool target_0
* This function is making an assumption about the layout of the response,
* which should be checked against the docs.
*/
-static bool intel_sdvo_get_trained_inputs(struct drm_output *output, bool *input_1, bool *input_2)
+static bool intel_sdvo_get_trained_inputs(struct intel_output *intel_output, bool *input_1, bool *input_2)
{
struct intel_sdvo_get_trained_inputs_response response;
u8 status;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
- status = intel_sdvo_read_response(output, &response, sizeof(response));
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_TRAINED_INPUTS, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, &response, sizeof(response));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -340,29 +335,29 @@ static bool intel_sdvo_get_trained_inputs(struct drm_output *output, bool *input
return true;
}
-static bool intel_sdvo_get_active_outputs(struct drm_output *output,
+static bool intel_sdvo_get_active_outputs(struct intel_output *intel_output,
u16 *outputs)
{
u8 status;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
- status = intel_sdvo_read_response(output, outputs, sizeof(*outputs));
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_OUTPUTS, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, outputs, sizeof(*outputs));
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_set_active_outputs(struct drm_output *output,
+static bool intel_sdvo_set_active_outputs(struct intel_output *intel_output,
u16 outputs)
{
u8 status;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_OUTPUTS, &outputs,
sizeof(outputs));
- status = intel_sdvo_read_response(output, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_set_encoder_power_state(struct drm_output *output,
+static bool intel_sdvo_set_encoder_power_state(struct intel_output *intel_output,
int mode)
{
u8 status, state = SDVO_ENCODER_STATE_ON;
@@ -382,24 +377,24 @@ static bool intel_sdvo_set_encoder_power_state(struct drm_output *output,
break;
}
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ENCODER_POWER_STATE, &state,
sizeof(state));
- status = intel_sdvo_read_response(output, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_get_input_pixel_clock_range(struct drm_output *output,
+static bool intel_sdvo_get_input_pixel_clock_range(struct intel_output *intel_output,
int *clock_min,
int *clock_max)
{
struct intel_sdvo_pixel_clock_range clocks;
u8 status;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_INPUT_PIXEL_CLOCK_RANGE,
NULL, 0);
- status = intel_sdvo_read_response(output, &clocks, sizeof(clocks));
+ status = intel_sdvo_read_response(intel_output, &clocks, sizeof(clocks));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -411,31 +406,31 @@ static bool intel_sdvo_get_input_pixel_clock_range(struct drm_output *output,
return true;
}
-static bool intel_sdvo_set_target_output(struct drm_output *output,
+static bool intel_sdvo_set_target_output(struct intel_output *intel_output,
u16 outputs)
{
u8 status;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_TARGET_OUTPUT, &outputs,
sizeof(outputs));
- status = intel_sdvo_read_response(output, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, NULL, 0);
return (status == SDVO_CMD_STATUS_SUCCESS);
}
-static bool intel_sdvo_get_timing(struct drm_output *output, u8 cmd,
+static bool intel_sdvo_get_timing(struct intel_output *intel_output, u8 cmd,
struct intel_sdvo_dtd *dtd)
{
u8 status;
- intel_sdvo_write_cmd(output, cmd, NULL, 0);
- status = intel_sdvo_read_response(output, &dtd->part1,
+ intel_sdvo_write_cmd(intel_output, cmd, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, &dtd->part1,
sizeof(dtd->part1));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
- intel_sdvo_write_cmd(output, cmd + 1, NULL, 0);
- status = intel_sdvo_read_response(output, &dtd->part2,
+ intel_sdvo_write_cmd(intel_output, cmd + 1, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, &dtd->part2,
sizeof(dtd->part2));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -443,71 +438,70 @@ static bool intel_sdvo_get_timing(struct drm_output *output, u8 cmd,
return true;
}
-static bool intel_sdvo_get_input_timing(struct drm_output *output,
+static bool intel_sdvo_get_input_timing(struct intel_output *intel_output,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_get_timing(output,
+ return intel_sdvo_get_timing(intel_output,
SDVO_CMD_GET_INPUT_TIMINGS_PART1, dtd);
}
-static bool intel_sdvo_get_output_timing(struct drm_output *output,
+static bool intel_sdvo_get_output_timing(struct intel_output *intel_output,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_get_timing(output,
+ return intel_sdvo_get_timing(intel_output,
SDVO_CMD_GET_OUTPUT_TIMINGS_PART1, dtd);
}
-static bool intel_sdvo_set_timing(struct drm_output *output, u8 cmd,
+static bool intel_sdvo_set_timing(struct intel_output *intel_output, u8 cmd,
struct intel_sdvo_dtd *dtd)
{
u8 status;
- intel_sdvo_write_cmd(output, cmd, &dtd->part1, sizeof(dtd->part1));
- status = intel_sdvo_read_response(output, NULL, 0);
+ intel_sdvo_write_cmd(intel_output, cmd, &dtd->part1, sizeof(dtd->part1));
+ status = intel_sdvo_read_response(intel_output, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
- intel_sdvo_write_cmd(output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
- status = intel_sdvo_read_response(output, NULL, 0);
+ intel_sdvo_write_cmd(intel_output, cmd + 1, &dtd->part2, sizeof(dtd->part2));
+ status = intel_sdvo_read_response(intel_output, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
return true;
}
-static bool intel_sdvo_set_input_timing(struct drm_output *output,
+static bool intel_sdvo_set_input_timing(struct intel_output *intel_output,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_set_timing(output,
+ return intel_sdvo_set_timing(intel_output,
SDVO_CMD_SET_INPUT_TIMINGS_PART1, dtd);
}
-static bool intel_sdvo_set_output_timing(struct drm_output *output,
+static bool intel_sdvo_set_output_timing(struct intel_output *intel_output,
struct intel_sdvo_dtd *dtd)
{
- return intel_sdvo_set_timing(output,
+ return intel_sdvo_set_timing(intel_output,
SDVO_CMD_SET_OUTPUT_TIMINGS_PART1, dtd);
}
#if 0
-static bool intel_sdvo_get_preferred_input_timing(struct drm_output *output,
+static bool intel_sdvo_get_preferred_input_timing(struct intel_output *intel_output,
struct intel_sdvo_dtd *dtd)
{
- struct intel_output *intel_output = to_intel_output(output);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
u8 status;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART1,
NULL, 0);
- status = intel_sdvo_read_response(output, &dtd->part1,
+ status = intel_sdvo_read_response(intel_output, &dtd->part1,
sizeof(dtd->part1));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_PREFERRED_INPUT_TIMING_PART2,
NULL, 0);
- status = intel_sdvo_read_response(output, &dtd->part2,
+ status = intel_sdvo_read_response(intel_output, &dtd->part2,
sizeof(dtd->part2));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
@@ -516,12 +510,12 @@ static bool intel_sdvo_get_preferred_input_timing(struct drm_output *output,
}
#endif
-static int intel_sdvo_get_clock_rate_mult(struct drm_output *output)
+static int intel_sdvo_get_clock_rate_mult(struct intel_output *intel_output)
{
u8 response, status;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
- status = intel_sdvo_read_response(output, &response, 1);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_CLOCK_RATE_MULT, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, &response, 1);
if (status != SDVO_CMD_STATUS_SUCCESS) {
DRM_DEBUG("Couldn't get SDVO clock rate multiplier\n");
@@ -533,19 +527,19 @@ static int intel_sdvo_get_clock_rate_mult(struct drm_output *output)
return response;
}
-static bool intel_sdvo_set_clock_rate_mult(struct drm_output *output, u8 val)
+static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8 val)
{
u8 status;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
- status = intel_sdvo_read_response(output, NULL, 0);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_CLOCK_RATE_MULT, &val, 1);
+ status = intel_sdvo_read_response(intel_output, NULL, 0);
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
return true;
}
-static bool intel_sdvo_mode_fixup(struct drm_output *output,
+static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
@@ -556,15 +550,15 @@ static bool intel_sdvo_mode_fixup(struct drm_output *output,
return true;
}
-static void intel_sdvo_mode_set(struct drm_output *output,
+static void intel_sdvo_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = output->crtc;
+ struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = enc_to_intel_output(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
u16 width, height;
u16 h_blank_len, h_sync_len, v_blank_len, v_sync_len;
@@ -618,11 +612,11 @@ static void intel_sdvo_mode_set(struct drm_output *output,
output_dtd.part2.reserved = 0;
/* Set the output timing to the screen */
- intel_sdvo_set_target_output(output, sdvo_priv->active_outputs);
- intel_sdvo_set_output_timing(output, &output_dtd);
+ intel_sdvo_set_target_output(intel_output, sdvo_priv->active_outputs);
+ intel_sdvo_set_output_timing(intel_output, &output_dtd);
/* Set the input timing to the screen. Assume always input 0. */
- intel_sdvo_set_target_input(output, true, false);
+ intel_sdvo_set_target_input(intel_output, true, false);
/* We would like to use i830_sdvo_create_preferred_input_timing() to
* provide the device with a timing it can support, if it supports that
@@ -630,29 +624,29 @@ static void intel_sdvo_mode_set(struct drm_output *output,
* output the preferred timing, and we don't support that currently.
*/
#if 0
- success = intel_sdvo_create_preferred_input_timing(output, clock,
+ success = intel_sdvo_create_preferred_input_timing(intel_output, clock,
width, height);
if (success) {
struct intel_sdvo_dtd *input_dtd;
- intel_sdvo_get_preferred_input_timing(output, &input_dtd);
- intel_sdvo_set_input_timing(output, &input_dtd);
+ intel_sdvo_get_preferred_input_timing(intel_output, &input_dtd);
+ intel_sdvo_set_input_timing(intel_output, &input_dtd);
}
#else
- intel_sdvo_set_input_timing(output, &output_dtd);
+ intel_sdvo_set_input_timing(intel_output, &output_dtd);
#endif
switch (intel_sdvo_get_pixel_multiplier(mode)) {
case 1:
- intel_sdvo_set_clock_rate_mult(output,
+ intel_sdvo_set_clock_rate_mult(intel_output,
SDVO_CLOCK_RATE_MULT_1X);
break;
case 2:
- intel_sdvo_set_clock_rate_mult(output,
+ intel_sdvo_set_clock_rate_mult(intel_output,
SDVO_CLOCK_RATE_MULT_2X);
break;
case 4:
- intel_sdvo_set_clock_rate_mult(output,
+ intel_sdvo_set_clock_rate_mult(intel_output,
SDVO_CLOCK_RATE_MULT_4X);
break;
}
@@ -686,26 +680,26 @@ static void intel_sdvo_mode_set(struct drm_output *output,
sdvox |= (sdvo_pixel_multiply - 1) << SDVO_PORT_MULTIPLY_SHIFT;
}
- intel_sdvo_write_sdvox(output, sdvox);
+ intel_sdvo_write_sdvox(intel_output, sdvox);
}
-static void intel_sdvo_dpms(struct drm_output *output, int mode)
+static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = enc_to_intel_output(encoder);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
u32 temp;
if (mode != DPMSModeOn) {
- intel_sdvo_set_active_outputs(output, 0);
+ intel_sdvo_set_active_outputs(intel_output, 0);
if (0)
- intel_sdvo_set_encoder_power_state(output, mode);
+ intel_sdvo_set_encoder_power_state(intel_output, mode);
if (mode == DPMSModeOff) {
temp = I915_READ(sdvo_priv->output_device);
if ((temp & SDVO_ENABLE) != 0) {
- intel_sdvo_write_sdvox(output, temp & ~SDVO_ENABLE);
+ intel_sdvo_write_sdvox(intel_output, temp & ~SDVO_ENABLE);
}
}
} else {
@@ -715,11 +709,11 @@ static void intel_sdvo_dpms(struct drm_output *output, int mode)
temp = I915_READ(sdvo_priv->output_device);
if ((temp & SDVO_ENABLE) == 0)
- intel_sdvo_write_sdvox(output, temp | SDVO_ENABLE);
+ intel_sdvo_write_sdvox(intel_output, temp | SDVO_ENABLE);
for (i = 0; i < 2; i++)
intel_wait_for_vblank(dev);
- status = intel_sdvo_get_trained_inputs(output, &input1,
+ status = intel_sdvo_get_trained_inputs(intel_output, &input1,
&input2);
@@ -733,32 +727,32 @@ static void intel_sdvo_dpms(struct drm_output *output, int mode)
}
if (0)
- intel_sdvo_set_encoder_power_state(output, mode);
- intel_sdvo_set_active_outputs(output, sdvo_priv->active_outputs);
+ intel_sdvo_set_encoder_power_state(intel_output, mode);
+ intel_sdvo_set_active_outputs(intel_output, sdvo_priv->active_outputs);
}
return;
}
-static void intel_sdvo_save(struct drm_output *output)
+static void intel_sdvo_save(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
int o;
- sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(output);
- intel_sdvo_get_active_outputs(output, &sdvo_priv->save_active_outputs);
+ sdvo_priv->save_sdvo_mult = intel_sdvo_get_clock_rate_mult(intel_output);
+ intel_sdvo_get_active_outputs(intel_output, &sdvo_priv->save_active_outputs);
if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
- intel_sdvo_set_target_input(output, true, false);
- intel_sdvo_get_input_timing(output,
+ intel_sdvo_set_target_input(intel_output, true, false);
+ intel_sdvo_get_input_timing(intel_output,
&sdvo_priv->save_input_dtd_1);
}
if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
- intel_sdvo_set_target_input(output, false, true);
- intel_sdvo_get_input_timing(output,
+ intel_sdvo_set_target_input(intel_output, false, true);
+ intel_sdvo_get_input_timing(intel_output,
&sdvo_priv->save_input_dtd_2);
}
@@ -767,8 +761,8 @@ static void intel_sdvo_save(struct drm_output *output)
u16 this_output = (1 << o);
if (sdvo_priv->caps.output_flags & this_output)
{
- intel_sdvo_set_target_output(output, this_output);
- intel_sdvo_get_output_timing(output,
+ intel_sdvo_set_target_output(intel_output, this_output);
+ intel_sdvo_get_output_timing(intel_output,
&sdvo_priv->save_output_dtd[o]);
}
}
@@ -776,39 +770,39 @@ static void intel_sdvo_save(struct drm_output *output)
sdvo_priv->save_SDVOX = I915_READ(sdvo_priv->output_device);
}
-static void intel_sdvo_restore(struct drm_output *output)
+static void intel_sdvo_restore(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
int o;
int i;
bool input1, input2;
u8 status;
- intel_sdvo_set_active_outputs(output, 0);
+ intel_sdvo_set_active_outputs(intel_output, 0);
for (o = SDVO_OUTPUT_FIRST; o <= SDVO_OUTPUT_LAST; o++)
{
u16 this_output = (1 << o);
if (sdvo_priv->caps.output_flags & this_output) {
- intel_sdvo_set_target_output(output, this_output);
- intel_sdvo_set_output_timing(output, &sdvo_priv->save_output_dtd[o]);
+ intel_sdvo_set_target_output(intel_output, this_output);
+ intel_sdvo_set_output_timing(intel_output, &sdvo_priv->save_output_dtd[o]);
}
}
if (sdvo_priv->caps.sdvo_inputs_mask & 0x1) {
- intel_sdvo_set_target_input(output, true, false);
- intel_sdvo_set_input_timing(output, &sdvo_priv->save_input_dtd_1);
+ intel_sdvo_set_target_input(intel_output, true, false);
+ intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_1);
}
if (sdvo_priv->caps.sdvo_inputs_mask & 0x2) {
- intel_sdvo_set_target_input(output, false, true);
- intel_sdvo_set_input_timing(output, &sdvo_priv->save_input_dtd_2);
+ intel_sdvo_set_target_input(intel_output, false, true);
+ intel_sdvo_set_input_timing(intel_output, &sdvo_priv->save_input_dtd_2);
}
- intel_sdvo_set_clock_rate_mult(output, sdvo_priv->save_sdvo_mult);
+ intel_sdvo_set_clock_rate_mult(intel_output, sdvo_priv->save_sdvo_mult);
I915_WRITE(sdvo_priv->output_device, sdvo_priv->save_SDVOX);
@@ -816,19 +810,19 @@ static void intel_sdvo_restore(struct drm_output *output)
{
for (i = 0; i < 2; i++)
intel_wait_for_vblank(dev);
- status = intel_sdvo_get_trained_inputs(output, &input1, &input2);
+ status = intel_sdvo_get_trained_inputs(intel_output, &input1, &input2);
if (status == SDVO_CMD_STATUS_SUCCESS && !input1)
DRM_DEBUG("First %s output reported failure to sync\n",
SDVO_NAME(sdvo_priv));
}
- intel_sdvo_set_active_outputs(output, sdvo_priv->save_active_outputs);
+ intel_sdvo_set_active_outputs(intel_output, sdvo_priv->save_active_outputs);
}
-static int intel_sdvo_mode_valid(struct drm_output *output,
+static int intel_sdvo_mode_valid(struct drm_connector *connector,
struct drm_display_mode *mode)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
if (mode->flags & V_DBLSCAN)
@@ -843,27 +837,27 @@ static int intel_sdvo_mode_valid(struct drm_output *output,
return MODE_OK;
}
-static bool intel_sdvo_get_capabilities(struct drm_output *output, struct intel_sdvo_caps *caps)
+static bool intel_sdvo_get_capabilities(struct intel_output *intel_output, struct intel_sdvo_caps *caps)
{
u8 status;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
- status = intel_sdvo_read_response(output, caps, sizeof(*caps));
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_DEVICE_CAPS, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, caps, sizeof(*caps));
if (status != SDVO_CMD_STATUS_SUCCESS)
return false;
return true;
}
-struct drm_output* intel_sdvo_find(struct drm_device *dev, int sdvoB)
+struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB)
{
- struct drm_output *output = 0;
- struct intel_output *iout = 0;
+ struct drm_connector *connector = NULL;
+ struct intel_output *iout = NULL;
struct intel_sdvo_priv *sdvo;
- /* find the sdvo output */
- list_for_each_entry(output, &dev->mode_config.output_list, head) {
- iout = to_intel_output(output);
+ /* find the sdvo connector */
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ iout = to_intel_output(connector);
if (iout->type != INTEL_OUTPUT_SDVO)
continue;
@@ -871,27 +865,30 @@ struct drm_output* intel_sdvo_find(struct drm_device *dev, int sdvoB)
sdvo = iout->dev_priv;
if (sdvo->output_device == SDVOB && sdvoB)
- return output;
+ return connector;
if (sdvo->output_device == SDVOC && !sdvoB)
- return output;
+ return connector;
- }
-
- return 0;
+ }
+
+ return NULL;
}
-int intel_sdvo_supports_hotplug(struct drm_output *output)
+int intel_sdvo_supports_hotplug(struct drm_connector *connector)
{
u8 response[2];
u8 status;
+ struct intel_output *intel_output;
DRM_DEBUG("\n");
- if (!output)
+ if (!connector)
return 0;
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
- status = intel_sdvo_read_response(output, &response, 2);
+ intel_output = to_intel_output(connector);
+
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, &response, 2);
if (response[0] !=0)
return 1;
@@ -899,51 +896,55 @@ int intel_sdvo_supports_hotplug(struct drm_output *output)
return 0;
}
-void intel_sdvo_set_hotplug(struct drm_output *output, int on)
+void intel_sdvo_set_hotplug(struct drm_connector *connector, int on)
{
u8 response[2];
u8 status;
+ struct intel_output *intel_output = to_intel_output(connector);
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
- intel_sdvo_read_response(output, &response, 2);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+ intel_sdvo_read_response(intel_output, &response, 2);
if (on) {
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
- status = intel_sdvo_read_response(output, &response, 2);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_HOT_PLUG_SUPPORT, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, &response, 2);
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
} else {
response[0] = 0;
response[1] = 0;
- intel_sdvo_write_cmd(output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_SET_ACTIVE_HOT_PLUG, &response, 2);
}
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
- intel_sdvo_read_response(output, &response, 2);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ACTIVE_HOT_PLUG, NULL, 0);
+ intel_sdvo_read_response(intel_output, &response, 2);
}
-static enum drm_output_status intel_sdvo_detect(struct drm_output *output)
+static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connector)
{
u8 response[2];
u8 status;
+ struct intel_output *intel_output = to_intel_output(connector);
- intel_sdvo_write_cmd(output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
- status = intel_sdvo_read_response(output, &response, 2);
+ intel_sdvo_write_cmd(intel_output, SDVO_CMD_GET_ATTACHED_DISPLAYS, NULL, 0);
+ status = intel_sdvo_read_response(intel_output, &response, 2);
DRM_DEBUG("SDVO response %d %d\n", response[0], response[1]);
if ((response[0] != 0) || (response[1] != 0))
- return output_status_connected;
+ return connector_status_connected;
else
- return output_status_disconnected;
+ return connector_status_disconnected;
}
-static int intel_sdvo_get_modes(struct drm_output *output)
+static int intel_sdvo_get_modes(struct drm_connector *connector)
{
+ struct intel_output *intel_output = to_intel_output(connector);
+
/* set the bus switch and get the modes */
- intel_sdvo_set_control_bus_switch(output, SDVO_CONTROL_BUS_DDC2);
- intel_ddc_get_modes(output);
+ intel_sdvo_set_control_bus_switch(intel_output, SDVO_CONTROL_BUS_DDC2);
+ intel_ddc_get_modes(intel_output);
- if (list_empty(&output->probed_modes))
+ if (list_empty(&connector->probed_modes))
return 0;
return 1;
#if 0
@@ -959,60 +960,75 @@ static int intel_sdvo_get_modes(struct drm_output *output)
#endif
}
-static void intel_sdvo_destroy(struct drm_output *output)
+static void intel_sdvo_destroy(struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
if (intel_output->i2c_bus)
intel_i2c_destroy(intel_output->i2c_bus);
- drm_output_cleanup(output);
+ drm_connector_cleanup(connector);
kfree(intel_output);
}
-static const struct drm_output_helper_funcs intel_sdvo_helper_funcs = {
+static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
+ .dpms = intel_sdvo_dpms,
.mode_fixup = intel_sdvo_mode_fixup,
- .prepare = intel_output_prepare,
+ .prepare = intel_encoder_prepare,
.mode_set = intel_sdvo_mode_set,
- .commit = intel_output_commit,
+ .commit = intel_encoder_commit,
};
-static const struct drm_output_funcs intel_sdvo_output_funcs = {
- .dpms = intel_sdvo_dpms,
+static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
.save = intel_sdvo_save,
.restore = intel_sdvo_restore,
.detect = intel_sdvo_detect,
- .get_modes = intel_sdvo_get_modes,
+ .fill_modes = drm_helper_probe_single_connector_modes,
.destroy = intel_sdvo_destroy,
+};
+
+static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
+ .get_modes = intel_sdvo_get_modes,
.mode_valid = intel_sdvo_mode_valid,
+ .best_encoder = intel_best_encoder,
};
+void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs intel_sdvo_enc_funcs = {
+ .destroy = intel_sdvo_enc_destroy,
+};
+
+
void intel_sdvo_init(struct drm_device *dev, int output_device)
{
- struct drm_output *output;
+ struct drm_connector *connector;
struct intel_output *intel_output;
struct intel_sdvo_priv *sdvo_priv;
struct intel_i2c_chan *i2cbus = NULL;
int connector_type;
u8 ch[0x40];
int i;
- int output_type, output_id;
+ int encoder_type, output_id;
intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL);
if (!intel_output) {
return;
}
- output = &intel_output->base;
-
- drm_output_init(dev, output, &intel_sdvo_output_funcs,
- DRM_MODE_OUTPUT_NONE);
+ connector = &intel_output->base;
+ drm_connector_init(dev, connector, &intel_sdvo_connector_funcs,
+ DRM_MODE_CONNECTOR_Unknown);
+ drm_connector_helper_add(connector, &intel_sdvo_connector_helper_funcs);
sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
intel_output->type = INTEL_OUTPUT_SDVO;
- drm_output_helper_add(output, &intel_sdvo_helper_funcs);
- output->interlace_allowed = 0;
- output->doublescan_allowed = 0;
+
+ connector->interlace_allowed = 0;
+ connector->doublescan_allowed = 0;
/* setup the DDC bus. */
if (output_device == SDVOB)
@@ -1021,7 +1037,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC");
if (i2cbus == NULL) {
- intel_sdvo_destroy(output);
+ intel_sdvo_destroy(connector);
return;
}
@@ -1042,15 +1058,15 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
/* Read the regs to test if we can talk to the device */
for (i = 0; i < 0x40; i++) {
- if (!intel_sdvo_read_byte(output, i, &ch[i])) {
+ if (!intel_sdvo_read_byte(intel_output, i, &ch[i])) {
DRM_DEBUG("No SDVO device found on SDVO%c\n",
output_device == SDVOB ? 'B' : 'C');
- intel_sdvo_destroy(output);
+ intel_sdvo_destroy(connector);
return;
}
}
- intel_sdvo_get_capabilities(output, &sdvo_priv->caps);
+ intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps);
memset(&sdvo_priv->active_outputs, 0, sizeof(sdvo_priv->active_outputs));
@@ -1058,30 +1074,30 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB0)
{
sdvo_priv->active_outputs = SDVO_OUTPUT_RGB0;
- output->display_info.subpixel_order = SubPixelHorizontalRGB;
- output_type = DRM_MODE_OUTPUT_DAC;
- connector_type = ConnectorVGA;
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ encoder_type = DRM_MODE_ENCODER_DAC;
+ connector_type = DRM_MODE_CONNECTOR_VGA;
}
else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_RGB1)
{
sdvo_priv->active_outputs = SDVO_OUTPUT_RGB1;
- output->display_info.subpixel_order = SubPixelHorizontalRGB;
- output_type = DRM_MODE_OUTPUT_DAC;
- connector_type = ConnectorVGA;
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ encoder_type = DRM_MODE_ENCODER_DAC;
+ connector_type = DRM_MODE_CONNECTOR_VGA;
}
else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS0)
{
sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS0;
- output->display_info.subpixel_order = SubPixelHorizontalRGB;
- output_type = DRM_MODE_OUTPUT_TMDS;
- connector_type = ConnectorDVID;
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ encoder_type = DRM_MODE_ENCODER_TMDS;
+ connector_type = DRM_MODE_CONNECTOR_DVID;
}
else if (sdvo_priv->caps.output_flags & SDVO_OUTPUT_TMDS1)
{
sdvo_priv->active_outputs = SDVO_OUTPUT_TMDS1;
- output->display_info.subpixel_order = SubPixelHorizontalRGB;
- output_type = DRM_MODE_OUTPUT_TMDS;
- connector_type = ConnectorDVID;
+ connector->display_info.subpixel_order = SubPixelHorizontalRGB;
+ encoder_type = DRM_MODE_ENCODER_TMDS;
+ connector_type = DRM_MODE_CONNECTOR_DVID;
}
else
{
@@ -1091,19 +1107,21 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
DRM_DEBUG("%s: No active RGB or TMDS outputs (0x%02x%02x)\n",
SDVO_NAME(sdvo_priv),
bytes[0], bytes[1]);
- intel_sdvo_destroy(output);
+ intel_sdvo_destroy(connector);
return;
}
- output->output_type = output_type;
- output->output_type_id = output_id;
+ drm_encoder_init(dev, &intel_output->enc, &intel_sdvo_enc_funcs, encoder_type);
+ drm_encoder_helper_add(&intel_output->enc, &intel_sdvo_helper_funcs);
+ connector->connector_type = connector_type;
- drm_sysfs_output_add(output);
+ drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
+ drm_sysfs_connector_add(connector);
/* Set the input timing to the screen. Assume always input 0. */
- intel_sdvo_set_target_input(output, true, false);
+ intel_sdvo_set_target_input(intel_output, true, false);
- intel_sdvo_get_input_pixel_clock_range(output,
+ intel_sdvo_get_input_pixel_clock_range(intel_output,
&sdvo_priv->pixel_clock_min,
&sdvo_priv->pixel_clock_max);
@@ -1127,5 +1145,4 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
intel_output->ddc_bus = i2cbus;
- drm_output_attach_property(output, dev->mode_config.connector_type_property, connector_type);
}
diff --git a/linux-core/intel_tv.c b/linux-core/intel_tv.c
index e3e78a9f..e45cfa3b 100644
--- a/linux-core/intel_tv.c
+++ b/linux-core/intel_tv.c
@@ -898,9 +898,9 @@ const static struct tv_mode tv_modes[] = {
#define NUM_TV_MODES sizeof(tv_modes) / sizeof (tv_modes[0])
static void
-intel_tv_dpms(struct drm_output *output, int mode)
+intel_tv_dpms(struct drm_encoder *encoder, int mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
switch(mode) {
@@ -916,11 +916,11 @@ intel_tv_dpms(struct drm_output *output, int mode)
}
static void
-intel_tv_save(struct drm_output *output)
+intel_tv_save(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
int i;
@@ -966,13 +966,13 @@ intel_tv_save(struct drm_output *output)
}
static void
-intel_tv_restore(struct drm_output *output)
+intel_tv_restore(struct drm_connector *connector)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = connector->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
- struct drm_crtc *crtc = output->crtc;
+ struct drm_crtc *crtc = connector->encoder->crtc;
struct intel_crtc *intel_crtc;
int i;
@@ -1067,18 +1067,18 @@ intel_tv_mode_lookup (char *tv_format)
}
static const struct tv_mode *
-intel_tv_mode_find (struct drm_output *output)
+intel_tv_mode_find (struct intel_output *intel_output)
{
- struct intel_output *intel_output = to_intel_output(output);
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
return intel_tv_mode_lookup(tv_priv->tv_format);
}
static enum drm_mode_status
-intel_tv_mode_valid(struct drm_output *output, struct drm_display_mode *mode)
+intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mode)
{
- const struct tv_mode *tv_mode = intel_tv_mode_find(output);
+ struct intel_output *intel_output = to_intel_output(connector);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
/* Ensure TV refresh is close to desired refresh */
if (tv_mode && abs(tv_mode->refresh - drm_mode_vrefresh(mode)) < 1)
@@ -1088,21 +1088,22 @@ intel_tv_mode_valid(struct drm_output *output, struct drm_display_mode *mode)
static bool
-intel_tv_mode_fixup(struct drm_output *output, struct drm_display_mode *mode,
+intel_tv_mode_fixup(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_mode_config *drm_config = &dev->mode_config;
- const struct tv_mode *tv_mode = intel_tv_mode_find (output);
- struct drm_output *other_output;
+ struct intel_output *intel_output = enc_to_intel_output(encoder);
+ const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
+ struct drm_encoder *other_encoder;
if (!tv_mode)
return FALSE;
- /* FIXME: lock output list */
- list_for_each_entry(other_output, &drm_config->output_list, head) {
- if (other_output != output &&
- other_output->crtc == output->crtc)
+ /* FIXME: lock encoder list */
+ list_for_each_entry(other_encoder, &drm_config->encoder_list, head) {
+ if (other_encoder != encoder &&
+ other_encoder->crtc == encoder->crtc)
return FALSE;
}
@@ -1111,16 +1112,16 @@ intel_tv_mode_fixup(struct drm_output *output, struct drm_display_mode *mode,
}
static void
-intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
+intel_tv_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
- struct drm_device *dev = output->dev;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_crtc *crtc = output->crtc;
+ struct drm_crtc *crtc = encoder->crtc;
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = enc_to_intel_output(encoder);
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
- const struct tv_mode *tv_mode = intel_tv_mode_find(output);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
u32 tv_ctl;
u32 hctl1, hctl2, hctl3;
u32 vctl1, vctl2, vctl3, vctl4, vctl5, vctl6, vctl7;
@@ -1137,14 +1138,14 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
switch (tv_priv->type) {
default:
- case ConnectorUnknown:
- case ConnectorComposite:
+ case DRM_MODE_CONNECTOR_Unknown:
+ case DRM_MODE_CONNECTOR_Composite:
tv_ctl |= TV_ENC_OUTPUT_COMPOSITE;
video_levels = tv_mode->composite_levels;
color_conversion = tv_mode->composite_color;
burst_ena = tv_mode->burst_ena;
break;
- case ConnectorComponent:
+ case DRM_MODE_CONNECTOR_Component:
tv_ctl |= TV_ENC_OUTPUT_COMPONENT;
video_levels = &component_levels;
if (tv_mode->burst_ena)
@@ -1153,7 +1154,7 @@ intel_tv_mode_set(struct drm_output *output, struct drm_display_mode *mode,
color_conversion = &hdtv_csc_yprpb;
burst_ena = FALSE;
break;
- case ConnectorSVIDEO:
+ case DRM_MODE_CONNECTOR_SVIDEO:
tv_ctl |= TV_ENC_OUTPUT_SVIDEO;
video_levels = tv_mode->svideo_levels;
color_conversion = tv_mode->svideo_color;
@@ -1355,15 +1356,15 @@ static const struct drm_display_mode reported_modes[] = {
* \return FALSE if TV is disconnected.
*/
static int
-intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output)
+intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
{
- struct drm_device *dev = output->dev;
+ struct drm_encoder *encoder = &intel_output->enc;
+ struct drm_device *dev = encoder->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_output *intel_output = to_intel_output(output);
u32 pipeastat, pipeastat_save;
u32 tv_ctl, save_tv_ctl;
u32 tv_dac, save_tv_dac;
- int type = ConnectorUnknown;
+ int type = DRM_MODE_CONNECTOR_Unknown;
tv_dac = I915_READ(TV_DAC);
@@ -1410,13 +1411,13 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output)
*/
if ((tv_dac & TVDAC_SENSE_MASK) == (TVDAC_B_SENSE | TVDAC_C_SENSE)) {
DRM_DEBUG("Detected Composite TV connection\n");
- type = ConnectorComposite;
+ type = DRM_MODE_CONNECTOR_Composite;
} else if ((tv_dac & (TVDAC_A_SENSE|TVDAC_B_SENSE)) == TVDAC_A_SENSE) {
DRM_DEBUG("Detected S-Video TV connection\n");
- type = ConnectorSVIDEO;
+ type = DRM_MODE_CONNECTOR_SVIDEO;
} else if ((tv_dac & TVDAC_SENSE_MASK) == 0) {
DRM_DEBUG("Detected Component TV connection\n");
- type = ConnectorComponent;
+ type = DRM_MODE_CONNECTOR_Component;
} else {
DRM_DEBUG("No TV connection detected\n");
type = -1;
@@ -1432,46 +1433,48 @@ intel_tv_detect_type (struct drm_crtc *crtc, struct drm_output *output)
/**
* Detect the TV connection.
*
- * Currently this always returns OUTPUT_STATUS_UNKNOWN, as we need to be sure
+ * Currently this always returns CONNECTOR_STATUS_UNKNOWN, as we need to be sure
* we have a pipe programmed in order to probe the TV.
*/
-static enum drm_output_status
-intel_tv_detect(struct drm_output *output)
+static enum drm_connector_status
+intel_tv_detect(struct drm_connector *connector)
{
struct drm_crtc *crtc;
struct drm_display_mode mode;
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
+ struct drm_encoder *encoder = &intel_output->enc;
int dpms_mode;
int type = tv_priv->type;
mode = reported_modes[0];
drm_mode_set_crtcinfo(&mode, CRTC_INTERLACE_HALVE_V);
- if (output->crtc) {
- type = intel_tv_detect_type(output->crtc, output);
+ if (encoder->crtc) {
+ type = intel_tv_detect_type(encoder->crtc, intel_output);
} else {
- crtc = intel_get_load_detect_pipe(output, &mode, &dpms_mode);
+ crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
if (crtc) {
- type = intel_tv_detect_type(crtc, output);
- intel_release_load_detect_pipe(output, dpms_mode);
+ type = intel_tv_detect_type(crtc, intel_output);
+ intel_release_load_detect_pipe(intel_output, dpms_mode);
} else
type = -1;
}
+#if 0
if (type != tv_priv->type) {
struct drm_property *connector_property =
- output->dev->mode_config.connector_type_property;
+ connector->dev->mode_config.connector_type_property;
tv_priv->type = type;
- drm_output_property_set_value(output, connector_property,
+ drm_connector_property_set_value(connector, connector_property,
type);
}
-
+#endif
if (type < 0)
- return output_status_disconnected;
+ return connector_status_disconnected;
- return output_status_connected;
+ return connector_status_connected;
}
static struct input_res {
@@ -1496,10 +1499,11 @@ static struct input_res {
*/
static int
-intel_tv_get_modes(struct drm_output *output)
+intel_tv_get_modes(struct drm_connector *connector)
{
struct drm_display_mode *mode_ptr;
- const struct tv_mode *tv_mode = intel_tv_mode_find(output);
+ struct intel_output *intel_output = to_intel_output(connector);
+ const struct tv_mode *tv_mode = intel_tv_mode_find(intel_output);
int j;
for (j = 0; j < sizeof(input_res_table) / sizeof(input_res_table[0]);
@@ -1538,33 +1542,33 @@ intel_tv_get_modes(struct drm_output *output)
mode_ptr->htotal / 1000) / 1000;
mode_ptr->type = DRM_MODE_TYPE_DRIVER;
- drm_mode_probed_add(output, mode_ptr);
+ drm_mode_probed_add(connector, mode_ptr);
}
return 0;
}
static void
-intel_tv_destroy (struct drm_output *output)
+intel_tv_destroy (struct drm_connector *connector)
{
- struct intel_output *intel_output = to_intel_output(output);
+ struct intel_output *intel_output = to_intel_output(connector);
- drm_output_cleanup(output);
+ drm_connector_cleanup(connector);
drm_free(intel_output, sizeof(struct intel_output) + sizeof(struct intel_tv_priv),
DRM_MEM_DRIVER);
}
static bool
-intel_tv_set_property(struct drm_output *output, struct drm_property *property,
+intel_tv_set_property(struct drm_connector *connector, struct drm_property *property,
uint64_t val)
{
- struct drm_device *dev = output->dev;
- struct intel_output *intel_output = to_intel_output(output);
+ struct drm_device *dev = connector->dev;
+ struct intel_output *intel_output = to_intel_output(connector);
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
int ret = 0;
- ret = drm_output_property_set_value(output, property, val);
+ ret = drm_connector_property_set_value(connector, property, val);
if (ret < 0)
goto out;
@@ -1582,40 +1586,55 @@ intel_tv_set_property(struct drm_output *output, struct drm_property *property,
goto out;
}
tv_priv->tv_format = tv_modes[val].name;
- intel_tv_mode_set(output, NULL, NULL);
+ intel_tv_mode_set(&intel_output->enc, NULL, NULL);
} else {
ret = -EINVAL;
goto out;
}
- intel_tv_mode_set(output, NULL, NULL);
+ intel_tv_mode_set(&intel_output->enc, NULL, NULL);
out:
return ret;
}
-static const struct drm_output_helper_funcs intel_tv_helper_funcs = {
+static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
+ .dpms = intel_tv_dpms,
.mode_fixup = intel_tv_mode_fixup,
- .prepare = intel_output_prepare,
+ .prepare = intel_encoder_prepare,
.mode_set = intel_tv_mode_set,
- .commit = intel_output_commit,
+ .commit = intel_encoder_commit,
};
-static const struct drm_output_funcs intel_tv_output_funcs = {
- .dpms = intel_tv_dpms,
+static const struct drm_connector_funcs intel_tv_connector_funcs = {
.save = intel_tv_save,
.restore = intel_tv_restore,
- .mode_valid = intel_tv_mode_valid,
.detect = intel_tv_detect,
- .get_modes = intel_tv_get_modes,
.destroy = intel_tv_destroy,
.set_property = intel_tv_set_property,
+ .fill_modes = drm_helper_probe_single_connector_modes,
+};
+
+static const struct drm_connector_helper_funcs intel_tv_connector_helper_funcs = {
+ .mode_valid = intel_tv_mode_valid,
+ .get_modes = intel_tv_get_modes,
+ .best_encoder = intel_best_encoder,
};
+void intel_tv_enc_destroy(struct drm_encoder *encoder)
+{
+ drm_encoder_cleanup(encoder);
+}
+
+static const struct drm_encoder_funcs intel_tv_enc_funcs = {
+ .destroy = intel_tv_enc_destroy,
+};
+
+
void
intel_tv_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct drm_output *output;
+ struct drm_connector *connector;
struct intel_output *intel_output;
struct intel_tv_priv *tv_priv;
u32 tv_dac_on, tv_dac_off, save_tv_dac;
@@ -1657,17 +1676,21 @@ intel_tv_init(struct drm_device *dev)
if (!intel_output) {
return;
}
- output = &intel_output->base;
+ connector = &intel_output->base;
- drm_output_init(dev, output, &intel_tv_output_funcs,
- DRM_MODE_OUTPUT_TVDAC);
+ drm_connector_init(dev, connector, &intel_tv_connector_funcs,
+ DRM_MODE_CONNECTOR_Unknown);
+ drm_encoder_init(dev, &intel_output->enc, &intel_tv_enc_funcs,
+ DRM_MODE_ENCODER_TVDAC);
+
+ drm_mode_connector_attach_encoder(&intel_output->base, &intel_output->enc);
tv_priv = (struct intel_tv_priv *)(intel_output + 1);
intel_output->type = INTEL_OUTPUT_TVOUT;
- output->possible_crtcs = ((1 << 0) | (1 << 1));
- output->possible_clones = (1 << INTEL_OUTPUT_TVOUT);
+ intel_output->enc.possible_crtcs = ((1 << 0) | (1 << 1));
+ intel_output->enc.possible_clones = (1 << INTEL_OUTPUT_TVOUT);
intel_output->dev_priv = tv_priv;
- tv_priv->type = ConnectorUnknown;
+ tv_priv->type = DRM_MODE_CONNECTOR_Unknown;
/* BIOS margin values */
tv_priv->margin[TV_MARGIN_LEFT] = 54;
@@ -1677,13 +1700,10 @@ intel_tv_init(struct drm_device *dev)
tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
- drm_output_helper_add(output, &intel_tv_helper_funcs);
- output->interlace_allowed = FALSE;
- output->doublescan_allowed = FALSE;
-
- drm_output_attach_property(output,
- dev->mode_config.connector_type_property,
- ConnectorUnknown);
+ drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
+ drm_connector_helper_add(connector, &intel_tv_connector_helper_funcs);
+ connector->interlace_allowed = FALSE;
+ connector->doublescan_allowed = FALSE;
/* Create TV properties then attach current values */
tv_format_names = drm_alloc(sizeof(char *) * NUM_TV_MODES,
@@ -1694,20 +1714,20 @@ intel_tv_init(struct drm_device *dev)
tv_format_names[i] = tv_modes[i].name;
drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names);
- drm_output_attach_property(output, dev->mode_config.tv_mode_property,
+ drm_connector_attach_property(connector, dev->mode_config.tv_mode_property,
initial_mode);
- drm_output_attach_property(output,
+ drm_connector_attach_property(connector,
dev->mode_config.tv_left_margin_property,
tv_priv->margin[TV_MARGIN_LEFT]);
- drm_output_attach_property(output,
+ drm_connector_attach_property(connector,
dev->mode_config.tv_top_margin_property,
tv_priv->margin[TV_MARGIN_TOP]);
- drm_output_attach_property(output,
+ drm_connector_attach_property(connector,
dev->mode_config.tv_right_margin_property,
tv_priv->margin[TV_MARGIN_RIGHT]);
- drm_output_attach_property(output,
+ drm_connector_attach_property(connector,
dev->mode_config.tv_bottom_margin_property,
tv_priv->margin[TV_MARGIN_BOTTOM]);
out:
- drm_sysfs_output_add(output);
+ drm_sysfs_connector_add(connector);
}