Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 4559 → Rev 4560

/drivers/video/drm/drm_crtc_helper.c
39,6 → 39,10
#include <drm/drm_fb_helper.h>
#include <drm/drm_edid.h>
 
MODULE_AUTHOR("David Airlie, Jesse Barnes");
MODULE_DESCRIPTION("DRM KMS helper");
MODULE_LICENSE("GPL and additional rights");
 
/**
* drm_helper_move_panel_connectors_to_head() - move panels to the front in the
* connector list
76,7 → 80,8
{
struct drm_display_mode *mode;
 
if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE))
if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
DRM_MODE_FLAG_3D_MASK))
return;
 
list_for_each_entry(mode, &connector->modes, head) {
86,6 → 91,9
if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
!(flags & DRM_MODE_FLAG_DBLSCAN))
mode->status = MODE_NO_DBLESCAN;
if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
!(flags & DRM_MODE_FLAG_3D_MASK))
mode->status = MODE_NO_STEREO;
}
 
return;
105,9 → 113,9
* then culled (based on validity and the @maxX, @maxY parameters) and put into
* the normal modes list.
*
* Intended to be use as a generic implementation of the ->probe() @connector
* callback for drivers that use the crtc helpers for output mode filtering and
* detection.
* Intended to be use as a generic implementation of the ->fill_modes()
* @connector vfunc for drivers that use the crtc helpers for output mode
* filtering and detection.
*
* RETURNS:
* Number of modes found on @connector.
175,6 → 183,8
mode_flags |= DRM_MODE_FLAG_INTERLACE;
if (connector->doublescan_allowed)
mode_flags |= DRM_MODE_FLAG_DBLSCAN;
if (connector->stereo_allowed)
mode_flags |= DRM_MODE_FLAG_3D_MASK;
drm_mode_validate_flag(connector, mode_flags);
 
list_for_each_entry(mode, &connector->modes, head) {
314,35 → 324,6
}
EXPORT_SYMBOL(drm_helper_disable_unused_functions);
 
/**
* drm_encoder_crtc_ok - can a given crtc drive a given encoder?
* @encoder: encoder to test
* @crtc: crtc to test
*
* Return false if @encoder can't be driven by @crtc, true otherwise.
*/
static bool drm_encoder_crtc_ok(struct drm_encoder *encoder,
struct drm_crtc *crtc)
{
struct drm_device *dev;
struct drm_crtc *tmp;
int crtc_mask = 1;
 
WARN(!crtc, "checking null crtc?\n");
 
dev = crtc->dev;
 
list_for_each_entry(tmp, &dev->mode_config.crtc_list, head) {
if (tmp == crtc)
break;
crtc_mask <<= 1;
}
 
if (encoder->possible_crtcs & crtc_mask)
return true;
return false;
}
 
/*
* Check the CRTC we're going to map each output to vs. its current
* CRTC. If they don't match, we have to disable the output and the CRTC
395,22 → 376,25
struct drm_framebuffer *old_fb)
{
struct drm_device *dev = crtc->dev;
struct drm_display_mode *adjusted_mode, saved_mode, saved_hwmode;
struct drm_display_mode *adjusted_mode, saved_mode;
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
struct drm_encoder_helper_funcs *encoder_funcs;
int saved_x, saved_y;
bool saved_enabled;
struct drm_encoder *encoder;
bool ret = true;
 
saved_enabled = crtc->enabled;
crtc->enabled = drm_helper_crtc_in_use(crtc);
if (!crtc->enabled)
return true;
 
adjusted_mode = drm_mode_duplicate(dev, mode);
if (!adjusted_mode)
if (!adjusted_mode) {
crtc->enabled = saved_enabled;
return false;
}
 
saved_hwmode = crtc->hwmode;
saved_mode = crtc->mode;
saved_x = crtc->x;
saved_y = crtc->y;
523,13 → 507,13
* are later needed by vblank and swap-completion
* timestamping. They are derived from true hwmode.
*/
drm_calc_timestamping_constants(crtc);
drm_calc_timestamping_constants(crtc, &crtc->hwmode);
 
/* FIXME: add subpixel order */
done:
drm_mode_destroy(dev, adjusted_mode);
if (!ret) {
crtc->hwmode = saved_hwmode;
crtc->enabled = saved_enabled;
crtc->mode = saved_mode;
crtc->x = saved_x;
crtc->y = saved_y;
557,6 → 541,14
continue;
 
connector->encoder = NULL;
 
/*
* drm_helper_disable_unused_functions() ought to be
* doing this, but since we've decoupled the encoder
* from the connector above, the required connection
* between them is henceforth no longer available.
*/
connector->dpms = DRM_MODE_DPMS_OFF;
}
}
 
583,9 → 575,8
int drm_crtc_helper_set_config(struct drm_mode_set *set)
{
struct drm_device *dev;
struct drm_crtc *save_crtcs, *new_crtc, *crtc;
struct drm_crtc *new_crtc;
struct drm_encoder *save_encoders, *new_encoder, *encoder;
struct drm_framebuffer *old_fb = NULL;
bool mode_changed = false; /* if true do a full mode set */
bool fb_changed = false; /* if true and !mode_changed just do a flip */
struct drm_connector *save_connectors, *connector;
621,38 → 612,28
 
dev = set->crtc->dev;
 
/* Allocate space for the backup of all (non-pointer) crtc, encoder and
* connector data. */
save_crtcs = kzalloc(dev->mode_config.num_crtc *
sizeof(struct drm_crtc), GFP_KERNEL);
if (!save_crtcs)
return -ENOMEM;
 
/*
* Allocate space for the backup of all (non-pointer) encoder and
* connector data.
*/
save_encoders = kzalloc(dev->mode_config.num_encoder *
sizeof(struct drm_encoder), GFP_KERNEL);
if (!save_encoders) {
kfree(save_crtcs);
if (!save_encoders)
return -ENOMEM;
}
 
save_connectors = kzalloc(dev->mode_config.num_connector *
sizeof(struct drm_connector), GFP_KERNEL);
if (!save_connectors) {
kfree(save_crtcs);
kfree(save_encoders);
return -ENOMEM;
}
 
/* Copy data. Note that driver private data is not affected.
/*
* Copy data. Note that driver private data is not affected.
* Should anything bad happen only the expected state is
* restored, not the drivers personal bookkeeping.
*/
count = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
save_crtcs[count++] = *crtc;
}
 
count = 0;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
save_encoders[count++] = *encoder;
}
775,19 → 756,17
mode_changed = true;
 
if (mode_changed) {
set->crtc->enabled = drm_helper_crtc_in_use(set->crtc);
if (set->crtc->enabled) {
if (drm_helper_crtc_in_use(set->crtc)) {
DRM_DEBUG_KMS("attempting to set mode from"
" userspace\n");
drm_mode_debug_printmodeline(set->mode);
old_fb = set->crtc->fb;
set->crtc->fb = set->fb;
if (!drm_crtc_helper_set_mode(set->crtc, set->mode,
set->x, set->y,
old_fb)) {
save_set.fb)) {
DRM_ERROR("failed to set mode on [CRTC:%d]\n",
set->crtc->base.id);
set->crtc->fb = old_fb;
set->crtc->fb = save_set.fb;
ret = -EINVAL;
goto fail;
}
802,14 → 781,13
} else if (fb_changed) {
set->crtc->x = set->x;
set->crtc->y = set->y;
 
old_fb = set->crtc->fb;
if (set->crtc->fb != set->fb)
set->crtc->fb = set->fb;
ret = crtc_funcs->mode_set_base(set->crtc,
set->x, set->y, old_fb);
set->x, set->y, save_set.fb);
if (ret != 0) {
set->crtc->fb = old_fb;
set->crtc->x = save_set.x;
set->crtc->y = save_set.y;
set->crtc->fb = save_set.fb;
goto fail;
}
}
816,17 → 794,11
 
kfree(save_connectors);
kfree(save_encoders);
kfree(save_crtcs);
return 0;
 
fail:
/* Restore all previous data. */
count = 0;
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
*crtc = save_crtcs[count++];
}
 
count = 0;
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
*encoder = save_encoders[count++];
}
844,7 → 816,6
 
kfree(save_connectors);
kfree(save_encoders);
kfree(save_crtcs);
return ret;
}
EXPORT_SYMBOL(drm_crtc_helper_set_config);
1124,7 → 1095,7
}
EXPORT_SYMBOL(drm_kms_helper_poll_fini);
 
void drm_helper_hpd_irq_event(struct drm_device *dev)
bool drm_helper_hpd_irq_event(struct drm_device *dev)
{
struct drm_connector *connector;
enum drm_connector_status old_status;
1131,7 → 1102,7
bool changed = false;
 
if (!dev->mode_config.poll_enabled)
return;
return false;
 
mutex_lock(&dev->mode_config.mutex);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
1156,5 → 1127,7
 
if (changed)
drm_kms_helper_hotplug_event(dev);
 
return changed;
}
EXPORT_SYMBOL(drm_helper_hpd_irq_event);