Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 129822
b: refs/heads/master
c: 40a518d
h: refs/heads/master
v: v3
  • Loading branch information
Jesse Barnes authored and Dave Airlie committed Jan 16, 2009
1 parent e479226 commit 24a6738
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 37 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 3a03ac1a0223f779a3de313523408ddb099e5679
refs/heads/master: 40a518d9f1fd8ed1061b8b4e2ce8a44794f4eb03
127 changes: 93 additions & 34 deletions trunk/drivers/gpu/drm/drm_crtc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
/*
* Detailed mode info for 800x600@60Hz
*/
static struct drm_display_mode std_mode[] = {
static struct drm_display_mode std_modes[] = {
{ DRM_MODE("800x600", DRM_MODE_TYPE_DEFAULT, 40000, 800, 840,
968, 1056, 0, 600, 601, 605, 628, 0,
DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) },
Expand All @@ -60,15 +60,18 @@ static struct drm_display_mode std_mode[] = {
* changes have occurred.
*
* FIXME: take into account monitor limits
*
* RETURNS:
* Number of modes found on @connector.
*/
void drm_helper_probe_single_connector_modes(struct drm_connector *connector,
uint32_t maxX, uint32_t maxY)
int 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;
int count = 0;

DRM_DEBUG("%s\n", drm_get_connector_name(connector));
/* set all modes to the unverified state */
Expand All @@ -81,14 +84,14 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector,
DRM_DEBUG("%s is disconnected\n",
drm_get_connector_name(connector));
/* TODO set EDID to NULL */
return;
return 0;
}

ret = (*connector_funcs->get_modes)(connector);
count = (*connector_funcs->get_modes)(connector);
if (!count)
return 0;

if (ret) {
drm_mode_connector_list_update(connector);
}
drm_mode_connector_list_update(connector);

if (maxX && maxY)
drm_mode_validate_size(dev, &connector->modes, maxX,
Expand All @@ -102,25 +105,8 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector,

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));
}
if (list_empty(&connector->modes))
return 0;

drm_mode_sort(&connector->modes);

Expand All @@ -131,20 +117,58 @@ void drm_helper_probe_single_connector_modes(struct drm_connector *connector,
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
drm_mode_debug_printmodeline(mode);
}

return count;
}
EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);

void drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
int drm_helper_probe_connector_modes(struct drm_device *dev, uint32_t maxX,
uint32_t maxY)
{
struct drm_connector *connector;
int count = 0;

list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
drm_helper_probe_single_connector_modes(connector, maxX, maxY);
count += drm_helper_probe_single_connector_modes(connector,
maxX, maxY);
}

return count;
}
EXPORT_SYMBOL(drm_helper_probe_connector_modes);

static void drm_helper_add_std_modes(struct drm_device *dev,
struct drm_connector *connector)
{
struct drm_display_mode *mode, *t;
int i;

for (i = 0; i < ARRAY_SIZE(std_modes); i++) {
struct drm_display_mode *stdmode;

/*
* When no valid EDID modes are available we end up
* here and bailed in the past, now we add some standard
* modes and move on.
*/
stdmode = drm_mode_duplicate(dev, &std_modes[i]);
drm_mode_probed_add(connector, stdmode);
drm_mode_list_concat(&connector->probed_modes,
&connector->modes);

DRM_DEBUG("Adding mode %s to %s\n", stdmode->name,
drm_get_connector_name(connector));
}
drm_mode_sort(&connector->modes);

DRM_DEBUG("Added std modes on %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);
}
}

/**
* drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
Expand Down Expand Up @@ -237,6 +261,8 @@ static void drm_enable_connectors(struct drm_device *dev, bool *enabled)

list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
enabled[i] = drm_connector_enabled(connector, true);
DRM_DEBUG("connector %d enabled? %s\n", connector->base.id,
enabled[i] ? "yes" : "no");
any_enabled |= enabled[i];
i++;
}
Expand Down Expand Up @@ -265,11 +291,17 @@ static bool drm_target_preferred(struct drm_device *dev,
continue;
}

DRM_DEBUG("looking for preferred mode on connector %d\n",
connector->base.id);

modes[i] = drm_has_preferred_mode(connector, width, height);
if (!modes[i]) {
/* No preferred modes, pick one off the list */
if (!modes[i] && !list_empty(&connector->modes)) {
list_for_each_entry(modes[i], &connector->modes, head)
break;
}
DRM_DEBUG("found mode %s\n", modes[i] ? modes[i]->name :
"none");
i++;
}
return true;
Expand Down Expand Up @@ -369,6 +401,8 @@ static void drm_setup_crtcs(struct drm_device *dev)
int width, height;
int i, ret;

DRM_DEBUG("\n");

width = dev->mode_config.max_width;
height = dev->mode_config.max_height;

Expand All @@ -390,6 +424,8 @@ static void drm_setup_crtcs(struct drm_device *dev)
if (!ret)
DRM_ERROR("Unable to find initial modes\n");

DRM_DEBUG("picking CRTCs for %dx%d config\n", width, height);

drm_pick_crtcs(dev, crtcs, modes, 0, width, height);

i = 0;
Expand All @@ -403,6 +439,8 @@ static void drm_setup_crtcs(struct drm_device *dev)
}

if (mode && crtc) {
DRM_DEBUG("desired mode %s set on crtc %d\n",
mode->name, crtc->base.id);
crtc->desired_mode = mode;
connector->encoder->crtc = crtc;
} else
Expand Down Expand Up @@ -764,10 +802,31 @@ bool drm_helper_plugged_event(struct drm_device *dev)
*/
bool drm_helper_initial_config(struct drm_device *dev, bool can_grow)
{
int ret = false;
struct drm_connector *connector;
int count = 0;

drm_helper_plugged_event(dev);
return ret;
count = drm_helper_probe_connector_modes(dev,
dev->mode_config.max_width,
dev->mode_config.max_height);

/*
* None of the available connectors had any modes, so add some
* and try to light them up anyway
*/
if (!count) {
DRM_ERROR("connectors have no modes, using standard modes\n");
list_for_each_entry(connector,
&dev->mode_config.connector_list,
head)
drm_helper_add_std_modes(dev, connector);
}

drm_setup_crtcs(dev);

/* alert the driver fb layer */
dev->mode_config.funcs->fb_changed(dev);

return 0;
}
EXPORT_SYMBOL(drm_helper_initial_config);

Expand Down
2 changes: 1 addition & 1 deletion trunk/include/drm/drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ 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);
void (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
int (*fill_modes)(struct drm_connector *connector, uint32_t max_width, uint32_t max_height);
int (*set_property)(struct drm_connector *connector, struct drm_property *property,
uint64_t val);
void (*destroy)(struct drm_connector *connector);
Expand Down
2 changes: 1 addition & 1 deletion trunk/include/drm/drm_crtc_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ struct drm_connector_helper_funcs {
struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
};

extern void drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
extern int 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);
extern bool drm_helper_initial_config(struct drm_device *dev, bool can_grow);
Expand Down

0 comments on commit 24a6738

Please sign in to comment.