Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 6083 → Rev 6084

/drivers/video/drm/drm_modes.c
35,6 → 35,8
#include <linux/export.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <video/of_videomode.h>
#include <video/videomode.h>
#include <drm/drm_modes.h>
 
#include "drm_crtc_internal.h"
276,7 → 278,7
hblank = drm_mode->hdisplay * hblank_percentage /
(100 * HV_FACTOR - hblank_percentage);
hblank -= hblank % (2 * CVT_H_GRANULARITY);
/* 14. find the total pixes per line */
/* 14. find the total pixels per line */
drm_mode->htotal = drm_mode->hdisplay + hblank;
drm_mode->hsync_end = drm_mode->hdisplay + hblank / 2;
drm_mode->hsync_start = drm_mode->hsync_end -
613,6 → 615,46
}
EXPORT_SYMBOL_GPL(drm_display_mode_from_videomode);
 
/**
* drm_display_mode_to_videomode - fill in @vm using @dmode,
* @dmode: drm_display_mode structure to use as source
* @vm: videomode structure to use as destination
*
* Fills out @vm using the display mode specified in @dmode.
*/
void drm_display_mode_to_videomode(const struct drm_display_mode *dmode,
struct videomode *vm)
{
vm->hactive = dmode->hdisplay;
vm->hfront_porch = dmode->hsync_start - dmode->hdisplay;
vm->hsync_len = dmode->hsync_end - dmode->hsync_start;
vm->hback_porch = dmode->htotal - dmode->hsync_end;
 
vm->vactive = dmode->vdisplay;
vm->vfront_porch = dmode->vsync_start - dmode->vdisplay;
vm->vsync_len = dmode->vsync_end - dmode->vsync_start;
vm->vback_porch = dmode->vtotal - dmode->vsync_end;
 
vm->pixelclock = dmode->clock * 1000;
 
vm->flags = 0;
if (dmode->flags & DRM_MODE_FLAG_PHSYNC)
vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
else if (dmode->flags & DRM_MODE_FLAG_NHSYNC)
vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
if (dmode->flags & DRM_MODE_FLAG_PVSYNC)
vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
else if (dmode->flags & DRM_MODE_FLAG_NVSYNC)
vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
if (dmode->flags & DRM_MODE_FLAG_INTERLACE)
vm->flags |= DISPLAY_FLAGS_INTERLACED;
if (dmode->flags & DRM_MODE_FLAG_DBLSCAN)
vm->flags |= DISPLAY_FLAGS_DOUBLESCAN;
if (dmode->flags & DRM_MODE_FLAG_DBLCLK)
vm->flags |= DISPLAY_FLAGS_DOUBLECLK;
}
EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
 
#ifdef CONFIG_OF
/**
* of_get_drm_display_mode - get a drm_display_mode from devicetree
737,6 → 779,8
* - The CRTC_STEREO_DOUBLE flag can be used to compute the timings for
* buffers containing two eyes (only adjust the timings when needed, eg. for
* "frame packing" or "side by side full").
* - The CRTC_NO_DBLSCAN and CRTC_NO_VSCAN flags request that adjustment *not*
* be performed for doublescan and vscan > 1 modes respectively.
*/
void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags)
{
763,6 → 807,7
}
}
 
if (!(adjust_flags & CRTC_NO_DBLSCAN)) {
if (p->flags & DRM_MODE_FLAG_DBLSCAN) {
p->crtc_vdisplay *= 2;
p->crtc_vsync_start *= 2;
769,7 → 814,9
p->crtc_vsync_end *= 2;
p->crtc_vtotal *= 2;
}
}
 
if (!(adjust_flags & CRTC_NO_VSCAN)) {
if (p->vscan > 1) {
p->crtc_vdisplay *= p->vscan;
p->crtc_vsync_start *= p->vscan;
776,6 → 823,7
p->crtc_vsync_end *= p->vscan;
p->crtc_vtotal *= p->vscan;
}
}
 
if (adjust_flags & CRTC_STEREO_DOUBLE) {
unsigned int layout = p->flags & DRM_MODE_FLAG_3D_MASK;
855,6 → 903,12
*/
bool drm_mode_equal(const struct drm_display_mode *mode1, const struct drm_display_mode *mode2)
{
if (!mode1 && !mode2)
return true;
 
if (!mode1 || !mode2)
return false;
 
/* do clock check convert to PICOS so fb modes get matched
* the same */
if (mode1->clock && mode2->clock) {
904,9 → 958,40
EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo);
 
/**
* drm_mode_validate_basic - make sure the mode is somewhat sane
* @mode: mode to check
*
* Check that the mode timings are at least somewhat reasonable.
* Any hardware specific limits are left up for each driver to check.
*
* Returns:
* The mode status
*/
enum drm_mode_status
drm_mode_validate_basic(const struct drm_display_mode *mode)
{
if (mode->clock == 0)
return MODE_CLOCK_LOW;
 
if (mode->hdisplay == 0 ||
mode->hsync_start < mode->hdisplay ||
mode->hsync_end < mode->hsync_start ||
mode->htotal < mode->hsync_end)
return MODE_H_ILLEGAL;
 
if (mode->vdisplay == 0 ||
mode->vsync_start < mode->vdisplay ||
mode->vsync_end < mode->vsync_start ||
mode->vtotal < mode->vsync_end)
return MODE_V_ILLEGAL;
 
return MODE_OK;
}
EXPORT_SYMBOL(drm_mode_validate_basic);
 
/**
* drm_mode_validate_size - make sure modes adhere to size constraints
* @dev: DRM device
* @mode_list: list of modes to check
* @mode: mode to check
* @maxX: maximum width
* @maxY: maximum height
*
914,23 → 999,80
* limitations of the DRM device/connector. If a mode is too big its status
* member is updated with the appropriate validation failure code. The list
* itself is not changed.
*
* Returns:
* The mode status
*/
void drm_mode_validate_size(struct drm_device *dev,
struct list_head *mode_list,
enum drm_mode_status
drm_mode_validate_size(const struct drm_display_mode *mode,
int maxX, int maxY)
{
struct drm_display_mode *mode;
 
list_for_each_entry(mode, mode_list, head) {
if (maxX > 0 && mode->hdisplay > maxX)
mode->status = MODE_VIRTUAL_X;
return MODE_VIRTUAL_X;
 
if (maxY > 0 && mode->vdisplay > maxY)
mode->status = MODE_VIRTUAL_Y;
return MODE_VIRTUAL_Y;
 
return MODE_OK;
}
}
EXPORT_SYMBOL(drm_mode_validate_size);
 
#define MODE_STATUS(status) [MODE_ ## status + 3] = #status
 
static const char * const drm_mode_status_names[] = {
MODE_STATUS(OK),
MODE_STATUS(HSYNC),
MODE_STATUS(VSYNC),
MODE_STATUS(H_ILLEGAL),
MODE_STATUS(V_ILLEGAL),
MODE_STATUS(BAD_WIDTH),
MODE_STATUS(NOMODE),
MODE_STATUS(NO_INTERLACE),
MODE_STATUS(NO_DBLESCAN),
MODE_STATUS(NO_VSCAN),
MODE_STATUS(MEM),
MODE_STATUS(VIRTUAL_X),
MODE_STATUS(VIRTUAL_Y),
MODE_STATUS(MEM_VIRT),
MODE_STATUS(NOCLOCK),
MODE_STATUS(CLOCK_HIGH),
MODE_STATUS(CLOCK_LOW),
MODE_STATUS(CLOCK_RANGE),
MODE_STATUS(BAD_HVALUE),
MODE_STATUS(BAD_VVALUE),
MODE_STATUS(BAD_VSCAN),
MODE_STATUS(HSYNC_NARROW),
MODE_STATUS(HSYNC_WIDE),
MODE_STATUS(HBLANK_NARROW),
MODE_STATUS(HBLANK_WIDE),
MODE_STATUS(VSYNC_NARROW),
MODE_STATUS(VSYNC_WIDE),
MODE_STATUS(VBLANK_NARROW),
MODE_STATUS(VBLANK_WIDE),
MODE_STATUS(PANEL),
MODE_STATUS(INTERLACE_WIDTH),
MODE_STATUS(ONE_WIDTH),
MODE_STATUS(ONE_HEIGHT),
MODE_STATUS(ONE_SIZE),
MODE_STATUS(NO_REDUCED),
MODE_STATUS(NO_STEREO),
MODE_STATUS(UNVERIFIED),
MODE_STATUS(BAD),
MODE_STATUS(ERROR),
};
 
#undef MODE_STATUS
 
static const char *drm_get_mode_status_name(enum drm_mode_status status)
{
int index = status + 3;
 
if (WARN_ON(index < 0 || index >= ARRAY_SIZE(drm_mode_status_names)))
return "";
 
return drm_mode_status_names[index];
}
 
/**
* drm_mode_prune_invalid - remove invalid modes from mode list
* @dev: DRM device
952,8 → 1094,9
list_del(&mode->head);
if (verbose) {
drm_mode_debug_printmodeline(mode);
DRM_DEBUG_KMS("Not using %s mode %d\n",
mode->name, mode->status);
DRM_DEBUG_KMS("Not using %s mode: %s\n",
mode->name,
drm_get_mode_status_name(mode->status));
}
drm_mode_destroy(dev, mode);
}
1011,7 → 1154,7
/**
* drm_mode_connector_list_update - update the mode list for the connector
* @connector: the connector to update
* @merge_type_bits: whether to merge or overright type bits.
* @merge_type_bits: whether to merge or overwrite type bits
*
* This moves the modes from the @connector probed_modes list
* to the actual mode list. It compares the probed mode against the current
1055,3 → 1198,89
}
}
EXPORT_SYMBOL(drm_mode_connector_list_update);
/**
* drm_crtc_convert_to_umode - convert a drm_display_mode into a modeinfo
* @out: drm_mode_modeinfo struct to return to the user
* @in: drm_display_mode to use
*
* Convert a drm_display_mode into a drm_mode_modeinfo structure to return to
* the user.
*/
void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
const struct drm_display_mode *in)
{
WARN(in->hdisplay > USHRT_MAX || in->hsync_start > USHRT_MAX ||
in->hsync_end > USHRT_MAX || in->htotal > USHRT_MAX ||
in->hskew > USHRT_MAX || in->vdisplay > USHRT_MAX ||
in->vsync_start > USHRT_MAX || in->vsync_end > USHRT_MAX ||
in->vtotal > USHRT_MAX || in->vscan > USHRT_MAX,
"timing values too large for mode info\n");
 
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
out->hsync_end = in->hsync_end;
out->htotal = in->htotal;
out->hskew = in->hskew;
out->vdisplay = in->vdisplay;
out->vsync_start = in->vsync_start;
out->vsync_end = in->vsync_end;
out->vtotal = in->vtotal;
out->vscan = in->vscan;
out->vrefresh = in->vrefresh;
out->flags = in->flags;
out->type = in->type;
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
}
 
/**
* drm_crtc_convert_umode - convert a modeinfo into a drm_display_mode
* @out: drm_display_mode to return to the user
* @in: drm_mode_modeinfo to use
*
* Convert a drm_mode_modeinfo into a drm_display_mode structure to return to
* the caller.
*
* Returns:
* Zero on success, negative errno on failure.
*/
int drm_mode_convert_umode(struct drm_display_mode *out,
const struct drm_mode_modeinfo *in)
{
int ret = -EINVAL;
 
if (in->clock > INT_MAX || in->vrefresh > INT_MAX) {
ret = -ERANGE;
goto out;
}
 
if ((in->flags & DRM_MODE_FLAG_3D_MASK) > DRM_MODE_FLAG_3D_MAX)
goto out;
 
out->clock = in->clock;
out->hdisplay = in->hdisplay;
out->hsync_start = in->hsync_start;
out->hsync_end = in->hsync_end;
out->htotal = in->htotal;
out->hskew = in->hskew;
out->vdisplay = in->vdisplay;
out->vsync_start = in->vsync_start;
out->vsync_end = in->vsync_end;
out->vtotal = in->vtotal;
out->vscan = in->vscan;
out->vrefresh = in->vrefresh;
out->flags = in->flags;
out->type = in->type;
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
 
out->status = drm_mode_validate_basic(out);
if (out->status != MODE_OK)
goto out;
 
ret = 0;
 
out:
return ret;
}