Merge commit 'origin/modesetting-101' into modesetting-radeon

main
Jerome Glisse 2007-12-06 22:42:17 +01:00
commit 931b4a84a0
12 changed files with 600 additions and 536 deletions

View File

@ -42,6 +42,9 @@
#include <drm.h>
#include <string.h>
#define U642VOID(x) ((void *)(unsigned long)(x))
#define VOID2U64(x) ((uint64_t)(unsigned long)(x))
/*
* Util functions
*/
@ -101,7 +104,6 @@ void drmModeFreeResources(drmModeResPtr ptr)
if (!ptr)
return;
drmFree(ptr->modes);
drmFree(ptr);
}
@ -150,13 +152,11 @@ drmModeResPtr drmModeGetResources(int fd)
return 0;
if (res.count_fbs)
res.fb_id = drmMalloc(res.count_fbs*sizeof(uint32_t));
res.fb_id_ptr = VOID2U64(drmMalloc(res.count_fbs*sizeof(uint32_t)));
if (res.count_crtcs)
res.crtc_id = drmMalloc(res.count_crtcs*sizeof(uint32_t));
res.crtc_id_ptr = VOID2U64(drmMalloc(res.count_crtcs*sizeof(uint32_t)));
if (res.count_outputs)
res.output_id = drmMalloc(res.count_outputs*sizeof(uint32_t));
if (res.count_modes)
res.modes = drmMalloc(res.count_modes*sizeof(*res.modes));
res.output_id_ptr = VOID2U64(drmMalloc(res.count_outputs*sizeof(uint32_t)));
if (ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res)) {
r = NULL;
@ -171,21 +171,22 @@ drmModeResPtr drmModeGetResources(int fd)
if (!(r = drmMalloc(sizeof(*r))))
return 0;
r->min_width = res.min_width;
r->max_width = res.max_width;
r->min_height = res.min_height;
r->max_height = res.max_height;
r->count_fbs = res.count_fbs;
r->count_crtcs = res.count_crtcs;
r->count_outputs = res.count_outputs;
r->count_modes = res.count_modes;
/* TODO we realy should test if these allocs fails. */
r->fbs = drmAllocCpy(res.fb_id, res.count_fbs, sizeof(uint32_t));
r->crtcs = drmAllocCpy(res.crtc_id, res.count_crtcs, sizeof(uint32_t));
r->outputs = drmAllocCpy(res.output_id, res.count_outputs, sizeof(uint32_t));
r->modes = drmAllocCpy(res.modes, res.count_modes, sizeof(struct drm_mode_modeinfo));
r->fbs = drmAllocCpy(U642VOID(res.fb_id_ptr), res.count_fbs, sizeof(uint32_t));
r->crtcs = drmAllocCpy(U642VOID(res.crtc_id_ptr), res.count_crtcs, sizeof(uint32_t));
r->outputs = drmAllocCpy(U642VOID(res.output_id_ptr), res.count_outputs, sizeof(uint32_t));
err_allocs:
drmFree(res.fb_id);
drmFree(res.crtc_id);
drmFree(res.output_id);
drmFree(res.modes);
drmFree(U642VOID(res.fb_id_ptr));
drmFree(U642VOID(res.crtc_id_ptr));
drmFree(U642VOID(res.output_id_ptr));
return r;
}
@ -269,7 +270,9 @@ drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId)
r->crtc_id = crtc.crtc_id;
r->x = crtc.x;
r->y = crtc.y;
r->mode = crtc.mode;
r->mode_valid = crtc.mode_valid;
if (r->mode_valid)
memcpy(&r->mode, &crtc.mode, sizeof(struct drm_mode_modeinfo));
r->buffer_id = crtc.fb_id;
r->gamma_size = crtc.gamma_size;
r->count_outputs = crtc.count_outputs;
@ -287,8 +290,8 @@ err_allocs:
int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
uint32_t x, uint32_t y, uint32_t modeId,
uint32_t *outputs, int count)
uint32_t x, uint32_t y, uint32_t *outputs, int count,
struct drm_mode_modeinfo *mode)
{
struct drm_mode_crtc crtc;
@ -301,9 +304,13 @@ int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
crtc.y = y;
crtc.crtc_id = crtcId;
crtc.fb_id = bufferId;
crtc.set_outputs = outputs;
crtc.set_outputs_ptr = VOID2U64(outputs);
crtc.count_outputs = count;
crtc.mode = modeId;
if (mode) {
memcpy(&crtc.mode, mode, sizeof(struct drm_mode_modeinfo));
crtc.mode_valid = 1;
} else
crtc.mode_valid = 0;
return ioctl(fd, DRM_IOCTL_MODE_SETCRTC, &crtc);
}
@ -324,21 +331,21 @@ drmModeOutputPtr drmModeGetOutput(int fd, uint32_t output_id)
out.count_clones = 0;
out.clones = 0;
out.count_modes = 0;
out.modes = 0;
out.modes_ptr = 0;
out.count_props = 0;
out.props = NULL;
out.prop_values = NULL;
out.props_ptr = 0;
out.prop_values_ptr = 0;
if (ioctl(fd, DRM_IOCTL_MODE_GETOUTPUT, &out))
return 0;
if (out.count_props) {
out.props = drmMalloc(out.count_props*sizeof(uint32_t));
out.prop_values = drmMalloc(out.count_props*sizeof(uint32_t));
out.props_ptr = VOID2U64(drmMalloc(out.count_props*sizeof(uint32_t)));
out.prop_values_ptr = VOID2U64(drmMalloc(out.count_props*sizeof(uint64_t)));
}
if (out.count_modes)
out.modes = drmMalloc(out.count_modes*sizeof(uint32_t));
out.modes_ptr = VOID2U64(drmMalloc(out.count_modes*sizeof(struct drm_mode_modeinfo)));
if (ioctl(fd, DRM_IOCTL_MODE_GETOUTPUT, &out))
goto err_allocs;
@ -360,50 +367,36 @@ drmModeOutputPtr drmModeGetOutput(int fd, uint32_t output_id)
r->crtcs = out.crtcs;
r->clones = out.clones;
r->count_props = out.count_props;
r->props = drmAllocCpy(out.props, out.count_props, sizeof(uint32_t));
r->prop_values = drmAllocCpy(out.prop_values, out.count_props, sizeof(uint32_t));
r->modes = drmAllocCpy(out.modes, out.count_modes, sizeof(uint32_t));
r->props = drmAllocCpy(U642VOID(out.props_ptr), out.count_props, sizeof(uint32_t));
r->prop_values = drmAllocCpy(U642VOID(out.prop_values_ptr), out.count_props, sizeof(uint64_t));
r->modes = drmAllocCpy(U642VOID(out.modes_ptr), out.count_modes, sizeof(struct drm_mode_modeinfo));
strncpy(r->name, out.name, DRM_OUTPUT_NAME_LEN);
r->name[DRM_OUTPUT_NAME_LEN-1] = 0;
err_allocs:
drmFree(out.prop_values);
drmFree(out.props);
drmFree(out.modes);
drmFree(U642VOID(out.prop_values_ptr));
drmFree(U642VOID(out.props_ptr));
drmFree(U642VOID(out.modes_ptr));
return r;
}
uint32_t drmModeAddMode(int fd, struct drm_mode_modeinfo *mode_info)
int drmModeAttachMode(int fd, uint32_t output_id, struct drm_mode_modeinfo *mode_info)
{
if (ioctl(fd, DRM_IOCTL_MODE_ADDMODE, mode_info))
return 0;
return mode_info->id;
}
int drmModeRmMode(int fd, uint32_t mode_id)
{
return ioctl(fd, DRM_IOCTL_MODE_RMMODE, &mode_id);
}
int drmModeAttachMode(int fd, uint32_t output_id, uint32_t mode_id)
{
struct drm_mode_mode_cmd res;
memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
res.output_id = output_id;
res.mode_id = mode_id;
return ioctl(fd, DRM_IOCTL_MODE_ATTACHMODE, &res);
}
int drmModeDetachMode(int fd, uint32_t output_id, uint32_t mode_id)
int drmModeDetachMode(int fd, uint32_t output_id, struct drm_mode_modeinfo *mode_info)
{
struct drm_mode_mode_cmd res;
memcpy(&res.mode, mode_info, sizeof(struct drm_mode_modeinfo));
res.output_id = output_id;
res.mode_id = mode_id;
return ioctl(fd, DRM_IOCTL_MODE_DETACHMODE, &res);
}
@ -413,22 +406,28 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
{
struct drm_mode_get_property prop;
drmModePropertyPtr r;
struct drm_mode_property_blob *blob_tmp;
int i;
prop.prop_id = property_id;
prop.count_enums = 0;
prop.count_enum_blobs = 0;
prop.count_values = 0;
prop.flags = 0;
prop.enums = NULL;
prop.values = NULL;
prop.enum_blob_ptr = 0;
prop.values_ptr = 0;
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop))
return 0;
if (prop.count_values)
prop.values = drmMalloc(prop.count_values * sizeof(uint32_t));
prop.values_ptr = VOID2U64(drmMalloc(prop.count_values * sizeof(uint64_t)));
if (prop.count_enums)
prop.enums = drmMalloc(prop.count_enums * sizeof(struct drm_mode_property_enum));
if (prop.count_enum_blobs & (prop.flags & DRM_MODE_PROP_ENUM))
prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(struct drm_mode_property_enum)));
if (prop.count_enum_blobs & (prop.flags & DRM_MODE_PROP_BLOB)) {
prop.values_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
prop.enum_blob_ptr = VOID2U64(drmMalloc(prop.count_enum_blobs * sizeof(uint32_t)));
}
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPERTY, &prop)) {
r = NULL;
@ -440,16 +439,24 @@ drmModePropertyPtr drmModeGetProperty(int fd, uint32_t property_id)
r->prop_id = prop.prop_id;
r->count_values = prop.count_values;
r->count_enums = prop.count_enums;
r->values = drmAllocCpy(prop.values, prop.count_values, sizeof(uint32_t));
r->enums = drmAllocCpy(prop.enums, prop.count_enums, sizeof(struct drm_mode_property_enum));
r->flags = prop.flags;
if (prop.count_values)
r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_values, sizeof(uint64_t));
if (prop.flags & DRM_MODE_PROP_ENUM) {
r->count_enums = prop.count_enum_blobs;
r->enums = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(struct drm_mode_property_enum));
} else if (prop.flags & DRM_MODE_PROP_ENUM) {
r->values = drmAllocCpy(U642VOID(prop.values_ptr), prop.count_enum_blobs, sizeof(uint32_t));
r->blob_ids = drmAllocCpy(U642VOID(prop.enum_blob_ptr), prop.count_enum_blobs, sizeof(uint32_t));
r->count_blobs = prop.count_enum_blobs;
}
strncpy(r->name, prop.name, DRM_PROP_NAME_LEN);
r->name[DRM_PROP_NAME_LEN-1] = 0;
err_allocs:
drmFree(prop.values);
drmFree(prop.enums);
drmFree(U642VOID(prop.values_ptr));
drmFree(U642VOID(prop.enum_blob_ptr));
return r;
}
@ -463,3 +470,44 @@ void drmModeFreeProperty(drmModePropertyPtr ptr)
drmFree(ptr->enums);
drmFree(ptr);
}
drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id)
{
struct drm_mode_get_blob blob;
drmModePropertyBlobPtr r;
blob.length = 0;
blob.data = 0;
blob.blob_id = blob_id;
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob))
return NULL;
if (blob.length)
blob.data = VOID2U64(drmMalloc(blob.length));
if (ioctl(fd, DRM_IOCTL_MODE_GETPROPBLOB, &blob)) {
r = NULL;
goto err_allocs;
}
if (!(r = drmMalloc(sizeof(*r))))
return NULL;
r->id = blob.blob_id;
r->length = blob.length;
r->data = drmAllocCpy(U642VOID(blob.data), 1, blob.length);
err_allocs:
drmFree(U642VOID(blob.data));
return r;
}
void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr)
{
if (!ptr)
return;
drmFree(ptr->data);
drmFree(ptr);
}

