Subversion Repositories Kolibri OS

Rev

Rev 6084 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2008 Intel Corporation <hong.liu@intel.com>
  3.  * Copyright 2008 Red Hat <mjg@redhat.com>
  4.  *
  5.  * Permission is hereby granted, free of charge, to any person obtaining
  6.  * a copy of this software and associated documentation files (the
  7.  * "Software"), to deal in the Software without restriction, including
  8.  * without limitation the rights to use, copy, modify, merge, publish,
  9.  * distribute, sub license, and/or sell copies of the Software, and to
  10.  * permit persons to whom the Software is furnished to do so, subject to
  11.  * the following conditions:
  12.  *
  13.  * The above copyright notice and this permission notice (including the
  14.  * next paragraph) shall be included in all copies or substantial
  15.  * portions of the Software.
  16.  *
  17.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  18.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  19.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  20.  * NON-INFRINGEMENT.  IN NO EVENT SHALL INTEL AND/OR ITS SUPPLIERS BE
  21.  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  22.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  23.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  24.  * SOFTWARE.
  25.  *
  26.  */
  27.  
  28. #include <linux/acpi.h>
  29. #include <acpi/video.h>
  30.  
  31. #include <drm/drmP.h>
  32. #include <drm/i915_drm.h>
  33. #include "i915_drv.h"
  34. #include "intel_drv.h"
  35.  
  36. #define PCI_ASLE                0xe4
  37. #define PCI_ASLS                0xfc
  38. #define PCI_SWSCI               0xe8
  39. #define PCI_SWSCI_SCISEL        (1 << 15)
  40. #define PCI_SWSCI_GSSCIE        (1 << 0)
  41.  
  42. #define OPREGION_HEADER_OFFSET 0
  43. #define OPREGION_ACPI_OFFSET   0x100
  44. #define   ACPI_CLID 0x01ac /* current lid state indicator */
  45. #define   ACPI_CDCK 0x01b0 /* current docking state indicator */
  46. #define OPREGION_SWSCI_OFFSET  0x200
  47. #define OPREGION_ASLE_OFFSET   0x300
  48. #define OPREGION_VBT_OFFSET    0x400
  49.  
  50. #define OPREGION_SIGNATURE "IntelGraphicsMem"
  51. #define MBOX_ACPI      (1<<0)
  52. #define MBOX_SWSCI     (1<<1)
  53. #define MBOX_ASLE      (1<<2)
  54. #define MBOX_ASLE_EXT  (1<<4)
  55.  
  56. struct opregion_header {
  57.         u8 signature[16];
  58.         u32 size;
  59.         u32 opregion_ver;
  60.         u8 bios_ver[32];
  61.         u8 vbios_ver[16];
  62.         u8 driver_ver[16];
  63.         u32 mboxes;
  64.         u32 driver_model;
  65.         u32 pcon;
  66.         u8 dver[32];
  67.         u8 rsvd[124];
  68. } __packed;
  69.  
  70. /* OpRegion mailbox #1: public ACPI methods */
  71. struct opregion_acpi {
  72.         u32 drdy;       /* driver readiness */
  73.         u32 csts;       /* notification status */
  74.         u32 cevt;       /* current event */
  75.         u8 rsvd1[20];
  76.         u32 didl[8];    /* supported display devices ID list */
  77.         u32 cpdl[8];    /* currently presented display list */
  78.         u32 cadl[8];    /* currently active display list */
  79.         u32 nadl[8];    /* next active devices list */
  80.         u32 aslp;       /* ASL sleep time-out */
  81.         u32 tidx;       /* toggle table index */
  82.         u32 chpd;       /* current hotplug enable indicator */
  83.         u32 clid;       /* current lid state*/
  84.         u32 cdck;       /* current docking state */
  85.         u32 sxsw;       /* Sx state resume */
  86.         u32 evts;       /* ASL supported events */
  87.         u32 cnot;       /* current OS notification */
  88.         u32 nrdy;       /* driver status */
  89.         u32 did2[7];    /* extended supported display devices ID list */
  90.         u32 cpd2[7];    /* extended attached display devices list */
  91.         u8 rsvd2[4];
  92. } __packed;
  93.  
  94. /* OpRegion mailbox #2: SWSCI */
  95. struct opregion_swsci {
  96.         u32 scic;       /* SWSCI command|status|data */
  97.         u32 parm;       /* command parameters */
  98.         u32 dslp;       /* driver sleep time-out */
  99.         u8 rsvd[244];
  100. } __packed;
  101.  
  102. /* OpRegion mailbox #3: ASLE */
  103. struct opregion_asle {
  104.         u32 ardy;       /* driver readiness */
  105.         u32 aslc;       /* ASLE interrupt command */
  106.         u32 tche;       /* technology enabled indicator */
  107.         u32 alsi;       /* current ALS illuminance reading */
  108.         u32 bclp;       /* backlight brightness to set */
  109.         u32 pfit;       /* panel fitting state */
  110.         u32 cblv;       /* current brightness level */
  111.         u16 bclm[20];   /* backlight level duty cycle mapping table */
  112.         u32 cpfm;       /* current panel fitting mode */
  113.         u32 epfm;       /* enabled panel fitting modes */
  114.         u8 plut[74];    /* panel LUT and identifier */
  115.         u32 pfmb;       /* PWM freq and min brightness */
  116.         u32 cddv;       /* color correction default values */
  117.         u32 pcft;       /* power conservation features */
  118.         u32 srot;       /* supported rotation angles */
  119.         u32 iuer;       /* IUER events */
  120.         u64 fdss;
  121.         u32 fdsp;
  122.         u32 stat;
  123.         u8 rsvd[70];
  124. } __packed;
  125.  
  126. /* Driver readiness indicator */
  127. #define ASLE_ARDY_READY         (1 << 0)
  128. #define ASLE_ARDY_NOT_READY     (0 << 0)
  129.  
  130. /* ASLE Interrupt Command (ASLC) bits */
  131. #define ASLC_SET_ALS_ILLUM              (1 << 0)
  132. #define ASLC_SET_BACKLIGHT              (1 << 1)
  133. #define ASLC_SET_PFIT                   (1 << 2)
  134. #define ASLC_SET_PWM_FREQ               (1 << 3)
  135. #define ASLC_SUPPORTED_ROTATION_ANGLES  (1 << 4)
  136. #define ASLC_BUTTON_ARRAY               (1 << 5)
  137. #define ASLC_CONVERTIBLE_INDICATOR      (1 << 6)
  138. #define ASLC_DOCKING_INDICATOR          (1 << 7)
  139. #define ASLC_ISCT_STATE_CHANGE          (1 << 8)
  140. #define ASLC_REQ_MSK                    0x1ff
  141. /* response bits */
  142. #define ASLC_ALS_ILLUM_FAILED           (1 << 10)
  143. #define ASLC_BACKLIGHT_FAILED           (1 << 12)
  144. #define ASLC_PFIT_FAILED                (1 << 14)
  145. #define ASLC_PWM_FREQ_FAILED            (1 << 16)
  146. #define ASLC_ROTATION_ANGLES_FAILED     (1 << 18)
  147. #define ASLC_BUTTON_ARRAY_FAILED        (1 << 20)
  148. #define ASLC_CONVERTIBLE_FAILED         (1 << 22)
  149. #define ASLC_DOCKING_FAILED             (1 << 24)
  150. #define ASLC_ISCT_STATE_FAILED          (1 << 26)
  151.  
  152. /* Technology enabled indicator */
  153. #define ASLE_TCHE_ALS_EN        (1 << 0)
  154. #define ASLE_TCHE_BLC_EN        (1 << 1)
  155. #define ASLE_TCHE_PFIT_EN       (1 << 2)
  156. #define ASLE_TCHE_PFMB_EN       (1 << 3)
  157.  
  158. /* ASLE backlight brightness to set */
  159. #define ASLE_BCLP_VALID                (1<<31)
  160. #define ASLE_BCLP_MSK          (~(1<<31))
  161.  
  162. /* ASLE panel fitting request */
  163. #define ASLE_PFIT_VALID         (1<<31)
  164. #define ASLE_PFIT_CENTER (1<<0)
  165. #define ASLE_PFIT_STRETCH_TEXT (1<<1)
  166. #define ASLE_PFIT_STRETCH_GFX (1<<2)
  167.  
  168. /* PWM frequency and minimum brightness */
  169. #define ASLE_PFMB_BRIGHTNESS_MASK (0xff)
  170. #define ASLE_PFMB_BRIGHTNESS_VALID (1<<8)
  171. #define ASLE_PFMB_PWM_MASK (0x7ffffe00)
  172. #define ASLE_PFMB_PWM_VALID (1<<31)
  173.  
  174. #define ASLE_CBLV_VALID         (1<<31)
  175.  
  176. /* IUER */
  177. #define ASLE_IUER_DOCKING               (1 << 7)
  178. #define ASLE_IUER_CONVERTIBLE           (1 << 6)
  179. #define ASLE_IUER_ROTATION_LOCK_BTN     (1 << 4)
  180. #define ASLE_IUER_VOLUME_DOWN_BTN       (1 << 3)
  181. #define ASLE_IUER_VOLUME_UP_BTN         (1 << 2)
  182. #define ASLE_IUER_WINDOWS_BTN           (1 << 1)
  183. #define ASLE_IUER_POWER_BTN             (1 << 0)
  184.  
  185. /* Software System Control Interrupt (SWSCI) */
  186. #define SWSCI_SCIC_INDICATOR            (1 << 0)
  187. #define SWSCI_SCIC_MAIN_FUNCTION_SHIFT  1
  188. #define SWSCI_SCIC_MAIN_FUNCTION_MASK   (0xf << 1)
  189. #define SWSCI_SCIC_SUB_FUNCTION_SHIFT   8
  190. #define SWSCI_SCIC_SUB_FUNCTION_MASK    (0xff << 8)
  191. #define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8
  192. #define SWSCI_SCIC_EXIT_PARAMETER_MASK  (0xff << 8)
  193. #define SWSCI_SCIC_EXIT_STATUS_SHIFT    5
  194. #define SWSCI_SCIC_EXIT_STATUS_MASK     (7 << 5)
  195. #define SWSCI_SCIC_EXIT_STATUS_SUCCESS  1
  196.  
  197. #define SWSCI_FUNCTION_CODE(main, sub) \
  198.         ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \
  199.          (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT)
  200.  
  201. /* SWSCI: Get BIOS Data (GBDA) */
  202. #define SWSCI_GBDA                      4
  203. #define SWSCI_GBDA_SUPPORTED_CALLS      SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0)
  204. #define SWSCI_GBDA_REQUESTED_CALLBACKS  SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1)
  205. #define SWSCI_GBDA_BOOT_DISPLAY_PREF    SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4)
  206. #define SWSCI_GBDA_PANEL_DETAILS        SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5)
  207. #define SWSCI_GBDA_TV_STANDARD          SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6)
  208. #define SWSCI_GBDA_INTERNAL_GRAPHICS    SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7)
  209. #define SWSCI_GBDA_SPREAD_SPECTRUM      SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10)
  210.  
  211. /* SWSCI: System BIOS Callbacks (SBCB) */
  212. #define SWSCI_SBCB                      6
  213. #define SWSCI_SBCB_SUPPORTED_CALLBACKS  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0)
  214. #define SWSCI_SBCB_INIT_COMPLETION      SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1)
  215. #define SWSCI_SBCB_PRE_HIRES_SET_MODE   SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3)
  216. #define SWSCI_SBCB_POST_HIRES_SET_MODE  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4)
  217. #define SWSCI_SBCB_DISPLAY_SWITCH       SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5)
  218. #define SWSCI_SBCB_SET_TV_FORMAT        SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6)
  219. #define SWSCI_SBCB_ADAPTER_POWER_STATE  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7)
  220. #define SWSCI_SBCB_DISPLAY_POWER_STATE  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8)
  221. #define SWSCI_SBCB_SET_BOOT_DISPLAY     SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9)
  222. #define SWSCI_SBCB_SET_PANEL_DETAILS    SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10)
  223. #define SWSCI_SBCB_SET_INTERNAL_GFX     SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11)
  224. #define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16)
  225. #define SWSCI_SBCB_SUSPEND_RESUME       SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17)
  226. #define SWSCI_SBCB_SET_SPREAD_SPECTRUM  SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18)
  227. #define SWSCI_SBCB_POST_VBE_PM          SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19)
  228. #define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21)
  229.  
  230. #define ACPI_OTHER_OUTPUT (0<<8)
  231. #define ACPI_VGA_OUTPUT (1<<8)
  232. #define ACPI_TV_OUTPUT (2<<8)
  233. #define ACPI_DIGITAL_OUTPUT (3<<8)
  234. #define ACPI_LVDS_OUTPUT (4<<8)
  235.  
  236. #define MAX_DSLP        1500
  237.  
  238. #ifdef CONFIG_ACPI
  239. static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out)
  240. {
  241.         struct drm_i915_private *dev_priv = dev->dev_private;
  242.         struct opregion_swsci *swsci = dev_priv->opregion.swsci;
  243.         u32 main_function, sub_function, scic;
  244.         u16 pci_swsci;
  245.         u32 dslp;
  246.  
  247.         if (!swsci)
  248.                 return -ENODEV;
  249.  
  250.         main_function = (function & SWSCI_SCIC_MAIN_FUNCTION_MASK) >>
  251.                 SWSCI_SCIC_MAIN_FUNCTION_SHIFT;
  252.         sub_function = (function & SWSCI_SCIC_SUB_FUNCTION_MASK) >>
  253.                 SWSCI_SCIC_SUB_FUNCTION_SHIFT;
  254.  
  255.         /* Check if we can call the function. See swsci_setup for details. */
  256.         if (main_function == SWSCI_SBCB) {
  257.                 if ((dev_priv->opregion.swsci_sbcb_sub_functions &
  258.                      (1 << sub_function)) == 0)
  259.                         return -EINVAL;
  260.         } else if (main_function == SWSCI_GBDA) {
  261.                 if ((dev_priv->opregion.swsci_gbda_sub_functions &
  262.                      (1 << sub_function)) == 0)
  263.                         return -EINVAL;
  264.         }
  265.  
  266.         /* Driver sleep timeout in ms. */
  267.         dslp = swsci->dslp;
  268.         if (!dslp) {
  269.                 /* The spec says 2ms should be the default, but it's too small
  270.                  * for some machines. */
  271.                 dslp = 50;
  272.         } else if (dslp > MAX_DSLP) {
  273.                 /* Hey bios, trust must be earned. */
  274.                 DRM_INFO_ONCE("ACPI BIOS requests an excessive sleep of %u ms, "
  275.                               "using %u ms instead\n", dslp, MAX_DSLP);
  276.                 dslp = MAX_DSLP;
  277.         }
  278.  
  279.         /* The spec tells us to do this, but we are the only user... */
  280.         scic = swsci->scic;
  281.         if (scic & SWSCI_SCIC_INDICATOR) {
  282.                 DRM_DEBUG_DRIVER("SWSCI request already in progress\n");
  283.                 return -EBUSY;
  284.         }
  285.  
  286.         scic = function | SWSCI_SCIC_INDICATOR;
  287.  
  288.         swsci->parm = parm;
  289.         swsci->scic = scic;
  290.  
  291.         /* Ensure SCI event is selected and event trigger is cleared. */
  292.         pci_read_config_word(dev->pdev, PCI_SWSCI, &pci_swsci);
  293.         if (!(pci_swsci & PCI_SWSCI_SCISEL) || (pci_swsci & PCI_SWSCI_GSSCIE)) {
  294.                 pci_swsci |= PCI_SWSCI_SCISEL;
  295.                 pci_swsci &= ~PCI_SWSCI_GSSCIE;
  296.                 pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
  297.         }
  298.  
  299.         /* Use event trigger to tell bios to check the mail. */
  300.         pci_swsci |= PCI_SWSCI_GSSCIE;
  301.         pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci);
  302.  
  303.         /* Poll for the result. */
  304. #define C (((scic = swsci->scic) & SWSCI_SCIC_INDICATOR) == 0)
  305.         if (wait_for(C, dslp)) {
  306.                 DRM_DEBUG_DRIVER("SWSCI request timed out\n");
  307.                 return -ETIMEDOUT;
  308.         }
  309.  
  310.         scic = (scic & SWSCI_SCIC_EXIT_STATUS_MASK) >>
  311.                 SWSCI_SCIC_EXIT_STATUS_SHIFT;
  312.  
  313.         /* Note: scic == 0 is an error! */
  314.         if (scic != SWSCI_SCIC_EXIT_STATUS_SUCCESS) {
  315.                 DRM_DEBUG_DRIVER("SWSCI request error %u\n", scic);
  316.                 return -EIO;
  317.         }
  318.  
  319.         if (parm_out)
  320.                 *parm_out = swsci->parm;
  321.  
  322.         return 0;
  323.  
  324. #undef C
  325. }
  326.  
  327. #define DISPLAY_TYPE_CRT                        0
  328. #define DISPLAY_TYPE_TV                         1
  329. #define DISPLAY_TYPE_EXTERNAL_FLAT_PANEL        2
  330. #define DISPLAY_TYPE_INTERNAL_FLAT_PANEL        3
  331.  
  332. int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder,
  333.                                   bool enable)
  334. {
  335.         struct drm_device *dev = intel_encoder->base.dev;
  336.         u32 parm = 0;
  337.         u32 type = 0;
  338.         u32 port;
  339.  
  340.         /* don't care about old stuff for now */
  341.         if (!HAS_DDI(dev))
  342.                 return 0;
  343.  
  344.         if (intel_encoder->type == INTEL_OUTPUT_DSI)
  345.                 port = 0;
  346.         else
  347.                 port = intel_ddi_get_encoder_port(intel_encoder);
  348.  
  349.         if (port == PORT_E)  {
  350.                 port = 0;
  351.         } else {
  352.                 parm |= 1 << port;
  353.                 port++;
  354.         }
  355.  
  356.         if (!enable)
  357.                 parm |= 4 << 8;
  358.  
  359.         switch (intel_encoder->type) {
  360.         case INTEL_OUTPUT_ANALOG:
  361.                 type = DISPLAY_TYPE_CRT;
  362.                 break;
  363.         case INTEL_OUTPUT_UNKNOWN:
  364.         case INTEL_OUTPUT_DISPLAYPORT:
  365.         case INTEL_OUTPUT_HDMI:
  366.         case INTEL_OUTPUT_DP_MST:
  367.                 type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL;
  368.                 break;
  369.         case INTEL_OUTPUT_EDP:
  370.         case INTEL_OUTPUT_DSI:
  371.                 type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL;
  372.                 break;
  373.         default:
  374.                 WARN_ONCE(1, "unsupported intel_encoder type %d\n",
  375.                           intel_encoder->type);
  376.                 return -EINVAL;
  377.         }
  378.  
  379.         parm |= type << (16 + port * 3);
  380.  
  381.         return swsci(dev, SWSCI_SBCB_DISPLAY_POWER_STATE, parm, NULL);
  382. }
  383.  
  384. static const struct {
  385.         pci_power_t pci_power_state;
  386.         u32 parm;
  387. } power_state_map[] = {
  388.         { PCI_D0,       0x00 },
  389.         { PCI_D1,       0x01 },
  390.         { PCI_D2,       0x02 },
  391.         { PCI_D3hot,    0x04 },
  392.         { PCI_D3cold,   0x04 },
  393. };
  394.  
  395. int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state)
  396. {
  397.         int i;
  398.  
  399.         if (!HAS_DDI(dev))
  400.                 return 0;
  401.  
  402.         for (i = 0; i < ARRAY_SIZE(power_state_map); i++) {
  403.                 if (state == power_state_map[i].pci_power_state)
  404.                         return swsci(dev, SWSCI_SBCB_ADAPTER_POWER_STATE,
  405.                                      power_state_map[i].parm, NULL);
  406.         }
  407.  
  408.         return -EINVAL;
  409. }
  410.  
  411. static u32 asle_set_backlight(struct drm_device *dev, u32 bclp)
  412. {
  413.         struct drm_i915_private *dev_priv = dev->dev_private;
  414.         struct intel_connector *intel_connector;
  415.         struct opregion_asle *asle = dev_priv->opregion.asle;
  416.  
  417.         DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp);
  418.  
  419.         if (acpi_video_get_backlight_type() == acpi_backlight_native) {
  420.                 DRM_DEBUG_KMS("opregion backlight request ignored\n");
  421.                 return 0;
  422.         }
  423.  
  424.         if (!(bclp & ASLE_BCLP_VALID))
  425.                 return ASLC_BACKLIGHT_FAILED;
  426.  
  427.         bclp &= ASLE_BCLP_MSK;
  428.         if (bclp > 255)
  429.                 return ASLC_BACKLIGHT_FAILED;
  430.  
  431.         drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
  432.  
  433.         /*
  434.          * Update backlight on all connectors that support backlight (usually
  435.          * only one).
  436.          */
  437.         DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp);
  438.         list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head)
  439.                 intel_panel_set_backlight_acpi(intel_connector, bclp, 255);
  440.         asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID;
  441.  
  442.         drm_modeset_unlock(&dev->mode_config.connection_mutex);
  443.  
  444.  
  445.         return 0;
  446. }
  447.  
  448. static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi)
  449. {
  450.         /* alsi is the current ALS reading in lux. 0 indicates below sensor
  451.            range, 0xffff indicates above sensor range. 1-0xfffe are valid */
  452.         DRM_DEBUG_DRIVER("Illum is not supported\n");
  453.         return ASLC_ALS_ILLUM_FAILED;
  454. }
  455.  
  456. static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb)
  457. {
  458.         DRM_DEBUG_DRIVER("PWM freq is not supported\n");
  459.         return ASLC_PWM_FREQ_FAILED;
  460. }
  461.  
  462. static u32 asle_set_pfit(struct drm_device *dev, u32 pfit)
  463. {
  464.         /* Panel fitting is currently controlled by the X code, so this is a
  465.            noop until modesetting support works fully */
  466.         DRM_DEBUG_DRIVER("Pfit is not supported\n");
  467.         return ASLC_PFIT_FAILED;
  468. }
  469.  
  470. static u32 asle_set_supported_rotation_angles(struct drm_device *dev, u32 srot)
  471. {
  472.         DRM_DEBUG_DRIVER("SROT is not supported\n");
  473.         return ASLC_ROTATION_ANGLES_FAILED;
  474. }
  475.  
  476. static u32 asle_set_button_array(struct drm_device *dev, u32 iuer)
  477. {
  478.         if (!iuer)
  479.                 DRM_DEBUG_DRIVER("Button array event is not supported (nothing)\n");
  480.         if (iuer & ASLE_IUER_ROTATION_LOCK_BTN)
  481.                 DRM_DEBUG_DRIVER("Button array event is not supported (rotation lock)\n");
  482.         if (iuer & ASLE_IUER_VOLUME_DOWN_BTN)
  483.                 DRM_DEBUG_DRIVER("Button array event is not supported (volume down)\n");
  484.         if (iuer & ASLE_IUER_VOLUME_UP_BTN)
  485.                 DRM_DEBUG_DRIVER("Button array event is not supported (volume up)\n");
  486.         if (iuer & ASLE_IUER_WINDOWS_BTN)
  487.                 DRM_DEBUG_DRIVER("Button array event is not supported (windows)\n");
  488.         if (iuer & ASLE_IUER_POWER_BTN)
  489.                 DRM_DEBUG_DRIVER("Button array event is not supported (power)\n");
  490.  
  491.         return ASLC_BUTTON_ARRAY_FAILED;
  492. }
  493.  
  494. static u32 asle_set_convertible(struct drm_device *dev, u32 iuer)
  495. {
  496.         if (iuer & ASLE_IUER_CONVERTIBLE)
  497.                 DRM_DEBUG_DRIVER("Convertible is not supported (clamshell)\n");
  498.         else
  499.                 DRM_DEBUG_DRIVER("Convertible is not supported (slate)\n");
  500.  
  501.         return ASLC_CONVERTIBLE_FAILED;
  502. }
  503.  
  504. static u32 asle_set_docking(struct drm_device *dev, u32 iuer)
  505. {
  506.         if (iuer & ASLE_IUER_DOCKING)
  507.                 DRM_DEBUG_DRIVER("Docking is not supported (docked)\n");
  508.         else
  509.                 DRM_DEBUG_DRIVER("Docking is not supported (undocked)\n");
  510.  
  511.         return ASLC_DOCKING_FAILED;
  512. }
  513.  
  514. static u32 asle_isct_state(struct drm_device *dev)
  515. {
  516.         DRM_DEBUG_DRIVER("ISCT is not supported\n");
  517.         return ASLC_ISCT_STATE_FAILED;
  518. }
  519.  
  520. static void asle_work(struct work_struct *work)
  521. {
  522.         struct intel_opregion *opregion =
  523.                 container_of(work, struct intel_opregion, asle_work);
  524.         struct drm_i915_private *dev_priv =
  525.                 container_of(opregion, struct drm_i915_private, opregion);
  526.         struct drm_device *dev = dev_priv->dev;
  527.         struct opregion_asle *asle = dev_priv->opregion.asle;
  528.         u32 aslc_stat = 0;
  529.         u32 aslc_req;
  530.  
  531.         if (!asle)
  532.                 return;
  533.  
  534.         aslc_req = asle->aslc;
  535.  
  536.         if (!(aslc_req & ASLC_REQ_MSK)) {
  537.                 DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n",
  538.                                  aslc_req);
  539.                 return;
  540.         }
  541.  
  542.         if (aslc_req & ASLC_SET_ALS_ILLUM)
  543.                 aslc_stat |= asle_set_als_illum(dev, asle->alsi);
  544.  
  545.         if (aslc_req & ASLC_SET_BACKLIGHT)
  546.                 aslc_stat |= asle_set_backlight(dev, asle->bclp);
  547.  
  548.         if (aslc_req & ASLC_SET_PFIT)
  549.                 aslc_stat |= asle_set_pfit(dev, asle->pfit);
  550.  
  551.         if (aslc_req & ASLC_SET_PWM_FREQ)
  552.                 aslc_stat |= asle_set_pwm_freq(dev, asle->pfmb);
  553.  
  554.         if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES)
  555.                 aslc_stat |= asle_set_supported_rotation_angles(dev,
  556.                                                         asle->srot);
  557.  
  558.         if (aslc_req & ASLC_BUTTON_ARRAY)
  559.                 aslc_stat |= asle_set_button_array(dev, asle->iuer);
  560.  
  561.         if (aslc_req & ASLC_CONVERTIBLE_INDICATOR)
  562.                 aslc_stat |= asle_set_convertible(dev, asle->iuer);
  563.  
  564.         if (aslc_req & ASLC_DOCKING_INDICATOR)
  565.                 aslc_stat |= asle_set_docking(dev, asle->iuer);
  566.  
  567.         if (aslc_req & ASLC_ISCT_STATE_CHANGE)
  568.                 aslc_stat |= asle_isct_state(dev);
  569.  
  570.         asle->aslc = aslc_stat;
  571. }
  572.  
  573. void intel_opregion_asle_intr(struct drm_device *dev)
  574. {
  575.         struct drm_i915_private *dev_priv = dev->dev_private;
  576.  
  577.         if (dev_priv->opregion.asle)
  578.                 schedule_work(&dev_priv->opregion.asle_work);
  579. }
  580.  
  581. #define ACPI_EV_DISPLAY_SWITCH (1<<0)
  582. #define ACPI_EV_LID            (1<<1)
  583. #define ACPI_EV_DOCK           (1<<2)
  584.  
  585. static struct intel_opregion *system_opregion;
  586.  
  587. static int intel_opregion_video_event(struct notifier_block *nb,
  588.                                       unsigned long val, void *data)
  589. {
  590.         /* The only video events relevant to opregion are 0x80. These indicate
  591.            either a docking event, lid switch or display switch request. In
  592.            Linux, these are handled by the dock, button and video drivers.
  593.         */
  594.  
  595.         struct acpi_bus_event *event = data;
  596.         struct opregion_acpi *acpi;
  597.         int ret = NOTIFY_OK;
  598.  
  599.         if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0)
  600.                 return NOTIFY_DONE;
  601.  
  602.         if (!system_opregion)
  603.                 return NOTIFY_DONE;
  604.  
  605.         acpi = system_opregion->acpi;
  606.  
  607.         if (event->type == 0x80 && ((acpi->cevt & 1) == 0))
  608.                 ret = NOTIFY_BAD;
  609.  
  610.         acpi->csts = 0;
  611.  
  612.         return ret;
  613. }
  614.  
  615. static struct notifier_block intel_opregion_notifier = {
  616.         .notifier_call = intel_opregion_video_event,
  617. };
  618.  
  619. /*
  620.  * Initialise the DIDL field in opregion. This passes a list of devices to
  621.  * the firmware. Values are defined by section B.4.2 of the ACPI specification
  622.  * (version 3)
  623.  */
  624.  
  625. static u32 get_did(struct intel_opregion *opregion, int i)
  626. {
  627.         u32 did;
  628.  
  629.         if (i < ARRAY_SIZE(opregion->acpi->didl)) {
  630.                 did = opregion->acpi->didl[i];
  631.         } else {
  632.                 i -= ARRAY_SIZE(opregion->acpi->didl);
  633.  
  634.                 if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
  635.                         return 0;
  636.  
  637.                 did = opregion->acpi->did2[i];
  638.         }
  639.  
  640.         return did;
  641. }
  642.  
  643. static void set_did(struct intel_opregion *opregion, int i, u32 val)
  644. {
  645.         if (i < ARRAY_SIZE(opregion->acpi->didl)) {
  646.                 opregion->acpi->didl[i] = val;
  647.         } else {
  648.                 i -= ARRAY_SIZE(opregion->acpi->didl);
  649.  
  650.                 if (WARN_ON(i >= ARRAY_SIZE(opregion->acpi->did2)))
  651.                         return;
  652.  
  653.                 opregion->acpi->did2[i] = val;
  654.         }
  655. }
  656.  
  657. static void intel_didl_outputs(struct drm_device *dev)
  658. {
  659.         struct drm_i915_private *dev_priv = dev->dev_private;
  660.         struct intel_opregion *opregion = &dev_priv->opregion;
  661.         struct drm_connector *connector;
  662.         acpi_handle handle;
  663.         struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL;
  664.         unsigned long long device_id;
  665.         acpi_status status;
  666.         u32 temp, max_outputs;
  667.         int i = 0;
  668.  
  669.         handle = ACPI_HANDLE(&dev->pdev->dev);
  670.         if (!handle || acpi_bus_get_device(handle, &acpi_dev))
  671.                 return;
  672.  
  673.         if (acpi_is_video_device(handle))
  674.                 acpi_video_bus = acpi_dev;
  675.         else {
  676.                 list_for_each_entry(acpi_cdev, &acpi_dev->children, node) {
  677.                         if (acpi_is_video_device(acpi_cdev->handle)) {
  678.                                 acpi_video_bus = acpi_cdev;
  679.                                 break;
  680.                         }
  681.                 }
  682.         }
  683.  
  684.         if (!acpi_video_bus) {
  685.                 DRM_ERROR("No ACPI video bus found\n");
  686.                 return;
  687.         }
  688.  
  689.         /*
  690.          * In theory, did2, the extended didl, gets added at opregion version
  691.          * 3.0. In practice, however, we're supposed to set it for earlier
  692.          * versions as well, since a BIOS that doesn't understand did2 should
  693.          * not look at it anyway. Use a variable so we can tweak this if a need
  694.          * arises later.
  695.          */
  696.         max_outputs = ARRAY_SIZE(opregion->acpi->didl) +
  697.                 ARRAY_SIZE(opregion->acpi->did2);
  698.  
  699.         list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) {
  700.                 if (i >= max_outputs) {
  701.                         DRM_DEBUG_KMS("More than %u outputs detected via ACPI\n",
  702.                                       max_outputs);
  703.                         return;
  704.                 }
  705.                 status = acpi_evaluate_integer(acpi_cdev->handle, "_ADR",
  706.                                                NULL, &device_id);
  707.                 if (ACPI_SUCCESS(status)) {
  708.                         if (!device_id)
  709.                                 goto blind_set;
  710.                         set_did(opregion, i++, (u32)(device_id & 0x0f0f));
  711.                 }
  712.         }
  713.  
  714. end:
  715.         DRM_DEBUG_KMS("%d outputs detected\n", i);
  716.  
  717.         /* If fewer than max outputs, the list must be null terminated */
  718.         if (i < max_outputs)
  719.                 set_did(opregion, i, 0);
  720.         return;
  721.  
  722. blind_set:
  723.         i = 0;
  724.         list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
  725.                 int output_type = ACPI_OTHER_OUTPUT;
  726.                 if (i >= max_outputs) {
  727.                         DRM_DEBUG_KMS("More than %u outputs in connector list\n",
  728.                                       max_outputs);
  729.                         return;
  730.                 }
  731.                 switch (connector->connector_type) {
  732.                 case DRM_MODE_CONNECTOR_VGA:
  733.                 case DRM_MODE_CONNECTOR_DVIA:
  734.                         output_type = ACPI_VGA_OUTPUT;
  735.                         break;
  736.                 case DRM_MODE_CONNECTOR_Composite:
  737.                 case DRM_MODE_CONNECTOR_SVIDEO:
  738.                 case DRM_MODE_CONNECTOR_Component:
  739.                 case DRM_MODE_CONNECTOR_9PinDIN:
  740.                         output_type = ACPI_TV_OUTPUT;
  741.                         break;
  742.                 case DRM_MODE_CONNECTOR_DVII:
  743.                 case DRM_MODE_CONNECTOR_DVID:
  744.                 case DRM_MODE_CONNECTOR_DisplayPort:
  745.                 case DRM_MODE_CONNECTOR_HDMIA:
  746.                 case DRM_MODE_CONNECTOR_HDMIB:
  747.                         output_type = ACPI_DIGITAL_OUTPUT;
  748.                         break;
  749.                 case DRM_MODE_CONNECTOR_LVDS:
  750.                         output_type = ACPI_LVDS_OUTPUT;
  751.                         break;
  752.                 }
  753.                 temp = get_did(opregion, i);
  754.                 set_did(opregion, i, temp | (1 << 31) | output_type | i);
  755.                 i++;
  756.         }
  757.         goto end;
  758. }
  759.  
  760. static void intel_setup_cadls(struct drm_device *dev)
  761. {
  762.         struct drm_i915_private *dev_priv = dev->dev_private;
  763.         struct intel_opregion *opregion = &dev_priv->opregion;
  764.         int i = 0;
  765.         u32 disp_id;
  766.  
  767.         /* Initialize the CADL field by duplicating the DIDL values.
  768.          * Technically, this is not always correct as display outputs may exist,
  769.          * but not active. This initialization is necessary for some Clevo
  770.          * laptops that check this field before processing the brightness and
  771.          * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if
  772.          * there are less than eight devices. */
  773.         do {
  774.                 disp_id = get_did(opregion, i);
  775.                 opregion->acpi->cadl[i] = disp_id;
  776.         } while (++i < 8 && disp_id != 0);
  777. }
  778.  
  779. void intel_opregion_init(struct drm_device *dev)
  780. {
  781.         struct drm_i915_private *dev_priv = dev->dev_private;
  782.         struct intel_opregion *opregion = &dev_priv->opregion;
  783.  
  784.         if (!opregion->header)
  785.                 return;
  786.  
  787.         if (opregion->acpi) {
  788.                 intel_didl_outputs(dev);
  789.                 intel_setup_cadls(dev);
  790.  
  791.                 /* Notify BIOS we are ready to handle ACPI video ext notifs.
  792.                  * Right now, all the events are handled by the ACPI video module.
  793.                  * We don't actually need to do anything with them. */
  794.                 opregion->acpi->csts = 0;
  795.                 opregion->acpi->drdy = 1;
  796.  
  797.                 system_opregion = opregion;
  798.                 register_acpi_notifier(&intel_opregion_notifier);
  799.         }
  800.  
  801.         if (opregion->asle) {
  802.                 opregion->asle->tche = ASLE_TCHE_BLC_EN;
  803.                 opregion->asle->ardy = ASLE_ARDY_READY;
  804.         }
  805. }
  806.  
  807. void intel_opregion_fini(struct drm_device *dev)
  808. {
  809.         struct drm_i915_private *dev_priv = dev->dev_private;
  810.         struct intel_opregion *opregion = &dev_priv->opregion;
  811.  
  812.         if (!opregion->header)
  813.                 return;
  814.  
  815.         if (opregion->asle)
  816.                 opregion->asle->ardy = ASLE_ARDY_NOT_READY;
  817.  
  818.         cancel_work_sync(&dev_priv->opregion.asle_work);
  819.  
  820.         if (opregion->acpi) {
  821.                 opregion->acpi->drdy = 0;
  822.  
  823.                 system_opregion = NULL;
  824.                 unregister_acpi_notifier(&intel_opregion_notifier);
  825.         }
  826.  
  827.         /* just clear all opregion memory pointers now */
  828.         memunmap(opregion->header);
  829.         opregion->header = NULL;
  830.         opregion->acpi = NULL;
  831.         opregion->swsci = NULL;
  832.         opregion->asle = NULL;
  833.         opregion->vbt = NULL;
  834.         opregion->lid_state = NULL;
  835. }
  836.  
  837. static void swsci_setup(struct drm_device *dev)
  838. {
  839.         struct drm_i915_private *dev_priv = dev->dev_private;
  840.         struct intel_opregion *opregion = &dev_priv->opregion;
  841.         bool requested_callbacks = false;
  842.         u32 tmp;
  843.  
  844.         /* Sub-function code 0 is okay, let's allow them. */
  845.         opregion->swsci_gbda_sub_functions = 1;
  846.         opregion->swsci_sbcb_sub_functions = 1;
  847.  
  848.         /* We use GBDA to ask for supported GBDA calls. */
  849.         if (swsci(dev, SWSCI_GBDA_SUPPORTED_CALLS, 0, &tmp) == 0) {
  850.                 /* make the bits match the sub-function codes */
  851.                 tmp <<= 1;
  852.                 opregion->swsci_gbda_sub_functions |= tmp;
  853.         }
  854.  
  855.         /*
  856.          * We also use GBDA to ask for _requested_ SBCB callbacks. The driver
  857.          * must not call interfaces that are not specifically requested by the
  858.          * bios.
  859.          */
  860.         if (swsci(dev, SWSCI_GBDA_REQUESTED_CALLBACKS, 0, &tmp) == 0) {
  861.                 /* here, the bits already match sub-function codes */
  862.                 opregion->swsci_sbcb_sub_functions |= tmp;
  863.                 requested_callbacks = true;
  864.         }
  865.  
  866.         /*
  867.          * But we use SBCB to ask for _supported_ SBCB calls. This does not mean
  868.          * the callback is _requested_. But we still can't call interfaces that
  869.          * are not requested.
  870.          */
  871.         if (swsci(dev, SWSCI_SBCB_SUPPORTED_CALLBACKS, 0, &tmp) == 0) {
  872.                 /* make the bits match the sub-function codes */
  873.                 u32 low = tmp & 0x7ff;
  874.                 u32 high = tmp & ~0xfff; /* bit 11 is reserved */
  875.                 tmp = (high << 4) | (low << 1) | 1;
  876.  
  877.                 /* best guess what to do with supported wrt requested */
  878.                 if (requested_callbacks) {
  879.                         u32 req = opregion->swsci_sbcb_sub_functions;
  880.                         if ((req & tmp) != req)
  881.                                 DRM_DEBUG_DRIVER("SWSCI BIOS requested (%08x) SBCB callbacks that are not supported (%08x)\n", req, tmp);
  882.                         /* XXX: for now, trust the requested callbacks */
  883.                         /* opregion->swsci_sbcb_sub_functions &= tmp; */
  884.                 } else {
  885.                         opregion->swsci_sbcb_sub_functions |= tmp;
  886.                 }
  887.         }
  888.  
  889.         DRM_DEBUG_DRIVER("SWSCI GBDA callbacks %08x, SBCB callbacks %08x\n",
  890.                          opregion->swsci_gbda_sub_functions,
  891.                          opregion->swsci_sbcb_sub_functions);
  892. }
  893. #else /* CONFIG_ACPI */
  894. static inline void swsci_setup(struct drm_device *dev) {}
  895. #endif  /* CONFIG_ACPI */
  896.  
  897. int intel_opregion_setup(struct drm_device *dev)
  898. {
  899.         struct drm_i915_private *dev_priv = dev->dev_private;
  900.         struct intel_opregion *opregion = &dev_priv->opregion;
  901.         u32 asls, mboxes;
  902.         char buf[sizeof(OPREGION_SIGNATURE)];
  903.         int err = 0;
  904.         void *base;
  905.  
  906.         BUILD_BUG_ON(sizeof(struct opregion_header) != 0x100);
  907.         BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100);
  908.         BUILD_BUG_ON(sizeof(struct opregion_swsci) != 0x100);
  909.         BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100);
  910.  
  911.         pci_read_config_dword(dev->pdev, PCI_ASLS, &asls);
  912.         DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls);
  913.         if (asls == 0) {
  914.                 DRM_DEBUG_DRIVER("ACPI OpRegion not supported!\n");
  915.                 return -ENOTSUPP;
  916.         }
  917.  
  918. #ifdef CONFIG_ACPI
  919.         INIT_WORK(&opregion->asle_work, asle_work);
  920. #endif
  921.  
  922.         base = memremap(asls, OPREGION_SIZE, MEMREMAP_WB);
  923.         if (!base)
  924.                 return -ENOMEM;
  925.  
  926.         memcpy(buf, base, sizeof(buf));
  927.  
  928.         if (memcmp(buf, OPREGION_SIGNATURE, 16)) {
  929.                 DRM_DEBUG_DRIVER("opregion signature mismatch\n");
  930.                 err = -EINVAL;
  931.                 goto err_out;
  932.         }
  933.         opregion->header = base;
  934.         opregion->vbt = base + OPREGION_VBT_OFFSET;
  935.  
  936.         opregion->lid_state = base + ACPI_CLID;
  937.  
  938.         mboxes = opregion->header->mboxes;
  939.         if (mboxes & MBOX_ACPI) {
  940.                 DRM_DEBUG_DRIVER("Public ACPI methods supported\n");
  941.                 opregion->acpi = base + OPREGION_ACPI_OFFSET;
  942.         }
  943.  
  944.         if (mboxes & MBOX_SWSCI) {
  945.                 DRM_DEBUG_DRIVER("SWSCI supported\n");
  946.                 opregion->swsci = base + OPREGION_SWSCI_OFFSET;
  947.                 swsci_setup(dev);
  948.         }
  949.         if (mboxes & MBOX_ASLE) {
  950.                 DRM_DEBUG_DRIVER("ASLE supported\n");
  951.                 opregion->asle = base + OPREGION_ASLE_OFFSET;
  952.  
  953.                 opregion->asle->ardy = ASLE_ARDY_NOT_READY;
  954.         }
  955.  
  956.         return 0;
  957.  
  958. err_out:
  959.         memunmap(base);
  960.         return err;
  961. }
  962.