Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /**************************************************************************
0003  * Copyright (c) 2007, Intel Corporation.
0004  *
0005  * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
0006  **************************************************************************/
0007 
0008 #include <linux/spinlock.h>
0009 
0010 #include "psb_drv.h"
0011 #include "psb_intel_reg.h"
0012 #include "psb_reg.h"
0013 
0014 static void psb_lid_timer_func(struct timer_list *t)
0015 {
0016     struct drm_psb_private *dev_priv = from_timer(dev_priv, t, lid_timer);
0017     struct drm_device *dev = (struct drm_device *)&dev_priv->dev;
0018     struct timer_list *lid_timer = &dev_priv->lid_timer;
0019     unsigned long irq_flags;
0020     u32 __iomem *lid_state = dev_priv->opregion.lid_state;
0021     u32 pp_status;
0022 
0023     if (readl(lid_state) == dev_priv->lid_last_state)
0024         goto lid_timer_schedule;
0025 
0026     if ((readl(lid_state)) & 0x01) {
0027         /*lid state is open*/
0028         REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON);
0029         do {
0030             pp_status = REG_READ(PP_STATUS);
0031         } while ((pp_status & PP_ON) == 0 &&
0032              (pp_status & PP_SEQUENCE_MASK) != 0);
0033 
0034         if (REG_READ(PP_STATUS) & PP_ON) {
0035             /*FIXME: should be backlight level before*/
0036             psb_intel_lvds_set_brightness(dev, 100);
0037         } else {
0038             DRM_DEBUG("LVDS panel never powered up");
0039             return;
0040         }
0041     } else {
0042         psb_intel_lvds_set_brightness(dev, 0);
0043 
0044         REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON);
0045         do {
0046             pp_status = REG_READ(PP_STATUS);
0047         } while ((pp_status & PP_ON) == 0);
0048     }
0049     dev_priv->lid_last_state =  readl(lid_state);
0050 
0051 lid_timer_schedule:
0052     spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
0053     if (!timer_pending(lid_timer)) {
0054         lid_timer->expires = jiffies + PSB_LID_DELAY;
0055         add_timer(lid_timer);
0056     }
0057     spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
0058 }
0059 
0060 void psb_lid_timer_init(struct drm_psb_private *dev_priv)
0061 {
0062     struct timer_list *lid_timer = &dev_priv->lid_timer;
0063     unsigned long irq_flags;
0064 
0065     spin_lock_init(&dev_priv->lid_lock);
0066     spin_lock_irqsave(&dev_priv->lid_lock, irq_flags);
0067 
0068     timer_setup(lid_timer, psb_lid_timer_func, 0);
0069 
0070     lid_timer->expires = jiffies + PSB_LID_DELAY;
0071 
0072     add_timer(lid_timer);
0073     spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags);
0074 }
0075 
0076 void psb_lid_timer_takedown(struct drm_psb_private *dev_priv)
0077 {
0078     del_timer_sync(&dev_priv->lid_timer);
0079 }
0080