drm/modesetting: move some connector functions to helper.
Migrated the output mode collection into the helper.main
parent
dba95ec343
commit
0dd000b578
|
@ -285,136 +285,6 @@ 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_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_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_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_crtc_probe_single_connector_modes(struct drm_connector *connector, int maxX, int maxY)
|
||||
{
|
||||
struct drm_device *dev = connector->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, &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);
|
||||
}
|
||||
}
|
||||
|
||||
void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
drm_crtc_probe_single_connector_modes(connector, maxX, maxY);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(drm_crtc_probe_connector_modes);
|
||||
|
||||
|
||||
/**
|
||||
* drm_mode_probed_add - add a mode to the specified connector's probed mode list
|
||||
* @connector: connector the new mode
|
||||
|
@ -1109,7 +979,7 @@ int drm_mode_getconnector(struct drm_device *dev,
|
|||
}
|
||||
|
||||
if (out_resp->count_modes == 0) {
|
||||
drm_crtc_probe_single_connector_modes(connector, 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->connector_type = connector->connector_type;
|
||||
|
|
|
@ -380,13 +380,10 @@ struct drm_connector_funcs {
|
|||
void (*save)(struct drm_connector *connector);
|
||||
void (*restore)(struct drm_connector *connector);
|
||||
enum drm_connector_status (*detect)(struct drm_connector *connector);
|
||||
int (*get_modes)(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_connector *connector);
|
||||
int (*mode_valid)(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode);
|
||||
|
||||
};
|
||||
|
||||
struct drm_encoder_funcs {
|
||||
|
|
|
@ -34,6 +34,136 @@
|
|||
#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_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
|
||||
|
@ -81,8 +211,8 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
int found;
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
connector->encoder->crtc = NULL;
|
||||
|
||||
connector->encoder->crtc = NULL;
|
||||
|
||||
/* Don't hook up connectors that are disconnected ??
|
||||
*
|
||||
* This is debateable. Do we want fixed /dev/fbX or
|
||||
|
@ -211,7 +341,7 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo
|
|||
|
||||
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;
|
||||
|
@ -456,7 +586,7 @@ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
|
|||
|
||||
mutex_lock(&dev->mode_config.mutex);
|
||||
|
||||
drm_crtc_probe_connector_modes(dev, 2048, 2048);
|
||||
drm_helper_probe_connector_modes(dev, 2048, 2048);
|
||||
|
||||
drm_pick_crtcs(dev);
|
||||
|
||||
|
@ -518,7 +648,7 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *c
|
|||
has_config = 1;
|
||||
}
|
||||
|
||||
drm_crtc_probe_connector_modes(dev, 2048, 2048);
|
||||
drm_helper_probe_connector_modes(dev, 2048, 2048);
|
||||
|
||||
if (!has_config)
|
||||
drm_pick_crtcs(dev);
|
||||
|
|
|
@ -55,8 +55,14 @@ struct drm_encoder_helper_funcs {
|
|||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
};
|
||||
|
||||
|
||||
struct drm_connector_helper_funcs {
|
||||
int (*get_modes)(struct drm_connector *connector);
|
||||
int (*mode_valid)(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode);
|
||||
};
|
||||
|
||||
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);
|
||||
|
@ -64,7 +70,7 @@ 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;
|
||||
|
@ -75,6 +81,11 @@ static inline void drm_encoder_helper_add(struct drm_encoder *encoder, const str
|
|||
encoder->helper_private = (void *)funcs;
|
||||
}
|
||||
|
||||
static inline void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs)
|
||||
{
|
||||
connector->helper_private = (void *)funcs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
@ -237,13 +237,16 @@ 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,
|
||||
.mode_valid = intel_crt_mode_valid,
|
||||
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs intel_crt_connector_helper_funcs = {
|
||||
.mode_valid = intel_crt_mode_valid,
|
||||
.get_modes = intel_crt_get_modes,
|
||||
};
|
||||
|
||||
void intel_crt_enc_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
drm_encoder_cleanup(encoder);
|
||||
|
@ -283,6 +286,7 @@ void intel_crt_init(struct drm_device *dev)
|
|||
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);
|
||||
|
||||
|
|
|
@ -1184,7 +1184,7 @@ void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_
|
|||
if (intel_output->load_detect_temp) {
|
||||
encoder->crtc = NULL;
|
||||
intel_output->load_detect_temp = FALSE;
|
||||
crtc->enabled = drm_crtc_in_use(crtc);
|
||||
crtc->enabled = drm_helper_crtc_in_use(crtc);
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
}
|
||||
|
||||
|
|
|
@ -335,9 +335,13 @@ 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,
|
||||
};
|
||||
|
||||
void intel_dvo_enc_destroy(struct drm_encoder *encoder)
|
||||
|
@ -464,6 +468,7 @@ void intel_dvo_init(struct drm_device *dev)
|
|||
break;
|
||||
}
|
||||
|
||||
drm_connector_helper_add(connector, &intel_dvo_connector_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
|
|
|
@ -342,13 +342,17 @@ static const struct drm_encoder_helper_funcs intel_lvds_helper_funcs = {
|
|||
.commit = intel_lvds_commit,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs = {
|
||||
.get_modes = intel_lvds_get_modes,
|
||||
.mode_valid = intel_lvds_mode_valid,
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
|
||||
|
@ -361,6 +365,8 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
|
|||
.destroy = intel_lvds_enc_destroy,
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* intel_lvds_init - setup LVDS connectors on this device
|
||||
* @dev: drm device
|
||||
|
@ -395,6 +401,7 @@ void intel_lvds_init(struct drm_device *dev)
|
|||
intel_output->type = INTEL_OUTPUT_LVDS;
|
||||
|
||||
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;
|
||||
|
|
|
@ -983,11 +983,14 @@ 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,
|
||||
.mode_valid = intel_sdvo_mode_valid,
|
||||
};
|
||||
|
||||
static const struct drm_connector_helper_funcs intel_sdvo_connector_helper_funcs = {
|
||||
.get_modes = intel_sdvo_get_modes,
|
||||
.mode_valid = intel_sdvo_mode_valid,
|
||||
};
|
||||
|
||||
void intel_sdvo_enc_destroy(struct drm_encoder *encoder)
|
||||
{
|
||||
|
@ -1019,7 +1022,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
|
|||
|
||||
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;
|
||||
|
||||
|
|
|
@ -1608,11 +1608,15 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
|
|||
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,
|
||||
};
|
||||
|
||||
void intel_tv_enc_destroy(struct drm_encoder *encoder)
|
||||
|
@ -1695,6 +1699,7 @@ intel_tv_init(struct drm_device *dev)
|
|||
tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
|
||||
|
||||
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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue