Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 174650
b: refs/heads/master
c: d4877cf
h: refs/heads/master
v: v3
  • Loading branch information
Alex Deucher authored and Dave Airlie committed Dec 8, 2009
1 parent f52b140 commit e09fa50
Show file tree
Hide file tree
Showing 11 changed files with 99 additions and 11 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: 429770b3e39999c4d025fbcb9959502adc3989d8
refs/heads/master: d4877cf2293f5463f531769fd12300cb3417c778
12 changes: 12 additions & 0 deletions trunk/drivers/gpu/drm/radeon/atombios_dp.c
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,18 @@ static bool atom_dp_get_link_status(struct radeon_connector *radeon_connector,
return true;
}

bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
{
struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
u8 link_status[DP_LINK_STATUS_SIZE];

if (!atom_dp_get_link_status(radeon_connector, link_status))
return false;
if (dp_channel_eq_ok(link_status, dig_connector->dp_lane_count))
return false;
return true;
}

static void dp_set_power(struct radeon_connector *radeon_connector, u8 power_state)
{
struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
Expand Down
9 changes: 7 additions & 2 deletions trunk/drivers/gpu/drm/radeon/r100.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,6 +289,7 @@ static inline uint32_t r100_irq_ack(struct radeon_device *rdev)
int r100_irq_process(struct radeon_device *rdev)
{
uint32_t status, msi_rearm;
bool queue_hotplug = false;

status = r100_irq_ack(rdev);
if (!status) {
Expand All @@ -310,13 +311,17 @@ int r100_irq_process(struct radeon_device *rdev)
drm_handle_vblank(rdev->ddev, 1);
}
if (status & RADEON_FP_DETECT_STAT) {
DRM_INFO("HPD1\n");
queue_hotplug = true;
DRM_DEBUG("HPD1\n");
}
if (status & RADEON_FP2_DETECT_STAT) {
DRM_INFO("HPD2\n");
queue_hotplug = true;
DRM_DEBUG("HPD2\n");
}
status = r100_irq_ack(rdev);
}
if (queue_hotplug)
queue_work(rdev->wq, &rdev->hotplug_work);
if (rdev->msi_enabled) {
switch (rdev->family) {
case CHIP_RS400:
Expand Down
21 changes: 15 additions & 6 deletions trunk/drivers/gpu/drm/radeon/r600.c
Original file line number Diff line number Diff line change
Expand Up @@ -2674,6 +2674,7 @@ int r600_irq_process(struct radeon_device *rdev)
u32 last_entry = rdev->ih.ring_size - 16;
u32 ring_index, disp_int, disp_int_cont, disp_int_cont2;
unsigned long flags;
bool queue_hotplug = false;

DRM_DEBUG("r600_irq_process start: rptr %d, wptr %d\n", rptr, wptr);

Expand Down Expand Up @@ -2745,37 +2746,43 @@ int r600_irq_process(struct radeon_device *rdev)
case 0:
if (disp_int & DC_HPD1_INTERRUPT) {
disp_int &= ~DC_HPD1_INTERRUPT;
DRM_INFO("IH: HPD1\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD1\n");
}
break;
case 1:
if (disp_int & DC_HPD2_INTERRUPT) {
disp_int &= ~DC_HPD2_INTERRUPT;
DRM_INFO("IH: HPD2\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD2\n");
}
break;
case 4:
if (disp_int_cont & DC_HPD3_INTERRUPT) {
disp_int_cont &= ~DC_HPD3_INTERRUPT;
DRM_INFO("IH: HPD3\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD3\n");
}
break;
case 5:
if (disp_int_cont & DC_HPD4_INTERRUPT) {
disp_int_cont &= ~DC_HPD4_INTERRUPT;
DRM_INFO("IH: HPD4\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD4\n");
}
break;
case 10:
if (disp_int_cont2 & DC_HPD5_INTERRUPT) {
disp_int_cont &= ~DC_HPD5_INTERRUPT;
DRM_INFO("IH: HPD5\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD5\n");
}
break;
case 12:
if (disp_int_cont2 & DC_HPD6_INTERRUPT) {
disp_int_cont &= ~DC_HPD6_INTERRUPT;
DRM_INFO("IH: HPD6\n");
queue_hotplug = true;
DRM_DEBUG("IH: HPD6\n");
}
break;
default:
Expand Down Expand Up @@ -2807,6 +2814,8 @@ int r600_irq_process(struct radeon_device *rdev)
wptr = r600_get_ih_wptr(rdev);
if (wptr != rdev->ih.wptr)
goto restart_ih;
if (queue_hotplug)
queue_work(rdev->wq, &rdev->hotplug_work);
rdev->ih.rptr = rptr;
WREG32(IH_RB_RPTR, rdev->ih.rptr);
spin_unlock_irqrestore(&rdev->ih.lock, flags);
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/radeon/radeon.h
Original file line number Diff line number Diff line change
Expand Up @@ -809,6 +809,8 @@ struct radeon_device {
struct r600_blit r600_blit;
int msi_enabled; /* msi enabled */
struct r600_ih ih; /* r6/700 interrupt ring */
struct workqueue_struct *wq;
struct work_struct hotplug_work;
};

int radeon_device_init(struct radeon_device *rdev,
Expand Down
20 changes: 20 additions & 0 deletions trunk/drivers/gpu/drm/radeon/radeon_connectors.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,26 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector,
struct drm_encoder *encoder,
bool connected);

void radeon_connector_hotplug(struct drm_connector *connector)
{
struct drm_device *dev = connector->dev;
struct radeon_device *rdev = dev->dev_private;
struct radeon_connector *radeon_connector = to_radeon_connector(connector);

if (radeon_connector->hpd.hpd != RADEON_HPD_NONE)
radeon_hpd_set_polarity(rdev, radeon_connector->hpd.hpd);

if (connector->connector_type == DRM_MODE_CONNECTOR_DisplayPort) {
if (radeon_dp_getsinktype(radeon_connector) == CONNECTOR_OBJECT_ID_DISPLAYPORT) {
if (radeon_dp_needs_link_train(radeon_connector)) {
if (connector->encoder)
dp_link_train(connector->encoder, connector);
}
}
}

}

static void radeon_property_change_mode(struct drm_encoder *encoder)
{
struct drm_crtc *crtc = encoder->crtc;
Expand Down
9 changes: 9 additions & 0 deletions trunk/drivers/gpu/drm/radeon/radeon_device.c
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,11 @@ int radeon_device_init(struct radeon_device *rdev,
rwlock_init(&rdev->fence_drv.lock);
INIT_LIST_HEAD(&rdev->gem.objects);

/* setup workqueue */
rdev->wq = create_workqueue("radeon");
if (rdev->wq == NULL)
return -ENOMEM;

/* Set asic functions */
r = radeon_asic_init(rdev);
if (r) {
Expand Down Expand Up @@ -643,6 +648,7 @@ void radeon_device_fini(struct radeon_device *rdev)
DRM_INFO("radeon: finishing device.\n");
rdev->shutdown = true;
radeon_fini(rdev);
destroy_workqueue(rdev->wq);
vga_client_register(rdev->pdev, NULL, NULL, NULL);
iounmap(rdev->rmmio);
rdev->rmmio = NULL;
Expand Down Expand Up @@ -689,6 +695,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state)
radeon_save_bios_scratch_regs(rdev);

radeon_suspend(rdev);
radeon_hpd_fini(rdev);
/* evict remaining vram memory */
radeon_bo_evict_vram(rdev);

Expand Down Expand Up @@ -723,6 +730,8 @@ int radeon_resume_kms(struct drm_device *dev)
fb_set_suspend(rdev->fbdev_info, 0);
release_console_sem();

/* reset hpd state */
radeon_hpd_init(rdev);
/* blat the mode back in */
drm_helper_resume_force_mode(dev);
return 0;
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/gpu/drm/radeon/radeon_display.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,13 +741,16 @@ int radeon_modeset_init(struct radeon_device *rdev)
if (!ret) {
return ret;
}
/* initialize hpd */
radeon_hpd_init(rdev);
drm_helper_initial_config(rdev->ddev);
return 0;
}

void radeon_modeset_fini(struct radeon_device *rdev)
{
if (rdev->mode_info.mode_config_initialized) {
radeon_hpd_fini(rdev);
drm_mode_config_cleanup(rdev->ddev);
rdev->mode_info.mode_config_initialized = false;
}
Expand Down
21 changes: 21 additions & 0 deletions trunk/drivers/gpu/drm/radeon/radeon_irq_kms.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,32 @@ irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS)
return radeon_irq_process(rdev);
}

/*
* Handle hotplug events outside the interrupt handler proper.
*/
static void radeon_hotplug_work_func(struct work_struct *work)
{
struct radeon_device *rdev = container_of(work, struct radeon_device,
hotplug_work);
struct drm_device *dev = rdev->ddev;
struct drm_mode_config *mode_config = &dev->mode_config;
struct drm_connector *connector;

if (mode_config->num_connector) {
list_for_each_entry(connector, &mode_config->connector_list, head)
radeon_connector_hotplug(connector);
}
/* Just fire off a uevent and let userspace tell us what to do */
drm_sysfs_hotplug_event(dev);
}

void radeon_driver_irq_preinstall_kms(struct drm_device *dev)
{
struct radeon_device *rdev = dev->dev_private;
unsigned i;

INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func);

/* Disable *all* interrupts */
rdev->irq.sw_int = false;
for (i = 0; i < 2; i++) {
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/gpu/drm/radeon/radeon_mode.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,8 @@ struct radeon_framebuffer {
struct drm_gem_object *obj;
};

extern void radeon_connector_hotplug(struct drm_connector *connector);
extern bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector);
extern int radeon_dp_mode_valid_helper(struct radeon_connector *radeon_connector,
struct drm_display_mode *mode);
extern void radeon_dp_set_link_config(struct drm_connector *connector,
Expand Down
9 changes: 7 additions & 2 deletions trunk/drivers/gpu/drm/radeon/rs600.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@ int rs600_irq_process(struct radeon_device *rdev)
{
uint32_t status, msi_rearm;
uint32_t r500_disp_int;
bool queue_hotplug = false;

status = rs600_irq_ack(rdev, &r500_disp_int);
if (!status && !r500_disp_int) {
Expand All @@ -403,13 +404,17 @@ int rs600_irq_process(struct radeon_device *rdev)
if (G_007EDC_LB_D2_VBLANK_INTERRUPT(r500_disp_int))
drm_handle_vblank(rdev->ddev, 1);
if (G_007EDC_DC_HOT_PLUG_DETECT1_INTERRUPT(r500_disp_int)) {
DRM_INFO("HPD1\n");
queue_hotplug = true;
DRM_DEBUG("HPD1\n");
}
if (G_007EDC_DC_HOT_PLUG_DETECT2_INTERRUPT(r500_disp_int)) {
DRM_INFO("HPD2\n");
queue_hotplug = true;
DRM_DEBUG("HPD2\n");
}
status = rs600_irq_ack(rdev, &r500_disp_int);
}
if (queue_hotplug)
queue_work(rdev->wq, &rdev->hotplug_work);
if (rdev->msi_enabled) {
switch (rdev->family) {
case CHIP_RS600:
Expand Down

0 comments on commit e09fa50

Please sign in to comment.