mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2025-12-24 18:20:11 +01:00
drm/modesetting: another re-org of some internals.
Move dpms into the helper functions. Move crtc into the encoder. Move disable unused functions into the helper.
This commit is contained in:
parent
5d47185eb6
commit
e439e74776
13 changed files with 274 additions and 250 deletions
|
|
@ -83,6 +83,15 @@ static struct drm_prop_enum_list drm_encoder_enum_list[] =
|
|||
{ DRM_MODE_ENCODER_TVDAC, "TV" },
|
||||
};
|
||||
|
||||
char *drm_get_encoder_name(struct drm_encoder *encoder)
|
||||
{
|
||||
static char buf[32];
|
||||
|
||||
snprintf(buf, 32, "%s-%d", drm_encoder_enum_list[encoder->encoder_type].name,
|
||||
encoder->id);
|
||||
return buf;
|
||||
}
|
||||
|
||||
char *drm_get_connector_name(struct drm_connector *connector)
|
||||
{
|
||||
static char buf[32];
|
||||
|
|
@ -290,11 +299,11 @@ EXPORT_SYMBOL(drm_crtc_cleanup);
|
|||
*/
|
||||
bool drm_crtc_in_use(struct drm_crtc *crtc)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_device *dev = crtc->dev;
|
||||
/* FIXME: Locking around list access? */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
||||
if (connector->crtc == crtc)
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
|
||||
if (encoder->crtc == crtc)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
|
@ -406,33 +415,6 @@ void drm_crtc_probe_connector_modes(struct drm_device *dev, int maxX, int maxY)
|
|||
EXPORT_SYMBOL(drm_crtc_probe_connector_modes);
|
||||
|
||||
|
||||
/**
|
||||
* 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_disable_unused_functions(struct drm_device *dev)
|
||||
{
|
||||
struct drm_connector *connector;
|
||||
struct drm_crtc *crtc;
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (!connector->crtc)
|
||||
(*connector->funcs->dpms)(connector, 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 connector's probed mode list
|
||||
* @connector: connector the new mode
|
||||
|
|
@ -1059,7 +1041,7 @@ int drm_mode_getcrtc(struct drm_device *dev,
|
|||
crtc_resp->mode_valid = 1;
|
||||
ocount = 0;
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (connector->crtc == crtc)
|
||||
if (connector->encoder->crtc == crtc)
|
||||
crtc_resp->connectors |= 1 << (ocount++);
|
||||
}
|
||||
|
||||
|
|
@ -1143,10 +1125,10 @@ int drm_mode_getconnector(struct drm_device *dev,
|
|||
out_resp->mm_height = connector->display_info.height_mm;
|
||||
out_resp->subpixel = connector->display_info.subpixel_order;
|
||||
out_resp->connection = connector->status;
|
||||
if (connector->crtc)
|
||||
out_resp->crtc = connector->crtc->id;
|
||||
if (connector->encoder)
|
||||
out_resp->encoder = connector->encoder->id;
|
||||
else
|
||||
out_resp->crtc = 0;
|
||||
out_resp->encoder = 0;
|
||||
|
||||
if ((out_resp->count_modes >= mode_count) && mode_count) {
|
||||
copied = 0;
|
||||
|
|
@ -1220,6 +1202,10 @@ int drm_mode_getencoder(struct drm_device *dev,
|
|||
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;
|
||||
|
|
@ -1630,7 +1616,9 @@ int drm_mode_attachmode_crtc(struct drm_device *dev, struct drm_crtc *crtc,
|
|||
struct drm_display_mode *dup_mode;
|
||||
int need_dup = 0;
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (connector->crtc == crtc) {
|
||||
if (!connector->encoder)
|
||||
break;
|
||||
if (connector->encoder->crtc == crtc) {
|
||||
if (need_dup)
|
||||
dup_mode = drm_mode_duplicate(dev, mode);
|
||||
else
|
||||
|
|
@ -2200,7 +2188,7 @@ int drm_mode_connector_attach_encoder(struct drm_connector *connector,
|
|||
connector->encoder_ids[i] = encoder->id;
|
||||
/* pick the first added encoder as the current */
|
||||
if (i == 0)
|
||||
connector->current_encoder_id = encoder->id;
|
||||
connector->encoder = encoder;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -2215,6 +2203,8 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector,
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,12 +304,6 @@ struct drm_encoder;
|
|||
* 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 */
|
||||
|
|
@ -416,6 +410,7 @@ struct drm_encoder {
|
|||
uint32_t possible_crtcs;
|
||||
uint32_t possible_clones;
|
||||
|
||||
struct drm_crtc *crtc;
|
||||
const struct drm_encoder_funcs *funcs;
|
||||
void *helper_private;
|
||||
};
|
||||
|
|
@ -441,7 +436,6 @@ struct drm_connector {
|
|||
struct device kdev;
|
||||
struct device_attribute *attr;
|
||||
struct list_head head;
|
||||
struct drm_crtc *crtc;
|
||||
int id; /* idr assigned */
|
||||
|
||||
int connector_type;
|
||||
|
|
@ -468,7 +462,7 @@ struct drm_connector {
|
|||
|
||||
uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
|
||||
uint32_t force_encoder_id;
|
||||
uint32_t current_encoder_id;
|
||||
struct drm_encoder *encoder; /* currently active encoder */
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
@ -582,7 +576,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,
|
||||
|
|
@ -631,6 +624,7 @@ 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);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,35 @@
|
|||
#include "drm_crtc.h"
|
||||
#include "drm_crtc_helper.h"
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
@ -52,7 +81,7 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
int found;
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
connector->crtc = NULL;
|
||||
connector->encoder->crtc = NULL;
|
||||
|
||||
/* Don't hook up connectors that are disconnected ??
|
||||
*
|
||||
|
|
@ -90,9 +119,7 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
}
|
||||
}
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
|
||||
if (encoder->id == connector->current_encoder_id)
|
||||
break;
|
||||
encoder = connector->encoder;
|
||||
|
||||
c = -1;
|
||||
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
|
||||
|
|
@ -107,7 +134,7 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
continue;
|
||||
|
||||
/* Find out if crtc has been assigned before */
|
||||
if (connector_equal->crtc == crtc)
|
||||
if (connector_equal->encoder->crtc == crtc)
|
||||
assigned = 1;
|
||||
}
|
||||
|
||||
|
|
@ -122,14 +149,12 @@ static void drm_pick_crtcs (struct drm_device *dev)
|
|||
if (connector->id == connector_equal->id)
|
||||
continue;
|
||||
|
||||
list_for_each_entry(encoder_equal, &dev->mode_config.encoder_list, head)
|
||||
if (encoder_equal->id == connector_equal->current_encoder_id)
|
||||
break;
|
||||
encoder_equal = connector_equal->encoder;
|
||||
|
||||
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 ((encoder->possible_clones & encoder_equal->possible_clones) && (connector_equal->crtc == crtc)) {
|
||||
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;
|
||||
|
|
@ -146,8 +171,8 @@ clone:
|
|||
continue;
|
||||
|
||||
/* Found a CRTC to attach to, do it ! */
|
||||
connector->crtc = crtc;
|
||||
connector->crtc->desired_mode = des_mode;
|
||||
connector->encoder->crtc = crtc;
|
||||
connector->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);
|
||||
|
|
@ -179,9 +204,9 @@ 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_connector_helper_funcs *connector_funcs;
|
||||
struct drm_encoder_helper_funcs *encoder_funcs;
|
||||
int saved_x, saved_y;
|
||||
struct drm_connector *connector;
|
||||
struct drm_encoder *encoder;
|
||||
bool ret = true;
|
||||
|
||||
adjusted_mode = drm_mode_duplicate(dev, mode);
|
||||
|
|
@ -213,12 +238,12 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo
|
|||
* adjust it according to limitations or connector properties, and also
|
||||
* a chance to reject the mode entirely.
|
||||
*/
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
|
||||
if (connector->crtc != crtc)
|
||||
if (encoder->crtc != crtc)
|
||||
continue;
|
||||
connector_funcs = connector->helper_private;
|
||||
if (!(ret = connector_funcs->mode_fixup(connector, mode, adjusted_mode))) {
|
||||
encoder_funcs = encoder->helper_private;
|
||||
if (!(ret = encoder_funcs->mode_fixup(encoder, mode, adjusted_mode))) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
|
|
@ -227,48 +252,44 @@ bool drm_crtc_helper_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Prepare the connectors and CRTCs before setting the mode. */
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
/* Prepare the encoders and CRTCs before setting the mode. */
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
|
||||
if (connector->crtc != crtc)
|
||||
if (encoder->crtc != crtc)
|
||||
continue;
|
||||
connector_funcs = connector->helper_private;
|
||||
/* Disable the connector as the first thing we do. */
|
||||
connector_funcs->prepare(connector);
|
||||
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 connector 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(connector, &dev->mode_config.connector_list, head) {
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
|
||||
if (connector->crtc != crtc)
|
||||
if (encoder->crtc != crtc)
|
||||
continue;
|
||||
|
||||
DRM_INFO("%s: set mode %s %x\n", drm_get_connector_name(connector), mode->name, mode->mode_id);
|
||||
connector_funcs = connector->helper_private;
|
||||
connector_funcs->mode_set(connector, 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 connectors that we set up. */
|
||||
crtc_funcs->commit(crtc);
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
|
||||
|
||||
if (connector->crtc != crtc)
|
||||
if (encoder->crtc != crtc)
|
||||
continue;
|
||||
|
||||
connector_funcs = connector->helper_private;
|
||||
connector_funcs->commit(connector);
|
||||
encoder_funcs = encoder->helper_private;
|
||||
encoder_funcs->commit(encoder);
|
||||
|
||||
#if 0 // TODO def RANDR_12_INTERFACE
|
||||
if (connector->randr_connector)
|
||||
RRPostPendingProperties (connector->randr_connector);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* XXX free adjustedmode */
|
||||
|
|
@ -357,20 +378,23 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
|||
}
|
||||
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
save_crtcs[count++] = connector->crtc;
|
||||
if (!connector->encoder)
|
||||
continue;
|
||||
|
||||
if (connector->crtc == set->crtc)
|
||||
save_crtcs[count++] = connector->encoder->crtc;
|
||||
|
||||
if (connector->encoder->crtc == set->crtc)
|
||||
new_crtc = NULL;
|
||||
else
|
||||
new_crtc = connector->crtc;
|
||||
new_crtc = connector->encoder->crtc;
|
||||
|
||||
for (ro = 0; ro < set->num_connectors; ro++) {
|
||||
if (set->connectors[ro] == connector)
|
||||
new_crtc = set->crtc;
|
||||
}
|
||||
if (new_crtc != connector->crtc) {
|
||||
if (new_crtc != connector->encoder->crtc) {
|
||||
changed = true;
|
||||
connector->crtc = new_crtc;
|
||||
connector->encoder->crtc = new_crtc;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -389,7 +413,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
|||
set->crtc->enabled = save_enabled;
|
||||
count = 0;
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
|
||||
connector->crtc = save_crtcs[count++];
|
||||
connector->encoder->crtc = save_crtcs[count++];
|
||||
kfree(save_crtcs);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -398,7 +422,7 @@ int drm_crtc_helper_set_config(struct drm_mode_set *set)
|
|||
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;
|
||||
|
|
@ -444,18 +468,19 @@ bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
|
|||
*/
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
|
||||
struct drm_crtc *crtc = connector->encoder->crtc;
|
||||
/* can't setup the connector if there's no assigned mode */
|
||||
if (!connector->crtc || !connector->crtc->desired_mode)
|
||||
if (!crtc || !crtc->desired_mode)
|
||||
continue;
|
||||
|
||||
dev->driver->fb_probe(dev, connector->crtc, connector);
|
||||
dev->driver->fb_probe(dev, crtc, connector);
|
||||
|
||||
/* and needs an attached fb */
|
||||
if (connector->crtc->fb)
|
||||
drm_crtc_helper_set_mode(connector->crtc, connector->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;
|
||||
|
|
@ -488,7 +513,7 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *c
|
|||
return 0;
|
||||
}
|
||||
|
||||
if (connector->crtc && connector->crtc->desired_mode) {
|
||||
if (connector->encoder->crtc && connector->encoder->crtc->desired_mode) {
|
||||
DRM_DEBUG("drm thinks that the connector already has a config\n");
|
||||
has_config = 1;
|
||||
}
|
||||
|
|
@ -498,27 +523,28 @@ int drm_helper_hotplug_stage_two(struct drm_device *dev, struct drm_connector *c
|
|||
if (!has_config)
|
||||
drm_pick_crtcs(dev);
|
||||
|
||||
if (!connector->crtc || !connector->crtc->desired_mode) {
|
||||
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, connector->crtc, connector);
|
||||
dev->driver->fb_probe(dev, connector->encoder->crtc, connector);
|
||||
else {
|
||||
dev->driver->fb_resize(dev, connector->crtc);
|
||||
dev->driver->fb_resize(dev, connector->encoder->crtc);
|
||||
|
||||
#if 0
|
||||
if (!drm_crtc_set_mode(connector->crtc, connector->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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,26 +41,23 @@ struct drm_crtc_helper_funcs {
|
|||
void (*mode_set_base)(struct drm_crtc *crtc, int x, int y);
|
||||
};
|
||||
|
||||
struct drm_connector_helper_funcs {
|
||||
bool (*mode_fixup)(struct drm_connector *connector,
|
||||
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_connector *connector);
|
||||
void (*commit)(struct drm_connector *connector);
|
||||
void (*mode_set)(struct drm_connector *connector,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode);
|
||||
};
|
||||
|
||||
struct drm_encoder_helper_funcs {
|
||||
void (*prepare)(struct drm_connector *connector);
|
||||
void (*commit)(struct drm_connector *connector);
|
||||
void (*mode_set)(struct drm_connector *connector,
|
||||
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 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);
|
||||
|
|
@ -68,9 +70,9 @@ static inline void drm_crtc_helper_add(struct drm_crtc *crtc, const struct drm_c
|
|||
crtc->helper_private = (void *)funcs;
|
||||
}
|
||||
|
||||
static inline void drm_connector_helper_add(struct drm_connector *connector, const struct drm_connector_helper_funcs *funcs)
|
||||
static inline void drm_encoder_helper_add(struct drm_encoder *encoder, const struct drm_encoder_helper_funcs *funcs)
|
||||
{
|
||||
connector->helper_private = (void *)funcs;
|
||||
encoder->helper_private = (void *)funcs;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@
|
|||
#include "i915_drm.h"
|
||||
#include "i915_drv.h"
|
||||
|
||||
static void intel_crt_dpms(struct drm_connector *connector, int mode)
|
||||
static void intel_crt_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
u32 temp;
|
||||
|
||||
|
|
@ -83,19 +83,20 @@ static int intel_crt_mode_valid(struct drm_connector *connector,
|
|||
return MODE_OK;
|
||||
}
|
||||
|
||||
static bool intel_crt_mode_fixup(struct drm_connector *connector,
|
||||
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_connector *connector,
|
||||
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 = connector->dev;
|
||||
struct drm_crtc *crtc = connector->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;
|
||||
|
|
@ -214,8 +215,8 @@ static bool intel_crt_set_property(struct drm_connector *connector,
|
|||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
|
||||
if (property == dev->mode_config.dpms_property)
|
||||
intel_crt_dpms(connector, (uint32_t)(value & 0xf));
|
||||
if (property == dev->mode_config.dpms_property && connector->encoder)
|
||||
intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -224,15 +225,15 @@ static bool intel_crt_set_property(struct drm_connector *connector,
|
|||
* Routines for controlling stuff on the analog port
|
||||
*/
|
||||
|
||||
static const struct drm_connector_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_connector_prepare,
|
||||
.commit = intel_connector_commit,
|
||||
.prepare = intel_encoder_prepare,
|
||||
.commit = intel_encoder_commit,
|
||||
.mode_set = intel_crt_mode_set,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_crt_connector_funcs = {
|
||||
.dpms = intel_crt_dpms,
|
||||
.save = intel_crt_save,
|
||||
.restore = intel_crt_restore,
|
||||
.detect = intel_crt_detect,
|
||||
|
|
@ -281,7 +282,7 @@ void intel_crt_init(struct drm_device *dev)
|
|||
connector->interlace_allowed = 0;
|
||||
connector->doublescan_allowed = 0;
|
||||
|
||||
drm_connector_helper_add(connector, &intel_crt_helper_funcs);
|
||||
drm_encoder_helper_add(&intel_output->enc, &intel_crt_helper_funcs);
|
||||
|
||||
drm_sysfs_connector_add(connector);
|
||||
|
||||
|
|
|
|||
|
|
@ -228,7 +228,7 @@ bool intel_pipe_has_type (struct drm_crtc *crtc, int type)
|
|||
struct drm_connector *l_entry;
|
||||
|
||||
list_for_each_entry(l_entry, &mode_config->connector_list, head) {
|
||||
if (l_entry->crtc == crtc) {
|
||||
if (l_entry->encoder->crtc == crtc) {
|
||||
struct intel_output *intel_output = to_intel_output(l_entry);
|
||||
if (intel_output->type == type)
|
||||
return true;
|
||||
|
|
@ -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_connector_prepare (struct drm_connector *connector)
|
||||
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 */
|
||||
connector->funcs->dpms(connector, DPMSModeOff);
|
||||
encoder_funcs->dpms(encoder, DPMSModeOff);
|
||||
}
|
||||
|
||||
void intel_connector_commit (struct drm_connector *connector)
|
||||
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 */
|
||||
connector->funcs->dpms(connector, DPMSModeOn);
|
||||
encoder_funcs->dpms(encoder, DPMSModeOn);
|
||||
}
|
||||
|
||||
static bool intel_crtc_mode_fixup(struct drm_crtc *crtc,
|
||||
|
|
@ -721,7 +725,7 @@ static void intel_crtc_mode_set(struct drm_crtc *crtc,
|
|||
list_for_each_entry(connector, &mode_config->connector_list, head) {
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
|
||||
if (connector->crtc != crtc)
|
||||
if (!connector->encoder || connector->encoder->crtc != crtc)
|
||||
continue;
|
||||
|
||||
switch (intel_output->type) {
|
||||
|
|
@ -1082,18 +1086,18 @@ 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_connector *connector,
|
||||
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 = connector->dev;
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_crtc *intel_crtc;
|
||||
struct drm_crtc *possible_crtc;
|
||||
struct drm_crtc *supported_crtc =NULL;
|
||||
struct drm_encoder *encoder = NULL;
|
||||
struct drm_encoder *encoder = &intel_output->enc;
|
||||
struct drm_crtc *crtc = NULL;
|
||||
struct drm_connector_helper_funcs *connector_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;
|
||||
|
||||
/*
|
||||
|
|
@ -1107,22 +1111,19 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector,
|
|||
*/
|
||||
|
||||
/* See if we already have a CRTC for this connector */
|
||||
if (connector->crtc) {
|
||||
crtc = connector->crtc;
|
||||
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);
|
||||
connector->funcs->dpms(connector, DPMSModeOn);
|
||||
crtc_funcs = crtc->helper_private;
|
||||
crtc_funcs->dpms(crtc, DPMSModeOn);
|
||||
encoder_funcs->dpms(encoder, DPMSModeOn);
|
||||
}
|
||||
return crtc;
|
||||
}
|
||||
|
||||
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
|
||||
if (encoder->id == connector->current_encoder_id)
|
||||
break;
|
||||
|
||||
/* Find an unused one (if possible) */
|
||||
list_for_each_entry(possible_crtc, &dev->mode_config.crtc_list, head) {
|
||||
i++;
|
||||
|
|
@ -1146,7 +1147,7 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
connector->crtc = crtc;
|
||||
encoder->crtc = crtc;
|
||||
intel_output->load_detect_temp = TRUE;
|
||||
|
||||
intel_crtc = to_intel_crtc(crtc);
|
||||
|
|
@ -1157,13 +1158,14 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector,
|
|||
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);
|
||||
}
|
||||
|
||||
connector_funcs = connector->helper_private;
|
||||
/* Add this connector to the crtc */
|
||||
connector_funcs->mode_set(connector, &crtc->mode, &crtc->mode);
|
||||
connector_funcs->commit(connector);
|
||||
encoder_funcs->mode_set(encoder, &crtc->mode, &crtc->mode);
|
||||
encoder_funcs->commit(encoder);
|
||||
}
|
||||
/* let the connector get through one full cycle before testing */
|
||||
intel_wait_for_vblank(dev);
|
||||
|
|
@ -1171,24 +1173,26 @@ struct drm_crtc *intel_get_load_detect_pipe(struct drm_connector *connector,
|
|||
return crtc;
|
||||
}
|
||||
|
||||
void intel_release_load_detect_pipe(struct drm_connector *connector, int dpms_mode)
|
||||
void intel_release_load_detect_pipe(struct intel_output *intel_output, int dpms_mode)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct drm_crtc *crtc = connector->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) {
|
||||
connector->crtc = NULL;
|
||||
encoder->crtc = NULL;
|
||||
intel_output->load_detect_temp = FALSE;
|
||||
crtc->enabled = drm_crtc_in_use(crtc);
|
||||
drm_disable_unused_functions(dev);
|
||||
drm_helper_disable_unused_functions(dev);
|
||||
}
|
||||
|
||||
/* Switch crtc and output back off if necessary */
|
||||
if (crtc->enabled && dpms_mode != DPMSModeOn) {
|
||||
if (connector->crtc == crtc)
|
||||
connector->funcs->dpms(connector, dpms_mode);
|
||||
crtc->funcs->dpms(crtc, dpms_mode);
|
||||
if (encoder->crtc == crtc)
|
||||
encoder_funcs->dpms(encoder, dpms_mode);
|
||||
crtc_funcs->dpms(crtc, dpms_mode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1311,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,
|
||||
|
|
@ -1319,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,
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ 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);
|
||||
|
|
@ -82,16 +83,16 @@ 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_connector_prepare (struct drm_connector *connector);
|
||||
extern void intel_connector_commit (struct drm_connector *connector);
|
||||
extern void intel_encoder_prepare (struct drm_encoder *encoder);
|
||||
extern void intel_encoder_commit (struct drm_encoder *encoder);
|
||||
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_connector *connector,
|
||||
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_connector *connector,
|
||||
extern void intel_release_load_detect_pipe(struct intel_output *intel_output,
|
||||
int dpms_mode);
|
||||
|
||||
extern struct drm_connector* intel_sdvo_find(struct drm_device *dev, int sdvoB);
|
||||
|
|
|
|||
|
|
@ -85,10 +85,10 @@ struct intel_dvo_device intel_dvo_devices[] = {
|
|||
}
|
||||
};
|
||||
|
||||
static void intel_dvo_dpms(struct drm_connector *connector, int mode)
|
||||
static void intel_dvo_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = connector->dev->dev_private;
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
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);
|
||||
|
|
@ -154,11 +154,11 @@ static int intel_dvo_mode_valid(struct drm_connector *connector,
|
|||
return dvo->dev_ops->mode_valid(dvo, mode);
|
||||
}
|
||||
|
||||
static bool intel_dvo_mode_fixup(struct drm_connector *connector,
|
||||
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(connector);
|
||||
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_connector *connector,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void intel_dvo_mode_set(struct drm_connector *connector,
|
||||
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 = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc);
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
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;
|
||||
|
|
@ -323,15 +323,15 @@ static struct drm_crtc *intel_dvo_get_crtc(struct drm_connector *connector)
|
|||
}
|
||||
#endif
|
||||
|
||||
static const struct drm_connector_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_connector_prepare,
|
||||
.prepare = intel_encoder_prepare,
|
||||
.mode_set = intel_dvo_mode_set,
|
||||
.commit = intel_connector_commit,
|
||||
.commit = intel_encoder_commit,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_dvo_connector_funcs = {
|
||||
.dpms = intel_dvo_dpms,
|
||||
.save = intel_dvo_save,
|
||||
.restore = intel_dvo_restore,
|
||||
.detect = intel_dvo_detect,
|
||||
|
|
@ -464,7 +464,6 @@ void intel_dvo_init(struct drm_device *dev)
|
|||
break;
|
||||
}
|
||||
|
||||
drm_connector_helper_add(connector, &intel_dvo_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->interlace_allowed = false;
|
||||
connector->doublescan_allowed = false;
|
||||
|
|
@ -473,6 +472,8 @@ void intel_dvo_init(struct drm_device *dev)
|
|||
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);
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -277,7 +277,7 @@ static int intelfb_set_par(struct fb_info *info)
|
|||
|
||||
found = 0;
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (connector->crtc == par->set.crtc){
|
||||
if (connector->encoder->crtc == par->set.crtc){
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -89,9 +89,9 @@ static void intel_lvds_set_power(struct drm_device *dev, bool on)
|
|||
}
|
||||
}
|
||||
|
||||
static void intel_lvds_dpms(struct drm_connector *connector, int mode)
|
||||
static void intel_lvds_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
|
||||
if (mode == DPMSModeOn)
|
||||
intel_lvds_set_power(dev, true);
|
||||
|
|
@ -155,14 +155,14 @@ static int intel_lvds_mode_valid(struct drm_connector *connector,
|
|||
return MODE_OK;
|
||||
}
|
||||
|
||||
static bool intel_lvds_mode_fixup(struct drm_connector *connector,
|
||||
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 = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc);
|
||||
struct drm_connector *tmp_connector;
|
||||
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_connector *connector,
|
|||
}
|
||||
|
||||
/* Should never happen!! */
|
||||
list_for_each_entry(tmp_connector, &dev->mode_config.connector_list, head) {
|
||||
if (tmp_connector != connector && tmp_connector->crtc == connector->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 "
|
||||
"connector 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_connector *connector,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void intel_lvds_prepare(struct drm_connector *connector)
|
||||
static void intel_lvds_prepare(struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_device *dev = connector->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_connector *connector)
|
|||
intel_lvds_set_power(dev, false);
|
||||
}
|
||||
|
||||
static void intel_lvds_commit( struct drm_connector *connector)
|
||||
static void intel_lvds_commit( struct drm_encoder *encoder)
|
||||
{
|
||||
struct drm_device *dev = connector->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_connector *connector)
|
|||
intel_lvds_set_power(dev, true);
|
||||
}
|
||||
|
||||
static void intel_lvds_mode_set(struct drm_connector *connector,
|
||||
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 = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(connector->crtc);
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(encoder->crtc);
|
||||
u32 pfit_control;
|
||||
|
||||
/*
|
||||
|
|
@ -334,7 +334,8 @@ static void intel_lvds_destroy(struct drm_connector *connector)
|
|||
kfree(connector);
|
||||
}
|
||||
|
||||
static const struct drm_connector_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,
|
||||
|
|
@ -342,7 +343,6 @@ static const struct drm_connector_helper_funcs intel_lvds_helper_funcs = {
|
|||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_lvds_connector_funcs = {
|
||||
.dpms = intel_lvds_dpms,
|
||||
.save = intel_lvds_save,
|
||||
.restore = intel_lvds_restore,
|
||||
.detect = intel_lvds_detect,
|
||||
|
|
@ -373,6 +373,7 @@ void intel_lvds_init(struct drm_device *dev)
|
|||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_output *intel_output;
|
||||
struct drm_connector *connector;
|
||||
struct drm_encoder *encoder;
|
||||
struct drm_display_mode *scan; /* *modes, *bios_mode; */
|
||||
struct drm_crtc *crtc;
|
||||
u32 lvds;
|
||||
|
|
@ -384,6 +385,7 @@ void intel_lvds_init(struct drm_device *dev)
|
|||
}
|
||||
|
||||
connector = &intel_output->base;
|
||||
encoder = &intel_output->enc;
|
||||
drm_connector_init(dev, &intel_output->base, &intel_lvds_connector_funcs,
|
||||
DRM_MODE_CONNECTOR_LVDS);
|
||||
|
||||
|
|
@ -392,7 +394,7 @@ void intel_lvds_init(struct drm_device *dev)
|
|||
|
||||
intel_output->type = INTEL_OUTPUT_LVDS;
|
||||
|
||||
drm_connector_helper_add(connector, &intel_lvds_helper_funcs);
|
||||
drm_encoder_helper_add(encoder, &intel_lvds_helper_funcs);
|
||||
connector->display_info.subpixel_order = SubPixelHorizontalRGB;
|
||||
connector->interlace_allowed = FALSE;
|
||||
connector->doublescan_allowed = FALSE;
|
||||
|
|
|
|||
|
|
@ -539,7 +539,7 @@ static bool intel_sdvo_set_clock_rate_mult(struct intel_output *intel_output, u8
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool intel_sdvo_mode_fixup(struct drm_connector *connector,
|
||||
static bool intel_sdvo_mode_fixup(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
|
|
@ -550,15 +550,15 @@ static bool intel_sdvo_mode_fixup(struct drm_connector *connector,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void intel_sdvo_mode_set(struct drm_connector *connector,
|
||||
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 = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc = connector->crtc;
|
||||
struct drm_crtc *crtc = encoder->crtc;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
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;
|
||||
|
|
@ -624,13 +624,13 @@ static void intel_sdvo_mode_set(struct drm_connector *connector,
|
|||
* output the preferred timing, and we don't support that currently.
|
||||
*/
|
||||
#if 0
|
||||
success = intel_sdvo_create_preferred_input_timing(connector, 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(connector, &input_dtd);
|
||||
intel_sdvo_set_input_timing(connector, &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(intel_output, &output_dtd);
|
||||
|
|
@ -683,11 +683,11 @@ static void intel_sdvo_mode_set(struct drm_connector *connector,
|
|||
intel_sdvo_write_sdvox(intel_output, sdvox);
|
||||
}
|
||||
|
||||
static void intel_sdvo_dpms(struct drm_connector *connector, int mode)
|
||||
static void intel_sdvo_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_output *intel_output = enc_to_intel_output(encoder);
|
||||
struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv;
|
||||
u32 temp;
|
||||
|
||||
|
|
@ -971,15 +971,15 @@ static void intel_sdvo_destroy(struct drm_connector *connector)
|
|||
kfree(intel_output);
|
||||
}
|
||||
|
||||
static const struct drm_connector_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_connector_prepare,
|
||||
.prepare = intel_encoder_prepare,
|
||||
.mode_set = intel_sdvo_mode_set,
|
||||
.commit = intel_connector_commit,
|
||||
.commit = intel_encoder_commit,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
|
||||
.dpms = intel_sdvo_dpms,
|
||||
.save = intel_sdvo_save,
|
||||
.restore = intel_sdvo_restore,
|
||||
.detect = intel_sdvo_detect,
|
||||
|
|
@ -1022,7 +1022,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
|
|||
|
||||
sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1);
|
||||
intel_output->type = INTEL_OUTPUT_SDVO;
|
||||
drm_connector_helper_add(connector, &intel_sdvo_helper_funcs);
|
||||
|
||||
connector->interlace_allowed = 0;
|
||||
connector->doublescan_allowed = 0;
|
||||
|
||||
|
|
@ -1108,6 +1108,7 @@ void intel_sdvo_init(struct drm_device *dev, int output_device)
|
|||
}
|
||||
|
||||
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_connector_add(connector);
|
||||
|
|
|
|||
|
|
@ -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_connector *connector, int mode)
|
||||
intel_tv_dpms(struct drm_encoder *encoder, int mode)
|
||||
{
|
||||
struct drm_device *dev = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
|
||||
switch(mode) {
|
||||
|
|
@ -972,7 +972,7 @@ intel_tv_restore(struct drm_connector *connector)
|
|||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_tv_priv *tv_priv = intel_output->dev_priv;
|
||||
struct drm_crtc *crtc = connector->crtc;
|
||||
struct drm_crtc *crtc = connector->encoder->crtc;
|
||||
struct intel_crtc *intel_crtc;
|
||||
int i;
|
||||
|
||||
|
|
@ -1088,22 +1088,22 @@ intel_tv_mode_valid(struct drm_connector *connector, struct drm_display_mode *mo
|
|||
|
||||
|
||||
static bool
|
||||
intel_tv_mode_fixup(struct drm_connector *connector, 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 = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_mode_config *drm_config = &dev->mode_config;
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
struct intel_output *intel_output = enc_to_intel_output(encoder);
|
||||
const struct tv_mode *tv_mode = intel_tv_mode_find (intel_output);
|
||||
struct drm_connector *other_connector;
|
||||
struct drm_encoder *other_encoder;
|
||||
|
||||
if (!tv_mode)
|
||||
return FALSE;
|
||||
|
||||
/* FIXME: lock connector list */
|
||||
list_for_each_entry(other_connector, &drm_config->connector_list, head) {
|
||||
if (other_connector != connector &&
|
||||
other_connector->crtc == connector->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;
|
||||
}
|
||||
|
||||
|
|
@ -1112,14 +1112,14 @@ intel_tv_mode_fixup(struct drm_connector *connector, struct drm_display_mode *mo
|
|||
}
|
||||
|
||||
static void
|
||||
intel_tv_mode_set(struct drm_connector *connector, 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 = connector->dev;
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_crtc *crtc = connector->crtc;
|
||||
struct drm_crtc *crtc = encoder->crtc;
|
||||
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
|
||||
struct intel_output *intel_output = to_intel_output(connector);
|
||||
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(intel_output);
|
||||
u32 tv_ctl;
|
||||
|
|
@ -1356,11 +1356,11 @@ 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_connector *connector)
|
||||
intel_tv_detect_type (struct drm_crtc *crtc, struct intel_output *intel_output)
|
||||
{
|
||||
struct drm_device *dev = connector->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(connector);
|
||||
u32 pipeastat, pipeastat_save;
|
||||
u32 tv_ctl, save_tv_ctl;
|
||||
u32 tv_dac, save_tv_dac;
|
||||
|
|
@ -1443,19 +1443,20 @@ intel_tv_detect(struct drm_connector *connector)
|
|||
struct drm_display_mode mode;
|
||||
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 (connector->crtc) {
|
||||
type = intel_tv_detect_type(connector->crtc, connector);
|
||||
if (encoder->crtc) {
|
||||
type = intel_tv_detect_type(encoder->crtc, intel_output);
|
||||
} else {
|
||||
crtc = intel_get_load_detect_pipe(connector, &mode, &dpms_mode);
|
||||
crtc = intel_get_load_detect_pipe(intel_output, &mode, &dpms_mode);
|
||||
if (crtc) {
|
||||
type = intel_tv_detect_type(crtc, connector);
|
||||
intel_release_load_detect_pipe(connector, dpms_mode);
|
||||
type = intel_tv_detect_type(crtc, intel_output);
|
||||
intel_release_load_detect_pipe(intel_output, dpms_mode);
|
||||
} else
|
||||
type = -1;
|
||||
}
|
||||
|
|
@ -1585,26 +1586,26 @@ intel_tv_set_property(struct drm_connector *connector, struct drm_property *prop
|
|||
goto out;
|
||||
}
|
||||
tv_priv->tv_format = tv_modes[val].name;
|
||||
intel_tv_mode_set(connector, NULL, NULL);
|
||||
intel_tv_mode_set(&intel_output->enc, NULL, NULL);
|
||||
} else {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
intel_tv_mode_set(connector, NULL, NULL);
|
||||
intel_tv_mode_set(&intel_output->enc, NULL, NULL);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct drm_connector_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_connector_prepare,
|
||||
.prepare = intel_encoder_prepare,
|
||||
.mode_set = intel_tv_mode_set,
|
||||
.commit = intel_connector_commit,
|
||||
.commit = intel_encoder_commit,
|
||||
};
|
||||
|
||||
static const struct drm_connector_funcs intel_tv_connector_funcs = {
|
||||
.dpms = intel_tv_dpms,
|
||||
.save = intel_tv_save,
|
||||
.restore = intel_tv_restore,
|
||||
.mode_valid = intel_tv_mode_valid,
|
||||
|
|
@ -1693,7 +1694,7 @@ intel_tv_init(struct drm_device *dev)
|
|||
|
||||
tv_priv->tv_format = kstrdup(tv_modes[initial_mode].name, GFP_KERNEL);
|
||||
|
||||
drm_connector_helper_add(connector, &intel_tv_helper_funcs);
|
||||
drm_encoder_helper_add(&intel_output->enc, &intel_tv_helper_funcs);
|
||||
connector->interlace_allowed = FALSE;
|
||||
connector->doublescan_allowed = FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -1058,6 +1058,7 @@ struct drm_mode_get_encoder {
|
|||
uint32_t encoder_type;
|
||||
uint32_t encoder_id;
|
||||
|
||||
unsigned int crtc; /**< Id of crtc */
|
||||
uint32_t crtcs;
|
||||
uint32_t clones;
|
||||
};
|
||||
|
|
@ -1079,8 +1080,8 @@ struct drm_mode_get_connector {
|
|||
int count_props;
|
||||
int count_encoders;
|
||||
|
||||
unsigned int encoder; /**< Current Encoder */
|
||||
unsigned int connector; /**< Id */
|
||||
unsigned int crtc; /**< Id of crtc */
|
||||
unsigned int connector_type;
|
||||
unsigned int connector_type_id;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue