* [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch
@ 2012-08-16 17:54 alexdeucher
2012-08-16 17:54 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler alexdeucher
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: alexdeucher @ 2012-08-16 17:54 UTC (permalink / raw)
To: airlied, dri-devel; +Cc: Alex Deucher, stable, David L
From: David L <equinox-freedesktopbugs@diac24.net>
This is required for pure UEFI systems. The vbios is stored
in ACPI rather than at the legacy vga location.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=26891
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 59 ++++++++++++++++++++++++++++++++++
1 files changed, 59 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 501f488..f06494a7 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,6 +32,9 @@
#include <linux/vga_switcheroo.h>
#include <linux/slab.h>
+#ifdef CONFIG_ACPI
+#include <linux/acpi.h>
+#endif
/*
* BIOS.
*/
@@ -476,6 +479,58 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
return legacy_read_disabled_bios(rdev);
}
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ struct acpi_table_header *hdr;
+ /* acpi_get_table_with_size is not exported :( */
+ acpi_size tbl_size = 0x7fffffff;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->pdev->bus->number ||
+ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+ vhdr->VendorID != rdev->pdev->vendor ||
+ vhdr->DeviceID != rdev->pdev->device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
+ ret = !!rdev->bios;
+
+out_unmap:
+ /* uh, no idea what to do here... */
+ return ret;
+}
+#endif
bool radeon_get_bios(struct radeon_device *rdev)
{
@@ -487,6 +542,10 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
+#ifdef CONFIG_ACPI
+ if (r == false)
+ r = radeon_acpi_vfct_bios(rdev);
+#endif
if (r == false) {
r = radeon_read_disabled_bios(rdev);
}
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler
2012-08-16 17:54 [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch alexdeucher
@ 2012-08-16 17:54 ` alexdeucher
2012-08-16 18:26 ` Greg KH
2012-08-16 18:25 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch Jerome Glisse
2012-08-16 18:25 ` Greg KH
2 siblings, 1 reply; 23+ messages in thread
From: alexdeucher @ 2012-08-16 17:54 UTC (permalink / raw)
To: airlied, dri-devel; +Cc: Alex Deucher, stable
From: Alex Deucher <alexander.deucher@amd.com>
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon.h | 15 -----
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +------------------
drivers/gpu/drm/radeon/radeon_bios.c | 79 ++++++++++++++++++++++++--
3 files changed, 75 insertions(+), 75 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index b70ec30..5dbd591 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -142,21 +142,6 @@ struct radeon_device;
/*
* BIOS.
*/
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){
- return -EINVAL;
-}
-#endif
bool radeon_get_bios(struct radeon_device *rdev);
/*
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 98724fc..2a2cf0b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
/* handle for device - and atpx */
acpi_handle dhandle;
acpi_handle atpx_handle;
- acpi_handle atrm_handle;
} radeon_atpx_priv;
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
- int offset, int len)
-{
- acpi_status status;
- union acpi_object atrm_arg_elements[2], *obj;
- struct acpi_object_list atrm_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
- atrm_arg.count = 2;
- atrm_arg.pointer = &atrm_arg_elements[0];
-
- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[0].integer.value = offset;
-
- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[1].integer.value = len;
-
- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
- return -ENODEV;
- }
-
- obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
- len = obj->buffer.length;
- kfree(buffer.pointer);
- return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- /* get the discrete ROM only via ATRM */
- if (!radeon_atpx_priv.atpx_detected)
- return false;
-
- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return false;
- return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len);
-}
-
static int radeon_atpx_get_version(acpi_handle handle)
{
acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- acpi_handle dhandle, atpx_handle, atrm_handle;
+ acpi_handle dhandle, atpx_handle;
acpi_status status;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
if (ACPI_FAILURE(status))
return false;
- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
- if (ACPI_FAILURE(status))
- return false;
-
radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx_handle = atpx_handle;
- radeon_atpx_priv.atrm_handle = atrm_handle;
return true;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index f06494a7..c36659a 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -101,16 +101,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+#ifdef CONFIG_ACPI
/* ATRM is used to get the BIOS on the discrete cards in
* dual-gpu systems.
*/
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
+ int offset, int len)
+{
+ acpi_status status;
+ union acpi_object atrm_arg_elements[2], *obj;
+ struct acpi_object_list atrm_arg;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+ atrm_arg.count = 2;
+ atrm_arg.pointer = &atrm_arg_elements[0];
+
+ atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
+ atrm_arg_elements[0].integer.value = offset;
+
+ atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
+ atrm_arg_elements[1].integer.value = len;
+
+ status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
+ if (ACPI_FAILURE(status)) {
+ printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
+ return -ENODEV;
+ }
+
+ obj = (union acpi_object *)buffer.pointer;
+ memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
+ len = obj->buffer.length;
+ kfree(buffer.pointer);
+ return len;
+}
+
static bool radeon_atrm_get_bios(struct radeon_device *rdev)
{
int ret;
int size = 256 * 1024;
int i;
+ struct pci_dev *pdev = NULL;
+ acpi_handle dhandle, atrm_handle;
+ acpi_status status;
+ bool found = false;
+
+ /* ATRM is for the discrete card only */
+ if (rdev->flags & RADEON_IS_IGP)
+ return false;
+
+ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+ if (!dhandle)
+ continue;
+
+ status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
+ if (!ACPI_FAILURE(status)) {
+ found = true;
+ break;
+ }
+ }
- if (!radeon_atrm_supported(rdev->pdev))
+ if (!found)
return false;
rdev->bios = kmalloc(size, GFP_KERNEL);
@@ -120,9 +185,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
- ret = radeon_atrm_get_bios_chunk(rdev->bios,
- (i * ATRM_BIOS_PAGE),
- ATRM_BIOS_PAGE);
+ ret = radeon_atrm_call(atrm_handle,
+ rdev->bios,
+ (i * ATRM_BIOS_PAGE),
+ ATRM_BIOS_PAGE);
if (ret < ATRM_BIOS_PAGE)
break;
}
@@ -133,6 +199,7 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
return true;
}
+#endif
static bool ni_read_disabled_bios(struct radeon_device *rdev)
{
@@ -534,10 +601,12 @@ out_unmap:
bool radeon_get_bios(struct radeon_device *rdev)
{
- bool r;
+ bool r = false;
uint16_t tmp;
+#ifdef CONFIG_ACPI
r = radeon_atrm_get_bios(rdev);
+#endif
if (r == false)
r = igp_read_bios_from_vram(rdev);
if (r == false)
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch
2012-08-16 17:54 [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch alexdeucher
2012-08-16 17:54 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler alexdeucher
@ 2012-08-16 18:25 ` Jerome Glisse
2012-08-16 18:25 ` Greg KH
2 siblings, 0 replies; 23+ messages in thread
From: Jerome Glisse @ 2012-08-16 18:25 UTC (permalink / raw)
To: alexdeucher; +Cc: Alex Deucher, stable, dri-devel, David L
On Thu, Aug 16, 2012 at 1:54 PM, <alexdeucher@gmail.com> wrote:
> From: David L <equinox-freedesktopbugs@diac24.net>
>
> This is required for pure UEFI systems. The vbios is stored
> in ACPI rather than at the legacy vga location.
>
> Fixes:
> https://bugs.freedesktop.org/show_bug.cgi?id=26891
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
> Cc: stable@vger.kernel.org
> ---
> drivers/gpu/drm/radeon/radeon_bios.c | 59 ++++++++++++++++++++++++++++++++++
> 1 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
> index 501f488..f06494a7 100644
> --- a/drivers/gpu/drm/radeon/radeon_bios.c
> +++ b/drivers/gpu/drm/radeon/radeon_bios.c
> @@ -32,6 +32,9 @@
>
> #include <linux/vga_switcheroo.h>
> #include <linux/slab.h>
> +#ifdef CONFIG_ACPI
> +#include <linux/acpi.h>
> +#endif
> /*
> * BIOS.
> */
> @@ -476,6 +479,58 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
> return legacy_read_disabled_bios(rdev);
> }
>
> +#ifdef CONFIG_ACPI
> +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
> +{
> + bool ret = false;
> + struct acpi_table_header *hdr;
> + /* acpi_get_table_with_size is not exported :( */
> + acpi_size tbl_size = 0x7fffffff;
> + UEFI_ACPI_VFCT *vfct;
> + GOP_VBIOS_CONTENT *vbios;
> + VFCT_IMAGE_HEADER *vhdr;
> +
> + if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
> + return false;
> + if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
> + DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
> + goto out_unmap;
> + }
> +
> + vfct = (UEFI_ACPI_VFCT *)hdr;
> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
> + DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
> + goto out_unmap;
> + }
> +
> + vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
> + vhdr = &vbios->VbiosHeader;
> + DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
> + vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
> + vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
> +
> + if (vhdr->PCIBus != rdev->pdev->bus->number ||
> + vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
> + vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
> + vhdr->VendorID != rdev->pdev->vendor ||
> + vhdr->DeviceID != rdev->pdev->device) {
> + DRM_INFO("ACPI VFCT table is not for this card\n");
> + goto out_unmap;
> + };
> +
> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
> + DRM_ERROR("ACPI VFCT image truncated\n");
> + goto out_unmap;
> + }
> +
> + rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
> + ret = !!rdev->bios;
> +
> +out_unmap:
> + /* uh, no idea what to do here... */
> + return ret;
> +}
> +#endif
>
> bool radeon_get_bios(struct radeon_device *rdev)
> {
> @@ -487,6 +542,10 @@ bool radeon_get_bios(struct radeon_device *rdev)
> r = igp_read_bios_from_vram(rdev);
> if (r == false)
> r = radeon_read_bios(rdev);
> +#ifdef CONFIG_ACPI
> + if (r == false)
> + r = radeon_acpi_vfct_bios(rdev);
> +#endif
> if (r == false) {
> r = radeon_read_disabled_bios(rdev);
> }
> --
> 1.7.7.5
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch
2012-08-16 17:54 [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch alexdeucher
2012-08-16 17:54 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler alexdeucher
2012-08-16 18:25 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch Jerome Glisse
@ 2012-08-16 18:25 ` Greg KH
2012-08-16 19:13 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) alexdeucher
2 siblings, 1 reply; 23+ messages in thread
From: Greg KH @ 2012-08-16 18:25 UTC (permalink / raw)
To: alexdeucher; +Cc: Alex Deucher, stable, dri-devel, David L
On Thu, Aug 16, 2012 at 01:54:55PM -0400, alexdeucher@gmail.com wrote:
> From: David L <equinox-freedesktopbugs@diac24.net>
>
> This is required for pure UEFI systems. The vbios is stored
> in ACPI rather than at the legacy vga location.
>
> Fixes:
> https://bugs.freedesktop.org/show_bug.cgi?id=26891
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: stable@vger.kernel.org
> ---
> drivers/gpu/drm/radeon/radeon_bios.c | 59 ++++++++++++++++++++++++++++++++++
> 1 files changed, 59 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
> index 501f488..f06494a7 100644
> --- a/drivers/gpu/drm/radeon/radeon_bios.c
> +++ b/drivers/gpu/drm/radeon/radeon_bios.c
> @@ -32,6 +32,9 @@
>
> #include <linux/vga_switcheroo.h>
> #include <linux/slab.h>
> +#ifdef CONFIG_ACPI
> +#include <linux/acpi.h>
> +#endif
This #ifdef should not be needed, right?
> +#ifdef CONFIG_ACPI
> +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
> +{
> + bool ret = false;
> + struct acpi_table_header *hdr;
> + /* acpi_get_table_with_size is not exported :( */
> + acpi_size tbl_size = 0x7fffffff;
> + UEFI_ACPI_VFCT *vfct;
> + GOP_VBIOS_CONTENT *vbios;
> + VFCT_IMAGE_HEADER *vhdr;
> +
> + if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
> + return false;
> + if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
> + DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
> + goto out_unmap;
> + }
> +
> + vfct = (UEFI_ACPI_VFCT *)hdr;
> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
> + DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
> + goto out_unmap;
> + }
> +
> + vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
> + vhdr = &vbios->VbiosHeader;
> + DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
> + vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
> + vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
> +
> + if (vhdr->PCIBus != rdev->pdev->bus->number ||
> + vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
> + vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
> + vhdr->VendorID != rdev->pdev->vendor ||
> + vhdr->DeviceID != rdev->pdev->device) {
> + DRM_INFO("ACPI VFCT table is not for this card\n");
> + goto out_unmap;
> + };
> +
> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
> + DRM_ERROR("ACPI VFCT image truncated\n");
> + goto out_unmap;
> + }
> +
> + rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
> + ret = !!rdev->bios;
> +
> +out_unmap:
> + /* uh, no idea what to do here... */
> + return ret;
> +}
> +#endif
Please provide an "empty" function here if the #ifdef is not true, which
then makes the following #ifdef not needed:
> @@ -487,6 +542,10 @@ bool radeon_get_bios(struct radeon_device *rdev)
> r = igp_read_bios_from_vram(rdev);
> if (r == false)
> r = radeon_read_bios(rdev);
> +#ifdef CONFIG_ACPI
> + if (r == false)
> + r = radeon_acpi_vfct_bios(rdev);
> +#endif
See, then that #ifdef isn't needed.
That cleans up the code more, remember, we don't want #ifdefs in .c
files unless we _really_ have to have them.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler
2012-08-16 17:54 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler alexdeucher
@ 2012-08-16 18:26 ` Greg KH
0 siblings, 0 replies; 23+ messages in thread
From: Greg KH @ 2012-08-16 18:26 UTC (permalink / raw)
To: alexdeucher; +Cc: Alex Deucher, stable, dri-devel
On Thu, Aug 16, 2012 at 01:54:56PM -0400, alexdeucher@gmail.com wrote:
> From: Alex Deucher <alexander.deucher@amd.com>
>
> There are systems that use ATRM, but not ATPX.
>
> Fixes:
> https://bugs.freedesktop.org/show_bug.cgi?id=41265
Same #ifdef comments here as for patch 1/2.
thanks,
greg k-h
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2)
2012-08-16 18:25 ` Greg KH
@ 2012-08-16 19:13 ` alexdeucher
2012-08-16 19:13 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v2) alexdeucher
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: alexdeucher @ 2012-08-16 19:13 UTC (permalink / raw)
To: airlied, dri-devel; +Cc: Alex Deucher, stable, David L
From: David L <equinox-freedesktopbugs@diac24.net>
This is required for pure UEFI systems. The vbios is stored
in ACPI rather than at the legacy vga location.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=26891
V2: fix #ifdefs as per Greg's comments
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 62 ++++++++++++++++++++++++++++++++++
1 files changed, 62 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 501f488..bf21f65 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,6 +32,9 @@
#include <linux/vga_switcheroo.h>
#include <linux/slab.h>
+#ifdef CONFIG_ACPI
+#include <linux/acpi.h>
+#endif
/*
* BIOS.
*/
@@ -476,6 +479,63 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
return legacy_read_disabled_bios(rdev);
}
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ struct acpi_table_header *hdr;
+ /* acpi_get_table_with_size is not exported :( */
+ acpi_size tbl_size = 0x7fffffff;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->pdev->bus->number ||
+ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+ vhdr->VendorID != rdev->pdev->vendor ||
+ vhdr->DeviceID != rdev->pdev->device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
+ ret = !!rdev->bios;
+
+out_unmap:
+ /* uh, no idea what to do here... */
+ return ret;
+}
+#else
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
bool radeon_get_bios(struct radeon_device *rdev)
{
@@ -484,6 +544,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = radeon_atrm_get_bios(rdev);
if (r == false)
+ r = radeon_acpi_vfct_bios(rdev);
+ if (r == false)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v2)
2012-08-16 19:13 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) alexdeucher
@ 2012-08-16 19:13 ` alexdeucher
2012-08-16 19:25 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) Greg KH
2012-08-16 19:40 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) David Lamparter
2 siblings, 0 replies; 23+ messages in thread
From: alexdeucher @ 2012-08-16 19:13 UTC (permalink / raw)
To: airlied, dri-devel; +Cc: Alex Deucher, stable
From: Alex Deucher <alexander.deucher@amd.com>
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
V2: fix #ifdefs as per Greg's comments
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon.h | 15 -----
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +-----------------
drivers/gpu/drm/radeon/radeon_bios.c | 82 ++++++++++++++++++++++++--
3 files changed, 77 insertions(+), 76 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9930419..59a1531 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -142,21 +142,6 @@ struct radeon_device;
/*
* BIOS.
*/
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){
- return -EINVAL;
-}
-#endif
bool radeon_get_bios(struct radeon_device *rdev);
/*
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 98724fc..2a2cf0b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
/* handle for device - and atpx */
acpi_handle dhandle;
acpi_handle atpx_handle;
- acpi_handle atrm_handle;
} radeon_atpx_priv;
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
- int offset, int len)
-{
- acpi_status status;
- union acpi_object atrm_arg_elements[2], *obj;
- struct acpi_object_list atrm_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
- atrm_arg.count = 2;
- atrm_arg.pointer = &atrm_arg_elements[0];
-
- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[0].integer.value = offset;
-
- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[1].integer.value = len;
-
- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
- return -ENODEV;
- }
-
- obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
- len = obj->buffer.length;
- kfree(buffer.pointer);
- return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- /* get the discrete ROM only via ATRM */
- if (!radeon_atpx_priv.atpx_detected)
- return false;
-
- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return false;
- return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len);
-}
-
static int radeon_atpx_get_version(acpi_handle handle)
{
acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- acpi_handle dhandle, atpx_handle, atrm_handle;
+ acpi_handle dhandle, atpx_handle;
acpi_status status;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
if (ACPI_FAILURE(status))
return false;
- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
- if (ACPI_FAILURE(status))
- return false;
-
radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx_handle = atpx_handle;
- radeon_atpx_priv.atrm_handle = atrm_handle;
return true;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index bf21f65..e97779d 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,9 +32,7 @@
#include <linux/vga_switcheroo.h>
#include <linux/slab.h>
-#ifdef CONFIG_ACPI
#include <linux/acpi.h>
-#endif
/*
* BIOS.
*/
@@ -101,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+#ifdef CONFIG_ACPI
/* ATRM is used to get the BIOS on the discrete cards in
* dual-gpu systems.
*/
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
+ int offset, int len)
+{
+ acpi_status status;
+ union acpi_object atrm_arg_elements[2], *obj;
+ struct acpi_object_list atrm_arg;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+ atrm_arg.count = 2;
+ atrm_arg.pointer = &atrm_arg_elements[0];
+
+ atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
+ atrm_arg_elements[0].integer.value = offset;
+
+ atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
+ atrm_arg_elements[1].integer.value = len;
+
+ status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
+ if (ACPI_FAILURE(status)) {
+ printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
+ return -ENODEV;
+ }
+
+ obj = (union acpi_object *)buffer.pointer;
+ memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
+ len = obj->buffer.length;
+ kfree(buffer.pointer);
+ return len;
+}
+
static bool radeon_atrm_get_bios(struct radeon_device *rdev)
{
int ret;
int size = 256 * 1024;
int i;
+ struct pci_dev *pdev = NULL;
+ acpi_handle dhandle, atrm_handle;
+ acpi_status status;
+ bool found = false;
+
+ /* ATRM is for the discrete card only */
+ if (rdev->flags & RADEON_IS_IGP)
+ return false;
+
+ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+ if (!dhandle)
+ continue;
+
+ status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
+ if (!ACPI_FAILURE(status)) {
+ found = true;
+ break;
+ }
+ }
- if (!radeon_atrm_supported(rdev->pdev))
+ if (!found)
return false;
rdev->bios = kmalloc(size, GFP_KERNEL);
@@ -120,9 +183,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
- ret = radeon_atrm_get_bios_chunk(rdev->bios,
- (i * ATRM_BIOS_PAGE),
- ATRM_BIOS_PAGE);
+ ret = radeon_atrm_call(atrm_handle,
+ rdev->bios,
+ (i * ATRM_BIOS_PAGE),
+ ATRM_BIOS_PAGE);
if (ret < ATRM_BIOS_PAGE)
break;
}
@@ -133,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
return true;
}
+#else
+static bool radeon_atrm_get_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
static bool ni_read_disabled_bios(struct radeon_device *rdev)
{
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2)
2012-08-16 19:13 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) alexdeucher
2012-08-16 19:13 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v2) alexdeucher
@ 2012-08-16 19:25 ` Greg KH
2012-08-16 19:38 ` Alex Deucher
2012-08-16 19:48 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
2012-08-16 19:40 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) David Lamparter
2 siblings, 2 replies; 23+ messages in thread
From: Greg KH @ 2012-08-16 19:25 UTC (permalink / raw)
To: alexdeucher; +Cc: Alex Deucher, stable, dri-devel, David L
On Thu, Aug 16, 2012 at 03:13:46PM -0400, alexdeucher@gmail.com wrote:
> From: David L <equinox-freedesktopbugs@diac24.net>
>
> This is required for pure UEFI systems. The vbios is stored
> in ACPI rather than at the legacy vga location.
>
> Fixes:
> https://bugs.freedesktop.org/show_bug.cgi?id=26891
>
> V2: fix #ifdefs as per Greg's comments
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: stable@vger.kernel.org
> ---
> drivers/gpu/drm/radeon/radeon_bios.c | 62 ++++++++++++++++++++++++++++++++++
> 1 files changed, 62 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
> index 501f488..bf21f65 100644
> --- a/drivers/gpu/drm/radeon/radeon_bios.c
> +++ b/drivers/gpu/drm/radeon/radeon_bios.c
> @@ -32,6 +32,9 @@
>
> #include <linux/vga_switcheroo.h>
> #include <linux/slab.h>
> +#ifdef CONFIG_ACPI
> +#include <linux/acpi.h>
> +#endif
You forgot to remove this one :(
> /*
> * BIOS.
> */
> @@ -476,6 +479,63 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
> return legacy_read_disabled_bios(rdev);
> }
>
> +#ifdef CONFIG_ACPI
> +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
> +{
> + bool ret = false;
> + struct acpi_table_header *hdr;
> + /* acpi_get_table_with_size is not exported :( */
> + acpi_size tbl_size = 0x7fffffff;
> + UEFI_ACPI_VFCT *vfct;
> + GOP_VBIOS_CONTENT *vbios;
> + VFCT_IMAGE_HEADER *vhdr;
> +
> + if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
> + return false;
> + if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
> + DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
> + goto out_unmap;
> + }
> +
> + vfct = (UEFI_ACPI_VFCT *)hdr;
> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
> + DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
> + goto out_unmap;
> + }
> +
> + vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
> + vhdr = &vbios->VbiosHeader;
> + DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
> + vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
> + vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
> +
> + if (vhdr->PCIBus != rdev->pdev->bus->number ||
> + vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
> + vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
> + vhdr->VendorID != rdev->pdev->vendor ||
> + vhdr->DeviceID != rdev->pdev->device) {
> + DRM_INFO("ACPI VFCT table is not for this card\n");
> + goto out_unmap;
> + };
> +
> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
> + DRM_ERROR("ACPI VFCT image truncated\n");
> + goto out_unmap;
> + }
> +
> + rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
> + ret = !!rdev->bios;
> +
> +out_unmap:
> + /* uh, no idea what to do here... */
> + return ret;
> +}
> +#else
> +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
Make it inline, and then the compiler is smart enough to just delete the
whole if () check you make when you call it.
Third time's a charm?
greg k-h
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2)
2012-08-16 19:25 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) Greg KH
@ 2012-08-16 19:38 ` Alex Deucher
2012-08-16 19:48 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
1 sibling, 0 replies; 23+ messages in thread
From: Alex Deucher @ 2012-08-16 19:38 UTC (permalink / raw)
To: Greg KH; +Cc: Alex Deucher, stable, dri-devel, David L
On Thu, Aug 16, 2012 at 3:25 PM, Greg KH <gregkh@linuxfoundation.org> wrote:
> On Thu, Aug 16, 2012 at 03:13:46PM -0400, alexdeucher@gmail.com wrote:
>> From: David L <equinox-freedesktopbugs@diac24.net>
>>
>> This is required for pure UEFI systems. The vbios is stored
>> in ACPI rather than at the legacy vga location.
>>
>> Fixes:
>> https://bugs.freedesktop.org/show_bug.cgi?id=26891
>>
>> V2: fix #ifdefs as per Greg's comments
>>
>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>> Cc: stable@vger.kernel.org
>> ---
>> drivers/gpu/drm/radeon/radeon_bios.c | 62 ++++++++++++++++++++++++++++++++++
>> 1 files changed, 62 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
>> index 501f488..bf21f65 100644
>> --- a/drivers/gpu/drm/radeon/radeon_bios.c
>> +++ b/drivers/gpu/drm/radeon/radeon_bios.c
>> @@ -32,6 +32,9 @@
>>
>> #include <linux/vga_switcheroo.h>
>> #include <linux/slab.h>
>> +#ifdef CONFIG_ACPI
>> +#include <linux/acpi.h>
>> +#endif
>
> You forgot to remove this one :(
Argh! I squashed that into the wrong patch when I rebased my fixes.
>
>> /*
>> * BIOS.
>> */
>> @@ -476,6 +479,63 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
>> return legacy_read_disabled_bios(rdev);
>> }
>>
>> +#ifdef CONFIG_ACPI
>> +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
>> +{
>> + bool ret = false;
>> + struct acpi_table_header *hdr;
>> + /* acpi_get_table_with_size is not exported :( */
>> + acpi_size tbl_size = 0x7fffffff;
>> + UEFI_ACPI_VFCT *vfct;
>> + GOP_VBIOS_CONTENT *vbios;
>> + VFCT_IMAGE_HEADER *vhdr;
>> +
>> + if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
>> + return false;
>> + if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
>> + DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
>> + goto out_unmap;
>> + }
>> +
>> + vfct = (UEFI_ACPI_VFCT *)hdr;
>> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
>> + DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
>> + goto out_unmap;
>> + }
>> +
>> + vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
>> + vhdr = &vbios->VbiosHeader;
>> + DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
>> + vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
>> + vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
>> +
>> + if (vhdr->PCIBus != rdev->pdev->bus->number ||
>> + vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
>> + vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
>> + vhdr->VendorID != rdev->pdev->vendor ||
>> + vhdr->DeviceID != rdev->pdev->device) {
>> + DRM_INFO("ACPI VFCT table is not for this card\n");
>> + goto out_unmap;
>> + };
>> +
>> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
>> + DRM_ERROR("ACPI VFCT image truncated\n");
>> + goto out_unmap;
>> + }
>> +
>> + rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
>> + ret = !!rdev->bios;
>> +
>> +out_unmap:
>> + /* uh, no idea what to do here... */
>> + return ret;
>> +}
>> +#else
>> +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
>
> Make it inline, and then the compiler is smart enough to just delete the
> whole if () check you make when you call it.
>
> Third time's a charm?
On the way.
Alex
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2)
2012-08-16 19:13 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) alexdeucher
2012-08-16 19:13 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v2) alexdeucher
2012-08-16 19:25 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) Greg KH
@ 2012-08-16 19:40 ` David Lamparter
2012-08-16 19:51 ` Alex Deucher
2 siblings, 1 reply; 23+ messages in thread
From: David Lamparter @ 2012-08-16 19:40 UTC (permalink / raw)
To: alexdeucher; +Cc: Alex Deucher, stable, dri-devel, David L
[-- Attachment #1.1: Type: text/plain, Size: 3318 bytes --]
On Thu, Aug 16, 2012 at 03:13:46PM -0400, alexdeucher@gmail.com wrote:
> From: David L <equinox-freedesktopbugs@diac24.net>
From: David Lamparter <equinox@diac24.net>
There are still two rough edges left in here, I didn't get around to
clean it up, other stuff came up -- sorry...
> This is required for pure UEFI systems. The vbios is stored
> in ACPI rather than at the legacy vga location.
>
> Fixes:
> https://bugs.freedesktop.org/show_bug.cgi?id=26891
>
> V2: fix #ifdefs as per Greg's comments
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: stable@vger.kernel.org
> ---
[...]
> + struct acpi_table_header *hdr;
> + /* acpi_get_table_with_size is not exported :( */
> + acpi_size tbl_size = 0x7fffffff;
I was using acpi_get_table_with_size, but that needs an export, with
0x7fffffff all the tests below are kinda useless because they always
succeed. I think it'd be useful to keep the length checks in case some
vendor breaks their ACPI tables, so this needs an EXPORT_SYMBOL.
> + UEFI_ACPI_VFCT *vfct;
> + GOP_VBIOS_CONTENT *vbios;
> + VFCT_IMAGE_HEADER *vhdr;
> +
> + if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
> + return false;
> + if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
> + DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
> + goto out_unmap;
> + }
> +
> + vfct = (UEFI_ACPI_VFCT *)hdr;
> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
> + DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
> + goto out_unmap;
> + }
> +
> + vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
> + vhdr = &vbios->VbiosHeader;
> + DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
> + vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
> + vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
> +
> + if (vhdr->PCIBus != rdev->pdev->bus->number ||
> + vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
> + vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
> + vhdr->VendorID != rdev->pdev->vendor ||
> + vhdr->DeviceID != rdev->pdev->device) {
> + DRM_INFO("ACPI VFCT table is not for this card\n");
> + goto out_unmap;
> + };
> +
> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
> + DRM_ERROR("ACPI VFCT image truncated\n");
> + goto out_unmap;
> + }
> +
> + rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
> + ret = !!rdev->bios;
> +
> +out_unmap:
> + /* uh, no idea what to do here... */
So, er, I had no clue how to clean up the return value of acpi_get_table
- does this actually need to be cleaned up? Or do you just get a
pointer straight to the "real" ACPI table?
> + return ret;
> +}
> +#else
> +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
> +{
> + return false;
> +}
> +#endif
>
> bool radeon_get_bios(struct radeon_device *rdev)
> {
> @@ -484,6 +544,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
>
> r = radeon_atrm_get_bios(rdev);
> if (r == false)
> + r = radeon_acpi_vfct_bios(rdev);
> + if (r == false)
> r = igp_read_bios_from_vram(rdev);
> if (r == false)
> r = radeon_read_bios(rdev);
> --
> 1.7.7.5
>
Cheers,
-David
[-- Attachment #1.2: Digital signature --]
[-- Type: application/pgp-signature, Size: 230 bytes --]
[-- Attachment #2: Type: text/plain, Size: 159 bytes --]
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v3)
2012-08-16 19:25 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) Greg KH
2012-08-16 19:38 ` Alex Deucher
@ 2012-08-16 19:48 ` alexdeucher
2012-08-16 19:48 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v3) alexdeucher
1 sibling, 1 reply; 23+ messages in thread
From: alexdeucher @ 2012-08-16 19:48 UTC (permalink / raw)
To: airlied, dri-devel; +Cc: Alex Deucher, stable
From: David Lamparter <equinox@diac24.net>
This is required for pure UEFI systems. The vbios is stored
in ACPI rather than at the legacy vga location.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=26891
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 60 ++++++++++++++++++++++++++++++++++
1 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 501f488..a32232f 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,6 +32,7 @@
#include <linux/vga_switcheroo.h>
#include <linux/slab.h>
+#include <linux/acpi.h>
/*
* BIOS.
*/
@@ -476,6 +477,63 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
return legacy_read_disabled_bios(rdev);
}
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ struct acpi_table_header *hdr;
+ /* acpi_get_table_with_size is not exported :( */
+ acpi_size tbl_size = 0x7fffffff;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->pdev->bus->number ||
+ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+ vhdr->VendorID != rdev->pdev->vendor ||
+ vhdr->DeviceID != rdev->pdev->device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
+ ret = !!rdev->bios;
+
+out_unmap:
+ /* uh, no idea what to do here... */
+ return ret;
+}
+#else
+static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
bool radeon_get_bios(struct radeon_device *rdev)
{
@@ -484,6 +542,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = radeon_atrm_get_bios(rdev);
if (r == false)
+ r = radeon_acpi_vfct_bios(rdev);
+ if (r == false)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v3)
2012-08-16 19:48 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
@ 2012-08-16 19:48 ` alexdeucher
0 siblings, 0 replies; 23+ messages in thread
From: alexdeucher @ 2012-08-16 19:48 UTC (permalink / raw)
To: airlied, dri-devel; +Cc: Alex Deucher, stable
From: Alex Deucher <alexander.deucher@amd.com>
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon.h | 15 -----
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +------------------
drivers/gpu/drm/radeon/radeon_bios.c | 80 ++++++++++++++++++++++++-
3 files changed, 77 insertions(+), 74 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9930419..59a1531 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -142,21 +142,6 @@ struct radeon_device;
/*
* BIOS.
*/
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){
- return -EINVAL;
-}
-#endif
bool radeon_get_bios(struct radeon_device *rdev);
/*
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 98724fc..2a2cf0b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
/* handle for device - and atpx */
acpi_handle dhandle;
acpi_handle atpx_handle;
- acpi_handle atrm_handle;
} radeon_atpx_priv;
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
- int offset, int len)
-{
- acpi_status status;
- union acpi_object atrm_arg_elements[2], *obj;
- struct acpi_object_list atrm_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
- atrm_arg.count = 2;
- atrm_arg.pointer = &atrm_arg_elements[0];
-
- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[0].integer.value = offset;
-
- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[1].integer.value = len;
-
- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
- return -ENODEV;
- }
-
- obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
- len = obj->buffer.length;
- kfree(buffer.pointer);
- return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- /* get the discrete ROM only via ATRM */
- if (!radeon_atpx_priv.atpx_detected)
- return false;
-
- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return false;
- return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len);
-}
-
static int radeon_atpx_get_version(acpi_handle handle)
{
acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- acpi_handle dhandle, atpx_handle, atrm_handle;
+ acpi_handle dhandle, atpx_handle;
acpi_status status;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
if (ACPI_FAILURE(status))
return false;
- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
- if (ACPI_FAILURE(status))
- return false;
-
radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx_handle = atpx_handle;
- radeon_atpx_priv.atrm_handle = atrm_handle;
return true;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index a32232f..602898d 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -99,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+#ifdef CONFIG_ACPI
/* ATRM is used to get the BIOS on the discrete cards in
* dual-gpu systems.
*/
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
+ int offset, int len)
+{
+ acpi_status status;
+ union acpi_object atrm_arg_elements[2], *obj;
+ struct acpi_object_list atrm_arg;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+ atrm_arg.count = 2;
+ atrm_arg.pointer = &atrm_arg_elements[0];
+
+ atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
+ atrm_arg_elements[0].integer.value = offset;
+
+ atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
+ atrm_arg_elements[1].integer.value = len;
+
+ status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
+ if (ACPI_FAILURE(status)) {
+ printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
+ return -ENODEV;
+ }
+
+ obj = (union acpi_object *)buffer.pointer;
+ memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
+ len = obj->buffer.length;
+ kfree(buffer.pointer);
+ return len;
+}
+
static bool radeon_atrm_get_bios(struct radeon_device *rdev)
{
int ret;
int size = 256 * 1024;
int i;
+ struct pci_dev *pdev = NULL;
+ acpi_handle dhandle, atrm_handle;
+ acpi_status status;
+ bool found = false;
- if (!radeon_atrm_supported(rdev->pdev))
+ /* ATRM is for the discrete card only */
+ if (rdev->flags & RADEON_IS_IGP)
+ return false;
+
+ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+ if (!dhandle)
+ continue;
+
+ status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
+ if (!ACPI_FAILURE(status)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
return false;
rdev->bios = kmalloc(size, GFP_KERNEL);
@@ -118,9 +183,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
- ret = radeon_atrm_get_bios_chunk(rdev->bios,
- (i * ATRM_BIOS_PAGE),
- ATRM_BIOS_PAGE);
+ ret = radeon_atrm_call(atrm_handle,
+ rdev->bios,
+ (i * ATRM_BIOS_PAGE),
+ ATRM_BIOS_PAGE);
if (ret < ATRM_BIOS_PAGE)
break;
}
@@ -131,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
return true;
}
+#else
+static inline bool radeon_atrm_get_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
static bool ni_read_disabled_bios(struct radeon_device *rdev)
{
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2)
2012-08-16 19:40 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) David Lamparter
@ 2012-08-16 19:51 ` Alex Deucher
2012-08-17 16:56 ` Alex Deucher
0 siblings, 1 reply; 23+ messages in thread
From: Alex Deucher @ 2012-08-16 19:51 UTC (permalink / raw)
To: David Lamparter; +Cc: Alex Deucher, stable, dri-devel, David L
On Thu, Aug 16, 2012 at 3:40 PM, David Lamparter <equinox@diac24.net> wrote:
> On Thu, Aug 16, 2012 at 03:13:46PM -0400, alexdeucher@gmail.com wrote:
>> From: David L <equinox-freedesktopbugs@diac24.net>
> From: David Lamparter <equinox@diac24.net>
>
> There are still two rough edges left in here, I didn't get around to
> clean it up, other stuff came up -- sorry...
>
>> This is required for pure UEFI systems. The vbios is stored
>> in ACPI rather than at the legacy vga location.
>>
>> Fixes:
>> https://bugs.freedesktop.org/show_bug.cgi?id=26891
>>
>> V2: fix #ifdefs as per Greg's comments
>>
>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>> Cc: stable@vger.kernel.org
>> ---
> [...]
>> + struct acpi_table_header *hdr;
>> + /* acpi_get_table_with_size is not exported :( */
>> + acpi_size tbl_size = 0x7fffffff;
>
> I was using acpi_get_table_with_size, but that needs an export, with
> 0x7fffffff all the tests below are kinda useless because they always
> succeed. I think it'd be useful to keep the length checks in case some
> vendor breaks their ACPI tables, so this needs an EXPORT_SYMBOL.
I guess we could leave it as is for now for -fixes and then switch it
use use the new exported symbol for -next? Is it ok to export a new
symbol for -fixes?
>
>> + UEFI_ACPI_VFCT *vfct;
>> + GOP_VBIOS_CONTENT *vbios;
>> + VFCT_IMAGE_HEADER *vhdr;
>> +
>> + if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
>> + return false;
>> + if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
>> + DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
>> + goto out_unmap;
>> + }
>> +
>> + vfct = (UEFI_ACPI_VFCT *)hdr;
>> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
>> + DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
>> + goto out_unmap;
>> + }
>> +
>> + vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
>> + vhdr = &vbios->VbiosHeader;
>> + DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
>> + vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
>> + vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
>> +
>> + if (vhdr->PCIBus != rdev->pdev->bus->number ||
>> + vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
>> + vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
>> + vhdr->VendorID != rdev->pdev->vendor ||
>> + vhdr->DeviceID != rdev->pdev->device) {
>> + DRM_INFO("ACPI VFCT table is not for this card\n");
>> + goto out_unmap;
>> + };
>> +
>> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
>> + DRM_ERROR("ACPI VFCT image truncated\n");
>> + goto out_unmap;
>> + }
>> +
>> + rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
>> + ret = !!rdev->bios;
>> +
>> +out_unmap:
>> + /* uh, no idea what to do here... */
>
> So, er, I had no clue how to clean up the return value of acpi_get_table
> - does this actually need to be cleaned up? Or do you just get a
> pointer straight to the "real" ACPI table?
Not sure on that. Anyone know more about the acpi code?
Alex
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2)
2012-08-16 19:51 ` Alex Deucher
@ 2012-08-17 16:56 ` Alex Deucher
2012-08-17 17:03 ` Matthew Garrett
0 siblings, 1 reply; 23+ messages in thread
From: Alex Deucher @ 2012-08-17 16:56 UTC (permalink / raw)
To: David Lamparter; +Cc: stable, dri-devel, David L, Alex Deucher, Matthew Garrett
Adding Matthew in case he as any ideas.
On Thu, Aug 16, 2012 at 3:51 PM, Alex Deucher <alexdeucher@gmail.com> wrote:
> On Thu, Aug 16, 2012 at 3:40 PM, David Lamparter <equinox@diac24.net> wrote:
>> On Thu, Aug 16, 2012 at 03:13:46PM -0400, alexdeucher@gmail.com wrote:
>>> From: David L <equinox-freedesktopbugs@diac24.net>
>> From: David Lamparter <equinox@diac24.net>
>>
>> There are still two rough edges left in here, I didn't get around to
>> clean it up, other stuff came up -- sorry...
>>
>>> This is required for pure UEFI systems. The vbios is stored
>>> in ACPI rather than at the legacy vga location.
>>>
>>> Fixes:
>>> https://bugs.freedesktop.org/show_bug.cgi?id=26891
>>>
>>> V2: fix #ifdefs as per Greg's comments
>>>
>>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>>> Cc: stable@vger.kernel.org
>>> ---
>> [...]
>>> + struct acpi_table_header *hdr;
>>> + /* acpi_get_table_with_size is not exported :( */
>>> + acpi_size tbl_size = 0x7fffffff;
>>
>> I was using acpi_get_table_with_size, but that needs an export, with
>> 0x7fffffff all the tests below are kinda useless because they always
>> succeed. I think it'd be useful to keep the length checks in case some
>> vendor breaks their ACPI tables, so this needs an EXPORT_SYMBOL.
>
> I guess we could leave it as is for now for -fixes and then switch it
> use use the new exported symbol for -next? Is it ok to export a new
> symbol for -fixes?
>
>>
>>> + UEFI_ACPI_VFCT *vfct;
>>> + GOP_VBIOS_CONTENT *vbios;
>>> + VFCT_IMAGE_HEADER *vhdr;
>>> +
>>> + if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
>>> + return false;
>>> + if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
>>> + DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
>>> + goto out_unmap;
>>> + }
>>> +
>>> + vfct = (UEFI_ACPI_VFCT *)hdr;
>>> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
>>> + DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
>>> + goto out_unmap;
>>> + }
>>> +
>>> + vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
>>> + vhdr = &vbios->VbiosHeader;
>>> + DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
>>> + vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
>>> + vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
>>> +
>>> + if (vhdr->PCIBus != rdev->pdev->bus->number ||
>>> + vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
>>> + vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
>>> + vhdr->VendorID != rdev->pdev->vendor ||
>>> + vhdr->DeviceID != rdev->pdev->device) {
>>> + DRM_INFO("ACPI VFCT table is not for this card\n");
>>> + goto out_unmap;
>>> + };
>>> +
>>> + if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
>>> + DRM_ERROR("ACPI VFCT image truncated\n");
>>> + goto out_unmap;
>>> + }
>>> +
>>> + rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
>>> + ret = !!rdev->bios;
>>> +
>>> +out_unmap:
>>> + /* uh, no idea what to do here... */
>>
>> So, er, I had no clue how to clean up the return value of acpi_get_table
>> - does this actually need to be cleaned up? Or do you just get a
>> pointer straight to the "real" ACPI table?
>
> Not sure on that. Anyone know more about the acpi code?
>
> Alex
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2)
2012-08-17 16:56 ` Alex Deucher
@ 2012-08-17 17:03 ` Matthew Garrett
2012-08-20 15:19 ` [PATCH 1/4] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
0 siblings, 1 reply; 23+ messages in thread
From: Matthew Garrett @ 2012-08-17 17:03 UTC (permalink / raw)
To: Alex Deucher; +Cc: stable, dri-devel, David L, Alex Deucher
On Fri, Aug 17, 2012 at 12:56:31PM -0400, Alex Deucher wrote:
> > I guess we could leave it as is for now for -fixes and then switch it
> > use use the new exported symbol for -next? Is it ok to export a new
> > symbol for -fixes?
I don't see why not, providing the ACPI people are happy with it.
> >> So, er, I had no clue how to clean up the return value of acpi_get_table
> >> - does this actually need to be cleaned up? Or do you just get a
> >> pointer straight to the "real" ACPI table?
> >
> > Not sure on that. Anyone know more about the acpi code?
Not sure what you're asking here - acpi_get_table returns acpi_status,
not a pointer.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 23+ messages in thread
* [PATCH 1/4] drm/radeon: implement ACPI VFCT vbios fetch (v3)
2012-08-17 17:03 ` Matthew Garrett
@ 2012-08-20 15:19 ` alexdeucher
2012-08-20 15:19 ` [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size alexdeucher
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: alexdeucher @ 2012-08-20 15:19 UTC (permalink / raw)
To: airlied, dri-devel, equinox; +Cc: linux-acpi, Alex Deucher, stable
From: David Lamparter <equinox@diac24.net>
This is required for pure UEFI systems. The vbios is stored
in ACPI rather than at the legacy vga location.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=26891
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Reviewed-by: Jerome Glisse <jglisse@redhat.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 60 ++++++++++++++++++++++++++++++++++
1 files changed, 60 insertions(+), 0 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index 501f488..a32232f 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -32,6 +32,7 @@
#include <linux/vga_switcheroo.h>
#include <linux/slab.h>
+#include <linux/acpi.h>
/*
* BIOS.
*/
@@ -476,6 +477,63 @@ static bool radeon_read_disabled_bios(struct radeon_device *rdev)
return legacy_read_disabled_bios(rdev);
}
+#ifdef CONFIG_ACPI
+static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ bool ret = false;
+ struct acpi_table_header *hdr;
+ /* acpi_get_table_with_size is not exported :( */
+ acpi_size tbl_size = 0x7fffffff;
+ UEFI_ACPI_VFCT *vfct;
+ GOP_VBIOS_CONTENT *vbios;
+ VFCT_IMAGE_HEADER *vhdr;
+
+ if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ return false;
+ if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
+ goto out_unmap;
+ }
+
+ vfct = (UEFI_ACPI_VFCT *)hdr;
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) > tbl_size) {
+ DRM_ERROR("ACPI VFCT table present but broken (too short #2)\n");
+ goto out_unmap;
+ }
+
+ vbios = (GOP_VBIOS_CONTENT *)((char *)hdr + vfct->VBIOSImageOffset);
+ vhdr = &vbios->VbiosHeader;
+ DRM_INFO("ACPI VFCT contains a BIOS for %02x:%02x.%d %04x:%04x, size %d\n",
+ vhdr->PCIBus, vhdr->PCIDevice, vhdr->PCIFunction,
+ vhdr->VendorID, vhdr->DeviceID, vhdr->ImageLength);
+
+ if (vhdr->PCIBus != rdev->pdev->bus->number ||
+ vhdr->PCIDevice != PCI_SLOT(rdev->pdev->devfn) ||
+ vhdr->PCIFunction != PCI_FUNC(rdev->pdev->devfn) ||
+ vhdr->VendorID != rdev->pdev->vendor ||
+ vhdr->DeviceID != rdev->pdev->device) {
+ DRM_INFO("ACPI VFCT table is not for this card\n");
+ goto out_unmap;
+ };
+
+ if (vfct->VBIOSImageOffset + sizeof(VFCT_IMAGE_HEADER) + vhdr->ImageLength > tbl_size) {
+ DRM_ERROR("ACPI VFCT image truncated\n");
+ goto out_unmap;
+ }
+
+ rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL);
+ ret = !!rdev->bios;
+
+out_unmap:
+ /* uh, no idea what to do here... */
+ return ret;
+}
+#else
+static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
bool radeon_get_bios(struct radeon_device *rdev)
{
@@ -484,6 +542,8 @@ bool radeon_get_bios(struct radeon_device *rdev)
r = radeon_atrm_get_bios(rdev);
if (r == false)
+ r = radeon_acpi_vfct_bios(rdev);
+ if (r == false)
r = igp_read_bios_from_vram(rdev);
if (r == false)
r = radeon_read_bios(rdev);
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size
2012-08-20 15:19 ` [PATCH 1/4] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
@ 2012-08-20 15:19 ` alexdeucher
2012-08-21 14:50 ` Alex Deucher
2012-08-20 15:19 ` [PATCH 3/4] drm/radeon: convert radeon vfct code to use acpi_get_table_with_size alexdeucher
2012-08-20 15:19 ` [PATCH 4/4] drm/radeon: split ATRM support out from the ATPX handler (v3) alexdeucher
2 siblings, 1 reply; 23+ messages in thread
From: alexdeucher @ 2012-08-20 15:19 UTC (permalink / raw)
To: airlied, dri-devel, equinox; +Cc: linux-acpi, Alex Deucher, stable
From: Alex Deucher <alexander.deucher@amd.com>
We need it in the radeon drm module to fetch
and verify the vbios image on UEFI systems.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/acpi/acpica/tbxface.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
index ea4c6d5..29e51bc 100644
--- a/drivers/acpi/acpica/tbxface.c
+++ b/drivers/acpi/acpica/tbxface.c
@@ -387,6 +387,7 @@ acpi_get_table_with_size(char *signature,
return (AE_NOT_FOUND);
}
+ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
acpi_status
acpi_get_table(char *signature,
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 3/4] drm/radeon: convert radeon vfct code to use acpi_get_table_with_size
2012-08-20 15:19 ` [PATCH 1/4] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
2012-08-20 15:19 ` [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size alexdeucher
@ 2012-08-20 15:19 ` alexdeucher
2012-08-20 15:19 ` [PATCH 4/4] drm/radeon: split ATRM support out from the ATPX handler (v3) alexdeucher
2 siblings, 0 replies; 23+ messages in thread
From: alexdeucher @ 2012-08-20 15:19 UTC (permalink / raw)
To: airlied, dri-devel, equinox; +Cc: linux-acpi, Alex Deucher, stable
From: Alex Deucher <alexander.deucher@amd.com>
Allows us to verify the table size.
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon_bios.c | 6 ++----
1 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index a32232f..ab0b2f7 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -482,13 +482,12 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
{
bool ret = false;
struct acpi_table_header *hdr;
- /* acpi_get_table_with_size is not exported :( */
- acpi_size tbl_size = 0x7fffffff;
+ acpi_size tbl_size;
UEFI_ACPI_VFCT *vfct;
GOP_VBIOS_CONTENT *vbios;
VFCT_IMAGE_HEADER *vhdr;
- if (!ACPI_SUCCESS(acpi_get_table("VFCT", 1, &hdr)))
+ if (!ACPI_SUCCESS(acpi_get_table_with_size("VFCT", 1, &hdr, &tbl_size)))
return false;
if (tbl_size < sizeof(UEFI_ACPI_VFCT)) {
DRM_ERROR("ACPI VFCT table present but broken (too short #1)\n");
@@ -525,7 +524,6 @@ static bool radeon_acpi_vfct_bios(struct radeon_device *rdev)
ret = !!rdev->bios;
out_unmap:
- /* uh, no idea what to do here... */
return ret;
}
#else
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* [PATCH 4/4] drm/radeon: split ATRM support out from the ATPX handler (v3)
2012-08-20 15:19 ` [PATCH 1/4] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
2012-08-20 15:19 ` [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size alexdeucher
2012-08-20 15:19 ` [PATCH 3/4] drm/radeon: convert radeon vfct code to use acpi_get_table_with_size alexdeucher
@ 2012-08-20 15:19 ` alexdeucher
2 siblings, 0 replies; 23+ messages in thread
From: alexdeucher @ 2012-08-20 15:19 UTC (permalink / raw)
To: airlied, dri-devel, equinox; +Cc: linux-acpi, Alex Deucher, stable
From: Alex Deucher <alexander.deucher@amd.com>
There are systems that use ATRM, but not ATPX.
Fixes:
https://bugs.freedesktop.org/show_bug.cgi?id=41265
V2: fix #ifdefs as per Greg's comments
V3: fix it harder
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Cc: stable@vger.kernel.org
---
drivers/gpu/drm/radeon/radeon.h | 15 -----
drivers/gpu/drm/radeon/radeon_atpx_handler.c | 56 +------------------
drivers/gpu/drm/radeon/radeon_bios.c | 80 ++++++++++++++++++++++++-
3 files changed, 77 insertions(+), 74 deletions(-)
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 9930419..59a1531 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -142,21 +142,6 @@ struct radeon_device;
/*
* BIOS.
*/
-#define ATRM_BIOS_PAGE 4096
-
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_atrm_supported(struct pci_dev *pdev);
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len);
-#else
-static inline bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- return false;
-}
-
-static inline int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len){
- return -EINVAL;
-}
-#endif
bool radeon_get_bios(struct radeon_device *rdev);
/*
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index 98724fc..2a2cf0b 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -30,57 +30,8 @@ static struct radeon_atpx_priv {
/* handle for device - and atpx */
acpi_handle dhandle;
acpi_handle atpx_handle;
- acpi_handle atrm_handle;
} radeon_atpx_priv;
-/* retrieve the ROM in 4k blocks */
-static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
- int offset, int len)
-{
- acpi_status status;
- union acpi_object atrm_arg_elements[2], *obj;
- struct acpi_object_list atrm_arg;
- struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
-
- atrm_arg.count = 2;
- atrm_arg.pointer = &atrm_arg_elements[0];
-
- atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[0].integer.value = offset;
-
- atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
- atrm_arg_elements[1].integer.value = len;
-
- status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
- if (ACPI_FAILURE(status)) {
- printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
- return -ENODEV;
- }
-
- obj = (union acpi_object *)buffer.pointer;
- memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
- len = obj->buffer.length;
- kfree(buffer.pointer);
- return len;
-}
-
-bool radeon_atrm_supported(struct pci_dev *pdev)
-{
- /* get the discrete ROM only via ATRM */
- if (!radeon_atpx_priv.atpx_detected)
- return false;
-
- if (radeon_atpx_priv.dhandle == DEVICE_ACPI_HANDLE(&pdev->dev))
- return false;
- return true;
-}
-
-
-int radeon_atrm_get_bios_chunk(uint8_t *bios, int offset, int len)
-{
- return radeon_atrm_call(radeon_atpx_priv.atrm_handle, bios, offset, len);
-}
-
static int radeon_atpx_get_version(acpi_handle handle)
{
acpi_status status;
@@ -198,7 +149,7 @@ static int radeon_atpx_power_state(enum vga_switcheroo_client_id id,
static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
{
- acpi_handle dhandle, atpx_handle, atrm_handle;
+ acpi_handle dhandle, atpx_handle;
acpi_status status;
dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
@@ -209,13 +160,8 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
if (ACPI_FAILURE(status))
return false;
- status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
- if (ACPI_FAILURE(status))
- return false;
-
radeon_atpx_priv.dhandle = dhandle;
radeon_atpx_priv.atpx_handle = atpx_handle;
- radeon_atpx_priv.atrm_handle = atrm_handle;
return true;
}
diff --git a/drivers/gpu/drm/radeon/radeon_bios.c b/drivers/gpu/drm/radeon/radeon_bios.c
index ab0b2f7..d306cc8 100644
--- a/drivers/gpu/drm/radeon/radeon_bios.c
+++ b/drivers/gpu/drm/radeon/radeon_bios.c
@@ -99,16 +99,81 @@ static bool radeon_read_bios(struct radeon_device *rdev)
return true;
}
+#ifdef CONFIG_ACPI
/* ATRM is used to get the BIOS on the discrete cards in
* dual-gpu systems.
*/
+/* retrieve the ROM in 4k blocks */
+#define ATRM_BIOS_PAGE 4096
+/**
+ * radeon_atrm_call - fetch a chunk of the vbios
+ *
+ * @atrm_handle: acpi ATRM handle
+ * @bios: vbios image pointer
+ * @offset: offset of vbios image data to fetch
+ * @len: length of vbios image data to fetch
+ *
+ * Executes ATRM to fetch a chunk of the discrete
+ * vbios image on PX systems (all asics).
+ * Returns the length of the buffer fetched.
+ */
+static int radeon_atrm_call(acpi_handle atrm_handle, uint8_t *bios,
+ int offset, int len)
+{
+ acpi_status status;
+ union acpi_object atrm_arg_elements[2], *obj;
+ struct acpi_object_list atrm_arg;
+ struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
+
+ atrm_arg.count = 2;
+ atrm_arg.pointer = &atrm_arg_elements[0];
+
+ atrm_arg_elements[0].type = ACPI_TYPE_INTEGER;
+ atrm_arg_elements[0].integer.value = offset;
+
+ atrm_arg_elements[1].type = ACPI_TYPE_INTEGER;
+ atrm_arg_elements[1].integer.value = len;
+
+ status = acpi_evaluate_object(atrm_handle, NULL, &atrm_arg, &buffer);
+ if (ACPI_FAILURE(status)) {
+ printk("failed to evaluate ATRM got %s\n", acpi_format_exception(status));
+ return -ENODEV;
+ }
+
+ obj = (union acpi_object *)buffer.pointer;
+ memcpy(bios+offset, obj->buffer.pointer, obj->buffer.length);
+ len = obj->buffer.length;
+ kfree(buffer.pointer);
+ return len;
+}
+
static bool radeon_atrm_get_bios(struct radeon_device *rdev)
{
int ret;
int size = 256 * 1024;
int i;
+ struct pci_dev *pdev = NULL;
+ acpi_handle dhandle, atrm_handle;
+ acpi_status status;
+ bool found = false;
- if (!radeon_atrm_supported(rdev->pdev))
+ /* ATRM is for the discrete card only */
+ if (rdev->flags & RADEON_IS_IGP)
+ return false;
+
+ while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, pdev)) != NULL) {
+ dhandle = DEVICE_ACPI_HANDLE(&pdev->dev);
+ if (!dhandle)
+ continue;
+
+ status = acpi_get_handle(dhandle, "ATRM", &atrm_handle);
+ if (!ACPI_FAILURE(status)) {
+ found = true;
+ break;
+ }
+ }
+
+ if (!found)
return false;
rdev->bios = kmalloc(size, GFP_KERNEL);
@@ -118,9 +183,10 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
for (i = 0; i < size / ATRM_BIOS_PAGE; i++) {
- ret = radeon_atrm_get_bios_chunk(rdev->bios,
- (i * ATRM_BIOS_PAGE),
- ATRM_BIOS_PAGE);
+ ret = radeon_atrm_call(atrm_handle,
+ rdev->bios,
+ (i * ATRM_BIOS_PAGE),
+ ATRM_BIOS_PAGE);
if (ret < ATRM_BIOS_PAGE)
break;
}
@@ -131,6 +197,12 @@ static bool radeon_atrm_get_bios(struct radeon_device *rdev)
}
return true;
}
+#else
+static inline bool radeon_atrm_get_bios(struct radeon_device *rdev)
+{
+ return false;
+}
+#endif
static bool ni_read_disabled_bios(struct radeon_device *rdev)
{
--
1.7.7.5
^ permalink raw reply related [flat|nested] 23+ messages in thread
* Re: [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size
2012-08-20 15:19 ` [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size alexdeucher
@ 2012-08-21 14:50 ` Alex Deucher
2012-08-21 14:51 ` Matthew Garrett
` (2 more replies)
0 siblings, 3 replies; 23+ messages in thread
From: Alex Deucher @ 2012-08-21 14:50 UTC (permalink / raw)
To: airlied, dri-devel, equinox
Cc: linux-acpi, Alex Deucher, stable, Matthew Garrett
Any objections from the ACPI folks to this patch going into 3.6 and stable?
Alex
On Mon, Aug 20, 2012 at 11:19 AM, <alexdeucher@gmail.com> wrote:
> From: Alex Deucher <alexander.deucher@amd.com>
>
> We need it in the radeon drm module to fetch
> and verify the vbios image on UEFI systems.
>
> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
> Cc: stable@vger.kernel.org
> ---
> drivers/acpi/acpica/tbxface.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
> index ea4c6d5..29e51bc 100644
> --- a/drivers/acpi/acpica/tbxface.c
> +++ b/drivers/acpi/acpica/tbxface.c
> @@ -387,6 +387,7 @@ acpi_get_table_with_size(char *signature,
>
> return (AE_NOT_FOUND);
> }
> +ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
>
> acpi_status
> acpi_get_table(char *signature,
> --
> 1.7.7.5
>
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size
2012-08-21 14:50 ` Alex Deucher
@ 2012-08-21 14:51 ` Matthew Garrett
2012-08-21 14:52 ` Matthew Garrett
2012-08-22 8:31 ` Lan Tianyu
2 siblings, 0 replies; 23+ messages in thread
From: Matthew Garrett @ 2012-08-21 14:51 UTC (permalink / raw)
To: Alex Deucher
Cc: airlied, dri-devel, equinox, linux-acpi, Alex Deucher, stable
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size
2012-08-21 14:50 ` Alex Deucher
2012-08-21 14:51 ` Matthew Garrett
@ 2012-08-21 14:52 ` Matthew Garrett
2012-08-22 8:31 ` Lan Tianyu
2 siblings, 0 replies; 23+ messages in thread
From: Matthew Garrett @ 2012-08-21 14:52 UTC (permalink / raw)
To: Alex Deucher
Cc: airlied, dri-devel, equinox, linux-acpi, Alex Deucher, stable
On Tue, Aug 21, 2012 at 10:50:35AM -0400, Alex Deucher wrote:
> Any objections from the ACPI folks to this patch going into 3.6 and stable?
Looks good to me.
--
Matthew Garrett | mjg59@srcf.ucam.org
^ permalink raw reply [flat|nested] 23+ messages in thread
* Re: [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size
2012-08-21 14:50 ` Alex Deucher
2012-08-21 14:51 ` Matthew Garrett
2012-08-21 14:52 ` Matthew Garrett
@ 2012-08-22 8:31 ` Lan Tianyu
2 siblings, 0 replies; 23+ messages in thread
From: Lan Tianyu @ 2012-08-22 8:31 UTC (permalink / raw)
To: Alex Deucher
Cc: airlied, dri-devel, equinox, linux-acpi, Alex Deucher, stable,
Matthew Garrett, feng.tang, robert.moore
2012/8/21 Alex Deucher <alexdeucher@gmail.com>:
> Any objections from the ACPI folks to this patch going into 3.6 and stable?
>
hi Alex:
I saw the patch from Feng Tang.
http://marc.info/?l=linux-acpi&m=134380363332502&w=2
which is trying to replace acpi_get_table_with_size() with
acpi_get_table(). Since the size can be get
via struct acpi_table_header->length, acpi_get_table_with_size() is
redundant and it will be removed.
> Alex
>
> On Mon, Aug 20, 2012 at 11:19 AM, <alexdeucher@gmail.com> wrote:
>> From: Alex Deucher <alexander.deucher@amd.com>
>>
>> We need it in the radeon drm module to fetch
>> and verify the vbios image on UEFI systems.
>>
>> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
>> Cc: stable@vger.kernel.org
>> ---
>> drivers/acpi/acpica/tbxface.c | 1 +
>> 1 files changed, 1 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/acpi/acpica/tbxface.c b/drivers/acpi/acpica/tbxface.c
>> index ea4c6d5..29e51bc 100644
>> --- a/drivers/acpi/acpica/tbxface.c
>> +++ b/drivers/acpi/acpica/tbxface.c
>> @@ -387,6 +387,7 @@ acpi_get_table_with_size(char *signature,
>>
>> return (AE_NOT_FOUND);
>> }
>> +ACPI_EXPORT_SYMBOL(acpi_get_table_with_size)
>>
>> acpi_status
>> acpi_get_table(char *signature,
>> --
>> 1.7.7.5
>>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Best regards
Tianyu Lan
^ permalink raw reply [flat|nested] 23+ messages in thread
end of thread, other threads:[~2012-08-22 8:31 UTC | newest]
Thread overview: 23+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-08-16 17:54 [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch alexdeucher
2012-08-16 17:54 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler alexdeucher
2012-08-16 18:26 ` Greg KH
2012-08-16 18:25 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch Jerome Glisse
2012-08-16 18:25 ` Greg KH
2012-08-16 19:13 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) alexdeucher
2012-08-16 19:13 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v2) alexdeucher
2012-08-16 19:25 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) Greg KH
2012-08-16 19:38 ` Alex Deucher
2012-08-16 19:48 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
2012-08-16 19:48 ` [PATCH 2/2] drm/radeon: split ATRM support out from the ATPX handler (v3) alexdeucher
2012-08-16 19:40 ` [PATCH 1/2] drm/radeon: implement ACPI VFCT vbios fetch (v2) David Lamparter
2012-08-16 19:51 ` Alex Deucher
2012-08-17 16:56 ` Alex Deucher
2012-08-17 17:03 ` Matthew Garrett
2012-08-20 15:19 ` [PATCH 1/4] drm/radeon: implement ACPI VFCT vbios fetch (v3) alexdeucher
2012-08-20 15:19 ` [PATCH 2/4] ACPI: export symbol acpi_get_table_with_size alexdeucher
2012-08-21 14:50 ` Alex Deucher
2012-08-21 14:51 ` Matthew Garrett
2012-08-21 14:52 ` Matthew Garrett
2012-08-22 8:31 ` Lan Tianyu
2012-08-20 15:19 ` [PATCH 3/4] drm/radeon: convert radeon vfct code to use acpi_get_table_with_size alexdeucher
2012-08-20 15:19 ` [PATCH 4/4] drm/radeon: split ATRM support out from the ATPX handler (v3) alexdeucher
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox