Skip to content

Commit

Permalink
Merge branch 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/airlied/drm-2.6

* 'drm-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/airlied/drm-2.6:
  drm: ignore EDID with really tiny modes.
  drm: don't associate _DRM_DRIVER maps with a master
  drm/i915: intel_lvds.c fix section mismatch
  drm: Hook up DPMS property handling in drm_crtc.c. Add drm_helper_connector_dpms.
  drm: set permissions on edid file to 0444
  drm: add newlines to text sysfs files
  drm/radeon: fix ring free alignment calculations
  drm: fix irq naming for kms drivers.
  • Loading branch information
torvalds committed Jun 4, 2009
2 parents 730c586 + fc43896 commit b63254c
Show file tree
Hide file tree
Showing 17 changed files with 151 additions and 32 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/drm_bufs.c
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,8 @@ static int drm_addmap_core(struct drm_device * dev, resource_size_t offset,
list->user_token = list->hash.key << PAGE_SHIFT;
mutex_unlock(&dev->struct_mutex);

list->master = dev->primary->master;
if (!(map->flags & _DRM_DRIVER))
list->master = dev->primary->master;
*maplist = list;
return 0;
}
Expand Down
7 changes: 6 additions & 1 deletion drivers/gpu/drm/drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2294,7 +2294,12 @@ int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
}
}

if (connector->funcs->set_property)
/* Do DPMS ourselves */
if (property == connector->dev->mode_config.dpms_property) {
if (connector->funcs->dpms)
(*connector->funcs->dpms)(connector, (int) out_resp->value);
ret = 0;
} else if (connector->funcs->set_property)
ret = connector->funcs->set_property(connector, property, out_resp->value);

/* store the property value if succesful */
Expand Down
109 changes: 107 additions & 2 deletions drivers/gpu/drm/drm_crtc_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,29 @@ static void drm_helper_add_std_modes(struct drm_device *dev,
}
}

/**
* drm_helper_encoder_in_use - check if a given encoder is in use
* @encoder: encoder to check
*
* LOCKING:
* Caller must hold mode config lock.
*
* Walk @encoders's DRM device's mode_config and see if it's in use.
*
* RETURNS:
* True if @encoder is part of the mode_config, false otherwise.
*/
bool drm_helper_encoder_in_use(struct drm_encoder *encoder)
{
struct drm_connector *connector;
struct drm_device *dev = encoder->dev;
list_for_each_entry(connector, &dev->mode_config.connector_list, head)
if (connector->encoder == encoder)
return true;
return false;
}
EXPORT_SYMBOL(drm_helper_encoder_in_use);

/**
* drm_helper_crtc_in_use - check if a given CRTC is in a mode_config
* @crtc: CRTC to check
Expand All @@ -216,7 +239,7 @@ bool drm_helper_crtc_in_use(struct drm_crtc *crtc)
struct drm_device *dev = crtc->dev;
/* FIXME: Locking around list access? */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, head)
if (encoder->crtc == crtc)
if (encoder->crtc == crtc && drm_helper_encoder_in_use(encoder))
return true;
return false;
}
Expand All @@ -240,7 +263,7 @@ void drm_helper_disable_unused_functions(struct drm_device *dev)

list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) {
encoder_funcs = encoder->helper_private;
if (!encoder->crtc)
if (!drm_helper_encoder_in_use(encoder))
(*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
}

Expand Down Expand Up @@ -935,6 +958,88 @@ bool drm_helper_initial_config(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_helper_initial_config);

static int drm_helper_choose_encoder_dpms(struct drm_encoder *encoder)
{
int dpms = DRM_MODE_DPMS_OFF;
struct drm_connector *connector;
struct drm_device *dev = encoder->dev;

list_for_each_entry(connector, &dev->mode_config.connector_list, head)
if (connector->encoder == encoder)
if (connector->dpms < dpms)
dpms = connector->dpms;
return dpms;
}

static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
{
int dpms = DRM_MODE_DPMS_OFF;
struct drm_connector *connector;
struct drm_device *dev = crtc->dev;

list_for_each_entry(connector, &dev->mode_config.connector_list, head)
if (connector->encoder && connector->encoder->crtc == crtc)
if (connector->dpms < dpms)
dpms = connector->dpms;
return dpms;
}

/**
* drm_helper_connector_dpms
* @connector affected connector
* @mode DPMS mode
*
* Calls the low-level connector DPMS function, then
* calls appropriate encoder and crtc DPMS functions as well
*/
void drm_helper_connector_dpms(struct drm_connector *connector, int mode)
{
struct drm_encoder *encoder = connector->encoder;
struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
int old_dpms;

if (mode == connector->dpms)
return;

old_dpms = connector->dpms;
connector->dpms = mode;

/* from off to on, do crtc then encoder */
if (mode < old_dpms) {
if (crtc) {
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
if (crtc_funcs->dpms)
(*crtc_funcs->dpms) (crtc,
drm_helper_choose_crtc_dpms(crtc));
}
if (encoder) {
struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
if (encoder_funcs->dpms)
(*encoder_funcs->dpms) (encoder,
drm_helper_choose_encoder_dpms(encoder));
}
}

/* from on to off, do encoder then crtc */
if (mode > old_dpms) {
if (encoder) {
struct drm_encoder_helper_funcs *encoder_funcs = encoder->helper_private;
if (encoder_funcs->dpms)
(*encoder_funcs->dpms) (encoder,
drm_helper_choose_encoder_dpms(encoder));
}
if (crtc) {
struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
if (crtc_funcs->dpms)
(*crtc_funcs->dpms) (crtc,
drm_helper_choose_crtc_dpms(crtc));
}
}

return;
}
EXPORT_SYMBOL(drm_helper_connector_dpms);

/**
* drm_hotplug_stage_two
* @dev DRM device
Expand Down
5 changes: 5 additions & 0 deletions drivers/gpu/drm/drm_edid.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,11 @@ static struct drm_display_mode *drm_mode_detailed(struct drm_device *dev,
struct drm_display_mode *mode;
struct detailed_pixel_timing *pt = &timing->data.pixel_data;

/* ignore tiny modes */
if (((pt->hactive_hi << 8) | pt->hactive_lo) < 64 ||
((pt->vactive_hi << 8) | pt->hactive_lo) < 64)
return NULL;

if (pt->stereo) {
printk(KERN_WARNING "stereo mode not supported\n");
return NULL;
Expand Down
8 changes: 7 additions & 1 deletion drivers/gpu/drm/drm_irq.c
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ int drm_irq_install(struct drm_device *dev)
{
int ret = 0;
unsigned long sh_flags = 0;
char *irqname;

if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
Expand Down Expand Up @@ -227,8 +228,13 @@ int drm_irq_install(struct drm_device *dev)
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
sh_flags = IRQF_SHARED;

if (dev->devname)
irqname = dev->devname;
else
irqname = dev->driver->name;

ret = request_irq(drm_dev_to_irq(dev), dev->driver->irq_handler,
sh_flags, dev->devname, dev);
sh_flags, irqname, dev);

if (ret < 0) {
mutex_lock(&dev->struct_mutex);
Expand Down
7 changes: 4 additions & 3 deletions drivers/gpu/drm/drm_sysfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ static ssize_t status_show(struct device *device,
enum drm_connector_status status;

status = connector->funcs->detect(connector);
return snprintf(buf, PAGE_SIZE, "%s",
return snprintf(buf, PAGE_SIZE, "%s\n",
drm_get_connector_status_name(status));
}

Expand All @@ -166,7 +166,7 @@ static ssize_t dpms_show(struct device *device,
if (ret)
return 0;

return snprintf(buf, PAGE_SIZE, "%s",
return snprintf(buf, PAGE_SIZE, "%s\n",
drm_get_dpms_name((int)dpms_status));
}

Expand All @@ -176,7 +176,7 @@ static ssize_t enabled_show(struct device *device,
{
struct drm_connector *connector = to_drm_connector(device);

return snprintf(buf, PAGE_SIZE, connector->encoder ? "enabled" :
return snprintf(buf, PAGE_SIZE, "%s\n", connector->encoder ? "enabled" :
"disabled");
}

Expand Down Expand Up @@ -317,6 +317,7 @@ static struct device_attribute connector_attrs_opt1[] = {

static struct bin_attribute edid_attr = {
.attr.name = "edid",
.attr.mode = 0444,
.size = 128,
.read = edid_show,
};
Expand Down
12 changes: 2 additions & 10 deletions drivers/gpu/drm/i915/i915_dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -987,12 +987,6 @@ static int i915_load_modeset_init(struct drm_device *dev)
int fb_bar = IS_I9XX(dev) ? 2 : 0;
int ret = 0;

dev->devname = kstrdup(DRIVER_NAME, GFP_KERNEL);
if (!dev->devname) {
ret = -ENOMEM;
goto out;
}

dev->mode_config.fb_base = drm_get_resource_start(dev, fb_bar) &
0xff000000;

Expand All @@ -1006,7 +1000,7 @@ static int i915_load_modeset_init(struct drm_device *dev)

ret = i915_probe_agp(dev, &agp_size, &prealloc_size);
if (ret)
goto kfree_devname;
goto out;

/* Basic memrange allocator for stolen space (aka vram) */
drm_mm_init(&dev_priv->vram, 0, prealloc_size);
Expand All @@ -1024,7 +1018,7 @@ static int i915_load_modeset_init(struct drm_device *dev)

ret = i915_gem_init_ringbuffer(dev);
if (ret)
goto kfree_devname;
goto out;

/* Allow hardware batchbuffers unless told otherwise.
*/
Expand Down Expand Up @@ -1056,8 +1050,6 @@ static int i915_load_modeset_init(struct drm_device *dev)

destroy_ringbuffer:
i915_gem_cleanup_ringbuffer(dev);
kfree_devname:
kfree(dev->devname);
out:
return ret;
}
Expand Down
6 changes: 1 addition & 5 deletions drivers/gpu/drm/i915/intel_crt.c
Original file line number Diff line number Diff line change
Expand Up @@ -381,11 +381,6 @@ static int intel_crt_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t value)
{
struct drm_device *dev = connector->dev;

if (property == dev->mode_config.dpms_property && connector->encoder)
intel_crt_dpms(connector->encoder, (uint32_t)(value & 0xf));

return 0;
}

Expand All @@ -402,6 +397,7 @@ static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = {
};

static const struct drm_connector_funcs intel_crt_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.detect = intel_crt_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = intel_crt_destroy,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_dvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,7 @@ static const struct drm_encoder_helper_funcs intel_dvo_helper_funcs = {
};

static const struct drm_connector_funcs intel_dvo_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.save = intel_dvo_save,
.restore = intel_dvo_restore,
.detect = intel_dvo_detect,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_hdmi.c
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ static const struct drm_encoder_helper_funcs intel_hdmi_helper_funcs = {
};

static const struct drm_connector_funcs intel_hdmi_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.save = intel_hdmi_save,
.restore = intel_hdmi_restore,
.detect = intel_hdmi_detect,
Expand Down
8 changes: 2 additions & 6 deletions drivers/gpu/drm/i915/intel_lvds.c
Original file line number Diff line number Diff line change
Expand Up @@ -343,11 +343,6 @@ static int intel_lvds_set_property(struct drm_connector *connector,
struct drm_property *property,
uint64_t value)
{
struct drm_device *dev = connector->dev;

if (property == dev->mode_config.dpms_property && connector->encoder)
intel_lvds_dpms(connector->encoder, (uint32_t)(value & 0xf));

return 0;
}

Expand All @@ -366,6 +361,7 @@ static const struct drm_connector_helper_funcs intel_lvds_connector_helper_funcs
};

static const struct drm_connector_funcs intel_lvds_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.save = intel_lvds_save,
.restore = intel_lvds_restore,
.detect = intel_lvds_detect,
Expand All @@ -391,7 +387,7 @@ static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
}

/* These systems claim to have LVDS, but really don't */
static const struct dmi_system_id __initdata intel_no_lvds[] = {
static const struct dmi_system_id intel_no_lvds[] = {
{
.callback = intel_no_lvds_dmi_callback,
.ident = "Apple Mac Mini (Core series)",
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_sdvo.c
Original file line number Diff line number Diff line change
Expand Up @@ -1616,6 +1616,7 @@ static const struct drm_encoder_helper_funcs intel_sdvo_helper_funcs = {
};

static const struct drm_connector_funcs intel_sdvo_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.save = intel_sdvo_save,
.restore = intel_sdvo_restore,
.detect = intel_sdvo_detect,
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/i915/intel_tv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1626,6 +1626,7 @@ static const struct drm_encoder_helper_funcs intel_tv_helper_funcs = {
};

static const struct drm_connector_funcs intel_tv_connector_funcs = {
.dpms = drm_helper_connector_dpms,
.save = intel_tv_save,
.restore = intel_tv_restore,
.detect = intel_tv_detect,
Expand Down
4 changes: 2 additions & 2 deletions drivers/gpu/drm/radeon/radeon_cp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2185,9 +2185,9 @@ void radeon_commit_ring(drm_radeon_private_t *dev_priv)

/* check if the ring is padded out to 16-dword alignment */

tail_aligned = dev_priv->ring.tail & 0xf;
tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN-1);
if (tail_aligned) {
int num_p2 = 16 - tail_aligned;
int num_p2 = RADEON_RING_ALIGN - tail_aligned;

ring = dev_priv->ring.start;
/* pad with some CP_PACKET2 */
Expand Down
5 changes: 4 additions & 1 deletion drivers/gpu/drm/radeon/radeon_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -1964,11 +1964,14 @@ do { \

#define RING_LOCALS int write, _nr, _align_nr; unsigned int mask; u32 *ring;

#define RADEON_RING_ALIGN 16

#define BEGIN_RING( n ) do { \
if ( RADEON_VERBOSE ) { \
DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
} \
_align_nr = (n + 0xf) & ~0xf; \
_align_nr = RADEON_RING_ALIGN - ((dev_priv->ring.tail + n) & (RADEON_RING_ALIGN-1)); \
_align_nr += n; \
if (dev_priv->ring.space <= (_align_nr * sizeof(u32))) { \
COMMIT_RING(); \
radeon_wait_ring( dev_priv, _align_nr * sizeof(u32)); \
Expand Down
3 changes: 3 additions & 0 deletions include/drm/drm_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,9 @@ struct drm_connector {
u32 property_ids[DRM_CONNECTOR_MAX_PROPERTY];
uint64_t property_values[DRM_CONNECTOR_MAX_PROPERTY];

/* requested DPMS state */
int dpms;

void *helper_private;

uint32_t encoder_ids[DRM_CONNECTOR_MAX_ENCODER];
Expand Down
2 changes: 2 additions & 0 deletions include/drm/drm_crtc_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
struct drm_framebuffer *old_fb);
extern bool drm_helper_crtc_in_use(struct drm_crtc *crtc);

extern void drm_helper_connector_dpms(struct drm_connector *connector, int mode);

extern int drm_helper_mode_fill_fb_struct(struct drm_framebuffer *fb,
struct drm_mode_fb_cmd *mode_cmd);

Expand Down

0 comments on commit b63254c

Please sign in to comment.