From: Dave Airlie airlied@redhat.com
this tells the drivers when the mux is switch to/from it, can be used to report outputs as disconnected to userspace etc.
Signed-off-by: Dave Airlie airlied@redhat.com --- drivers/gpu/vga/vga_switcheroo.c | 19 +++++++++++++++++++ include/linux/vga_switcheroo.h | 1 + 2 files changed, 20 insertions(+)
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index fa60add..2362175 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -93,6 +93,9 @@ static void vga_switcheroo_enable(void) return;
client->id = ret; + + if (client->ops->mux_switched) + client->ops->mux_switched(client->pdev, client->active ? VGA_SWITCHEROO_ON : VGA_SWITCHEROO_OFF); } vga_switcheroo_debugfs_init(&vgasr_priv); vgasr_priv.active = true; @@ -345,6 +348,13 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) if (ret) return ret;
+ /* call mux switched callbacks */ + if (active->ops->mux_switched) + active->ops->mux_switched(active->pdev, VGA_SWITCHEROO_OFF); + + if (new_client->ops->mux_switched) + new_client->ops->mux_switched(new_client->pdev, VGA_SWITCHEROO_ON); + if (new_client->ops->reprobe) new_client->ops->reprobe(new_client->pdev);
@@ -452,7 +462,16 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, vgasr_priv.delayed_switch_active = false;
if (just_mux) { + struct vga_switcheroo_client *active; + active = find_active_client(&vgasr_priv.clients); + if (!active) + return 0; ret = vgasr_priv.handler->switchto(client_id); + + if (active->ops->mux_switched) + active->ops->mux_switched(active->pdev, VGA_SWITCHEROO_OFF); + if (client->ops->mux_switched) + client->ops->mux_switched(client->pdev, VGA_SWITCHEROO_ON); goto out; }
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index ddb419c..6275719 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -40,6 +40,7 @@ struct vga_switcheroo_client_ops { void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state); void (*reprobe)(struct pci_dev *dev); bool (*can_switch)(struct pci_dev *dev); + void (*mux_switched)(struct pci_dev *dev, enum vga_switcheroo_state); };
#if defined(CONFIG_VGA_SWITCHEROO)
From: Dave Airlie airlied@redhat.com
otherwise userspace can get very confused --- drivers/gpu/drm/radeon/radeon_connectors.c | 4 ++++ drivers/gpu/drm/radeon/radeon_device.c | 14 ++++++++++++++ drivers/gpu/drm/radeon/radeon_mode.h | 2 ++ 3 files changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2399f25..e5a4a10 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -611,6 +611,10 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = radeon_best_single_encoder(connector); enum drm_connector_status ret = connector_status_disconnected; + struct radeon_device *rdev = connector->dev->dev_private; + + if (rdev->mode_info.mux_force_disconnected) + return connector_status_disconnected;
if (encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index cd75626..bf66f09 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -945,10 +945,24 @@ static bool radeon_switcheroo_can_switch(struct pci_dev *pdev) return can_switch; }
+static void radeon_switcheroo_mux_switched(struct pci_dev *pdev, enum vga_switcheroo_state state) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct radeon_device *rdev = dev->dev_private; + + if (state == VGA_SWITCHEROO_OFF) + rdev->mode_info.mux_force_disconnected = true; + else + rdev->mode_info.mux_force_disconnected = false; + + drm_kms_helper_hotplug_event(dev); +} + static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = { .set_gpu_state = radeon_switcheroo_set_state, .reprobe = NULL, .can_switch = radeon_switcheroo_can_switch, + .mux_switched = radeon_switcheroo_mux_switched, };
/** diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 4003f5a..172eed8 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -256,6 +256,8 @@ struct radeon_mode_info { u16 firmware_flags; /* pointer to backlight encoder */ struct radeon_encoder *bl_encoder; + + bool mux_force_disconnected; };
#define RADEON_MAX_BL_LEVEL 0xFF
On Mon, Jan 7, 2013 at 11:53 PM, Dave Airlie airlied@gmail.com wrote:
From: Dave Airlie airlied@redhat.com
otherwise userspace can get very confused
It might be worth adding the switch state checks to the dp_detect function to handle eDP and DP to LVDS bridges, but I think all the laptops with eDP or DP bridges are mux-less, so probably not a big deal. Other than that:
Reviewed-by: Alex Deucher alexander.deucher@amd.com
drivers/gpu/drm/radeon/radeon_connectors.c | 4 ++++ drivers/gpu/drm/radeon/radeon_device.c | 14 ++++++++++++++ drivers/gpu/drm/radeon/radeon_mode.h | 2 ++ 3 files changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2399f25..e5a4a10 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -611,6 +611,10 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = radeon_best_single_encoder(connector); enum drm_connector_status ret = connector_status_disconnected;
struct radeon_device *rdev = connector->dev->dev_private;
if (rdev->mode_info.mux_force_disconnected)
return connector_status_disconnected; if (encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index cd75626..bf66f09 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -945,10 +945,24 @@ static bool radeon_switcheroo_can_switch(struct pci_dev *pdev) return can_switch; }
+static void radeon_switcheroo_mux_switched(struct pci_dev *pdev, enum vga_switcheroo_state state) +{
struct drm_device *dev = pci_get_drvdata(pdev);
struct radeon_device *rdev = dev->dev_private;
if (state == VGA_SWITCHEROO_OFF)
rdev->mode_info.mux_force_disconnected = true;
else
rdev->mode_info.mux_force_disconnected = false;
drm_kms_helper_hotplug_event(dev);
+}
static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = { .set_gpu_state = radeon_switcheroo_set_state, .reprobe = NULL, .can_switch = radeon_switcheroo_can_switch,
.mux_switched = radeon_switcheroo_mux_switched,
};
/** diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 4003f5a..172eed8 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -256,6 +256,8 @@ struct radeon_mode_info { u16 firmware_flags; /* pointer to backlight encoder */ struct radeon_encoder *bl_encoder;
bool mux_force_disconnected;
};
#define RADEON_MAX_BL_LEVEL 0xFF
1.8.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Mon, Jan 7, 2013 at 11:53 PM, Dave Airlie airlied@gmail.com wrote:
From: Dave Airlie airlied@redhat.com
otherwise userspace can get very confused
Thinking about this more, we probably want to check whether we have a muxed to mux-less system otherwise we'll be disconnecting the display when we switch. Looks like the first patch is cognizant of that, but this one is not unless I'm missing something.
Alex
drivers/gpu/drm/radeon/radeon_connectors.c | 4 ++++ drivers/gpu/drm/radeon/radeon_device.c | 14 ++++++++++++++ drivers/gpu/drm/radeon/radeon_mode.h | 2 ++ 3 files changed, 20 insertions(+)
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c index 2399f25..e5a4a10 100644 --- a/drivers/gpu/drm/radeon/radeon_connectors.c +++ b/drivers/gpu/drm/radeon/radeon_connectors.c @@ -611,6 +611,10 @@ radeon_lvds_detect(struct drm_connector *connector, bool force) struct radeon_connector *radeon_connector = to_radeon_connector(connector); struct drm_encoder *encoder = radeon_best_single_encoder(connector); enum drm_connector_status ret = connector_status_disconnected;
struct radeon_device *rdev = connector->dev->dev_private;
if (rdev->mode_info.mux_force_disconnected)
return connector_status_disconnected; if (encoder) { struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index cd75626..bf66f09 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c @@ -945,10 +945,24 @@ static bool radeon_switcheroo_can_switch(struct pci_dev *pdev) return can_switch; }
+static void radeon_switcheroo_mux_switched(struct pci_dev *pdev, enum vga_switcheroo_state state) +{
struct drm_device *dev = pci_get_drvdata(pdev);
struct radeon_device *rdev = dev->dev_private;
if (state == VGA_SWITCHEROO_OFF)
rdev->mode_info.mux_force_disconnected = true;
else
rdev->mode_info.mux_force_disconnected = false;
drm_kms_helper_hotplug_event(dev);
+}
static const struct vga_switcheroo_client_ops radeon_switcheroo_ops = { .set_gpu_state = radeon_switcheroo_set_state, .reprobe = NULL, .can_switch = radeon_switcheroo_can_switch,
.mux_switched = radeon_switcheroo_mux_switched,
};
/** diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index 4003f5a..172eed8 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h @@ -256,6 +256,8 @@ struct radeon_mode_info { u16 firmware_flags; /* pointer to backlight encoder */ struct radeon_encoder *bl_encoder;
bool mux_force_disconnected;
};
#define RADEON_MAX_BL_LEVEL 0xFF
1.8.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
On Thu, Jan 10, 2013 at 12:16 AM, Alex Deucher alexdeucher@gmail.com wrote:
On Mon, Jan 7, 2013 at 11:53 PM, Dave Airlie airlied@gmail.com wrote:
From: Dave Airlie airlied@redhat.com
otherwise userspace can get very confused
Thinking about this more, we probably want to check whether we have a muxed to mux-less system otherwise we'll be disconnecting the display when we switch. Looks like the first patch is cognizant of that, but this one is not unless I'm missing something.
vga switcheroo is only for muxed systems, for muxless there is no "switching".
Dave.
On Mon, Jan 7, 2013 at 11:53 PM, Dave Airlie airlied@gmail.com wrote:
From: Dave Airlie airlied@redhat.com
this tells the drivers when the mux is switch to/from it, can be used to report outputs as disconnected to userspace etc.
Signed-off-by: Dave Airlie airlied@redhat.com
Reviewed-by: Alex Deucher alexander.deucher@amd.com
drivers/gpu/vga/vga_switcheroo.c | 19 +++++++++++++++++++ include/linux/vga_switcheroo.h | 1 + 2 files changed, 20 insertions(+)
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index fa60add..2362175 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c @@ -93,6 +93,9 @@ static void vga_switcheroo_enable(void) return;
client->id = ret;
if (client->ops->mux_switched)
client->ops->mux_switched(client->pdev, client->active ? VGA_SWITCHEROO_ON : VGA_SWITCHEROO_OFF); } vga_switcheroo_debugfs_init(&vgasr_priv); vgasr_priv.active = true;
@@ -345,6 +348,13 @@ static int vga_switchto_stage2(struct vga_switcheroo_client *new_client) if (ret) return ret;
/* call mux switched callbacks */
if (active->ops->mux_switched)
active->ops->mux_switched(active->pdev, VGA_SWITCHEROO_OFF);
if (new_client->ops->mux_switched)
new_client->ops->mux_switched(new_client->pdev, VGA_SWITCHEROO_ON);
if (new_client->ops->reprobe) new_client->ops->reprobe(new_client->pdev);
@@ -452,7 +462,16 @@ vga_switcheroo_debugfs_write(struct file *filp, const char __user *ubuf, vgasr_priv.delayed_switch_active = false;
if (just_mux) {
struct vga_switcheroo_client *active;
active = find_active_client(&vgasr_priv.clients);
if (!active)
return 0; ret = vgasr_priv.handler->switchto(client_id);
if (active->ops->mux_switched)
active->ops->mux_switched(active->pdev, VGA_SWITCHEROO_OFF);
if (client->ops->mux_switched)
client->ops->mux_switched(client->pdev, VGA_SWITCHEROO_ON); goto out; }
diff --git a/include/linux/vga_switcheroo.h b/include/linux/vga_switcheroo.h index ddb419c..6275719 100644 --- a/include/linux/vga_switcheroo.h +++ b/include/linux/vga_switcheroo.h @@ -40,6 +40,7 @@ struct vga_switcheroo_client_ops { void (*set_gpu_state)(struct pci_dev *dev, enum vga_switcheroo_state); void (*reprobe)(struct pci_dev *dev); bool (*can_switch)(struct pci_dev *dev);
void (*mux_switched)(struct pci_dev *dev, enum vga_switcheroo_state);
};
#if defined(CONFIG_VGA_SWITCHEROO)
1.8.1
dri-devel mailing list dri-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/dri-devel
dri-devel@lists.freedesktop.org