18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/************************************************************************** 38c2ecf20Sopenharmony_ci * Copyright (c) 2007, Intel Corporation. 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com> 68c2ecf20Sopenharmony_ci **************************************************************************/ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include "psb_drv.h" 118c2ecf20Sopenharmony_ci#include "psb_intel_reg.h" 128c2ecf20Sopenharmony_ci#include "psb_reg.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic void psb_lid_timer_func(struct timer_list *t) 158c2ecf20Sopenharmony_ci{ 168c2ecf20Sopenharmony_ci struct drm_psb_private *dev_priv = from_timer(dev_priv, t, lid_timer); 178c2ecf20Sopenharmony_ci struct drm_device *dev = (struct drm_device *)dev_priv->dev; 188c2ecf20Sopenharmony_ci struct timer_list *lid_timer = &dev_priv->lid_timer; 198c2ecf20Sopenharmony_ci unsigned long irq_flags; 208c2ecf20Sopenharmony_ci u32 __iomem *lid_state = dev_priv->opregion.lid_state; 218c2ecf20Sopenharmony_ci u32 pp_status; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci if (readl(lid_state) == dev_priv->lid_last_state) 248c2ecf20Sopenharmony_ci goto lid_timer_schedule; 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci if ((readl(lid_state)) & 0x01) { 278c2ecf20Sopenharmony_ci /*lid state is open*/ 288c2ecf20Sopenharmony_ci REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) | POWER_TARGET_ON); 298c2ecf20Sopenharmony_ci do { 308c2ecf20Sopenharmony_ci pp_status = REG_READ(PP_STATUS); 318c2ecf20Sopenharmony_ci } while ((pp_status & PP_ON) == 0 && 328c2ecf20Sopenharmony_ci (pp_status & PP_SEQUENCE_MASK) != 0); 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci if (REG_READ(PP_STATUS) & PP_ON) { 358c2ecf20Sopenharmony_ci /*FIXME: should be backlight level before*/ 368c2ecf20Sopenharmony_ci psb_intel_lvds_set_brightness(dev, 100); 378c2ecf20Sopenharmony_ci } else { 388c2ecf20Sopenharmony_ci DRM_DEBUG("LVDS panel never powered up"); 398c2ecf20Sopenharmony_ci return; 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci } else { 428c2ecf20Sopenharmony_ci psb_intel_lvds_set_brightness(dev, 0); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci REG_WRITE(PP_CONTROL, REG_READ(PP_CONTROL) & ~POWER_TARGET_ON); 458c2ecf20Sopenharmony_ci do { 468c2ecf20Sopenharmony_ci pp_status = REG_READ(PP_STATUS); 478c2ecf20Sopenharmony_ci } while ((pp_status & PP_ON) == 0); 488c2ecf20Sopenharmony_ci } 498c2ecf20Sopenharmony_ci dev_priv->lid_last_state = readl(lid_state); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cilid_timer_schedule: 528c2ecf20Sopenharmony_ci spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); 538c2ecf20Sopenharmony_ci if (!timer_pending(lid_timer)) { 548c2ecf20Sopenharmony_ci lid_timer->expires = jiffies + PSB_LID_DELAY; 558c2ecf20Sopenharmony_ci add_timer(lid_timer); 568c2ecf20Sopenharmony_ci } 578c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags); 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_civoid psb_lid_timer_init(struct drm_psb_private *dev_priv) 618c2ecf20Sopenharmony_ci{ 628c2ecf20Sopenharmony_ci struct timer_list *lid_timer = &dev_priv->lid_timer; 638c2ecf20Sopenharmony_ci unsigned long irq_flags; 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci spin_lock_init(&dev_priv->lid_lock); 668c2ecf20Sopenharmony_ci spin_lock_irqsave(&dev_priv->lid_lock, irq_flags); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci timer_setup(lid_timer, psb_lid_timer_func, 0); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci lid_timer->expires = jiffies + PSB_LID_DELAY; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci add_timer(lid_timer); 738c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&dev_priv->lid_lock, irq_flags); 748c2ecf20Sopenharmony_ci} 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_civoid psb_lid_timer_takedown(struct drm_psb_private *dev_priv) 778c2ecf20Sopenharmony_ci{ 788c2ecf20Sopenharmony_ci del_timer_sync(&dev_priv->lid_timer); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 81