[modesetting-101] Add subconnector and select_subconnector properties.
- These facilitate DVI-I and tv-out that can drive multiple types of signals.main
parent
142a309604
commit
b29578103f
|
@ -60,6 +60,48 @@ char *drm_get_dpms_name(int val)
|
|||
return "unknown";
|
||||
}
|
||||
|
||||
static struct drm_prop_enum_list drm_select_subconnector_enum_list[] =
|
||||
{
|
||||
{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
|
||||
{ DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
|
||||
{ DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
|
||||
{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
|
||||
{ DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
|
||||
{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
|
||||
};
|
||||
|
||||
char *drm_get_select_subconnector_name(int val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(drm_select_subconnector_enum_list); i++)
|
||||
if (drm_select_subconnector_enum_list[i].type == val)
|
||||
return drm_select_subconnector_enum_list[i].name;
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static struct drm_prop_enum_list drm_subconnector_enum_list[] =
|
||||
{
|
||||
{ DRM_MODE_SUBCONNECTOR_Unknown, "Unknown" }, /* DVI-I and TV-out */
|
||||
{ DRM_MODE_SUBCONNECTOR_DVID, "DVI-D" }, /* DVI-I */
|
||||
{ DRM_MODE_SUBCONNECTOR_DVIA, "DVI-A" }, /* DVI-I */
|
||||
{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
|
||||
{ DRM_MODE_SUBCONNECTOR_SVIDEO, "SVIDEO" }, /* TV-out */
|
||||
{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
|
||||
};
|
||||
|
||||
char *drm_get_subconnector_name(int val)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(drm_subconnector_enum_list); i++)
|
||||
if (drm_subconnector_enum_list[i].type == val)
|
||||
return drm_subconnector_enum_list[i].name;
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
static struct drm_prop_enum_list drm_connector_enum_list[] =
|
||||
{ { DRM_MODE_CONNECTOR_Unknown, "Unknown" },
|
||||
{ DRM_MODE_CONNECTOR_VGA, "VGA" },
|
||||
|
@ -497,6 +539,38 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* drm_mode_create_dvi_i_properties - create DVI-I specific connector properties
|
||||
* @dev: DRM device
|
||||
*
|
||||
* Called by a driver the first time a DVI-I connector is made.
|
||||
*/
|
||||
int drm_mode_create_dvi_i_properties(struct drm_device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dev->mode_config.dvi_i_select_subconnector_property)
|
||||
return 0;
|
||||
|
||||
dev->mode_config.dvi_i_select_subconnector_property = drm_property_create(dev, DRM_MODE_PROP_ENUM,
|
||||
"select subconnector", 3);
|
||||
/* add enum element 0-2 */
|
||||
for (i = 0; i < 3; i++)
|
||||
drm_property_add_enum(dev->mode_config.dvi_i_select_subconnector_property, i, drm_select_subconnector_enum_list[i].type,
|
||||
drm_select_subconnector_enum_list[i].name);
|
||||
|
||||
/* This is a property which indicates the most likely thing to be connected. */
|
||||
dev->mode_config.dvi_i_subconnector_property = drm_property_create(dev, DRM_MODE_PROP_ENUM | DRM_MODE_PROP_IMMUTABLE,
|
||||
"subconnector", 3);
|
||||
/* add enum element 0-2 */
|
||||
for (i = 0; i < 3; i++)
|
||||
drm_property_add_enum(dev->mode_config.dvi_i_subconnector_property, i, drm_subconnector_enum_list[i].type,
|
||||
drm_subconnector_enum_list[i].name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_mode_create_dvi_i_properties);
|
||||
|
||||
/**
|
||||
* drm_create_tv_properties - create TV specific connector properties
|
||||
* @dev: DRM device
|
||||
|
@ -508,11 +582,29 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev)
|
|||
* responsible for allocating a list of format names and passing them to
|
||||
* this routine.
|
||||
*/
|
||||
bool drm_create_tv_properties(struct drm_device *dev, int num_modes,
|
||||
int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
|
||||
char *modes[])
|
||||
{
|
||||
int i;
|
||||
|
||||
if (dev->mode_config.tv_select_subconnector_property) /* already done */
|
||||
return 0;
|
||||
|
||||
dev->mode_config.tv_select_subconnector_property = drm_property_create(dev, DRM_MODE_PROP_ENUM,
|
||||
"select subconnector", 4);
|
||||
/* add enum element 3-5 */
|
||||
for (i = 1; i < 4; i++)
|
||||
drm_property_add_enum(dev->mode_config.tv_select_subconnector_property, i, drm_select_subconnector_enum_list[i + 2].type,
|
||||
drm_select_subconnector_enum_list[i + 2].name);
|
||||
|
||||
/* This is a property which indicates the most likely thing to be connected. */
|
||||
dev->mode_config.tv_subconnector_property = drm_property_create(dev, DRM_MODE_PROP_ENUM | DRM_MODE_PROP_IMMUTABLE,
|
||||
"subconnector", 4);
|
||||
/* add enum element 3-5 */
|
||||
for (i = 1; i < 4; i++)
|
||||
drm_property_add_enum(dev->mode_config.tv_subconnector_property, i, drm_subconnector_enum_list[i + 2].type,
|
||||
drm_subconnector_enum_list[i + 2].name);
|
||||
|
||||
dev->mode_config.tv_left_margin_property =
|
||||
drm_property_create(dev, DRM_MODE_PROP_RANGE |
|
||||
DRM_MODE_PROP_IMMUTABLE,
|
||||
|
@ -547,7 +639,7 @@ bool drm_create_tv_properties(struct drm_device *dev, int num_modes,
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(drm_create_tv_properties);
|
||||
EXPORT_SYMBOL(drm_mode_create_tv_properties);
|
||||
|
||||
/**
|
||||
* drm_mode_config_init - initialize DRM mode_configuration structure
|
||||
|
|
|
@ -170,6 +170,14 @@ struct drm_display_mode {
|
|||
#define DPMSModeSuspend 2
|
||||
#define DPMSModeOff 3
|
||||
|
||||
#define DRM_MODE_SUBCONNECTOR_Automatic 0
|
||||
#define DRM_MODE_SUBCONNECTOR_Unknown 0
|
||||
#define DRM_MODE_SUBCONNECTOR_DVID 3
|
||||
#define DRM_MODE_SUBCONNECTOR_DVIA 4
|
||||
#define DRM_MODE_SUBCONNECTOR_Composite 5
|
||||
#define DRM_MODE_SUBCONNECTOR_SVIDEO 6
|
||||
#define DRM_MODE_SUBCONNECTOR_Component 8
|
||||
|
||||
#define DRM_MODE_CONNECTOR_Unknown 0
|
||||
#define DRM_MODE_CONNECTOR_VGA 1
|
||||
#define DRM_MODE_CONNECTOR_DVII 2
|
||||
|
@ -571,7 +579,13 @@ struct drm_mode_config {
|
|||
struct drm_property *edid_property;
|
||||
struct drm_property *dpms_property;
|
||||
|
||||
/* optional properties */
|
||||
struct drm_property *dvi_i_subconnector_property;
|
||||
struct drm_property *dvi_i_select_subconnector_property;
|
||||
|
||||
/* TV properties */
|
||||
struct drm_property *tv_subconnector_property;
|
||||
struct drm_property *tv_select_subconnector_property;
|
||||
struct drm_property *tv_mode_property;
|
||||
struct drm_property *tv_left_margin_property;
|
||||
struct drm_property *tv_right_margin_property;
|
||||
|
@ -612,6 +626,8 @@ 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 char *drm_get_select_subconnector_name(int val);
|
||||
extern char *drm_get_subconnector_name(int val);
|
||||
extern void drm_fb_release(struct file *filp);
|
||||
extern int drm_mode_group_init_legacy_group(struct drm_device *dev, struct drm_mode_group *group);
|
||||
extern struct edid *drm_get_edid(struct drm_connector *connector,
|
||||
|
@ -674,7 +690,8 @@ extern struct drm_property *drm_property_create(struct drm_device *dev, int flag
|
|||
extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
|
||||
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,
|
||||
extern int drm_mode_create_dvi_i_properties(struct drm_device *dev);
|
||||
extern int drm_mode_create_tv_properties(struct drm_device *dev, int num_formats,
|
||||
char *formats[]);
|
||||
extern char *drm_get_encoder_name(struct drm_encoder *encoder);
|
||||
|
||||
|
|
|
@ -231,6 +231,78 @@ static ssize_t modes_show(struct device *device,
|
|||
return written;
|
||||
}
|
||||
|
||||
static ssize_t subconnector_show(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct drm_connector *connector = container_of(device, struct drm_connector, kdev);
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_property *prop = NULL;
|
||||
uint64_t subconnector;
|
||||
int ret;
|
||||
|
||||
switch (connector->connector_type) {
|
||||
case DRM_MODE_CONNECTOR_DVII:
|
||||
prop = dev->mode_config.dvi_i_subconnector_property;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_Composite:
|
||||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
case DRM_MODE_CONNECTOR_Component:
|
||||
prop = dev->mode_config.tv_subconnector_property;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Wrong connector type for this property\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!prop) {
|
||||
DRM_ERROR("Unable to find subconnector property\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = drm_connector_property_get_value(connector, prop, &subconnector);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s", drm_get_subconnector_name((int)subconnector));
|
||||
}
|
||||
|
||||
static ssize_t select_subconnector_show(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct drm_connector *connector = container_of(device, struct drm_connector, kdev);
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_property *prop = NULL;
|
||||
uint64_t subconnector;
|
||||
int ret;
|
||||
|
||||
switch (connector->connector_type) {
|
||||
case DRM_MODE_CONNECTOR_DVII:
|
||||
prop = dev->mode_config.dvi_i_select_subconnector_property;
|
||||
break;
|
||||
case DRM_MODE_CONNECTOR_Composite:
|
||||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
case DRM_MODE_CONNECTOR_Component:
|
||||
prop = dev->mode_config.tv_select_subconnector_property;
|
||||
break;
|
||||
default:
|
||||
DRM_ERROR("Wrong connector type for this property\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!prop) {
|
||||
DRM_ERROR("Unable to find select subconnector property\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = drm_connector_property_get_value(connector, prop, &subconnector);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return snprintf(buf, PAGE_SIZE, "%s", drm_get_select_subconnector_name((int)subconnector));
|
||||
}
|
||||
|
||||
static struct device_attribute connector_attrs[] = {
|
||||
__ATTR_RO(status),
|
||||
__ATTR_RO(enabled),
|
||||
|
@ -238,6 +310,12 @@ static struct device_attribute connector_attrs[] = {
|
|||
__ATTR_RO(modes),
|
||||
};
|
||||
|
||||
/* These attributes are for both DVI-I connectors and all types of tv-out. */
|
||||
static struct device_attribute connector_attrs_opt1[] = {
|
||||
__ATTR_RO(subconnector),
|
||||
__ATTR_RO(select_subconnector),
|
||||
};
|
||||
|
||||
static struct bin_attribute edid_attr = {
|
||||
.attr.name = "edid",
|
||||
.size = 128,
|
||||
|
@ -282,12 +360,32 @@ int drm_sysfs_connector_add(struct drm_connector *connector)
|
|||
goto out;
|
||||
}
|
||||
|
||||
/* Standard attributes */
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(connector_attrs); i++) {
|
||||
ret = device_create_file(&connector->kdev, &connector_attrs[i]);
|
||||
if (ret)
|
||||
goto err_out_files;
|
||||
}
|
||||
|
||||
/* Optional attributes */
|
||||
/* On the long run it maybe a good idea to make one set of optionals per connector type. */
|
||||
|
||||
switch (connector->connector_type) {
|
||||
case DRM_MODE_CONNECTOR_DVII:
|
||||
case DRM_MODE_CONNECTOR_Composite:
|
||||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
case DRM_MODE_CONNECTOR_Component:
|
||||
for (i = 0; i < ARRAY_SIZE(connector_attrs_opt1); i++) {
|
||||
ret = device_create_file(&connector->kdev, &connector_attrs_opt1[i]);
|
||||
if (ret)
|
||||
goto err_out_files;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
ret = sysfs_create_bin_file(&connector->kdev.kobj, &edid_attr);
|
||||
if (ret)
|
||||
goto err_out_files;
|
||||
|
|
|
@ -1713,7 +1713,7 @@ intel_tv_init(struct drm_device *dev)
|
|||
goto out;
|
||||
for (i = 0; i < NUM_TV_MODES; i++)
|
||||
tv_format_names[i] = tv_modes[i].name;
|
||||
drm_create_tv_properties(dev, NUM_TV_MODES, tv_format_names);
|
||||
drm_mode_create_tv_properties(dev, NUM_TV_MODES, tv_format_names);
|
||||
|
||||
drm_connector_attach_property(connector, dev->mode_config.tv_mode_property,
|
||||
initial_mode);
|
||||
|
|
|
@ -48,7 +48,6 @@ struct nv50_connector {
|
|||
struct nv50_output *output;
|
||||
|
||||
int scaling_mode;
|
||||
bool digital; /* last connected output, this has to be set from the outside*/
|
||||
|
||||
bool (*detect) (struct nv50_connector *connector);
|
||||
int (*destroy) (struct nv50_connector *connector);
|
||||
|
|
|
@ -387,7 +387,7 @@ int nv50_kms_crtc_set_config(struct drm_mode_set *set)
|
|||
}
|
||||
connector = to_nv50_connector(drm_connector);
|
||||
|
||||
output = connector->to_output(connector, connector->digital);
|
||||
output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
|
||||
if (!output) {
|
||||
DRM_ERROR("No output\n");
|
||||
goto out;
|
||||
|
@ -447,7 +447,7 @@ int nv50_kms_crtc_set_config(struct drm_mode_set *set)
|
|||
goto out;
|
||||
}
|
||||
|
||||
output = connector->to_output(connector, connector->digital);
|
||||
output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
|
||||
if (!output) {
|
||||
DRM_ERROR("No output\n");
|
||||
goto out;
|
||||
|
@ -806,6 +806,63 @@ static int nv50_kms_encoders_init(struct drm_device *dev)
|
|||
* Connector functions
|
||||
*/
|
||||
|
||||
bool nv50_kms_connector_is_digital(struct drm_connector *drm_connector)
|
||||
{
|
||||
struct drm_device *dev = drm_connector->dev;
|
||||
|
||||
switch (drm_connector->connector_type) {
|
||||
case DRM_MODE_CONNECTOR_VGA:
|
||||
case DRM_MODE_CONNECTOR_SVIDEO:
|
||||
return false;
|
||||
case DRM_MODE_CONNECTOR_DVID:
|
||||
case DRM_MODE_CONNECTOR_LVDS:
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (drm_connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
|
||||
int rval;
|
||||
uint64_t prop_val;
|
||||
|
||||
rval = drm_connector_property_get_value(drm_connector, dev->mode_config.dvi_i_select_subconnector_property, &prop_val);
|
||||
if (!rval) {
|
||||
DRM_ERROR("Unable to find select subconnector property, defaulting to DVI-D\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Is a subconnector explicitly selected? */
|
||||
switch (prop_val) {
|
||||
case DRM_MODE_SUBCONNECTOR_DVID:
|
||||
return true;
|
||||
case DRM_MODE_SUBCONNECTOR_DVIA:
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rval = drm_connector_property_get_value(drm_connector, dev->mode_config.dvi_i_subconnector_property, &prop_val);
|
||||
if (!rval) {
|
||||
DRM_ERROR("Unable to find subconnector property, defaulting to DVI-D\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Do we know what subconnector we currently have connected? */
|
||||
switch (prop_val) {
|
||||
case DRM_MODE_SUBCONNECTOR_DVID:
|
||||
return true;
|
||||
case DRM_MODE_SUBCONNECTOR_DVIA:
|
||||
return false;
|
||||
default:
|
||||
DRM_ERROR("Unknown subconnector value, defaulting to DVI-D\n");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
DRM_ERROR("Unknown connector type, defaulting to analog\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
void nv50_kms_connector_detect_all(struct drm_device *dev)
|
||||
{
|
||||
struct drm_connector *drm_connector = NULL;
|
||||
|
@ -867,7 +924,8 @@ static struct drm_display_mode std_mode[] = {
|
|||
static void nv50_kms_connector_fill_modes(struct drm_connector *drm_connector, uint32_t maxX, uint32_t maxY)
|
||||
{
|
||||
struct nv50_connector *connector = to_nv50_connector(drm_connector);
|
||||
int ret = 0;
|
||||
struct drm_device *dev = drm_connector->dev;
|
||||
int rval = 0;
|
||||
bool connected;
|
||||
struct drm_display_mode *mode, *t;
|
||||
struct edid *edid = NULL;
|
||||
|
@ -896,21 +954,32 @@ static void nv50_kms_connector_fill_modes(struct drm_connector *drm_connector, u
|
|||
|
||||
if (edid) {
|
||||
drm_mode_connector_update_edid_property(drm_connector, edid);
|
||||
ret = drm_add_edid_modes(drm_connector, edid);
|
||||
connector->digital = edid->digital; /* cache */
|
||||
rval = drm_add_edid_modes(drm_connector, edid);
|
||||
|
||||
/* 2 encoders per connector */
|
||||
/* eventually do this based on load detect and hot plug detect */
|
||||
if (drm_connector->connector_type == DRM_MODE_CONNECTOR_DVII) {
|
||||
uint64_t subtype = 0;
|
||||
if (edid->digital)
|
||||
subtype = DRM_MODE_SUBCONNECTOR_DVID;
|
||||
else
|
||||
subtype = DRM_MODE_SUBCONNECTOR_DVIA;
|
||||
drm_connector_property_set_value(drm_connector, dev->mode_config.dvi_i_subconnector_property, subtype);
|
||||
}
|
||||
|
||||
kfree(edid);
|
||||
}
|
||||
|
||||
if (ret) /* number of modes > 1 */
|
||||
if (rval) /* number of modes > 1 */
|
||||
drm_mode_connector_list_update(drm_connector);
|
||||
|
||||
if (maxX && maxY)
|
||||
drm_mode_validate_size(drm_connector->dev, &drm_connector->modes, maxX, maxY, 0);
|
||||
drm_mode_validate_size(dev, &drm_connector->modes, maxX, maxY, 0);
|
||||
|
||||
list_for_each_entry_safe(mode, t, &drm_connector->modes, head) {
|
||||
if (mode->status == MODE_OK) {
|
||||
struct nouveau_hw_mode *hw_mode = nv50_kms_to_hw_mode(mode);
|
||||
struct nv50_output *output = connector->to_output(connector, connector->digital);
|
||||
struct nv50_output *output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
|
||||
|
||||
mode->status = output->validate_mode(output, hw_mode);
|
||||
/* find native mode, TODO: also check if we actually found one */
|
||||
|
@ -926,14 +995,14 @@ static void nv50_kms_connector_fill_modes(struct drm_connector *drm_connector, u
|
|||
list_for_each_entry_safe(mode, t, &drm_connector->modes, head) {
|
||||
if (mode->status == MODE_OK) {
|
||||
struct nouveau_hw_mode *hw_mode = nv50_kms_to_hw_mode(mode);
|
||||
struct nv50_output *output = connector->to_output(connector, connector->digital);
|
||||
struct nv50_output *output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
|
||||
|
||||
mode->status = output->validate_mode(output, hw_mode);
|
||||
kfree(hw_mode);
|
||||
}
|
||||
}
|
||||
|
||||
drm_mode_prune_invalid(drm_connector->dev, &drm_connector->modes, true);
|
||||
drm_mode_prune_invalid(dev, &drm_connector->modes, true);
|
||||
|
||||
if (list_empty(&drm_connector->modes)) {
|
||||
struct drm_display_mode *stdmode;
|
||||
|
@ -947,14 +1016,14 @@ static void nv50_kms_connector_fill_modes(struct drm_connector *drm_connector, u
|
|||
* here and bailed in the past, now we add a standard
|
||||
* 640x480@60Hz mode and carry on.
|
||||
*/
|
||||
stdmode = drm_mode_duplicate(drm_connector->dev, &std_mode[0]);
|
||||
stdmode = drm_mode_duplicate(dev, &std_mode[0]);
|
||||
drm_mode_probed_add(drm_connector, stdmode);
|
||||
drm_mode_list_concat(&drm_connector->probed_modes,
|
||||
&drm_connector->modes);
|
||||
|
||||
/* also add it as native mode */
|
||||
hw_mode = nv50_kms_to_hw_mode(mode);
|
||||
output = connector->to_output(connector, connector->digital);
|
||||
output = connector->to_output(connector, nv50_kms_connector_is_digital(drm_connector));
|
||||
|
||||
if (hw_mode)
|
||||
*output->native_mode = *hw_mode;
|
||||
|
@ -1045,6 +1114,13 @@ static int nv50_kms_connectors_init(struct drm_device *dev)
|
|||
|
||||
drm_connector_init(dev, drm_connector, &nv50_kms_connector_funcs, type);
|
||||
|
||||
/* Init DVI-I specific properties */
|
||||
if (type == DRM_MODE_CONNECTOR_DVII) {
|
||||
drm_mode_create_dvi_i_properties(dev);
|
||||
drm_connector_attach_property(drm_connector, dev->mode_config.dvi_i_subconnector_property, 0);
|
||||
drm_connector_attach_property(drm_connector, dev->mode_config.dvi_i_select_subconnector_property, 0);
|
||||
}
|
||||
|
||||
/* attach encoders, possibilities are analog + digital */
|
||||
for (i = 0; i < 2; i++) {
|
||||
struct drm_encoder *drm_encoder = NULL;
|
||||
|
|
|
@ -87,6 +87,7 @@ struct nv50_kms_priv {
|
|||
|
||||
struct nv50_kms_priv *nv50_get_kms_priv(struct drm_device *dev);
|
||||
void nv50_kms_connector_detect_all(struct drm_device *dev);
|
||||
bool nv50_kms_connector_is_digital(struct drm_connector *drm_connector);
|
||||
|
||||
int nv50_kms_init(struct drm_device *dev);
|
||||
int nv50_kms_destroy(struct drm_device *dev);
|
||||
|
|
Loading…
Reference in New Issue