26,6 → 26,7 |
*/ |
|
#include <linux/acpi.h> |
#include <linux/dmi.h> |
#include <acpi/video.h> |
|
#include <drm/drmP.h> |
46,6 → 47,7 |
#define OPREGION_SWSCI_OFFSET 0x200 |
#define OPREGION_ASLE_OFFSET 0x300 |
#define OPREGION_VBT_OFFSET 0x400 |
#define OPREGION_ASLE_EXT_OFFSET 0x1C00 |
|
#define OPREGION_SIGNATURE "IntelGraphicsMem" |
#define MBOX_ACPI (1<<0) |
120,9 → 122,18 |
u64 fdss; |
u32 fdsp; |
u32 stat; |
u8 rsvd[70]; |
u64 rvda; /* Physical address of raw vbt data */ |
u32 rvds; /* Size of raw vbt data */ |
u8 rsvd[58]; |
} __packed; |
|
/* OpRegion mailbox #5: ASLE ext */ |
struct opregion_asle_ext { |
u32 phed; /* Panel Header */ |
u8 bddc[256]; /* Panel EDID */ |
u8 rsvd[764]; |
} __packed; |
|
/* Driver readiness indicator */ |
#define ASLE_ARDY_READY (1 << 0) |
#define ASLE_ARDY_NOT_READY (0 << 0) |
411,7 → 422,7 |
static u32 asle_set_backlight(struct drm_device *dev, u32 bclp) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
struct intel_connector *intel_connector; |
struct intel_connector *connector; |
struct opregion_asle *asle = dev_priv->opregion.asle; |
|
DRM_DEBUG_DRIVER("bclp = 0x%08x\n", bclp); |
435,8 → 446,8 |
* only one). |
*/ |
DRM_DEBUG_KMS("updating opregion backlight %d/255\n", bclp); |
list_for_each_entry(intel_connector, &dev->mode_config.connector_list, base.head) |
intel_panel_set_backlight_acpi(intel_connector, bclp, 255); |
for_each_intel_connector(dev, connector) |
intel_panel_set_backlight_acpi(connector, bclp, 255); |
asle->cblv = DIV_ROUND_UP(bclp * 100, 255) | ASLE_CBLV_VALID; |
|
drm_modeset_unlock(&dev->mode_config.connection_mutex); |
826,6 → 837,10 |
|
/* just clear all opregion memory pointers now */ |
memunmap(opregion->header); |
if (opregion->rvda) { |
memunmap(opregion->rvda); |
opregion->rvda = NULL; |
} |
opregion->header = NULL; |
opregion->acpi = NULL; |
opregion->swsci = NULL; |
894,6 → 909,25 |
static inline void swsci_setup(struct drm_device *dev) {} |
#endif /* CONFIG_ACPI */ |
|
static int intel_no_opregion_vbt_callback(const struct dmi_system_id *id) |
{ |
DRM_DEBUG_KMS("Falling back to manually reading VBT from " |
"VBIOS ROM for %s\n", id->ident); |
return 1; |
} |
|
static const struct dmi_system_id intel_no_opregion_vbt[] = { |
{ |
.callback = intel_no_opregion_vbt_callback, |
.ident = "ThinkCentre A57", |
.matches = { |
DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
DMI_MATCH(DMI_PRODUCT_NAME, "97027RG"), |
}, |
}, |
{ } |
}; |
|
int intel_opregion_setup(struct drm_device *dev) |
{ |
struct drm_i915_private *dev_priv = dev->dev_private; |
907,6 → 941,7 |
BUILD_BUG_ON(sizeof(struct opregion_acpi) != 0x100); |
BUILD_BUG_ON(sizeof(struct opregion_swsci) != 0x100); |
BUILD_BUG_ON(sizeof(struct opregion_asle) != 0x100); |
BUILD_BUG_ON(sizeof(struct opregion_asle_ext) != 0x400); |
|
pci_read_config_dword(dev->pdev, PCI_ASLS, &asls); |
DRM_DEBUG_DRIVER("graphic opregion physical addr: 0x%x\n", asls); |
931,8 → 966,6 |
goto err_out; |
} |
opregion->header = base; |
opregion->vbt = base + OPREGION_VBT_OFFSET; |
|
opregion->lid_state = base + ACPI_CLID; |
|
mboxes = opregion->header->mboxes; |
946,6 → 979,7 |
opregion->swsci = base + OPREGION_SWSCI_OFFSET; |
swsci_setup(dev); |
} |
|
if (mboxes & MBOX_ASLE) { |
DRM_DEBUG_DRIVER("ASLE supported\n"); |
opregion->asle = base + OPREGION_ASLE_OFFSET; |
953,6 → 987,37 |
opregion->asle->ardy = ASLE_ARDY_NOT_READY; |
} |
|
if (mboxes & MBOX_ASLE_EXT) |
DRM_DEBUG_DRIVER("ASLE extension supported\n"); |
|
if (!dmi_check_system(intel_no_opregion_vbt)) { |
const void *vbt = NULL; |
u32 vbt_size = 0; |
|
if (opregion->header->opregion_ver >= 2 && opregion->asle && |
opregion->asle->rvda && opregion->asle->rvds) { |
opregion->rvda = memremap(opregion->asle->rvda, |
opregion->asle->rvds, |
MEMREMAP_WB); |
vbt = opregion->rvda; |
vbt_size = opregion->asle->rvds; |
} |
|
if (intel_bios_is_valid_vbt(vbt, vbt_size)) { |
DRM_DEBUG_KMS("Found valid VBT in ACPI OpRegion (RVDA)\n"); |
opregion->vbt = vbt; |
opregion->vbt_size = vbt_size; |
} else { |
vbt = base + OPREGION_VBT_OFFSET; |
vbt_size = OPREGION_ASLE_EXT_OFFSET - OPREGION_VBT_OFFSET; |
if (intel_bios_is_valid_vbt(vbt, vbt_size)) { |
DRM_DEBUG_KMS("Found valid VBT in ACPI OpRegion (Mailbox #4)\n"); |
opregion->vbt = vbt; |
opregion->vbt_size = vbt_size; |
} |
} |
} |
|
return 0; |
|
err_out: |