View File

@ -63,22 +63,28 @@ typedef struct _drmModeRes {
int count_outputs;
uint32_t *outputs;
int count_modes;
struct drm_mode_modeinfo *modes;
uint32_t min_width, max_width;
uint32_t min_height, max_height;
} drmModeRes, *drmModeResPtr;
typedef struct drm_mode_fb_cmd drmModeFB, *drmModeFBPtr;
typedef struct _drmModePropertyBlob {
uint32_t id;
uint32_t length;
void *data;
} drmModePropertyBlobRes, *drmModePropertyBlobPtr;
typedef struct _drmModeProperty {
unsigned int prop_id;
unsigned int flags;
unsigned char name[DRM_PROP_NAME_LEN];
int count_values;
uint32_t *values;
uint64_t *values; // store the blob lengths
int count_enums;
struct drm_mode_property_enum *enums;
int count_blobs;
uint32_t *blob_ids; // store the blob IDs
} drmModePropertyRes, *drmModePropertyPtr;
typedef struct _drmModeCrtc {
@ -87,7 +93,8 @@ typedef struct _drmModeCrtc {
uint32_t x, y; /**< Position on the frameuffer */
uint32_t width, height;
uint32_t mode; /**< Current mode used */
int mode_valid;
struct drm_mode_modeinfo mode;
int count_outputs;
uint32_t outputs; /**< Outputs that are connected */
@ -130,11 +137,11 @@ typedef struct _drmModeOutput {
uint32_t clones; /**< Mask of clones */
int count_modes;
uint32_t *modes; /**< List of modes ids */
struct drm_mode_modeinfo *modes;
int count_props;
uint32_t *props; /**< List of property ids */
uint32_t *prop_values; /**< List of property values */
uint64_t *prop_values; /**< List of property values */
} drmModeOutput, *drmModeOutputPtr;
@ -185,9 +192,9 @@ extern drmModeCrtcPtr drmModeGetCrtc(int fd, uint32_t crtcId);
/**
* Set the mode on a crtc crtcId with the given mode modeId.
*/
extern int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
uint32_t x, uint32_t y, uint32_t modeId,
uint32_t *outputs, int count);
int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
uint32_t x, uint32_t y, uint32_t *outputs, int count,
struct drm_mode_modeinfo *mode);
/*
@ -200,27 +207,19 @@ extern int drmModeSetCrtc(int fd, uint32_t crtcId, uint32_t bufferId,
extern drmModeOutputPtr drmModeGetOutput(int fd,
uint32_t outputId);
/**
* Adds a new mode from the given mode info.
* Name must be unique.
*/
extern uint32_t drmModeAddMode(int fd, struct drm_mode_modeinfo *modeInfo);
/**
* Removes a mode created with AddMode, must be unused.
*/
extern int drmModeRmMode(int fd, uint32_t modeId);
/**
* Attaches the given mode to an output.
*/
extern int drmModeAttachMode(int fd, uint32_t outputId, uint32_t modeId);
extern int drmModeAttachMode(int fd, uint32_t outputId, struct drm_mode_modeinfo *mode_info);
/**
* Detaches a mode from the output
* must be unused, by the given mode.
*/
extern int drmModeDetachMode(int fd, uint32_t outputId, uint32_t modeId);
extern int drmModeDetachMode(int fd, uint32_t outputId, struct drm_mode_modeinfo *mode_info);
extern drmModePropertyPtr drmModeGetProperty(int fd, uint32_t propertyId);
extern void drmModeFreeProperty(drmModePropertyPtr ptr);
extern drmModePropertyBlobPtr drmModeGetPropertyBlob(int fd, uint32_t blob_id);
extern void drmModeFreePropertyBlob(drmModePropertyBlobPtr ptr);

View File

@ -413,6 +413,8 @@ int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
case _DRM_SHM:
vfree(map->handle);
dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
dev->lock.file_priv = NULL;
wake_up_interruptible(&dev->lock.lock_queue);
break;
case _DRM_AGP:
case _DRM_SCATTER_GATHER:

File diff suppressed because it is too large Load Diff

View File

@ -234,9 +234,16 @@ struct drm_framebuffer {
struct list_head filp_head;
};
struct drm_property_blob {
struct list_head head;
unsigned int length;
unsigned int id;
void *data;
};
struct drm_property_enum {
struct list_head head;
uint32_t value;
uint64_t value;
unsigned char name[DRM_PROP_NAME_LEN];
};
@ -246,9 +253,9 @@ struct drm_property {
uint32_t flags;
char name[DRM_PROP_NAME_LEN];
uint32_t num_values;
uint32_t *values;
uint64_t *values;
struct list_head enum_list;
struct list_head enum_blob_list;
};
struct drm_crtc;
@ -448,10 +455,10 @@ struct drm_output {
const struct drm_output_funcs *funcs;
void *driver_private;
u32 user_mode_ids[DRM_OUTPUT_MAX_UMODES];
struct list_head user_modes;
struct drm_property_blob *edid_blob_ptr;
u32 property_ids[DRM_OUTPUT_MAX_PROPERTY];
u32 property_values[DRM_OUTPUT_MAX_PROPERTY];
uint64_t property_values[DRM_OUTPUT_MAX_PROPERTY];
};
/**
@ -484,8 +491,6 @@ struct drm_mode_config {
int num_crtc;
struct list_head crtc_list;
struct list_head usermode_list;
struct list_head property_list;
int min_width, min_height;
@ -494,6 +499,10 @@ struct drm_mode_config {
/* DGA stuff? */
struct drm_mode_config_funcs *funcs;
unsigned long fb_base;
/* pointers to standard properties */
struct list_head property_blob_list;
struct drm_property *edid_property;
};
struct drm_output *drm_output_create(struct drm_device *dev,
@ -518,9 +527,6 @@ 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);
extern void drm_mode_addmode(struct drm_device *dev, struct drm_display_mode *user_mode);
extern int drm_mode_rmmode(struct drm_device *dev, struct drm_display_mode *mode);
/* for us by fb module */
extern int drm_mode_attachmode_crtc(struct drm_device *dev,
struct drm_crtc *crtc,
@ -541,7 +547,7 @@ extern int drm_mode_vrefresh(struct drm_display_mode *mode);
extern void drm_mode_set_crtcinfo(struct drm_display_mode *p,
int adjust_flags);
extern void drm_mode_output_list_update(struct drm_output *output);
extern int drm_mode_output_update_edid_property(struct drm_output *output, unsigned char *edid);
extern struct drm_display_mode *drm_crtc_mode_create(struct drm_device *dev);
extern bool drm_initial_config(struct drm_device *dev, bool cangrow);
extern void drm_framebuffer_set_object(struct drm_device *dev,
@ -554,12 +560,12 @@ extern bool drm_crtc_set_mode(struct drm_crtc *crtc, struct drm_display_mode *mo
int x, int y);
extern int drm_output_attach_property(struct drm_output *output,
struct drm_property *property, int init_val);
struct drm_property *property, uint64_t init_val);
extern struct drm_property *drm_property_create(struct drm_device *dev, int flags,
const char *name, int num_values);
extern void drm_property_destroy(struct drm_device *dev, struct drm_property *property);
extern int drm_property_add_enum(struct drm_property *property, int index,
uint32_t value, const char *name);
uint64_t value, const char *name);
/* IOCTLs */
extern int drm_mode_getresources(struct drm_device *dev,
@ -588,5 +594,7 @@ extern int drm_mode_detachmode_ioctl(struct drm_device *dev,
extern int drm_mode_getproperty_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
extern int drm_mode_getblob_ioctl(struct drm_device *dev,
void *data, struct drm_file *file_priv);
#endif /* __DRM_CRTC_H__ */

View File

@ -124,8 +124,8 @@ static struct drm_ioctl_desc drm_ioctls[] = {
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDMODE, drm_mode_addmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMMODE, drm_mode_rmmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_ROOT_ONLY),
DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_ROOT_ONLY),
@ -277,11 +277,6 @@ int drm_lastclose(struct drm_device * dev)
if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
drm_dma_takedown(dev);
if (dev->lock.hw_lock) {
dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
dev->lock.file_priv = NULL;
wake_up_interruptible(&dev->lock.lock_queue);
}
dev->dev_mapping = NULL;
mutex_unlock(&dev->struct_mutex);

View File

@ -46,12 +46,12 @@
void drm_mode_debug_printmodeline(struct drm_device *dev,
struct drm_display_mode *mode)
{
DRM_DEBUG("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x\n",
DRM_DEBUG("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
mode->mode_id, mode->name, mode->vrefresh, mode->clock,
mode->hdisplay, mode->hsync_start,
mode->hsync_end, mode->htotal,
mode->vdisplay, mode->vsync_start,
mode->vsync_end, mode->vtotal, mode->type);
mode->vsync_end, mode->vtotal, mode->type, mode->flags);
}
EXPORT_SYMBOL(drm_mode_debug_printmodeline);

View File

@ -245,4 +245,5 @@ void intel_crt_init(struct drm_device *dev)
output->driver_private = intel_output;
output->interlace_allowed = 0;
output->doublescan_allowed = 0;
}

View File

@ -216,6 +216,32 @@ static int intelfb_check_var(struct fb_var_screeninfo *var,
return 0;
}
bool i915_drmfb_mode_equal(struct drm_display_mode *mode1, struct drm_display_mode *mode2, unsigned int pixclock)
{
if (mode1->hdisplay == mode2->hdisplay &&
mode1->hsync_start == mode2->hsync_start &&
mode1->hsync_end == mode2->hsync_end &&
mode1->htotal == mode2->htotal &&
mode1->hskew == mode2->hskew &&
mode1->vdisplay == mode2->vdisplay &&
mode1->vsync_start == mode2->vsync_start &&
mode1->vsync_end == mode2->vsync_end &&
mode1->vtotal == mode2->vtotal &&
mode1->vscan == mode2->vscan &&
mode1->flags == mode2->flags)
{
if (mode1->clock == mode2->clock)
return true;
if (KHZ2PICOS(mode2->clock) == pixclock)
return true;
return false;
}
return false;
}
/* this will let fbcon do the mode init */
/* FIXME: take mode config lock? */
static int intelfb_set_par(struct fb_info *info)
@ -260,6 +286,10 @@ static int intelfb_set_par(struct fb_info *info)
drm_mode->vtotal = drm_mode->vsync_end + var->upper_margin;
drm_mode->clock = PICOS2KHZ(var->pixclock);
drm_mode->vrefresh = drm_mode_vrefresh(drm_mode);
drm_mode->flags = 0;
drm_mode->flags |= var->sync & FB_SYNC_HOR_HIGH_ACT ? V_PHSYNC : V_NHSYNC;
drm_mode->flags |= var->sync & FB_SYNC_VERT_HIGH_ACT ? V_PVSYNC : V_NVSYNC;
drm_mode_set_name(drm_mode);
drm_mode_set_crtcinfo(drm_mode, CRTC_INTERLACE_HALVE_V);
@ -270,9 +300,8 @@ static int intelfb_set_par(struct fb_info *info)
drm_mode_debug_printmodeline(dev, drm_mode);
list_for_each_entry(search_mode, &output->modes, head) {
DRM_ERROR("mode %s : %s\n", drm_mode->name, search_mode->name);
drm_mode_debug_printmodeline(dev, search_mode);
if (drm_mode_equal(drm_mode, search_mode)) {
if (i915_drmfb_mode_equal(drm_mode, search_mode, var->pixclock)) {
drm_mode_destroy(dev, drm_mode);
drm_mode = search_mode;
found = 1;
@ -281,10 +310,8 @@ static int intelfb_set_par(struct fb_info *info)
}
if (!found) {
drm_mode_addmode(dev, drm_mode);
if (par->fb_mode) {
drm_mode_detachmode_crtc(dev, par->fb_mode);
drm_mode_rmmode(dev, par->fb_mode);
}
par->fb_mode = drm_mode;
@ -293,9 +320,11 @@ static int intelfb_set_par(struct fb_info *info)
drm_mode_attachmode_crtc(dev, par->crtc, par->fb_mode);
}
if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0))
return -EINVAL;
if (par->crtc->enabled) {
if (!drm_mode_equal(&par->crtc->mode, drm_mode))
if (!drm_crtc_set_mode(par->crtc, drm_mode, 0, 0))
return -EINVAL;
}
return 0;
}
@ -552,7 +581,6 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
info->var.activate = FB_ACTIVATE_NOW;
info->var.height = -1;
info->var.width = -1;
info->var.vmode = FB_VMODE_NONINTERLACED;
info->var.xres = mode->hdisplay;
info->var.right_margin = mode->hsync_start - mode->hdisplay;
@ -562,10 +590,20 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
info->var.lower_margin = mode->vsync_start - mode->vdisplay;
info->var.vsync_len = mode->vsync_end - mode->vsync_start;
info->var.upper_margin = mode->vtotal - mode->vsync_end;
info->var.pixclock = 10000000 / mode->htotal * 1000 /
mode->vtotal * 100;
/* avoid overflow */
info->var.pixclock = info->var.pixclock * 1000 / mode->vrefresh;
info->var.pixclock = KHZ2PICOS(mode->clock);
if (mode->flags & V_PHSYNC)
info->var.sync |= FB_SYNC_HOR_HIGH_ACT;
if (mode->flags & V_PVSYNC)
info->var.sync |= FB_SYNC_VERT_HIGH_ACT;
if (mode->flags & V_INTERLACE)
info->var.vmode = FB_VMODE_INTERLACED;
else if (mode->flags & V_DBLSCAN)
info->var.vmode = FB_VMODE_DOUBLE;
else
info->var.vmode = FB_VMODE_NONINTERLACED;
info->pixmap.size = 64*1024;
info->pixmap.buf_align = 8;

View File

@ -55,6 +55,7 @@ int intel_ddc_get_modes(struct drm_output *output)
edid = drm_get_edid(output, &intel_output->ddc_bus->adapter);
if (edid) {
drm_mode_output_update_edid_property(output, edid);
ret = drm_add_edid_modes(output, edid);
kfree(edid);
}

View File

@ -908,9 +908,6 @@ struct drm_mm_init_arg {
#define DRM_MODE_TYPE_DRIVER (1<<6)
struct drm_mode_modeinfo {
unsigned int id;
unsigned int clock;
unsigned short hdisplay, hsync_start, hsync_end, htotal, hskew;
unsigned short vdisplay, vsync_start, vsync_end, vtotal, vscan;
@ -923,43 +920,42 @@ struct drm_mode_modeinfo {
};
struct drm_mode_card_res {
uint64_t fb_id_ptr;
uint64_t crtc_id_ptr;
uint64_t output_id_ptr;
int count_fbs;
unsigned int __user *fb_id;
int count_crtcs;
unsigned int __user *crtc_id;
int count_outputs;
unsigned int __user *output_id;
int count_modes;
struct drm_mode_modeinfo __user *modes;
int min_width, max_width;
int min_height, max_height;
};
struct drm_mode_crtc {
uint64_t set_outputs_ptr;
unsigned int crtc_id; /**< Id */
unsigned int fb_id; /**< Id of framebuffer */
int x, y; /**< Position on the frameuffer */
unsigned int mode; /**< Current mode used */
int count_outputs;
unsigned int outputs; /**< Outputs that are connected */
int count_possibles;
unsigned int possibles; /**< Outputs that can be connected */
unsigned int __user *set_outputs; /**< Outputs to be connected */
int gamma_size;
int mode_valid;
struct drm_mode_modeinfo mode;
};
struct drm_mode_get_output {
uint64_t modes_ptr;
uint64_t props_ptr;
uint64_t prop_values_ptr;
int count_modes;
int count_props;
unsigned int output; /**< Id */
unsigned int crtc; /**< Id of crtc */
unsigned char name[DRM_OUTPUT_NAME_LEN];
@ -967,42 +963,39 @@ struct drm_mode_get_output {
unsigned int connection;
unsigned int mm_width, mm_height; /**< HxW in millimeters */
unsigned int subpixel;
int count_crtcs;
unsigned int crtcs; /**< possible crtc to connect to */
int count_clones;
unsigned int crtcs; /**< possible crtc to connect to */
unsigned int clones; /**< list of clones */
int count_modes;
unsigned int __user *modes; /**< list of modes it supports */
int count_props;
unsigned int __user *props;
unsigned int __user *prop_values;
};
#define DRM_MODE_PROP_PENDING (1<<0)
#define DRM_MODE_PROP_RANGE (1<<1)
#define DRM_MODE_PROP_IMMUTABLE (1<<2)
#define DRM_MODE_PROP_ENUM (1<<3) // enumerated type with text strings
#define DRM_MODE_PROP_BLOB (1<<4)
struct drm_mode_property_enum {
uint32_t value;
uint64_t value;
unsigned char name[DRM_PROP_NAME_LEN];
};
struct drm_mode_get_property {
uint64_t values_ptr; /* values and blob lengths */
uint64_t enum_blob_ptr; /* enum and blob id ptrs */
unsigned int prop_id;
unsigned int flags;
unsigned char name[DRM_PROP_NAME_LEN];
int count_values;
uint32_t __user *values;
int count_enum_blobs;
};
int count_enums;
struct drm_mode_property_enum *enums;
struct drm_mode_get_blob {
uint32_t blob_id;
uint32_t length;
uint64_t data;
};
struct drm_mode_fb_cmd {
@ -1016,7 +1009,7 @@ struct drm_mode_fb_cmd {
struct drm_mode_mode_cmd {
unsigned int output_id;
unsigned int mode_id;
struct drm_mode_modeinfo mode;
};
/**
@ -1119,8 +1112,7 @@ struct drm_mode_mode_cmd {
#define DRM_IOCTL_MODE_RMFB DRM_IOWR(0xA5, unsigned int)
#define DRM_IOCTL_MODE_GETFB DRM_IOWR(0xA6, struct drm_mode_fb_cmd)
#define DRM_IOCTL_MODE_ADDMODE DRM_IOWR(0xA7, struct drm_mode_modeinfo)
#define DRM_IOCTL_MODE_RMMODE DRM_IOWR(0xA8, unsigned int)
#define DRM_IOCTL_MODE_GETPROPBLOB DRM_IOWR(0xA8, struct drm_mode_get_blob)
#define DRM_IOCTL_MODE_ATTACHMODE DRM_IOWR(0xA9, struct drm_mode_mode_cmd)
#define DRM_IOCTL_MODE_DETACHMODE DRM_IOWR(0xAA, struct drm_mode_mode_cmd)

View File

@ -20,20 +20,9 @@ const char* getConnectionText(drmModeConnection conn)
}
struct drm_mode_modeinfo* findMode(drmModeResPtr res, uint32_t id)
{
int i;
for (i = 0; i < res->count_modes; i++) {
if (res->modes[i].id == id)
return &res->modes[i];
}
return 0;
}
int printMode(struct drm_mode_modeinfo *mode)
{
#if 0
#if 1
printf("Mode: %s\n", mode->name);
printf("\tclock : %i\n", mode->clock);
printf("\thdisplay : %i\n", mode->hdisplay);
@ -49,7 +38,7 @@ int printMode(struct drm_mode_modeinfo *mode)
printf("\tvrefresh : %i\n", mode->vrefresh);
printf("\tflags : %i\n", mode->flags);
#else
printf("Mode: %i \"%s\" %ix%i %.0f\n", mode->id, mode->name,
printf("Mode: \"%s\" %ix%i %.0f\n", mode->name,
mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000.0);
#endif
return 0;
@ -86,17 +75,27 @@ int printOutput(int fd, drmModeResPtr res, drmModeOutputPtr output, uint32_t id)
printf("%d ", props->values[j]);
printf("\n\tenums %d: \n", props->count_enums);
if (props->flags & DRM_MODE_PROP_BLOB) {
drmModePropertyBlobPtr blob;
for (j = 0; j < props->count_enums; j++) {
if (output->prop_values[i] == props->enums[j].value)
name = props->enums[j].name;
printf("\t\t%d = %s\n", props->enums[j].value, props->enums[j].name);
}
blob = drmModeGetPropertyBlob(fd, output->prop_values[i]);
printf("blob is %d length, %08X\n", blob->length, *(uint32_t *)blob->data);
drmModeFreePropertyBlob(blob);
if (props->count_enums && name) {
printf("\toutput property name %s %s\n", props->name, name);
} else {
printf("\toutput property id %s %i\n", props->name, output->prop_values[i]);
for (j = 0; j < props->count_enums; j++) {
if (output->prop_values[i] == props->enums[j].value)
name = props->enums[j].name;
printf("\t\t%d = %s\n", props->enums[j].value, props->enums[j].name);
}
if (props->count_enums && name) {
printf("\toutput property name %s %s\n", props->name, name);
} else {
printf("\toutput property id %s %i\n", props->name, output->prop_values[i]);
}
}
drmModeFreeProperty(props);
@ -104,11 +103,9 @@ int printOutput(int fd, drmModeResPtr res, drmModeOutputPtr output, uint32_t id)
}
for (i = 0; i < output->count_modes; i++) {
mode = findMode(res, output->modes[i]);
mode = &output->modes[i];
if (mode)
printf("\t\tmode: %i \"%s\" %ix%i %.0f\n", mode->id, mode->name,
mode->hdisplay, mode->vdisplay, mode->vrefresh / 1000.0);
printMode(mode);
else
printf("\t\tmode: Invalid mode %i\n", output->modes[i]);
}
@ -154,10 +151,6 @@ int printRes(int fd, drmModeResPtr res)
drmModeCrtcPtr crtc;
drmModeFBPtr fb;
for (i = 0; i < res->count_modes; i++) {
printMode(&res->modes[i]);
}
for (i = 0; i < res->count_outputs; i++) {
output = drmModeGetOutput(fd, res->outputs[i]);
@ -222,40 +215,26 @@ int testMode(int fd, drmModeResPtr res)
/* printMode(&mode); */
printf("\tAdding mode\n");
newMode = drmModeAddMode(fd, &mode);
if (!newMode)
goto err;
printf("\tAttaching mode %i to output %i\n", newMode, output);
ret = drmModeAttachMode(fd, output, newMode);
ret = drmModeAttachMode(fd, output, &mode);
if (ret)
goto err_mode;
printf("\tDetaching mode %i from output %i\n", newMode, output);
ret = drmModeDetachMode(fd, output, newMode);
ret = drmModeDetachMode(fd, output, &mode);
if (ret)
goto err_mode;
printf("\tRemoveing new mode %i\n", newMode);
ret = drmModeRmMode(fd, newMode);
if (ret)
goto err;
return 0;
err_mode:
error = drmModeRmMode(fd, newMode);
err:
printf("\tFailed\n");
if (error)
printf("\tFailed to delete mode %i\n", newMode);
return 1;
}