Last active
August 29, 2015 14:05
-
-
Save nonakap/3f23a166d0bcda3b302d to your computer and use it in GitHub Desktop.
NetBSD/amd64 DRMKMS with my patch on ThinkPad X121e (AMD)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Index: sys/external/bsd/drm2/radeon/radeondrmkmsfb.c | |
| =================================================================== | |
| RCS file: /cvsroot/src/sys/external/bsd/drm2/radeon/radeondrmkmsfb.c,v | |
| retrieving revision 1.3 | |
| diff -u -r1.3 radeondrmkmsfb.c | |
| --- sys/external/bsd/drm2/radeon/radeondrmkmsfb.c 26 Jul 2014 07:02:13 -0000 1.3 | |
| +++ sys/external/bsd/drm2/radeon/radeondrmkmsfb.c 9 Aug 2014 03:48:19 -0000 | |
| @@ -165,8 +165,13 @@ | |
| prop_dictionary_set_uint32(dict, "width", sizes->fb_width); | |
| prop_dictionary_set_uint32(dict, "height", sizes->fb_height); | |
| prop_dictionary_set_uint8(dict, "depth", sizes->surface_bpp); | |
| +#if 1 /* XXXNONAKA */ | |
| + prop_dictionary_set_uint16(dict, "linebytes", | |
| + roundup2(sizes->fb_width, 64) * howmany(sizes->surface_bpp, 8)); | |
| +#else | |
| prop_dictionary_set_uint16(dict, "linebytes", | |
| roundup2((sizes->fb_width * howmany(sizes->surface_bpp, 8)), 64)); | |
| +#endif | |
| prop_dictionary_set_uint32(dict, "address", 0); /* XXX >32-bit */ | |
| CTASSERT(sizeof(uintptr_t) <= sizeof(uint64_t)); | |
| prop_dictionary_set_uint64(dict, "virtual_address", | |
| Index: sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c | |
| =================================================================== | |
| RCS file: /cvsroot/src/sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c,v | |
| retrieving revision 1.2 | |
| diff -u -r1.2 radeon_bios.c | |
| --- sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c 16 Jul 2014 20:59:57 -0000 1.2 | |
| +++ sys/external/bsd/drm2/dist/drm/radeon/radeon_bios.c 9 Aug 2014 03:48:19 -0000 | |
| @@ -34,6 +34,18 @@ | |
| #include <linux/slab.h> | |
| #include <linux/acpi.h> | |
| #include <linux/string.h> | |
| + | |
| +#if defined(__NetBSD__) && (defined(i386) || defined(amd64)) | |
| +#include <dev/isa/isareg.h> | |
| +#include <dev/isa/isavar.h> | |
| + | |
| +#include "acpica.h" | |
| +#if NACPICA > 0 | |
| +#include <dev/acpi/acpireg.h> | |
| +#include <dev/acpi/acpivar.h> | |
| +#endif /* NACPICA > 0 */ | |
| +#endif /* __NetBSD__ && (i386 || amd64) */ | |
| + | |
| /* | |
| * BIOS. | |
| */ | |
| @@ -50,6 +62,7 @@ | |
| bus_space_tag_t bst; | |
| bus_space_handle_t bsh; | |
| bus_size_t size; | |
| + bus_size_t mapsize = 256 * 1024; | |
| #else | |
| uint8_t __iomem *bios; | |
| resource_size_t vram_base; | |
| @@ -68,15 +81,14 @@ | |
| rdev->pdev->pd_pa.pa_tag, PCI_BAR(0)), | |
| 0, &bst, &bsh, NULL, &size)) | |
| return false; | |
| - if ((size == 0) || | |
| - (size < 256 * 1024) || | |
| + if ((size < mapsize) || | |
| (bus_space_read_1(bst, bsh, 0) != 0x55) || | |
| (bus_space_read_1(bst, bsh, 1) != 0xaa) || | |
| - ((rdev = kmalloc(size, GFP_KERNEL)) != NULL)) { | |
| + ((rdev = kmalloc(mapsize, GFP_KERNEL)) != NULL)) { | |
| bus_space_unmap(bst, bsh, size); | |
| return false; | |
| } | |
| - bus_space_read_region_1(bst, bsh, 0, rdev->bios, size); | |
| + bus_space_read_region_1(bst, bsh, 0, rdev->bios, mapsize); | |
| bus_space_unmap(bst, bsh, size); | |
| #else | |
| vram_base = pci_resource_start(rdev->pdev, 0); | |
| @@ -129,14 +141,42 @@ | |
| return true; | |
| } | |
| -#ifdef __NetBSD__ | |
| -#undef __iomem | |
| -#endif | |
| - | |
| static bool radeon_read_platform_bios(struct radeon_device *rdev) | |
| { | |
| #ifdef __NetBSD__ /* XXX radeon platform bios */ | |
| +#if defined(i386) || defined(amd64) | |
| + uint8_t __iomem *bios; | |
| + bus_size_t size = 256 * 1024; /* ??? */ | |
| + uint8_t *found = NULL; | |
| + int i; | |
| + | |
| + if (!(rdev->flags & RADEON_IS_IGP)) | |
| + if (!radeon_card_posted(rdev)) | |
| + return false; | |
| + | |
| + rdev->bios = NULL; | |
| + bios = (u8 *)ISA_HOLE_VADDR(0xc0000); | |
| + for (i = 0; i + 2 < size; i++) { | |
| + if (bios[i] == 0x55 && bios[i + 1] == 0xaa) { | |
| + found = bios + i; | |
| + break; | |
| + } | |
| + | |
| + } | |
| + if (found == NULL) { | |
| + DRM_ERROR("bios size zero or checksum mismatch\n"); | |
| + return false; | |
| + } | |
| + | |
| + rdev->bios = kmalloc(size, GFP_KERNEL); | |
| + if (rdev->bios == NULL) | |
| + return false; | |
| + | |
| + memcpy(rdev->bios, found, size); | |
| + return true; | |
| +#else | |
| return false; | |
| +#endif | |
| #else | |
| uint8_t __iomem *bios; | |
| size_t size; | |
| @@ -160,6 +200,10 @@ | |
| #endif | |
| } | |
| +#ifdef __NetBSD__ | |
| +#undef __iomem | |
| +#endif | |
| + | |
| /* XXX radeon acpi */ | |
| #ifdef CONFIG_ACPI | |
| /* ATRM is used to get the BIOS on the discrete cards in | |
| @@ -678,6 +722,54 @@ | |
| out_unmap: | |
| return ret; | |
| } | |
| +#elif defined(__NetBSD__) && (NACPICA > 0) | |
| +static bool radeon_acpi_vfct_bios(struct radeon_device *rdev) | |
| +{ | |
| + bool ret = false; | |
| + struct acpi_table_header *hdr; | |
| + UEFI_ACPI_VFCT *vfct; | |
| + GOP_VBIOS_CONTENT *vbios; | |
| + VFCT_IMAGE_HEADER *vhdr; | |
| + | |
| + if (!ACPI_SUCCESS(AcpiGetTable("VFCT", 1, &hdr))) | |
| + return false; | |
| + if (hdr->Length < 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) > hdr->Length) { | |
| + 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 > hdr->Length) { | |
| + DRM_ERROR("ACPI VFCT image truncated\n"); | |
| + goto out_unmap; | |
| + } | |
| + | |
| + rdev->bios = kmemdup(&vbios->VbiosContent, vhdr->ImageLength, GFP_KERNEL); | |
| + ret = !!rdev->bios; | |
| + | |
| +out_unmap: | |
| + return ret; | |
| +} | |
| #else | |
| static inline bool radeon_acpi_vfct_bios(struct radeon_device *rdev) | |
| { | |
| @@ -697,12 +789,10 @@ | |
| r = igp_read_bios_from_vram(rdev); | |
| if (r == false) | |
| r = radeon_read_bios(rdev); | |
| - if (r == false) { | |
| + if (r == false) | |
| r = radeon_read_disabled_bios(rdev); | |
| - } | |
| - if (r == false) { | |
| + if (r == false) | |
| r = radeon_read_platform_bios(rdev); | |
| - } | |
| if (r == false || rdev->bios == NULL) { | |
| DRM_ERROR("Unable to locate a BIOS ROM\n"); | |
| rdev->bios = NULL; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment