Rev 4104 | Rev 5060 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4104 | Rev 4560 | ||
---|---|---|---|
Line 38... | Line 38... | ||
38 | #include "i915_drv.h" |
38 | #include "i915_drv.h" |
39 | #include "intel_drv.h" |
39 | #include "intel_drv.h" |
Line 40... | Line 40... | ||
40 | 40 | ||
41 | #define PCI_ASLE 0xe4 |
41 | #define PCI_ASLE 0xe4 |
- | 42 | #define PCI_ASLS 0xfc |
|
- | 43 | #define PCI_SWSCI 0xe8 |
|
- | 44 | #define PCI_SWSCI_SCISEL (1 << 15) |
|
Line 42... | Line 45... | ||
42 | #define PCI_ASLS 0xfc |
45 | #define PCI_SWSCI_GSSCIE (1 << 0) |
43 | 46 | ||
44 | #define OPREGION_HEADER_OFFSET 0 |
47 | #define OPREGION_HEADER_OFFSET 0 |
45 | #define OPREGION_ACPI_OFFSET 0x100 |
48 | #define OPREGION_ACPI_OFFSET 0x100 |
Line 61... | Line 64... | ||
61 | u8 bios_ver[32]; |
64 | u8 bios_ver[32]; |
62 | u8 vbios_ver[16]; |
65 | u8 vbios_ver[16]; |
63 | u8 driver_ver[16]; |
66 | u8 driver_ver[16]; |
64 | u32 mboxes; |
67 | u32 mboxes; |
65 | u8 reserved[164]; |
68 | u8 reserved[164]; |
66 | } __attribute__((packed)); |
69 | } __packed; |
Line 67... | Line 70... | ||
67 | 70 | ||
68 | /* OpRegion mailbox #1: public ACPI methods */ |
71 | /* OpRegion mailbox #1: public ACPI methods */ |
69 | struct opregion_acpi { |
72 | struct opregion_acpi { |
70 | u32 drdy; /* driver readiness */ |
73 | u32 drdy; /* driver readiness */ |
Line 83... | Line 86... | ||
83 | u32 sxsw; /* Sx state resume */ |
86 | u32 sxsw; /* Sx state resume */ |
84 | u32 evts; /* ASL supported events */ |
87 | u32 evts; /* ASL supported events */ |
85 | u32 cnot; /* current OS notification */ |
88 | u32 cnot; /* current OS notification */ |
86 | u32 nrdy; /* driver status */ |
89 | u32 nrdy; /* driver status */ |
87 | u8 rsvd2[60]; |
90 | u8 rsvd2[60]; |
88 | } __attribute__((packed)); |
91 | } __packed; |
Line 89... | Line 92... | ||
89 | 92 | ||
90 | /* OpRegion mailbox #2: SWSCI */ |
93 | /* OpRegion mailbox #2: SWSCI */ |
91 | struct opregion_swsci { |
94 | struct opregion_swsci { |
92 | u32 scic; /* SWSCI command|status|data */ |
95 | u32 scic; /* SWSCI command|status|data */ |
93 | u32 parm; /* command parameters */ |
96 | u32 parm; /* command parameters */ |
94 | u32 dslp; /* driver sleep time-out */ |
97 | u32 dslp; /* driver sleep time-out */ |
95 | u8 rsvd[244]; |
98 | u8 rsvd[244]; |
Line 96... | Line 99... | ||
96 | } __attribute__((packed)); |
99 | } __packed; |
97 | 100 | ||
98 | /* OpRegion mailbox #3: ASLE */ |
101 | /* OpRegion mailbox #3: ASLE */ |
99 | struct opregion_asle { |
102 | struct opregion_asle { |
Line 107... | Line 110... | ||
107 | u16 bclm[20]; /* backlight level duty cycle mapping table */ |
110 | u16 bclm[20]; /* backlight level duty cycle mapping table */ |
108 | u32 cpfm; /* current panel fitting mode */ |
111 | u32 cpfm; /* current panel fitting mode */ |
109 | u32 epfm; /* enabled panel fitting modes */ |
112 | u32 epfm; /* enabled panel fitting modes */ |
110 | u8 plut[74]; /* panel LUT and identifier */ |
113 | u8 plut[74]; /* panel LUT and identifier */ |
111 | u32 pfmb; /* PWM freq and min brightness */ |
114 | u32 pfmb; /* PWM freq and min brightness */ |
- | 115 | u32 cddv; /* color correction default values */ |
|
- | 116 | u32 pcft; /* power conservation features */ |
|
- | 117 | u32 srot; /* supported rotation angles */ |
|
- | 118 | u32 iuer; /* IUER events */ |
|
112 | u8 rsvd[102]; |
119 | u8 rsvd[86]; |
113 | } __attribute__((packed)); |
120 | } __packed; |
Line 114... | Line 121... | ||
114 | 121 | ||
115 | /* Driver readiness indicator */ |
122 | /* Driver readiness indicator */ |
116 | #define ASLE_ARDY_READY (1 << 0) |
123 | #define ASLE_ARDY_READY (1 << 0) |
Line 117... | Line 124... | ||
117 | #define ASLE_ARDY_NOT_READY (0 << 0) |
124 | #define ASLE_ARDY_NOT_READY (0 << 0) |
118 | 125 | ||
119 | /* ASLE irq request bits */ |
126 | /* ASLE Interrupt Command (ASLC) bits */ |
120 | #define ASLE_SET_ALS_ILLUM (1 << 0) |
127 | #define ASLC_SET_ALS_ILLUM (1 << 0) |
121 | #define ASLE_SET_BACKLIGHT (1 << 1) |
128 | #define ASLC_SET_BACKLIGHT (1 << 1) |
- | 129 | #define ASLC_SET_PFIT (1 << 2) |
|
- | 130 | #define ASLC_SET_PWM_FREQ (1 << 3) |
|
- | 131 | #define ASLC_SUPPORTED_ROTATION_ANGLES (1 << 4) |
|
- | 132 | #define ASLC_BUTTON_ARRAY (1 << 5) |
|
- | 133 | #define ASLC_CONVERTIBLE_INDICATOR (1 << 6) |
|
122 | #define ASLE_SET_PFIT (1 << 2) |
134 | #define ASLC_DOCKING_INDICATOR (1 << 7) |
123 | #define ASLE_SET_PWM_FREQ (1 << 3) |
- | |
124 | #define ASLE_REQ_MSK 0xf |
135 | #define ASLC_ISCT_STATE_CHANGE (1 << 8) |
125 | 136 | #define ASLC_REQ_MSK 0x1ff |
|
126 | /* response bits of ASLE irq request */ |
137 | /* response bits */ |
127 | #define ASLE_ALS_ILLUM_FAILED (1<<10) |
138 | #define ASLC_ALS_ILLUM_FAILED (1 << 10) |
128 | #define ASLE_BACKLIGHT_FAILED (1<<12) |
139 | #define ASLC_BACKLIGHT_FAILED (1 << 12) |
- | 140 | #define ASLC_PFIT_FAILED (1 << 14) |
|
- | 141 | #define ASLC_PWM_FREQ_FAILED (1 << 16) |
|
- | 142 | #define ASLC_ROTATION_ANGLES_FAILED (1 << 18) |
|
- | 143 | #define ASLC_BUTTON_ARRAY_FAILED (1 << 20) |
|
- | 144 | #define ASLC_CONVERTIBLE_FAILED (1 << 22) |
|
Line 129... | Line 145... | ||
129 | #define ASLE_PFIT_FAILED (1<<14) |
145 | #define ASLC_DOCKING_FAILED (1 << 24) |
130 | #define ASLE_PWM_FREQ_FAILED (1<<16) |
146 | #define ASLC_ISCT_STATE_FAILED (1 << 26) |
131 | 147 | ||
132 | /* Technology enabled indicator */ |
148 | /* Technology enabled indicator */ |
Line 151... | Line 167... | ||
151 | #define ASLE_PFMB_PWM_MASK (0x7ffffe00) |
167 | #define ASLE_PFMB_PWM_MASK (0x7ffffe00) |
152 | #define ASLE_PFMB_PWM_VALID (1<<31) |
168 | #define ASLE_PFMB_PWM_VALID (1<<31) |
Line 153... | Line 169... | ||
153 | 169 | ||
Line -... | Line 170... | ||
- | 170 | #define ASLE_CBLV_VALID (1<<31) |
|
- | 171 | ||
- | 172 | /* IUER */ |
|
- | 173 | #define ASLE_IUER_DOCKING (1 << 7) |
|
- | 174 | #define ASLE_IUER_CONVERTIBLE (1 << 6) |
|
- | 175 | #define ASLE_IUER_ROTATION_LOCK_BTN (1 << 4) |
|
- | 176 | #define ASLE_IUER_VOLUME_DOWN_BTN (1 << 3) |
|
- | 177 | #define ASLE_IUER_VOLUME_UP_BTN (1 << 2) |
|
- | 178 | #define ASLE_IUER_WINDOWS_BTN (1 << 1) |
|
- | 179 | #define ASLE_IUER_POWER_BTN (1 << 0) |
|
- | 180 | ||
- | 181 | /* Software System Control Interrupt (SWSCI) */ |
|
- | 182 | #define SWSCI_SCIC_INDICATOR (1 << 0) |
|
- | 183 | #define SWSCI_SCIC_MAIN_FUNCTION_SHIFT 1 |
|
- | 184 | #define SWSCI_SCIC_MAIN_FUNCTION_MASK (0xf << 1) |
|
- | 185 | #define SWSCI_SCIC_SUB_FUNCTION_SHIFT 8 |
|
- | 186 | #define SWSCI_SCIC_SUB_FUNCTION_MASK (0xff << 8) |
|
- | 187 | #define SWSCI_SCIC_EXIT_PARAMETER_SHIFT 8 |
|
- | 188 | #define SWSCI_SCIC_EXIT_PARAMETER_MASK (0xff << 8) |
|
- | 189 | #define SWSCI_SCIC_EXIT_STATUS_SHIFT 5 |
|
- | 190 | #define SWSCI_SCIC_EXIT_STATUS_MASK (7 << 5) |
|
- | 191 | #define SWSCI_SCIC_EXIT_STATUS_SUCCESS 1 |
|
- | 192 | ||
- | 193 | #define SWSCI_FUNCTION_CODE(main, sub) \ |
|
- | 194 | ((main) << SWSCI_SCIC_MAIN_FUNCTION_SHIFT | \ |
|
- | 195 | (sub) << SWSCI_SCIC_SUB_FUNCTION_SHIFT) |
|
- | 196 | ||
- | 197 | /* SWSCI: Get BIOS Data (GBDA) */ |
|
- | 198 | #define SWSCI_GBDA 4 |
|
- | 199 | #define SWSCI_GBDA_SUPPORTED_CALLS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 0) |
|
- | 200 | #define SWSCI_GBDA_REQUESTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 1) |
|
- | 201 | #define SWSCI_GBDA_BOOT_DISPLAY_PREF SWSCI_FUNCTION_CODE(SWSCI_GBDA, 4) |
|
- | 202 | #define SWSCI_GBDA_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 5) |
|
- | 203 | #define SWSCI_GBDA_TV_STANDARD SWSCI_FUNCTION_CODE(SWSCI_GBDA, 6) |
|
- | 204 | #define SWSCI_GBDA_INTERNAL_GRAPHICS SWSCI_FUNCTION_CODE(SWSCI_GBDA, 7) |
|
- | 205 | #define SWSCI_GBDA_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_GBDA, 10) |
|
- | 206 | ||
- | 207 | /* SWSCI: System BIOS Callbacks (SBCB) */ |
|
- | 208 | #define SWSCI_SBCB 6 |
|
- | 209 | #define SWSCI_SBCB_SUPPORTED_CALLBACKS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 0) |
|
- | 210 | #define SWSCI_SBCB_INIT_COMPLETION SWSCI_FUNCTION_CODE(SWSCI_SBCB, 1) |
|
- | 211 | #define SWSCI_SBCB_PRE_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 3) |
|
- | 212 | #define SWSCI_SBCB_POST_HIRES_SET_MODE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 4) |
|
- | 213 | #define SWSCI_SBCB_DISPLAY_SWITCH SWSCI_FUNCTION_CODE(SWSCI_SBCB, 5) |
|
- | 214 | #define SWSCI_SBCB_SET_TV_FORMAT SWSCI_FUNCTION_CODE(SWSCI_SBCB, 6) |
|
- | 215 | #define SWSCI_SBCB_ADAPTER_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 7) |
|
- | 216 | #define SWSCI_SBCB_DISPLAY_POWER_STATE SWSCI_FUNCTION_CODE(SWSCI_SBCB, 8) |
|
- | 217 | #define SWSCI_SBCB_SET_BOOT_DISPLAY SWSCI_FUNCTION_CODE(SWSCI_SBCB, 9) |
|
- | 218 | #define SWSCI_SBCB_SET_PANEL_DETAILS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 10) |
|
- | 219 | #define SWSCI_SBCB_SET_INTERNAL_GFX SWSCI_FUNCTION_CODE(SWSCI_SBCB, 11) |
|
- | 220 | #define SWSCI_SBCB_POST_HIRES_TO_DOS_FS SWSCI_FUNCTION_CODE(SWSCI_SBCB, 16) |
|
- | 221 | #define SWSCI_SBCB_SUSPEND_RESUME SWSCI_FUNCTION_CODE(SWSCI_SBCB, 17) |
|
- | 222 | #define SWSCI_SBCB_SET_SPREAD_SPECTRUM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 18) |
|
- | 223 | #define SWSCI_SBCB_POST_VBE_PM SWSCI_FUNCTION_CODE(SWSCI_SBCB, 19) |
|
154 | #define ASLE_CBLV_VALID (1<<31) |
224 | #define SWSCI_SBCB_ENABLE_DISABLE_AUDIO SWSCI_FUNCTION_CODE(SWSCI_SBCB, 21) |
155 | 225 | ||
156 | #define ACPI_OTHER_OUTPUT (0<<8) |
226 | #define ACPI_OTHER_OUTPUT (0<<8) |
157 | #define ACPI_VGA_OUTPUT (1<<8) |
227 | #define ACPI_VGA_OUTPUT (1<<8) |
158 | #define ACPI_TV_OUTPUT (2<<8) |
228 | #define ACPI_TV_OUTPUT (2<<8) |
Line 159... | Line 229... | ||
159 | #define ACPI_DIGITAL_OUTPUT (3<<8) |
229 | #define ACPI_DIGITAL_OUTPUT (3<<8) |
- | 230 | #define ACPI_LVDS_OUTPUT (4<<8) |
|
- | 231 | ||
- | 232 | #ifdef CONFIG_ACPI |
|
- | 233 | static int swsci(struct drm_device *dev, u32 function, u32 parm, u32 *parm_out) |
|
- | 234 | { |
|
- | 235 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 236 | struct opregion_swsci __iomem *swsci = dev_priv->opregion.swsci; |
|
- | 237 | u32 main_function, sub_function, scic; |
|
- | 238 | u16 pci_swsci; |
|
- | 239 | u32 dslp; |
|
- | 240 | ||
- | 241 | if (!swsci) |
|
- | 242 | return -ENODEV; |
|
- | 243 | ||
- | 244 | main_function = (function & SWSCI_SCIC_MAIN_FUNCTION_MASK) >> |
|
- | 245 | SWSCI_SCIC_MAIN_FUNCTION_SHIFT; |
|
- | 246 | sub_function = (function & SWSCI_SCIC_SUB_FUNCTION_MASK) >> |
|
- | 247 | SWSCI_SCIC_SUB_FUNCTION_SHIFT; |
|
- | 248 | ||
- | 249 | /* Check if we can call the function. See swsci_setup for details. */ |
|
- | 250 | if (main_function == SWSCI_SBCB) { |
|
- | 251 | if ((dev_priv->opregion.swsci_sbcb_sub_functions & |
|
- | 252 | (1 << sub_function)) == 0) |
|
- | 253 | return -EINVAL; |
|
- | 254 | } else if (main_function == SWSCI_GBDA) { |
|
- | 255 | if ((dev_priv->opregion.swsci_gbda_sub_functions & |
|
- | 256 | (1 << sub_function)) == 0) |
|
- | 257 | return -EINVAL; |
|
- | 258 | } |
|
- | 259 | ||
- | 260 | /* Driver sleep timeout in ms. */ |
|
- | 261 | dslp = ioread32(&swsci->dslp); |
|
- | 262 | if (!dslp) { |
|
- | 263 | /* The spec says 2ms should be the default, but it's too small |
|
- | 264 | * for some machines. */ |
|
- | 265 | dslp = 50; |
|
- | 266 | } else if (dslp > 500) { |
|
- | 267 | /* Hey bios, trust must be earned. */ |
|
- | 268 | WARN_ONCE(1, "excessive driver sleep timeout (DSPL) %u\n", dslp); |
|
- | 269 | dslp = 500; |
|
- | 270 | } |
|
- | 271 | ||
- | 272 | /* The spec tells us to do this, but we are the only user... */ |
|
- | 273 | scic = ioread32(&swsci->scic); |
|
- | 274 | if (scic & SWSCI_SCIC_INDICATOR) { |
|
- | 275 | DRM_DEBUG_DRIVER("SWSCI request already in progress\n"); |
|
- | 276 | return -EBUSY; |
|
- | 277 | } |
|
- | 278 | ||
- | 279 | scic = function | SWSCI_SCIC_INDICATOR; |
|
- | 280 | ||
- | 281 | iowrite32(parm, &swsci->parm); |
|
- | 282 | iowrite32(scic, &swsci->scic); |
|
- | 283 | ||
- | 284 | /* Ensure SCI event is selected and event trigger is cleared. */ |
|
- | 285 | pci_read_config_word(dev->pdev, PCI_SWSCI, &pci_swsci); |
|
- | 286 | if (!(pci_swsci & PCI_SWSCI_SCISEL) || (pci_swsci & PCI_SWSCI_GSSCIE)) { |
|
- | 287 | pci_swsci |= PCI_SWSCI_SCISEL; |
|
- | 288 | pci_swsci &= ~PCI_SWSCI_GSSCIE; |
|
- | 289 | pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci); |
|
- | 290 | } |
|
- | 291 | ||
- | 292 | /* Use event trigger to tell bios to check the mail. */ |
|
- | 293 | pci_swsci |= PCI_SWSCI_GSSCIE; |
|
- | 294 | pci_write_config_word(dev->pdev, PCI_SWSCI, pci_swsci); |
|
- | 295 | ||
- | 296 | /* Poll for the result. */ |
|
- | 297 | #define C (((scic = ioread32(&swsci->scic)) & SWSCI_SCIC_INDICATOR) == 0) |
|
- | 298 | if (wait_for(C, dslp)) { |
|
- | 299 | DRM_DEBUG_DRIVER("SWSCI request timed out\n"); |
|
- | 300 | return -ETIMEDOUT; |
|
- | 301 | } |
|
- | 302 | ||
- | 303 | scic = (scic & SWSCI_SCIC_EXIT_STATUS_MASK) >> |
|
- | 304 | SWSCI_SCIC_EXIT_STATUS_SHIFT; |
|
- | 305 | ||
- | 306 | /* Note: scic == 0 is an error! */ |
|
- | 307 | if (scic != SWSCI_SCIC_EXIT_STATUS_SUCCESS) { |
|
- | 308 | DRM_DEBUG_DRIVER("SWSCI request error %u\n", scic); |
|
- | 309 | return -EIO; |
|
- | 310 | } |
|
- | 311 | ||
- | 312 | if (parm_out) |
|
- | 313 | *parm_out = ioread32(&swsci->parm); |
|
- | 314 | ||
- | 315 | return 0; |
|
- | 316 | ||
- | 317 | #undef C |
|
- | 318 | } |
|
- | 319 | ||
- | 320 | #define DISPLAY_TYPE_CRT 0 |
|
- | 321 | #define DISPLAY_TYPE_TV 1 |
|
- | 322 | #define DISPLAY_TYPE_EXTERNAL_FLAT_PANEL 2 |
|
- | 323 | #define DISPLAY_TYPE_INTERNAL_FLAT_PANEL 3 |
|
- | 324 | ||
- | 325 | int intel_opregion_notify_encoder(struct intel_encoder *intel_encoder, |
|
- | 326 | bool enable) |
|
- | 327 | { |
|
- | 328 | struct drm_device *dev = intel_encoder->base.dev; |
|
- | 329 | u32 parm = 0; |
|
- | 330 | u32 type = 0; |
|
- | 331 | u32 port; |
|
- | 332 | ||
- | 333 | /* don't care about old stuff for now */ |
|
- | 334 | if (!HAS_DDI(dev)) |
|
- | 335 | return 0; |
|
- | 336 | ||
- | 337 | port = intel_ddi_get_encoder_port(intel_encoder); |
|
- | 338 | if (port == PORT_E) { |
|
- | 339 | port = 0; |
|
- | 340 | } else { |
|
- | 341 | parm |= 1 << port; |
|
- | 342 | port++; |
|
- | 343 | } |
|
- | 344 | ||
- | 345 | if (!enable) |
|
- | 346 | parm |= 4 << 8; |
|
- | 347 | ||
- | 348 | switch (intel_encoder->type) { |
|
- | 349 | case INTEL_OUTPUT_ANALOG: |
|
- | 350 | type = DISPLAY_TYPE_CRT; |
|
- | 351 | break; |
|
- | 352 | case INTEL_OUTPUT_UNKNOWN: |
|
- | 353 | case INTEL_OUTPUT_DISPLAYPORT: |
|
- | 354 | case INTEL_OUTPUT_HDMI: |
|
- | 355 | type = DISPLAY_TYPE_EXTERNAL_FLAT_PANEL; |
|
- | 356 | break; |
|
- | 357 | case INTEL_OUTPUT_EDP: |
|
- | 358 | type = DISPLAY_TYPE_INTERNAL_FLAT_PANEL; |
|
- | 359 | break; |
|
- | 360 | default: |
|
- | 361 | WARN_ONCE(1, "unsupported intel_encoder type %d\n", |
|
- | 362 | intel_encoder->type); |
|
- | 363 | return -EINVAL; |
|
- | 364 | } |
|
- | 365 | ||
- | 366 | parm |= type << (16 + port * 3); |
|
- | 367 | ||
- | 368 | return swsci(dev, SWSCI_SBCB_DISPLAY_POWER_STATE, parm, NULL); |
|
- | 369 | } |
|
- | 370 | ||
- | 371 | static const struct { |
|
- | 372 | pci_power_t pci_power_state; |
|
- | 373 | u32 parm; |
|
- | 374 | } power_state_map[] = { |
|
- | 375 | { PCI_D0, 0x00 }, |
|
- | 376 | { PCI_D1, 0x01 }, |
|
- | 377 | { PCI_D2, 0x02 }, |
|
- | 378 | { PCI_D3hot, 0x04 }, |
|
- | 379 | { PCI_D3cold, 0x04 }, |
|
- | 380 | }; |
|
- | 381 | ||
- | 382 | int intel_opregion_notify_adapter(struct drm_device *dev, pci_power_t state) |
|
- | 383 | { |
|
- | 384 | int i; |
|
- | 385 | ||
- | 386 | if (!HAS_DDI(dev)) |
|
- | 387 | return 0; |
|
- | 388 | ||
- | 389 | for (i = 0; i < ARRAY_SIZE(power_state_map); i++) { |
|
- | 390 | if (state == power_state_map[i].pci_power_state) |
|
- | 391 | return swsci(dev, SWSCI_SBCB_ADAPTER_POWER_STATE, |
|
- | 392 | power_state_map[i].parm, NULL); |
|
- | 393 | } |
|
- | 394 | ||
- | 395 | return -EINVAL; |
|
- | 396 | } |
|
- | 397 | ||
- | 398 | static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
|
- | 399 | { |
|
- | 400 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 401 | struct intel_connector *intel_connector; |
|
- | 402 | struct opregion_asle __iomem *asle = dev_priv->opregion.asle; |
|
- | 403 | ||
- | 404 | DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); |
|
- | 405 | ||
- | 406 | if (!(bclp & ASLE_BCLP_VALID)) |
|
- | 407 | return ASLC_BACKLIGHT_FAILED; |
|
- | 408 | ||
- | 409 | bclp &= ASLE_BCLP_MSK; |
|
- | 410 | if (bclp > 255) |
|
- | 411 | return ASLC_BACKLIGHT_FAILED; |
|
- | 412 | ||
- | 413 | mutex_lock(&dev->mode_config.mutex); |
|
- | 414 | ||
- | 415 | /* |
|
- | 416 | * Update backlight on all connectors that support backlight (usually |
|
- | 417 | * only one). |
|
- | 418 | */ |
|
- | 419 | DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); |
|
- | 420 | list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) |
|
- | 421 | intel_panel_set_backlight(intel_connector, bclp, 255); |
|
- | 422 | iowrite32(DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID, &asle->cblv); |
|
- | 423 | ||
- | 424 | mutex_unlock(&dev->mode_config.mutex); |
|
- | 425 | ||
- | 426 | ||
- | 427 | return 0; |
|
- | 428 | } |
|
- | 429 | ||
- | 430 | static u32 asle_set_als_illum(struct drm_device *dev, u32 alsi) |
|
- | 431 | { |
|
- | 432 | /* alsi is the current ALS reading in lux. 0 indicates below sensor |
|
- | 433 | range, 0xffff indicates above sensor range. 1-0xfffe are valid */ |
|
- | 434 | DRM_DEBUG_DRIVER("Illum is not supported\n"); |
|
- | 435 | return ASLC_ALS_ILLUM_FAILED; |
|
- | 436 | } |
|
- | 437 | ||
- | 438 | static u32 asle_set_pwm_freq(struct drm_device *dev, u32 pfmb) |
|
- | 439 | { |
|
- | 440 | DRM_DEBUG_DRIVER("PWM freq is not supported\n"); |
|
- | 441 | return ASLC_PWM_FREQ_FAILED; |
|
- | 442 | } |
|
- | 443 | ||
- | 444 | static u32 asle_set_pfit(struct drm_device *dev, u32 pfit) |
|
- | 445 | { |
|
- | 446 | /* Panel fitting is currently controlled by the X code, so this is a |
|
- | 447 | noop until modesetting support works fully */ |
|
- | 448 | DRM_DEBUG_DRIVER("Pfit is not supported\n"); |
|
- | 449 | return ASLC_PFIT_FAILED; |
|
- | 450 | } |
|
- | 451 | ||
- | 452 | static u32 asle_set_supported_rotation_angles(struct drm_device *dev, u32 srot) |
|
- | 453 | { |
|
- | 454 | DRM_DEBUG_DRIVER("SROT is not supported\n"); |
|
- | 455 | return ASLC_ROTATION_ANGLES_FAILED; |
|
- | 456 | } |
|
- | 457 | ||
- | 458 | static u32 asle_set_button_array(struct drm_device *dev, u32 iuer) |
|
- | 459 | { |
|
- | 460 | if (!iuer) |
|
- | 461 | DRM_DEBUG_DRIVER("Button array event is not supported (nothing)\n"); |
|
- | 462 | if (iuer & ASLE_IUER_ROTATION_LOCK_BTN) |
|
- | 463 | DRM_DEBUG_DRIVER("Button array event is not supported (rotation lock)\n"); |
|
- | 464 | if (iuer & ASLE_IUER_VOLUME_DOWN_BTN) |
|
- | 465 | DRM_DEBUG_DRIVER("Button array event is not supported (volume down)\n"); |
|
- | 466 | if (iuer & ASLE_IUER_VOLUME_UP_BTN) |
|
- | 467 | DRM_DEBUG_DRIVER("Button array event is not supported (volume up)\n"); |
|
- | 468 | if (iuer & ASLE_IUER_WINDOWS_BTN) |
|
- | 469 | DRM_DEBUG_DRIVER("Button array event is not supported (windows)\n"); |
|
- | 470 | if (iuer & ASLE_IUER_POWER_BTN) |
|
- | 471 | DRM_DEBUG_DRIVER("Button array event is not supported (power)\n"); |
|
- | 472 | ||
- | 473 | return ASLC_BUTTON_ARRAY_FAILED; |
|
- | 474 | } |
|
- | 475 | ||
- | 476 | static u32 asle_set_convertible(struct drm_device *dev, u32 iuer) |
|
- | 477 | { |
|
- | 478 | if (iuer & ASLE_IUER_CONVERTIBLE) |
|
- | 479 | DRM_DEBUG_DRIVER("Convertible is not supported (clamshell)\n"); |
|
- | 480 | else |
|
- | 481 | DRM_DEBUG_DRIVER("Convertible is not supported (slate)\n"); |
|
- | 482 | ||
- | 483 | return ASLC_CONVERTIBLE_FAILED; |
|
- | 484 | } |
|
- | 485 | ||
- | 486 | static u32 asle_set_docking(struct drm_device *dev, u32 iuer) |
|
- | 487 | { |
|
- | 488 | if (iuer & ASLE_IUER_DOCKING) |
|
- | 489 | DRM_DEBUG_DRIVER("Docking is not supported (docked)\n"); |
|
- | 490 | else |
|
- | 491 | DRM_DEBUG_DRIVER("Docking is not supported (undocked)\n"); |
|
- | 492 | ||
- | 493 | return ASLC_DOCKING_FAILED; |
|
- | 494 | } |
|
- | 495 | ||
- | 496 | static u32 asle_isct_state(struct drm_device *dev) |
|
- | 497 | { |
|
- | 498 | DRM_DEBUG_DRIVER("ISCT is not supported\n"); |
|
- | 499 | return ASLC_ISCT_STATE_FAILED; |
|
- | 500 | } |
|
- | 501 | ||
- | 502 | static void asle_work(struct work_struct *work) |
|
- | 503 | { |
|
- | 504 | struct intel_opregion *opregion = |
|
- | 505 | container_of(work, struct intel_opregion, asle_work); |
|
- | 506 | struct drm_i915_private *dev_priv = |
|
- | 507 | container_of(opregion, struct drm_i915_private, opregion); |
|
- | 508 | struct drm_device *dev = dev_priv->dev; |
|
- | 509 | struct opregion_asle __iomem *asle = dev_priv->opregion.asle; |
|
- | 510 | u32 aslc_stat = 0; |
|
- | 511 | u32 aslc_req; |
|
- | 512 | ||
- | 513 | if (!asle) |
|
- | 514 | return; |
|
- | 515 | ||
- | 516 | aslc_req = ioread32(&asle->aslc); |
|
- | 517 | ||
- | 518 | if (!(aslc_req & ASLC_REQ_MSK)) { |
|
- | 519 | DRM_DEBUG_DRIVER("No request on ASLC interrupt 0x%08x\n", |
|
- | 520 | aslc_req); |
|
- | 521 | return; |
|
- | 522 | } |
|
- | 523 | ||
- | 524 | if (aslc_req & ASLC_SET_ALS_ILLUM) |
|
- | 525 | aslc_stat |= asle_set_als_illum(dev, ioread32(&asle->alsi)); |
|
- | 526 | ||
- | 527 | if (aslc_req & ASLC_SET_BACKLIGHT) |
|
- | 528 | aslc_stat |= asle_set_backlight(dev, ioread32(&asle->bclp)); |
|
- | 529 | ||
- | 530 | if (aslc_req & ASLC_SET_PFIT) |
|
- | 531 | aslc_stat |= asle_set_pfit(dev, ioread32(&asle->pfit)); |
|
- | 532 | ||
- | 533 | if (aslc_req & ASLC_SET_PWM_FREQ) |
|
- | 534 | aslc_stat |= asle_set_pwm_freq(dev, ioread32(&asle->pfmb)); |
|
- | 535 | ||
- | 536 | if (aslc_req & ASLC_SUPPORTED_ROTATION_ANGLES) |
|
- | 537 | aslc_stat |= asle_set_supported_rotation_angles(dev, |
|
- | 538 | ioread32(&asle->srot)); |
|
- | 539 | ||
- | 540 | if (aslc_req & ASLC_BUTTON_ARRAY) |
|
- | 541 | aslc_stat |= asle_set_button_array(dev, ioread32(&asle->iuer)); |
|
- | 542 | ||
- | 543 | if (aslc_req & ASLC_CONVERTIBLE_INDICATOR) |
|
- | 544 | aslc_stat |= asle_set_convertible(dev, ioread32(&asle->iuer)); |
|
- | 545 | ||
- | 546 | if (aslc_req & ASLC_DOCKING_INDICATOR) |
|
- | 547 | aslc_stat |= asle_set_docking(dev, ioread32(&asle->iuer)); |
|
- | 548 | ||
- | 549 | if (aslc_req & ASLC_ISCT_STATE_CHANGE) |
|
- | 550 | aslc_stat |= asle_isct_state(dev); |
|
- | 551 | ||
- | 552 | iowrite32(aslc_stat, &asle->aslc); |
|
- | 553 | } |
|
- | 554 | ||
- | 555 | void intel_opregion_asle_intr(struct drm_device *dev) |
|
- | 556 | { |
|
- | 557 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 558 | ||
- | 559 | if (dev_priv->opregion.asle) |
|
- | 560 | schedule_work(&dev_priv->opregion.asle_work); |
|
- | 561 | } |
|
- | 562 | ||
- | 563 | #define ACPI_EV_DISPLAY_SWITCH (1<<0) |
|
- | 564 | #define ACPI_EV_LID (1<<1) |
|
- | 565 | #define ACPI_EV_DOCK (1<<2) |
|
- | 566 | ||
- | 567 | static struct intel_opregion *system_opregion; |
|
- | 568 | ||
- | 569 | static int intel_opregion_video_event(struct notifier_block *nb, |
|
- | 570 | unsigned long val, void *data) |
|
- | 571 | { |
|
- | 572 | /* The only video events relevant to opregion are 0x80. These indicate |
|
- | 573 | either a docking event, lid switch or display switch request. In |
|
- | 574 | Linux, these are handled by the dock, button and video drivers. |
|
- | 575 | */ |
|
- | 576 | ||
- | 577 | struct opregion_acpi __iomem *acpi; |
|
- | 578 | struct acpi_bus_event *event = data; |
|
- | 579 | int ret = NOTIFY_OK; |
|
- | 580 | ||
- | 581 | if (strcmp(event->device_class, ACPI_VIDEO_CLASS) != 0) |
|
- | 582 | return NOTIFY_DONE; |
|
- | 583 | ||
- | 584 | if (!system_opregion) |
|
- | 585 | return NOTIFY_DONE; |
|
- | 586 | ||
- | 587 | acpi = system_opregion->acpi; |
|
- | 588 | ||
- | 589 | if (event->type == 0x80 && |
|
- | 590 | (ioread32(&acpi->cevt) & 1) == 0) |
|
- | 591 | ret = NOTIFY_BAD; |
|
- | 592 | ||
- | 593 | iowrite32(0, &acpi->csts); |
|
- | 594 | ||
- | 595 | return ret; |
|
- | 596 | } |
|
- | 597 | ||
- | 598 | static struct notifier_block intel_opregion_notifier = { |
|
- | 599 | .notifier_call = intel_opregion_video_event, |
|
- | 600 | }; |
|
- | 601 | ||
- | 602 | /* |
|
- | 603 | * Initialise the DIDL field in opregion. This passes a list of devices to |
|
- | 604 | * the firmware. Values are defined by section B.4.2 of the ACPI specification |
|
- | 605 | * (version 3) |
|
- | 606 | */ |
|
- | 607 | ||
- | 608 | static void intel_didl_outputs(struct drm_device *dev) |
|
- | 609 | { |
|
- | 610 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 611 | struct intel_opregion *opregion = &dev_priv->opregion; |
|
- | 612 | struct drm_connector *connector; |
|
- | 613 | acpi_handle handle; |
|
- | 614 | struct acpi_device *acpi_dev, *acpi_cdev, *acpi_video_bus = NULL; |
|
- | 615 | unsigned long long device_id; |
|
- | 616 | acpi_status status; |
|
- | 617 | u32 temp; |
|
- | 618 | int i = 0; |
|
- | 619 | ||
- | 620 | handle = ACPI_HANDLE(&dev->pdev->dev); |
|
- | 621 | if (!handle || acpi_bus_get_device(handle, &acpi_dev)) |
|
- | 622 | return; |
|
- | 623 | ||
- | 624 | if (acpi_is_video_device(handle)) |
|
- | 625 | acpi_video_bus = acpi_dev; |
|
- | 626 | else { |
|
- | 627 | list_for_each_entry(acpi_cdev, &acpi_dev->children, node) { |
|
- | 628 | if (acpi_is_video_device(acpi_cdev->handle)) { |
|
- | 629 | acpi_video_bus = acpi_cdev; |
|
- | 630 | break; |
|
- | 631 | } |
|
- | 632 | } |
|
- | 633 | } |
|
- | 634 | ||
- | 635 | if (!acpi_video_bus) { |
|
- | 636 | pr_warn("No ACPI video bus found\n"); |
|
- | 637 | return; |
|
- | 638 | } |
|
- | 639 | ||
- | 640 | list_for_each_entry(acpi_cdev, &acpi_video_bus->children, node) { |
|
- | 641 | if (i >= 8) { |
|
- | 642 | dev_dbg(&dev->pdev->dev, |
|
- | 643 | "More than 8 outputs detected via ACPI\n"); |
|
- | 644 | return; |
|
- | 645 | } |
|
- | 646 | status = |
|
- | 647 | acpi_evaluate_integer(acpi_cdev->handle, "_ADR", |
|
- | 648 | NULL, &device_id); |
|
- | 649 | if (ACPI_SUCCESS(status)) { |
|
- | 650 | if (!device_id) |
|
- | 651 | goto blind_set; |
|
- | 652 | iowrite32((u32)(device_id & 0x0f0f), |
|
- | 653 | &opregion->acpi->didl[i]); |
|
- | 654 | i++; |
|
160 | #define ACPI_LVDS_OUTPUT (4<<8) |
655 | } |
- | 656 | } |
|
- | 657 | ||
- | 658 | end: |
|
- | 659 | /* If fewer than 8 outputs, the list must be null terminated */ |
|
- | 660 | if (i < 8) |
|
- | 661 | iowrite32(0, &opregion->acpi->didl[i]); |
|
- | 662 | return; |
|
- | 663 | ||
- | 664 | blind_set: |
|
- | 665 | i = 0; |
|
- | 666 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) { |
|
- | 667 | int output_type = ACPI_OTHER_OUTPUT; |
|
- | 668 | if (i >= 8) { |
|
- | 669 | dev_dbg(&dev->pdev->dev, |
|
- | 670 | "More than 8 outputs in connector list\n"); |
|
- | 671 | return; |
|
- | 672 | } |
|
- | 673 | switch (connector->connector_type) { |
|
- | 674 | case DRM_MODE_CONNECTOR_VGA: |
|
- | 675 | case DRM_MODE_CONNECTOR_DVIA: |
|
- | 676 | output_type = ACPI_VGA_OUTPUT; |
|
- | 677 | break; |
|
- | 678 | case DRM_MODE_CONNECTOR_Composite: |
|
- | 679 | case DRM_MODE_CONNECTOR_SVIDEO: |
|
- | 680 | case DRM_MODE_CONNECTOR_Component: |
|
- | 681 | case DRM_MODE_CONNECTOR_9PinDIN: |
|
- | 682 | output_type = ACPI_TV_OUTPUT; |
|
- | 683 | break; |
|
- | 684 | case DRM_MODE_CONNECTOR_DVII: |
|
- | 685 | case DRM_MODE_CONNECTOR_DVID: |
|
- | 686 | case DRM_MODE_CONNECTOR_DisplayPort: |
|
- | 687 | case DRM_MODE_CONNECTOR_HDMIA: |
|
- | 688 | case DRM_MODE_CONNECTOR_HDMIB: |
|
- | 689 | output_type = ACPI_DIGITAL_OUTPUT; |
|
- | 690 | break; |
|
- | 691 | case DRM_MODE_CONNECTOR_LVDS: |
|
- | 692 | output_type = ACPI_LVDS_OUTPUT; |
|
- | 693 | break; |
|
- | 694 | } |
|
- | 695 | temp = ioread32(&opregion->acpi->didl[i]); |
|
- | 696 | iowrite32(temp | (1<<31) | output_type | i, |
|
- | 697 | &opregion->acpi->didl[i]); |
|
- | 698 | i++; |
|
- | 699 | } |
|
- | 700 | goto end; |
|
- | 701 | } |
|
- | 702 | ||
- | 703 | static void intel_setup_cadls(struct drm_device *dev) |
|
- | 704 | { |
|
- | 705 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 706 | struct intel_opregion *opregion = &dev_priv->opregion; |
|
- | 707 | int i = 0; |
|
- | 708 | u32 disp_id; |
|
- | 709 | ||
- | 710 | /* Initialize the CADL field by duplicating the DIDL values. |
|
- | 711 | * Technically, this is not always correct as display outputs may exist, |
|
- | 712 | * but not active. This initialization is necessary for some Clevo |
|
- | 713 | * laptops that check this field before processing the brightness and |
|
- | 714 | * display switching hotkeys. Just like DIDL, CADL is NULL-terminated if |
|
- | 715 | * there are less than eight devices. */ |
|
- | 716 | do { |
|
- | 717 | disp_id = ioread32(&opregion->acpi->didl[i]); |
|
- | 718 | iowrite32(disp_id, &opregion->acpi->cadl[i]); |
|
- | 719 | } while (++i < 8 && disp_id != 0); |
|
- | 720 | } |
|
- | 721 | ||
- | 722 | void intel_opregion_init(struct drm_device *dev) |
|
- | 723 | { |
|
- | 724 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 725 | struct intel_opregion *opregion = &dev_priv->opregion; |
|
- | 726 | ||
- | 727 | if (!opregion->header) |
|
- | 728 | return; |
|
- | 729 | ||
- | 730 | if (opregion->acpi) { |
|
- | 731 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
|
- | 732 | intel_didl_outputs(dev); |
|
- | 733 | intel_setup_cadls(dev); |
|
- | 734 | } |
|
- | 735 | ||
- | 736 | /* Notify BIOS we are ready to handle ACPI video ext notifs. |
|
- | 737 | * Right now, all the events are handled by the ACPI video module. |
|
- | 738 | * We don't actually need to do anything with them. */ |
|
- | 739 | iowrite32(0, &opregion->acpi->csts); |
|
- | 740 | iowrite32(1, &opregion->acpi->drdy); |
|
- | 741 | ||
- | 742 | system_opregion = opregion; |
|
- | 743 | register_acpi_notifier(&intel_opregion_notifier); |
|
- | 744 | } |
|
- | 745 | ||
- | 746 | if (opregion->asle) { |
|
- | 747 | iowrite32(ASLE_TCHE_BLC_EN, &opregion->asle->tche); |
|
- | 748 | iowrite32(ASLE_ARDY_READY, &opregion->asle->ardy); |
|
- | 749 | } |
|
- | 750 | } |
|
- | 751 | ||
- | 752 | void intel_opregion_fini(struct drm_device *dev) |
|
- | 753 | { |
|
- | 754 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 755 | struct intel_opregion *opregion = &dev_priv->opregion; |
|
- | 756 | ||
- | 757 | if (!opregion->header) |
|
- | 758 | return; |
|
- | 759 | ||
- | 760 | if (opregion->asle) |
|
- | 761 | iowrite32(ASLE_ARDY_NOT_READY, &opregion->asle->ardy); |
|
- | 762 | ||
- | 763 | cancel_work_sync(&dev_priv->opregion.asle_work); |
|
- | 764 | ||
- | 765 | if (opregion->acpi) { |
|
- | 766 | iowrite32(0, &opregion->acpi->drdy); |
|
- | 767 | ||
- | 768 | system_opregion = NULL; |
|
- | 769 | unregister_acpi_notifier(&intel_opregion_notifier); |
|
- | 770 | } |
|
- | 771 | ||
- | 772 | /* just clear all opregion memory pointers now */ |
|
- | 773 | iounmap(opregion->header); |
|
- | 774 | opregion->header = NULL; |
|
- | 775 | opregion->acpi = NULL; |
|
- | 776 | opregion->swsci = NULL; |
|
- | 777 | opregion->asle = NULL; |
|
- | 778 | opregion->vbt = NULL; |
|
- | 779 | opregion->lid_state = NULL; |
|
- | 780 | } |
|
- | 781 | ||
- | 782 | static void swsci_setup(struct drm_device *dev) |
|
- | 783 | { |
|
- | 784 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 785 | struct intel_opregion *opregion = &dev_priv->opregion; |
|
- | 786 | bool requested_callbacks = false; |
|
- | 787 | u32 tmp; |
|
- | 788 | ||
- | 789 | /* Sub-function code 0 is okay, let's allow them. */ |
|
- | 790 | opregion->swsci_gbda_sub_functions = 1; |
|
- | 791 | opregion->swsci_sbcb_sub_functions = 1; |
|
- | 792 | ||
- | 793 | /* We use GBDA to ask for supported GBDA calls. */ |
|
- | 794 | if (swsci(dev, SWSCI_GBDA_SUPPORTED_CALLS, 0, &tmp) == 0) { |
|
- | 795 | /* make the bits match the sub-function codes */ |
|
- | 796 | tmp <<= 1; |
|
- | 797 | opregion->swsci_gbda_sub_functions |= tmp; |
|
- | 798 | } |
|
- | 799 | ||
- | 800 | /* |
|
- | 801 | * We also use GBDA to ask for _requested_ SBCB callbacks. The driver |
|
- | 802 | * must not call interfaces that are not specifically requested by the |
|
- | 803 | * bios. |
|
- | 804 | */ |
|
- | 805 | if (swsci(dev, SWSCI_GBDA_REQUESTED_CALLBACKS, 0, &tmp) == 0) { |
|
- | 806 | /* here, the bits already match sub-function codes */ |
|
- | 807 | opregion->swsci_sbcb_sub_functions |= tmp; |
|
- | 808 | requested_callbacks = true; |
|
- | 809 | } |
|
- | 810 | ||
- | 811 | /* |
|
- | 812 | * But we use SBCB to ask for _supported_ SBCB calls. This does not mean |
|
- | 813 | * the callback is _requested_. But we still can't call interfaces that |
|
- | 814 | * are not requested. |
|
- | 815 | */ |
|
- | 816 | if (swsci(dev, SWSCI_SBCB_SUPPORTED_CALLBACKS, 0, &tmp) == 0) { |
|
- | 817 | /* make the bits match the sub-function codes */ |
|
- | 818 | u32 low = tmp & 0x7ff; |
|
- | 819 | u32 high = tmp & ~0xfff; /* bit 11 is reserved */ |
|
- | 820 | tmp = (high << 4) | (low << 1) | 1; |
|
- | 821 | ||
- | 822 | /* best guess what to do with supported wrt requested */ |
|
- | 823 | if (requested_callbacks) { |
|
- | 824 | u32 req = opregion->swsci_sbcb_sub_functions; |
|
- | 825 | if ((req & tmp) != req) |
|
- | 826 | DRM_DEBUG_DRIVER("SWSCI BIOS requested (%08x) SBCB callbacks that are not supported (%08x)\n", req, tmp); |
|
- | 827 | /* XXX: for now, trust the requested callbacks */ |
|
- | 828 | /* opregion->swsci_sbcb_sub_functions &= tmp; */ |
|
- | 829 | } else { |
|
- | 830 | opregion->swsci_sbcb_sub_functions |= tmp; |
|
- | 831 | } |
|
- | 832 | } |
|
- | 833 | ||
- | 834 | DRM_DEBUG_DRIVER("SWSCI GBDA callbacks %08x, SBCB callbacks %08x\n", |
|
- | 835 | opregion->swsci_gbda_sub_functions, |
|
- | 836 | opregion->swsci_sbcb_sub_functions); |
|
- | 837 | } |
|
Line 161... | Line 838... | ||
161 | 838 | #else /* CONFIG_ACPI */ |
|
162 | #ifdef CONFIG_ACPI |
839 | static inline void swsci_setup(struct drm_device *dev) {} |
163 | #endif |
840 | #endif /* CONFIG_ACPI */ |
164 | 841 | ||
Line 201... | Line 878... | ||
201 | } |
878 | } |
Line 202... | Line 879... | ||
202 | 879 | ||
203 | if (mboxes & MBOX_SWSCI) { |
880 | if (mboxes & MBOX_SWSCI) { |
204 | DRM_DEBUG_DRIVER("SWSCI supported\n"); |
881 | DRM_DEBUG_DRIVER("SWSCI supported\n"); |
- | 882 | opregion->swsci = base + OPREGION_SWSCI_OFFSET; |
|
205 | opregion->swsci = base + OPREGION_SWSCI_OFFSET; |
883 | swsci_setup(dev); |
206 | } |
884 | } |
207 | if (mboxes & MBOX_ASLE) { |
885 | if (mboxes & MBOX_ASLE) { |
208 | DRM_DEBUG_DRIVER("ASLE supported\n"); |
886 | DRM_DEBUG_DRIVER("ASLE supported\n"); |