From patchwork Fri Apr 22 09:19:13 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chris Wilson X-Patchwork-Id: 726621 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id p3M9LhkJ007150 for ; Fri, 22 Apr 2011 09:22:03 GMT Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B27679E7F9 for ; Fri, 22 Apr 2011 02:21:43 -0700 (PDT) X-Original-To: intel-gfx@lists.freedesktop.org Delivered-To: intel-gfx@lists.freedesktop.org Received: from fireflyinternet.com (server109-228-6-236.live-servers.net [109.228.6.236]) by gabe.freedesktop.org (Postfix) with ESMTP id 380089E799 for ; Fri, 22 Apr 2011 02:19:26 -0700 (PDT) X-Default-Received-SPF: pass (skip=forwardok (res=PASS)) x-ip-name=78.156.66.37; Received: from arrandale.alporthouse.com (unverified [78.156.66.37]) by fireflyinternet.com (Firefly Internet SMTP) with ESMTP id 32777570-1500050 for multiple; Fri, 22 Apr 2011 10:19:23 +0100 From: Chris Wilson To: intel-gfx@lists.freedesktop.org Date: Fri, 22 Apr 2011 10:19:13 +0100 Message-Id: <1303463958-17128-6-git-send-email-chris@chris-wilson.co.uk> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1303463958-17128-1-git-send-email-chris@chris-wilson.co.uk> References: <1303463958-17128-1-git-send-email-chris@chris-wilson.co.uk> X-Originating-IP: 78.156.66.37 Subject: [Intel-gfx] [PATCH 05/10] drm/i915: Move the ACPI lid notifier away from LVDS to the generic panel X-BeenThere: intel-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.11 Precedence: list List-Id: Intel graphics driver community testing & development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org Errors-To: intel-gfx-bounces+patchwork-intel-gfx=patchwork.kernel.org@lists.freedesktop.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Fri, 22 Apr 2011 09:22:04 +0000 (UTC) ... in preparation for enabling it from eDP as well. Signed-off-by: Chris Wilson --- drivers/gpu/drm/i915/intel_drv.h | 8 +++ drivers/gpu/drm/i915/intel_lvds.c | 79 ++----------------------------- drivers/gpu/drm/i915/intel_panel.c | 92 ++++++++++++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 75 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index f5b0d83..7ca9003 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h @@ -257,6 +257,14 @@ extern void intel_edp_link_config (struct intel_encoder *, int *, int *); extern bool intel_encoder_is_pch_edp(struct drm_encoder *encoder); /* intel_panel.c */ +struct intel_panel { + struct intel_connector *connector; + struct notifier_block lid_notifier; +}; +extern int intel_panel_init(struct intel_panel *panel, + struct intel_connector *connector); +extern void intel_panel_fini(struct intel_panel *panel); + extern void intel_fixed_panel_mode(struct drm_display_mode *fixed_mode, struct drm_display_mode *adjusted_mode); extern void intel_pch_panel_fitting(struct drm_device *dev, diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c index f87adaa..20d6235 100644 --- a/drivers/gpu/drm/i915/intel_lvds.c +++ b/drivers/gpu/drm/i915/intel_lvds.c @@ -27,7 +27,6 @@ * Jesse Barnes */ -#include #include #include #include @@ -38,13 +37,12 @@ #include "intel_drv.h" #include "i915_drm.h" #include "i915_drv.h" -#include /* Private structure for the integrated LVDS support */ struct intel_lvds_connector { struct intel_connector base; + struct intel_panel panel; - struct notifier_block lid_notifier; struct drm_display_mode *fixed_mode; struct edid *edid; @@ -509,71 +507,6 @@ static int intel_lvds_connector_get_modes(struct drm_connector *connector) return 1; } -static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) -{ - DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident); - return 1; -} - -/* The GPU hangs up on these systems if modeset is performed on LID open */ -static const struct dmi_system_id intel_no_modeset_on_lid[] = { - { - .callback = intel_no_modeset_on_lid_dmi_callback, - .ident = "Toshiba Tecra A11", - .matches = { - DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), - DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"), - }, - }, - - { } /* terminating entry */ -}; - -/* - * Lid events. Note the use of 'modeset_on_lid': - * - we set it on lid close, and reset it on open - * - we use it as a "only once" bit (ie we ignore - * duplicate events where it was already properly - * set/reset) - * - the suspend/resume paths will also set it to - * zero, since they restore the mode ("lid open"). - */ -static int intel_lid_notify(struct notifier_block *nb, unsigned long val, - void *unused) -{ - struct intel_lvds_connector *lvds_connector = - container_of(nb, struct intel_lvds_connector, lid_notifier); - struct drm_device *dev = lvds_connector->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; - - /* - * check and update the status of LVDS connector after receiving - * the LID nofication event. - */ - lvds_connector->base.base.status = - lvds_connector->base.base.funcs->detect(&lvds_connector->base.base, - false); - - /* Don't force modeset on machines where it causes a GPU lockup */ - if (dmi_check_system(intel_no_modeset_on_lid)) - return NOTIFY_OK; - if (!acpi_lid_open()) { - dev_priv->modeset_on_lid = 1; - return NOTIFY_OK; - } - - if (!dev_priv->modeset_on_lid) - return NOTIFY_OK; - - dev_priv->modeset_on_lid = 0; - - mutex_lock(&dev->mode_config.mutex); - drm_helper_resume_force_mode(dev); - mutex_unlock(&dev->mode_config.mutex); - - return NOTIFY_OK; -} - /** * intel_lvds_encoder_destroy - unregister and free LVDS structures * @connector: connector to free @@ -586,8 +519,7 @@ static void intel_lvds_connector_destroy(struct drm_connector *connector) struct intel_lvds_connector *lvds_connector = to_lvds_connector(connector); - if (lvds_connector->lid_notifier.notifier_call) - acpi_lid_notifier_unregister(&lvds_connector->lid_notifier); + intel_panel_fini(&lvds_connector->panel); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); @@ -1063,11 +995,8 @@ out: pwm |= PWM_PCH_ENABLE; I915_WRITE(BLC_PWM_PCH_CTL1, pwm); } - lvds_connector->lid_notifier.notifier_call = intel_lid_notify; - if (acpi_lid_notifier_register(&lvds_connector->lid_notifier)) { - DRM_DEBUG_KMS("lid notifier registration failed\n"); - lvds_connector->lid_notifier.notifier_call = NULL; - } + + intel_panel_init(&lvds_connector->panel, &lvds_connector->base); drm_sysfs_connector_add(connector); return true; diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index a06ff07..d2dc066 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c @@ -28,6 +28,10 @@ * Chris Wilson */ +#include +#include +#include + #include "intel_drv.h" #define PCI_LBPC 0xf4 /* legacy/combination backlight modes */ @@ -112,6 +116,94 @@ done: dev_priv->pch_pf_size = (width << 16) | height; } +/* Lid interactions */ + +static int intel_no_modeset_on_lid_dmi_callback(const struct dmi_system_id *id) +{ + DRM_DEBUG_KMS("Skipping forced modeset for %s\n", id->ident); + return 1; +} + +/* The GPU hangs up on these systems if modeset is performed on LID open */ +static const struct dmi_system_id intel_no_modeset_on_lid[] = { + { + .callback = intel_no_modeset_on_lid_dmi_callback, + .ident = "Toshiba Tecra A11", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "TOSHIBA"), + DMI_MATCH(DMI_PRODUCT_NAME, "TECRA A11"), + }, + }, + + { } /* terminating entry */ +}; + +/* + * Lid events. Note the use of 'modeset_on_lid': + * - we set it on lid close, and reset it on open + * - we use it as a "only once" bit (ie we ignore + * duplicate events where it was already properly + * set/reset) + * - the suspend/resume paths will also set it to + * zero, since they restore the mode ("lid open"). + */ +static int intel_panel_lid_notify(struct notifier_block *nb, unsigned long val, + void *unused) +{ + struct intel_panel *panel = + container_of(nb, struct intel_panel, lid_notifier); + struct intel_connector *connector = panel->connector; + struct drm_device *dev = connector->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + /* + * check and update the status of LVDS connector after receiving + * the LID nofication event. + */ + connector->base.status = + connector->base.funcs->detect(&connector->base, false); + + /* Don't force modeset on machines where it causes a GPU lockup */ + if (dmi_check_system(intel_no_modeset_on_lid)) + return NOTIFY_OK; + if (!acpi_lid_open()) { + dev_priv->modeset_on_lid = 1; + return NOTIFY_OK; + } + + if (!dev_priv->modeset_on_lid) + return NOTIFY_OK; + + dev_priv->modeset_on_lid = 0; + + mutex_lock(&dev->mode_config.mutex); + drm_helper_resume_force_mode(dev); + mutex_unlock(&dev->mode_config.mutex); + + return NOTIFY_OK; +} + +int intel_panel_init(struct intel_panel *panel, struct intel_connector *connector) +{ + panel->connector = connector; + + panel->lid_notifier.notifier_call = intel_panel_lid_notify; + if (acpi_lid_notifier_register(&panel->lid_notifier)) { + DRM_DEBUG_KMS("lid notifier registration failed\n"); + panel->lid_notifier.notifier_call = NULL; + } + + return 0; +} + +void intel_panel_fini(struct intel_panel *panel) +{ + if (panel->lid_notifier.notifier_call) + acpi_lid_notifier_unregister(&panel->lid_notifier); +} + +/* Panel backlight controls */ + static int is_backlight_combination_mode(struct drm_device *dev) { struct drm_i915_private *dev_priv = dev->dev_private;