mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-22 01:10:28 +00:00
drm/radeon: properly validate the atpx interface
Some bioses don't set the function mask correctly which caused required functions to be disabled. Fixes: https://bugzilla.kernel.org/show_bug.cgi?id=53111 Signed-off-by: Alex Deucher <alexander.deucher@amd.com> Cc: stable@vger.kernel.org
This commit is contained in:
parent
d041889414
commit
43a23aa450
@ -43,6 +43,12 @@ struct atpx_verify_interface {
|
||||
u32 function_bits; /* supported functions bit vector */
|
||||
} __packed;
|
||||
|
||||
struct atpx_px_params {
|
||||
u16 size; /* structure size in bytes (includes size field) */
|
||||
u32 valid_flags; /* which flags are valid */
|
||||
u32 flags; /* flags */
|
||||
} __packed;
|
||||
|
||||
struct atpx_power_control {
|
||||
u16 size;
|
||||
u8 dgpu_state;
|
||||
@ -122,10 +128,62 @@ static void radeon_atpx_parse_functions(struct radeon_atpx_functions *f, u32 mas
|
||||
f->disp_detetion_ports = mask & ATPX_GET_DISPLAY_DETECTION_PORTS_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_atpx_validate_functions - validate ATPX functions
|
||||
*
|
||||
* @atpx: radeon atpx struct
|
||||
*
|
||||
* Validate that required functions are enabled (all asics).
|
||||
* returns 0 on success, error on failure.
|
||||
*/
|
||||
static int radeon_atpx_validate(struct radeon_atpx *atpx)
|
||||
{
|
||||
/* make sure required functions are enabled */
|
||||
/* dGPU power control is required */
|
||||
atpx->functions.power_cntl = true;
|
||||
|
||||
if (atpx->functions.px_params) {
|
||||
union acpi_object *info;
|
||||
struct atpx_px_params output;
|
||||
size_t size;
|
||||
u32 valid_bits;
|
||||
|
||||
info = radeon_atpx_call(atpx->handle, ATPX_FUNCTION_GET_PX_PARAMETERS, NULL);
|
||||
if (!info)
|
||||
return -EIO;
|
||||
|
||||
memset(&output, 0, sizeof(output));
|
||||
|
||||
size = *(u16 *) info->buffer.pointer;
|
||||
if (size < 10) {
|
||||
printk("ATPX buffer is too small: %zu\n", size);
|
||||
kfree(info);
|
||||
return -EINVAL;
|
||||
}
|
||||
size = min(sizeof(output), size);
|
||||
|
||||
memcpy(&output, info->buffer.pointer, size);
|
||||
|
||||
valid_bits = output.flags & output.valid_flags;
|
||||
/* if separate mux flag is set, mux controls are required */
|
||||
if (valid_bits & ATPX_SEPARATE_MUX_FOR_I2C) {
|
||||
atpx->functions.i2c_mux_cntl = true;
|
||||
atpx->functions.disp_mux_cntl = true;
|
||||
}
|
||||
/* if any outputs are muxed, mux controls are required */
|
||||
if (valid_bits & (ATPX_CRT1_RGB_SIGNAL_MUXED |
|
||||
ATPX_TV_SIGNAL_MUXED |
|
||||
ATPX_DFP_SIGNAL_MUXED))
|
||||
atpx->functions.disp_mux_cntl = true;
|
||||
|
||||
kfree(info);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* radeon_atpx_verify_interface - verify ATPX
|
||||
*
|
||||
* @handle: acpi handle
|
||||
* @atpx: radeon atpx struct
|
||||
*
|
||||
* Execute the ATPX_FUNCTION_VERIFY_INTERFACE ATPX function
|
||||
@ -406,8 +464,19 @@ static bool radeon_atpx_pci_probe_handle(struct pci_dev *pdev)
|
||||
*/
|
||||
static int radeon_atpx_init(void)
|
||||
{
|
||||
int r;
|
||||
|
||||
/* set up the ATPX handle */
|
||||
return radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
|
||||
r = radeon_atpx_verify_interface(&radeon_atpx_priv.atpx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
/* validate the atpx setup */
|
||||
r = radeon_atpx_validate(&radeon_atpx_priv.atpx);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user