Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/radeon: implement radeon_atif_verify_interface

Wrap the call to VERIFY_INTERFACE and add the parsing of the support
vectors.
v2: use a packed struct for handling the output of ACPI calls, hides
ugly pointer arithmetics (Lee, Chun-Yi <jlee@suse.com>).
v3: fix radeon_atif_parse_functions handling (Alex Deucher)

Signed-off-by: Luca Tettamanti <kronos.it@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Luca Tettamanti and committed by
Alex Deucher
fd64ca8a 86504672

+113 -6
+40
drivers/gpu/drm/radeon/radeon.h
··· 1424 1424 u64 gpu_addr; 1425 1425 }; 1426 1426 1427 + /* 1428 + * ACPI 1429 + */ 1430 + struct radeon_atif_notification_cfg { 1431 + bool enabled; 1432 + int command_code; 1433 + }; 1434 + 1435 + struct radeon_atif_notifications { 1436 + bool display_switch; 1437 + bool expansion_mode_change; 1438 + bool thermal_state; 1439 + bool forced_power_state; 1440 + bool system_power_state; 1441 + bool display_conf_change; 1442 + bool px_gfx_switch; 1443 + bool brightness_change; 1444 + bool dgpu_display_event; 1445 + }; 1446 + 1447 + struct radeon_atif_functions { 1448 + bool system_params; 1449 + bool sbios_requests; 1450 + bool select_active_disp; 1451 + bool lid_state; 1452 + bool get_tv_standard; 1453 + bool set_tv_standard; 1454 + bool get_panel_expansion_mode; 1455 + bool set_panel_expansion_mode; 1456 + bool temperature_change; 1457 + bool graphics_device_types; 1458 + }; 1459 + 1460 + struct radeon_atif { 1461 + struct radeon_atif_notifications notifications; 1462 + struct radeon_atif_functions functions; 1463 + struct radeon_atif_notification_cfg notification_cfg; 1464 + }; 1427 1465 1428 1466 /* 1429 1467 * Core structure, functions and helpers. ··· 1554 1516 /* virtual memory */ 1555 1517 struct radeon_vm_manager vm_manager; 1556 1518 struct mutex gpu_clock_mutex; 1519 + /* ACPI interface */ 1520 + struct radeon_atif atif; 1557 1521 }; 1558 1522 1559 1523 int radeon_device_init(struct radeon_device *rdev,
+73 -6
drivers/gpu/drm/radeon/radeon_acpi.c
··· 36 36 37 37 #include <linux/vga_switcheroo.h> 38 38 39 + struct atif_verify_interface { 40 + u16 size; /* structure size in bytes (includes size field) */ 41 + u16 version; /* version */ 42 + u32 notification_mask; /* supported notifications mask */ 43 + u32 function_bits; /* supported functions bit vector */ 44 + } __packed; 45 + 39 46 /* Call the ATIF method 40 47 */ 41 48 static union acpi_object *radeon_atif_call(acpi_handle handle, int function, ··· 82 75 return buffer.pointer; 83 76 } 84 77 78 + static void radeon_atif_parse_notification(struct radeon_atif_notifications *n, u32 mask) 79 + { 80 + n->display_switch = mask & ATIF_DISPLAY_SWITCH_REQUEST_SUPPORTED; 81 + n->expansion_mode_change = mask & ATIF_EXPANSION_MODE_CHANGE_REQUEST_SUPPORTED; 82 + n->thermal_state = mask & ATIF_THERMAL_STATE_CHANGE_REQUEST_SUPPORTED; 83 + n->forced_power_state = mask & ATIF_FORCED_POWER_STATE_CHANGE_REQUEST_SUPPORTED; 84 + n->system_power_state = mask & ATIF_SYSTEM_POWER_SOURCE_CHANGE_REQUEST_SUPPORTED; 85 + n->display_conf_change = mask & ATIF_DISPLAY_CONF_CHANGE_REQUEST_SUPPORTED; 86 + n->px_gfx_switch = mask & ATIF_PX_GFX_SWITCH_REQUEST_SUPPORTED; 87 + n->brightness_change = mask & ATIF_PANEL_BRIGHTNESS_CHANGE_REQUEST_SUPPORTED; 88 + n->dgpu_display_event = mask & ATIF_DGPU_DISPLAY_EVENT_SUPPORTED; 89 + } 90 + 91 + static void radeon_atif_parse_functions(struct radeon_atif_functions *f, u32 mask) 92 + { 93 + f->system_params = mask & ATIF_GET_SYSTEM_PARAMETERS_SUPPORTED; 94 + f->sbios_requests = mask & ATIF_GET_SYSTEM_BIOS_REQUESTS_SUPPORTED; 95 + f->select_active_disp = mask & ATIF_SELECT_ACTIVE_DISPLAYS_SUPPORTED; 96 + f->lid_state = mask & ATIF_GET_LID_STATE_SUPPORTED; 97 + f->get_tv_standard = mask & ATIF_GET_TV_STANDARD_FROM_CMOS_SUPPORTED; 98 + f->set_tv_standard = mask & ATIF_SET_TV_STANDARD_IN_CMOS_SUPPORTED; 99 + f->get_panel_expansion_mode = mask & ATIF_GET_PANEL_EXPANSION_MODE_FROM_CMOS_SUPPORTED; 100 + f->set_panel_expansion_mode = mask & ATIF_SET_PANEL_EXPANSION_MODE_IN_CMOS_SUPPORTED; 101 + f->temperature_change = mask & ATIF_TEMPERATURE_CHANGE_NOTIFICATION_SUPPORTED; 102 + f->graphics_device_types = mask & ATIF_GET_GRAPHICS_DEVICE_TYPES_SUPPORTED; 103 + } 104 + 105 + static int radeon_atif_verify_interface(acpi_handle handle, 106 + struct radeon_atif *atif) 107 + { 108 + union acpi_object *info; 109 + struct atif_verify_interface output; 110 + size_t size; 111 + int err = 0; 112 + 113 + info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); 114 + if (!info) 115 + return -EIO; 116 + 117 + memset(&output, 0, sizeof(output)); 118 + 119 + size = *(u16 *) info->buffer.pointer; 120 + if (size < 12) { 121 + DRM_INFO("ATIF buffer is too small: %lu\n", size); 122 + err = -EINVAL; 123 + goto out; 124 + } 125 + size = min(sizeof(output), size); 126 + 127 + memcpy(&output, info->buffer.pointer, size); 128 + 129 + /* TODO: check version? */ 130 + DRM_DEBUG_DRIVER("ATIF version %u\n", output.version); 131 + 132 + radeon_atif_parse_notification(&atif->notifications, output.notification_mask); 133 + radeon_atif_parse_functions(&atif->functions, output.function_bits); 134 + 135 + out: 136 + kfree(info); 137 + return err; 138 + } 139 + 85 140 /* Call all ACPI methods here */ 86 141 int radeon_acpi_init(struct radeon_device *rdev) 87 142 { 88 143 acpi_handle handle; 89 - union acpi_object *info; 90 - int ret = 0; 144 + int ret; 91 145 92 146 /* Get the device handle */ 93 147 handle = DEVICE_ACPI_HANDLE(&rdev->pdev->dev); ··· 158 90 return 0; 159 91 160 92 /* Call the ATIF method */ 161 - info = radeon_atif_call(handle, ATIF_FUNCTION_VERIFY_INTERFACE, NULL); 162 - if (!info) 163 - ret = -EIO; 93 + ret = radeon_atif_verify_interface(handle, &rdev->atif); 94 + if (ret) 95 + DRM_DEBUG_DRIVER("Call to verify_interface failed: %d\n", ret); 164 96 165 - kfree(info); 166 97 return ret; 167 98 } 168 99