Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 196449
b: refs/heads/master
c: 5c4426a
h: refs/heads/master
i:
  196447: 586184c
v: v3
  • Loading branch information
Dave Airlie committed Apr 7, 2010
1 parent 7f479af commit dc2268a
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 13 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: 19b4b44503ccdf834062d68e022dc1e2721695a5
refs/heads/master: 5c4426a782bc9509573fc7958a786ebd14fafdf3
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ config DRM_KMS_HELPER
depends on DRM
select FB
select FRAMEBUFFER_CONSOLE if !EMBEDDED
select SLOW_WORK
help
FB and CRTC helpers for KMS drivers.

Expand Down
82 changes: 76 additions & 6 deletions trunk/drivers/gpu/drm/drm_fb_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -1308,25 +1308,95 @@ bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper)
/*
* we shouldn't end up with no modes here.
*/
if (count == 0)
printk(KERN_INFO "No connectors reported connected with modes\n");

if (count == 0) {
if (fb_helper->poll_enabled) {
delayed_slow_work_enqueue(&fb_helper->output_poll_slow_work,
5*HZ);
printk(KERN_INFO "No connectors reported connected with modes - started polling\n");
} else
printk(KERN_INFO "No connectors reported connected with modes\n");
}
drm_setup_crtcs(fb_helper);

return 0;
}
EXPORT_SYMBOL(drm_fb_helper_initial_config);

bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper,
u32 max_width, u32 max_height)
u32 max_width, u32 max_height, bool polled)
{
int count = 0;
int ret;
DRM_DEBUG_KMS("\n");

drm_fb_helper_probe_connector_modes(fb_helper, max_width,
count = drm_fb_helper_probe_connector_modes(fb_helper, max_width,
max_height);

if (fb_helper->poll_enabled && !polled) {
if (count) {
delayed_slow_work_cancel(&fb_helper->output_poll_slow_work);
} else {
ret = delayed_slow_work_enqueue(&fb_helper->output_poll_slow_work, 5*HZ);
}
}
drm_setup_crtcs(fb_helper);

return true;
}
EXPORT_SYMBOL(drm_helper_fb_hotplug_event);

static void output_poll_execute(struct slow_work *work)
{
struct delayed_slow_work *delayed_work = container_of(work, struct delayed_slow_work, work);
struct drm_fb_helper *fb_helper = container_of(delayed_work, struct drm_fb_helper, output_poll_slow_work);
struct drm_device *dev = fb_helper->dev;
struct drm_connector *connector;
enum drm_connector_status old_status, status;
bool repoll = true, changed = false;
int ret;

list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
old_status = connector->status;
status = connector->funcs->detect(connector);
if (old_status != status) {
changed = true;
/* something changed */
}
if (status == connector_status_connected) {
DRM_DEBUG("%s is connected - stop polling\n", drm_get_connector_name(connector));
repoll = false;
}
}

if (repoll) {
ret = delayed_slow_work_enqueue(delayed_work, 5*HZ);
if (ret)
DRM_ERROR("delayed enqueue failed %d\n", ret);
}

if (changed) {
if (fb_helper->fb_poll_changed)
fb_helper->fb_poll_changed(fb_helper);
}
}

struct slow_work_ops output_poll_ops = {
.execute = output_poll_execute,
};

void drm_fb_helper_poll_init(struct drm_fb_helper *fb_helper)
{
int ret;

ret = slow_work_register_user(THIS_MODULE);

delayed_slow_work_init(&fb_helper->output_poll_slow_work, &output_poll_ops);
fb_helper->poll_enabled = true;
}
EXPORT_SYMBOL(drm_fb_helper_poll_init);

void drm_fb_helper_poll_fini(struct drm_fb_helper *fb_helper)
{
delayed_slow_work_cancel(&fb_helper->output_poll_slow_work);
slow_work_unregister_user(THIS_MODULE);
}
EXPORT_SYMBOL(drm_fb_helper_poll_fini);
14 changes: 12 additions & 2 deletions trunk/drivers/gpu/drm/radeon/radeon_fb.c
Original file line number Diff line number Diff line change
Expand Up @@ -321,18 +321,23 @@ static int radeonfb_probe(struct radeon_fbdev *rfbdev)
return drm_fb_helper_single_fb_probe(&rfbdev->helper, bpp_sel);
}

void radeonfb_hotplug(struct drm_device *dev)
void radeonfb_hotplug(struct drm_device *dev, bool polled)
{
struct radeon_device *rdev = dev->dev_private;
int max_width, max_height;

max_width = rdev->mode_info.rfbdev->rfb.base.width;
max_height = rdev->mode_info.rfbdev->rfb.base.height;
drm_helper_fb_hotplug_event(&rdev->mode_info.rfbdev->helper, max_width, max_height);
drm_helper_fb_hotplug_event(&rdev->mode_info.rfbdev->helper, max_width, max_height, polled);

radeonfb_probe(rdev->mode_info.rfbdev);
}

static void radeon_fb_poll_changed(struct drm_fb_helper *fb_helper)
{
radeonfb_hotplug(fb_helper->dev, true);
}

static int radeon_fbdev_destroy(struct drm_device *dev, struct radeon_fbdev *rfbdev)
{
struct fb_info *info;
Expand Down Expand Up @@ -381,8 +386,12 @@ int radeon_fbdev_init(struct radeon_device *rdev)

drm_fb_helper_single_add_all_connectors(&rfbdev->helper);

rfbdev->helper.fb_poll_changed = radeon_fb_poll_changed;
drm_fb_helper_poll_init(&rfbdev->helper);

drm_fb_helper_initial_config(&rfbdev->helper);
radeonfb_probe(rfbdev);

return 0;

}
Expand All @@ -392,6 +401,7 @@ void radeon_fbdev_fini(struct radeon_device *rdev)
if (!rdev->mode_info.rfbdev)
return;

drm_fb_helper_poll_fini(&rdev->mode_info.rfbdev->helper);
radeon_fbdev_destroy(rdev->ddev, rdev->mode_info.rfbdev);
kfree(rdev->mode_info.rfbdev);
rdev->mode_info.rfbdev = NULL;
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ static void radeon_hotplug_work_func(struct work_struct *work)
radeon_connector_hotplug(connector);
}
/* Just fire off a uevent and let userspace tell us what to do */
radeonfb_hotplug(dev);
radeonfb_hotplug(dev, false);

drm_sysfs_hotplug_event(dev);
}
Expand Down
2 changes: 1 addition & 1 deletion trunk/drivers/gpu/drm/radeon/radeon_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -585,5 +585,5 @@ void radeon_fbdev_fini(struct radeon_device *rdev);
void radeon_fbdev_set_suspend(struct radeon_device *rdev, int state);
int radeon_fbdev_total_size(struct radeon_device *rdev);
bool radeon_fbdev_robj_is_fb(struct radeon_device *rdev, struct radeon_bo *robj);
void radeonfb_hotplug(struct drm_device *dev);
void radeonfb_hotplug(struct drm_device *dev, bool polled);
#endif
12 changes: 10 additions & 2 deletions trunk/include/drm/drm_fb_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
#ifndef DRM_FB_HELPER_H
#define DRM_FB_HELPER_H

#include <linux/slow-work.h>

struct drm_fb_helper_crtc {
uint32_t crtc_id;
struct drm_mode_set mode_set;
Expand Down Expand Up @@ -86,8 +88,12 @@ struct drm_fb_helper {
u32 pseudo_palette[17];
struct list_head kernel_fb_list;

struct delayed_slow_work output_poll_slow_work;
bool poll_enabled;
int (*fb_probe)(struct drm_fb_helper *helper,
struct drm_fb_helper_surface_size *sizes);

void (*fb_poll_changed)(struct drm_fb_helper *helper);
};

int drm_fb_helper_single_fb_probe(struct drm_fb_helper *helper,
Expand Down Expand Up @@ -118,9 +124,11 @@ void drm_fb_helper_fill_fix(struct fb_info *info, uint32_t pitch,

int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info);

bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper, u32 max_width,
u32 max_height);
bool drm_helper_fb_hotplug_event(struct drm_fb_helper *fb_helper,
u32 max_width, u32 max_height, bool polled);
bool drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);
int drm_fb_helper_single_add_all_connectors(struct drm_fb_helper *fb_helper);

void drm_fb_helper_poll_init(struct drm_fb_helper *fb_helper);
void drm_fb_helper_poll_fini(struct drm_fb_helper *fb_helper);
#endif

0 comments on commit dc2268a

Please sign in to comment.