forked from Minki/linux
drm/nouveau/bios: move ACPI _ROM handling
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
2dd4d163cd
commit
b950c8c5d0
@ -49,7 +49,6 @@ static struct nouveau_dsm_priv {
|
||||
bool optimus_flags_detected;
|
||||
bool optimus_skip_dsm;
|
||||
acpi_handle dhandle;
|
||||
acpi_handle rom_handle;
|
||||
} nouveau_dsm_priv;
|
||||
|
||||
bool nouveau_is_optimus(void) {
|
||||
@ -385,59 +384,6 @@ void nouveau_unregister_dsm_handler(void) {}
|
||||
void nouveau_switcheroo_optimus_dsm(void) {}
|
||||
#endif
|
||||
|
||||
/* retrieve the ROM in 4k blocks */
|
||||
static int nouveau_rom_call(acpi_handle rom_handle, uint8_t *bios,
|
||||
int offset, int len)
|
||||
{
|
||||
acpi_status status;
|
||||
union acpi_object rom_arg_elements[2], *obj;
|
||||
struct acpi_object_list rom_arg;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
|
||||
|
||||
rom_arg.count = 2;
|
||||
rom_arg.pointer = &rom_arg_elements[0];
|
||||
|
||||
rom_arg_elements[0].type = ACPI_TYPE_INTEGER;
|
||||
rom_arg_elements[0].integer.value = offset;
|
||||
|
||||
rom_arg_elements[1].type = ACPI_TYPE_INTEGER;
|
||||
rom_arg_elements[1].integer.value = len;
|
||||
|
||||
status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_info("failed to evaluate ROM got %s\n",
|
||||
acpi_format_exception(status));
|
||||
return -ENODEV;
|
||||
}
|
||||
obj = (union acpi_object *)buffer.pointer;
|
||||
len = min(len, (int)obj->buffer.length);
|
||||
memcpy(bios+offset, obj->buffer.pointer, len);
|
||||
kfree(buffer.pointer);
|
||||
return len;
|
||||
}
|
||||
|
||||
bool nouveau_acpi_rom_supported(struct device *dev)
|
||||
{
|
||||
acpi_status status;
|
||||
acpi_handle dhandle, rom_handle;
|
||||
|
||||
dhandle = ACPI_HANDLE(dev);
|
||||
if (!dhandle)
|
||||
return false;
|
||||
|
||||
status = acpi_get_handle(dhandle, "_ROM", &rom_handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return false;
|
||||
|
||||
nouveau_dsm_priv.rom_handle = rom_handle;
|
||||
return true;
|
||||
}
|
||||
|
||||
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
|
||||
{
|
||||
return nouveau_rom_call(nouveau_dsm_priv.rom_handle, bios, offset, len);
|
||||
}
|
||||
|
||||
void *
|
||||
nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector)
|
||||
{
|
||||
|
@ -10,8 +10,6 @@ bool nouveau_is_v1_dsm(void);
|
||||
void nouveau_register_dsm_handler(void);
|
||||
void nouveau_unregister_dsm_handler(void);
|
||||
void nouveau_switcheroo_optimus_dsm(void);
|
||||
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
|
||||
bool nouveau_acpi_rom_supported(struct device *);
|
||||
void *nouveau_acpi_edid(struct drm_device *, struct drm_connector *);
|
||||
#else
|
||||
static inline bool nouveau_is_optimus(void) { return false; };
|
||||
@ -19,8 +17,6 @@ static inline bool nouveau_is_v1_dsm(void) { return false; };
|
||||
static inline void nouveau_register_dsm_handler(void) {}
|
||||
static inline void nouveau_unregister_dsm_handler(void) {}
|
||||
static inline void nouveau_switcheroo_optimus_dsm(void) {}
|
||||
static inline bool nouveau_acpi_rom_supported(struct device *dev) { return false; }
|
||||
static inline int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) { return -EINVAL; }
|
||||
static inline void *nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) { return NULL; }
|
||||
#endif
|
||||
|
||||
|
@ -22,22 +22,39 @@
|
||||
*/
|
||||
#include "priv.h"
|
||||
|
||||
static int
|
||||
acpi_read_bios(acpi_handle rom_handle, u8 *bios, u32 offset, u32 length)
|
||||
{
|
||||
#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
|
||||
int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
|
||||
bool nouveau_acpi_rom_supported(struct device *);
|
||||
#else
|
||||
static inline bool
|
||||
nouveau_acpi_rom_supported(struct device *dev)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
acpi_status status;
|
||||
union acpi_object rom_arg_elements[2], *obj;
|
||||
struct acpi_object_list rom_arg;
|
||||
struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL};
|
||||
|
||||
static inline int
|
||||
nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
|
||||
{
|
||||
rom_arg.count = 2;
|
||||
rom_arg.pointer = &rom_arg_elements[0];
|
||||
|
||||
rom_arg_elements[0].type = ACPI_TYPE_INTEGER;
|
||||
rom_arg_elements[0].integer.value = offset;
|
||||
|
||||
rom_arg_elements[1].type = ACPI_TYPE_INTEGER;
|
||||
rom_arg_elements[1].integer.value = length;
|
||||
|
||||
status = acpi_evaluate_object(rom_handle, NULL, &rom_arg, &buffer);
|
||||
if (ACPI_FAILURE(status)) {
|
||||
pr_info("failed to evaluate ROM got %s\n",
|
||||
acpi_format_exception(status));
|
||||
return -ENODEV;
|
||||
}
|
||||
obj = (union acpi_object *)buffer.pointer;
|
||||
length = min(length, obj->buffer.length);
|
||||
memcpy(bios+offset, obj->buffer.pointer, length);
|
||||
kfree(buffer.pointer);
|
||||
return length;
|
||||
#else
|
||||
return -EINVAL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* This version of the shadow function disobeys the ACPI spec and tries
|
||||
* to fetch in units of more than 4KiB at a time. This is a LOT faster
|
||||
@ -51,7 +68,7 @@ acpi_read_fast(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
|
||||
u32 fetch = limit - start;
|
||||
|
||||
if (nvbios_extend(bios, limit) >= 0) {
|
||||
int ret = nouveau_acpi_get_bios_chunk(bios->data, start, fetch);
|
||||
int ret = acpi_read_bios(data, bios->data, start, fetch);
|
||||
if (ret == fetch)
|
||||
return fetch;
|
||||
}
|
||||
@ -73,9 +90,8 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
|
||||
|
||||
if (nvbios_extend(bios, limit) >= 0) {
|
||||
while (start + fetch < limit) {
|
||||
int ret = nouveau_acpi_get_bios_chunk(bios->data,
|
||||
start + fetch,
|
||||
0x1000);
|
||||
int ret = acpi_read_bios(data, bios->data,
|
||||
start + fetch, 0x1000);
|
||||
if (ret != 0x1000)
|
||||
break;
|
||||
fetch += 0x1000;
|
||||
@ -88,9 +104,22 @@ acpi_read_slow(void *data, u32 offset, u32 length, struct nvkm_bios *bios)
|
||||
static void *
|
||||
acpi_init(struct nvkm_bios *bios, const char *name)
|
||||
{
|
||||
if (!nouveau_acpi_rom_supported(bios->subdev.device->dev))
|
||||
#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
|
||||
acpi_status status;
|
||||
acpi_handle dhandle, rom_handle;
|
||||
|
||||
dhandle = ACPI_HANDLE(bios->subdev.device->dev);
|
||||
if (!dhandle)
|
||||
return ERR_PTR(-ENODEV);
|
||||
return NULL;
|
||||
|
||||
status = acpi_get_handle(dhandle, "_ROM", &rom_handle);
|
||||
if (ACPI_FAILURE(status))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return rom_handle;
|
||||
#else
|
||||
return ERR_PTR(-ENODEV);
|
||||
#endif
|
||||
}
|
||||
|
||||
const struct nvbios_source
|
||||
|
Loading…
Reference in New Issue
Block a user