diff options
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 550 |
1 files changed, 9 insertions, 541 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 4466f3535e2d..71a57b2f7f04 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
@@ -24,12 +24,10 @@ | |||
24 | #include <linux/list.h> | 24 | #include <linux/list.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/pci.h> | 26 | #include <linux/pci.h> |
27 | #include <linux/acpi.h> | ||
28 | #include <drm/drmP.h> | 27 | #include <drm/drmP.h> |
29 | #include <linux/firmware.h> | 28 | #include <linux/firmware.h> |
30 | #include <drm/amdgpu_drm.h> | 29 | #include <drm/amdgpu_drm.h> |
31 | #include "amdgpu.h" | 30 | #include "amdgpu.h" |
32 | #include "cgs_linux.h" | ||
33 | #include "atom.h" | 31 | #include "atom.h" |
34 | #include "amdgpu_ucode.h" | 32 | #include "amdgpu_ucode.h" |
35 | 33 | ||
@@ -42,152 +40,6 @@ struct amdgpu_cgs_device { | |||
42 | struct amdgpu_device *adev = \ | 40 | struct amdgpu_device *adev = \ |
43 | ((struct amdgpu_cgs_device *)cgs_device)->adev | 41 | ((struct amdgpu_cgs_device *)cgs_device)->adev |
44 | 42 | ||
45 | static void *amdgpu_cgs_register_pp_handle(struct cgs_device *cgs_device, | ||
46 | int (*call_back_func)(struct amd_pp_init *, void **)) | ||
47 | { | ||
48 | CGS_FUNC_ADEV; | ||
49 | struct amd_pp_init pp_init; | ||
50 | struct amd_powerplay *amd_pp; | ||
51 | |||
52 | if (call_back_func == NULL) | ||
53 | return NULL; | ||
54 | |||
55 | amd_pp = &(adev->powerplay); | ||
56 | pp_init.chip_family = adev->family; | ||
57 | pp_init.chip_id = adev->asic_type; | ||
58 | pp_init.pm_en = (amdgpu_dpm != 0 && !amdgpu_sriov_vf(adev)) ? true : false; | ||
59 | pp_init.feature_mask = amdgpu_pp_feature_mask; | ||
60 | pp_init.device = cgs_device; | ||
61 | if (call_back_func(&pp_init, &(amd_pp->pp_handle))) | ||
62 | return NULL; | ||
63 | |||
64 | return adev->powerplay.pp_handle; | ||
65 | } | ||
66 | |||
67 | static int amdgpu_cgs_alloc_gpu_mem(struct cgs_device *cgs_device, | ||
68 | enum cgs_gpu_mem_type type, | ||
69 | uint64_t size, uint64_t align, | ||
70 | cgs_handle_t *handle) | ||
71 | { | ||
72 | CGS_FUNC_ADEV; | ||
73 | uint16_t flags = 0; | ||
74 | int ret = 0; | ||
75 | uint32_t domain = 0; | ||
76 | struct amdgpu_bo *obj; | ||
77 | |||
78 | /* fail if the alignment is not a power of 2 */ | ||
79 | if (((align != 1) && (align & (align - 1))) | ||
80 | || size == 0 || align == 0) | ||
81 | return -EINVAL; | ||
82 | |||
83 | |||
84 | switch(type) { | ||
85 | case CGS_GPU_MEM_TYPE__VISIBLE_CONTIG_FB: | ||
86 | case CGS_GPU_MEM_TYPE__VISIBLE_FB: | ||
87 | flags = AMDGPU_GEM_CREATE_CPU_ACCESS_REQUIRED | | ||
88 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; | ||
89 | domain = AMDGPU_GEM_DOMAIN_VRAM; | ||
90 | break; | ||
91 | case CGS_GPU_MEM_TYPE__INVISIBLE_CONTIG_FB: | ||
92 | case CGS_GPU_MEM_TYPE__INVISIBLE_FB: | ||
93 | flags = AMDGPU_GEM_CREATE_NO_CPU_ACCESS | | ||
94 | AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS; | ||
95 | domain = AMDGPU_GEM_DOMAIN_VRAM; | ||
96 | break; | ||
97 | case CGS_GPU_MEM_TYPE__GART_CACHEABLE: | ||
98 | domain = AMDGPU_GEM_DOMAIN_GTT; | ||
99 | break; | ||
100 | case CGS_GPU_MEM_TYPE__GART_WRITECOMBINE: | ||
101 | flags = AMDGPU_GEM_CREATE_CPU_GTT_USWC; | ||
102 | domain = AMDGPU_GEM_DOMAIN_GTT; | ||
103 | break; | ||
104 | default: | ||
105 | return -EINVAL; | ||
106 | } | ||
107 | |||
108 | |||
109 | *handle = 0; | ||
110 | |||
111 | ret = amdgpu_bo_create(adev, size, align, true, domain, flags, | ||
112 | NULL, NULL, 0, &obj); | ||
113 | if (ret) { | ||
114 | DRM_ERROR("(%d) bo create failed\n", ret); | ||
115 | return ret; | ||
116 | } | ||
117 | *handle = (cgs_handle_t)obj; | ||
118 | |||
119 | return ret; | ||
120 | } | ||
121 | |||
122 | static int amdgpu_cgs_free_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle) | ||
123 | { | ||
124 | struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; | ||
125 | |||
126 | if (obj) { | ||
127 | int r = amdgpu_bo_reserve(obj, true); | ||
128 | if (likely(r == 0)) { | ||
129 | amdgpu_bo_kunmap(obj); | ||
130 | amdgpu_bo_unpin(obj); | ||
131 | amdgpu_bo_unreserve(obj); | ||
132 | } | ||
133 | amdgpu_bo_unref(&obj); | ||
134 | |||
135 | } | ||
136 | return 0; | ||
137 | } | ||
138 | |||
139 | static int amdgpu_cgs_gmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle, | ||
140 | uint64_t *mcaddr) | ||
141 | { | ||
142 | int r; | ||
143 | struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; | ||
144 | |||
145 | WARN_ON_ONCE(obj->placement.num_placement > 1); | ||
146 | |||
147 | r = amdgpu_bo_reserve(obj, true); | ||
148 | if (unlikely(r != 0)) | ||
149 | return r; | ||
150 | r = amdgpu_bo_pin(obj, obj->preferred_domains, mcaddr); | ||
151 | amdgpu_bo_unreserve(obj); | ||
152 | return r; | ||
153 | } | ||
154 | |||
155 | static int amdgpu_cgs_gunmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle) | ||
156 | { | ||
157 | int r; | ||
158 | struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; | ||
159 | r = amdgpu_bo_reserve(obj, true); | ||
160 | if (unlikely(r != 0)) | ||
161 | return r; | ||
162 | r = amdgpu_bo_unpin(obj); | ||
163 | amdgpu_bo_unreserve(obj); | ||
164 | return r; | ||
165 | } | ||
166 | |||
167 | static int amdgpu_cgs_kmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle, | ||
168 | void **map) | ||
169 | { | ||
170 | int r; | ||
171 | struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; | ||
172 | r = amdgpu_bo_reserve(obj, true); | ||
173 | if (unlikely(r != 0)) | ||
174 | return r; | ||
175 | r = amdgpu_bo_kmap(obj, map); | ||
176 | amdgpu_bo_unreserve(obj); | ||
177 | return r; | ||
178 | } | ||
179 | |||
180 | static int amdgpu_cgs_kunmap_gpu_mem(struct cgs_device *cgs_device, cgs_handle_t handle) | ||
181 | { | ||
182 | int r; | ||
183 | struct amdgpu_bo *obj = (struct amdgpu_bo *)handle; | ||
184 | r = amdgpu_bo_reserve(obj, true); | ||
185 | if (unlikely(r != 0)) | ||
186 | return r; | ||
187 | amdgpu_bo_kunmap(obj); | ||
188 | amdgpu_bo_unreserve(obj); | ||
189 | return r; | ||
190 | } | ||
191 | 43 | ||
192 | static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned offset) | 44 | static uint32_t amdgpu_cgs_read_register(struct cgs_device *cgs_device, unsigned offset) |
193 | { | 45 | { |
@@ -329,109 +181,6 @@ static int amdgpu_cgs_atom_exec_cmd_table(struct cgs_device *cgs_device, unsigne | |||
329 | adev->mode_info.atom_context, table, args); | 181 | adev->mode_info.atom_context, table, args); |
330 | } | 182 | } |
331 | 183 | ||
332 | struct cgs_irq_params { | ||
333 | unsigned src_id; | ||
334 | cgs_irq_source_set_func_t set; | ||
335 | cgs_irq_handler_func_t handler; | ||
336 | void *private_data; | ||
337 | }; | ||
338 | |||
339 | static int cgs_set_irq_state(struct amdgpu_device *adev, | ||
340 | struct amdgpu_irq_src *src, | ||
341 | unsigned type, | ||
342 | enum amdgpu_interrupt_state state) | ||
343 | { | ||
344 | struct cgs_irq_params *irq_params = | ||
345 | (struct cgs_irq_params *)src->data; | ||
346 | if (!irq_params) | ||
347 | return -EINVAL; | ||
348 | if (!irq_params->set) | ||
349 | return -EINVAL; | ||
350 | return irq_params->set(irq_params->private_data, | ||
351 | irq_params->src_id, | ||
352 | type, | ||
353 | (int)state); | ||
354 | } | ||
355 | |||
356 | static int cgs_process_irq(struct amdgpu_device *adev, | ||
357 | struct amdgpu_irq_src *source, | ||
358 | struct amdgpu_iv_entry *entry) | ||
359 | { | ||
360 | struct cgs_irq_params *irq_params = | ||
361 | (struct cgs_irq_params *)source->data; | ||
362 | if (!irq_params) | ||
363 | return -EINVAL; | ||
364 | if (!irq_params->handler) | ||
365 | return -EINVAL; | ||
366 | return irq_params->handler(irq_params->private_data, | ||
367 | irq_params->src_id, | ||
368 | entry->iv_entry); | ||
369 | } | ||
370 | |||
371 | static const struct amdgpu_irq_src_funcs cgs_irq_funcs = { | ||
372 | .set = cgs_set_irq_state, | ||
373 | .process = cgs_process_irq, | ||
374 | }; | ||
375 | |||
376 | static int amdgpu_cgs_add_irq_source(void *cgs_device, | ||
377 | unsigned client_id, | ||
378 | unsigned src_id, | ||
379 | unsigned num_types, | ||
380 | cgs_irq_source_set_func_t set, | ||
381 | cgs_irq_handler_func_t handler, | ||
382 | void *private_data) | ||
383 | { | ||
384 | CGS_FUNC_ADEV; | ||
385 | int ret = 0; | ||
386 | struct cgs_irq_params *irq_params; | ||
387 | struct amdgpu_irq_src *source = | ||
388 | kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL); | ||
389 | if (!source) | ||
390 | return -ENOMEM; | ||
391 | irq_params = | ||
392 | kzalloc(sizeof(struct cgs_irq_params), GFP_KERNEL); | ||
393 | if (!irq_params) { | ||
394 | kfree(source); | ||
395 | return -ENOMEM; | ||
396 | } | ||
397 | source->num_types = num_types; | ||
398 | source->funcs = &cgs_irq_funcs; | ||
399 | irq_params->src_id = src_id; | ||
400 | irq_params->set = set; | ||
401 | irq_params->handler = handler; | ||
402 | irq_params->private_data = private_data; | ||
403 | source->data = (void *)irq_params; | ||
404 | ret = amdgpu_irq_add_id(adev, client_id, src_id, source); | ||
405 | if (ret) { | ||
406 | kfree(irq_params); | ||
407 | kfree(source); | ||
408 | } | ||
409 | |||
410 | return ret; | ||
411 | } | ||
412 | |||
413 | static int amdgpu_cgs_irq_get(void *cgs_device, unsigned client_id, | ||
414 | unsigned src_id, unsigned type) | ||
415 | { | ||
416 | CGS_FUNC_ADEV; | ||
417 | |||
418 | if (!adev->irq.client[client_id].sources) | ||
419 | return -EINVAL; | ||
420 | |||
421 | return amdgpu_irq_get(adev, adev->irq.client[client_id].sources[src_id], type); | ||
422 | } | ||
423 | |||
424 | static int amdgpu_cgs_irq_put(void *cgs_device, unsigned client_id, | ||
425 | unsigned src_id, unsigned type) | ||
426 | { | ||
427 | CGS_FUNC_ADEV; | ||
428 | |||
429 | if (!adev->irq.client[client_id].sources) | ||
430 | return -EINVAL; | ||
431 | |||
432 | return amdgpu_irq_put(adev, adev->irq.client[client_id].sources[src_id], type); | ||
433 | } | ||
434 | |||
435 | static int amdgpu_cgs_set_clockgating_state(struct cgs_device *cgs_device, | 184 | static int amdgpu_cgs_set_clockgating_state(struct cgs_device *cgs_device, |
436 | enum amd_ip_block_type block_type, | 185 | enum amd_ip_block_type block_type, |
437 | enum amd_clockgating_state state) | 186 | enum amd_clockgating_state state) |
@@ -801,11 +550,9 @@ static int amdgpu_cgs_get_firmware_info(struct cgs_device *cgs_device, | |||
801 | else | 550 | else |
802 | strcpy(fw_name, "amdgpu/vega10_smc.bin"); | 551 | strcpy(fw_name, "amdgpu/vega10_smc.bin"); |
803 | break; | 552 | break; |
804 | case CHIP_CARRIZO: | 553 | case CHIP_VEGA12: |
805 | case CHIP_STONEY: | 554 | strcpy(fw_name, "amdgpu/vega12_smc.bin"); |
806 | case CHIP_RAVEN: | 555 | break; |
807 | adev->pm.fw_version = info->version; | ||
808 | return 0; | ||
809 | default: | 556 | default: |
810 | DRM_ERROR("SMC firmware not supported\n"); | 557 | DRM_ERROR("SMC firmware not supported\n"); |
811 | return -EINVAL; | 558 | return -EINVAL; |
@@ -857,61 +604,6 @@ static int amdgpu_cgs_is_virtualization_enabled(void *cgs_device) | |||
857 | return amdgpu_sriov_vf(adev); | 604 | return amdgpu_sriov_vf(adev); |
858 | } | 605 | } |
859 | 606 | ||
860 | static int amdgpu_cgs_query_system_info(struct cgs_device *cgs_device, | ||
861 | struct cgs_system_info *sys_info) | ||
862 | { | ||
863 | CGS_FUNC_ADEV; | ||
864 | |||
865 | if (NULL == sys_info) | ||
866 | return -ENODEV; | ||
867 | |||
868 | if (sizeof(struct cgs_system_info) != sys_info->size) | ||
869 | return -ENODEV; | ||
870 | |||
871 | switch (sys_info->info_id) { | ||
872 | case CGS_SYSTEM_INFO_ADAPTER_BDF_ID: | ||
873 | sys_info->value = adev->pdev->devfn | (adev->pdev->bus->number << 8); | ||
874 | break; | ||
875 | case CGS_SYSTEM_INFO_PCIE_GEN_INFO: | ||
876 | sys_info->value = adev->pm.pcie_gen_mask; | ||
877 | break; | ||
878 | case CGS_SYSTEM_INFO_PCIE_MLW: | ||
879 | sys_info->value = adev->pm.pcie_mlw_mask; | ||
880 | break; | ||
881 | case CGS_SYSTEM_INFO_PCIE_DEV: | ||
882 | sys_info->value = adev->pdev->device; | ||
883 | break; | ||
884 | case CGS_SYSTEM_INFO_PCIE_REV: | ||
885 | sys_info->value = adev->pdev->revision; | ||
886 | break; | ||
887 | case CGS_SYSTEM_INFO_CG_FLAGS: | ||
888 | sys_info->value = adev->cg_flags; | ||
889 | break; | ||
890 | case CGS_SYSTEM_INFO_PG_FLAGS: | ||
891 | sys_info->value = adev->pg_flags; | ||
892 | break; | ||
893 | case CGS_SYSTEM_INFO_GFX_CU_INFO: | ||
894 | sys_info->value = adev->gfx.cu_info.number; | ||
895 | break; | ||
896 | case CGS_SYSTEM_INFO_GFX_SE_INFO: | ||
897 | sys_info->value = adev->gfx.config.max_shader_engines; | ||
898 | break; | ||
899 | case CGS_SYSTEM_INFO_PCIE_SUB_SYS_ID: | ||
900 | sys_info->value = adev->pdev->subsystem_device; | ||
901 | break; | ||
902 | case CGS_SYSTEM_INFO_PCIE_SUB_SYS_VENDOR_ID: | ||
903 | sys_info->value = adev->pdev->subsystem_vendor; | ||
904 | break; | ||
905 | case CGS_SYSTEM_INFO_PCIE_BUS_DEVFN: | ||
906 | sys_info->value = adev->pdev->devfn; | ||
907 | break; | ||
908 | default: | ||
909 | return -ENODEV; | ||
910 | } | ||
911 | |||
912 | return 0; | ||
913 | } | ||
914 | |||
915 | static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device, | 607 | static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device, |
916 | struct cgs_display_info *info) | 608 | struct cgs_display_info *info) |
917 | { | 609 | { |
@@ -922,12 +614,9 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device, | |||
922 | return -EINVAL; | 614 | return -EINVAL; |
923 | 615 | ||
924 | mode_info = info->mode_info; | 616 | mode_info = info->mode_info; |
925 | if (mode_info) { | 617 | if (mode_info) |
926 | /* if the displays are off, vblank time is max */ | 618 | /* if the displays are off, vblank time is max */ |
927 | mode_info->vblank_time_us = 0xffffffff; | 619 | mode_info->vblank_time_us = 0xffffffff; |
928 | /* always set the reference clock */ | ||
929 | mode_info->ref_clock = adev->clock.spll.reference_freq; | ||
930 | } | ||
931 | 620 | ||
932 | if (!amdgpu_device_has_dc_support(adev)) { | 621 | if (!amdgpu_device_has_dc_support(adev)) { |
933 | struct amdgpu_crtc *amdgpu_crtc; | 622 | struct amdgpu_crtc *amdgpu_crtc; |
@@ -953,6 +642,11 @@ static int amdgpu_cgs_get_active_displays_info(struct cgs_device *cgs_device, | |||
953 | (amdgpu_crtc->v_border * 2); | 642 | (amdgpu_crtc->v_border * 2); |
954 | mode_info->vblank_time_us = vblank_lines * line_time_us; | 643 | mode_info->vblank_time_us = vblank_lines * line_time_us; |
955 | mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); | 644 | mode_info->refresh_rate = drm_mode_vrefresh(&amdgpu_crtc->hw_mode); |
645 | /* we have issues with mclk switching with refresh rates | ||
646 | * over 120 hz on the non-DC code. | ||
647 | */ | ||
648 | if (mode_info->refresh_rate > 120) | ||
649 | mode_info->vblank_time_us = 0; | ||
956 | mode_info = NULL; | 650 | mode_info = NULL; |
957 | } | 651 | } |
958 | } | 652 | } |
@@ -977,223 +671,7 @@ static int amdgpu_cgs_notify_dpm_enabled(struct cgs_device *cgs_device, bool ena | |||
977 | return 0; | 671 | return 0; |
978 | } | 672 | } |
979 | 673 | ||
980 | /** \brief evaluate acpi namespace object, handle or pathname must be valid | ||
981 | * \param cgs_device | ||
982 | * \param info input/output arguments for the control method | ||
983 | * \return status | ||
984 | */ | ||
985 | |||
986 | #if defined(CONFIG_ACPI) | ||
987 | static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device, | ||
988 | struct cgs_acpi_method_info *info) | ||
989 | { | ||
990 | CGS_FUNC_ADEV; | ||
991 | acpi_handle handle; | ||
992 | struct acpi_object_list input; | ||
993 | struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
994 | union acpi_object *params, *obj; | ||
995 | uint8_t name[5] = {'\0'}; | ||
996 | struct cgs_acpi_method_argument *argument; | ||
997 | uint32_t i, count; | ||
998 | acpi_status status; | ||
999 | int result; | ||
1000 | |||
1001 | handle = ACPI_HANDLE(&adev->pdev->dev); | ||
1002 | if (!handle) | ||
1003 | return -ENODEV; | ||
1004 | |||
1005 | memset(&input, 0, sizeof(struct acpi_object_list)); | ||
1006 | |||
1007 | /* validate input info */ | ||
1008 | if (info->size != sizeof(struct cgs_acpi_method_info)) | ||
1009 | return -EINVAL; | ||
1010 | |||
1011 | input.count = info->input_count; | ||
1012 | if (info->input_count > 0) { | ||
1013 | if (info->pinput_argument == NULL) | ||
1014 | return -EINVAL; | ||
1015 | argument = info->pinput_argument; | ||
1016 | for (i = 0; i < info->input_count; i++) { | ||
1017 | if (((argument->type == ACPI_TYPE_STRING) || | ||
1018 | (argument->type == ACPI_TYPE_BUFFER)) && | ||
1019 | (argument->pointer == NULL)) | ||
1020 | return -EINVAL; | ||
1021 | argument++; | ||
1022 | } | ||
1023 | } | ||
1024 | |||
1025 | if (info->output_count > 0) { | ||
1026 | if (info->poutput_argument == NULL) | ||
1027 | return -EINVAL; | ||
1028 | argument = info->poutput_argument; | ||
1029 | for (i = 0; i < info->output_count; i++) { | ||
1030 | if (((argument->type == ACPI_TYPE_STRING) || | ||
1031 | (argument->type == ACPI_TYPE_BUFFER)) | ||
1032 | && (argument->pointer == NULL)) | ||
1033 | return -EINVAL; | ||
1034 | argument++; | ||
1035 | } | ||
1036 | } | ||
1037 | |||
1038 | /* The path name passed to acpi_evaluate_object should be null terminated */ | ||
1039 | if ((info->field & CGS_ACPI_FIELD_METHOD_NAME) != 0) { | ||
1040 | strncpy(name, (char *)&(info->name), sizeof(uint32_t)); | ||
1041 | name[4] = '\0'; | ||
1042 | } | ||
1043 | |||
1044 | /* parse input parameters */ | ||
1045 | if (input.count > 0) { | ||
1046 | input.pointer = params = | ||
1047 | kzalloc(sizeof(union acpi_object) * input.count, GFP_KERNEL); | ||
1048 | if (params == NULL) | ||
1049 | return -EINVAL; | ||
1050 | |||
1051 | argument = info->pinput_argument; | ||
1052 | |||
1053 | for (i = 0; i < input.count; i++) { | ||
1054 | params->type = argument->type; | ||
1055 | switch (params->type) { | ||
1056 | case ACPI_TYPE_INTEGER: | ||
1057 | params->integer.value = argument->value; | ||
1058 | break; | ||
1059 | case ACPI_TYPE_STRING: | ||
1060 | params->string.length = argument->data_length; | ||
1061 | params->string.pointer = argument->pointer; | ||
1062 | break; | ||
1063 | case ACPI_TYPE_BUFFER: | ||
1064 | params->buffer.length = argument->data_length; | ||
1065 | params->buffer.pointer = argument->pointer; | ||
1066 | break; | ||
1067 | default: | ||
1068 | break; | ||
1069 | } | ||
1070 | params++; | ||
1071 | argument++; | ||
1072 | } | ||
1073 | } | ||
1074 | |||
1075 | /* parse output info */ | ||
1076 | count = info->output_count; | ||
1077 | argument = info->poutput_argument; | ||
1078 | |||
1079 | /* evaluate the acpi method */ | ||
1080 | status = acpi_evaluate_object(handle, name, &input, &output); | ||
1081 | |||
1082 | if (ACPI_FAILURE(status)) { | ||
1083 | result = -EIO; | ||
1084 | goto free_input; | ||
1085 | } | ||
1086 | |||
1087 | /* return the output info */ | ||
1088 | obj = output.pointer; | ||
1089 | |||
1090 | if (count > 1) { | ||
1091 | if ((obj->type != ACPI_TYPE_PACKAGE) || | ||
1092 | (obj->package.count != count)) { | ||
1093 | result = -EIO; | ||
1094 | goto free_obj; | ||
1095 | } | ||
1096 | params = obj->package.elements; | ||
1097 | } else | ||
1098 | params = obj; | ||
1099 | |||
1100 | if (params == NULL) { | ||
1101 | result = -EIO; | ||
1102 | goto free_obj; | ||
1103 | } | ||
1104 | |||
1105 | for (i = 0; i < count; i++) { | ||
1106 | if (argument->type != params->type) { | ||
1107 | result = -EIO; | ||
1108 | goto free_obj; | ||
1109 | } | ||
1110 | switch (params->type) { | ||
1111 | case ACPI_TYPE_INTEGER: | ||
1112 | argument->value = params->integer.value; | ||
1113 | break; | ||
1114 | case ACPI_TYPE_STRING: | ||
1115 | if ((params->string.length != argument->data_length) || | ||
1116 | (params->string.pointer == NULL)) { | ||
1117 | result = -EIO; | ||
1118 | goto free_obj; | ||
1119 | } | ||
1120 | strncpy(argument->pointer, | ||
1121 | params->string.pointer, | ||
1122 | params->string.length); | ||
1123 | break; | ||
1124 | case ACPI_TYPE_BUFFER: | ||
1125 | if (params->buffer.pointer == NULL) { | ||
1126 | result = -EIO; | ||
1127 | goto free_obj; | ||
1128 | } | ||
1129 | memcpy(argument->pointer, | ||
1130 | params->buffer.pointer, | ||
1131 | argument->data_length); | ||
1132 | break; | ||
1133 | default: | ||
1134 | break; | ||
1135 | } | ||
1136 | argument++; | ||
1137 | params++; | ||
1138 | } | ||
1139 | |||
1140 | result = 0; | ||
1141 | free_obj: | ||
1142 | kfree(obj); | ||
1143 | free_input: | ||
1144 | kfree((void *)input.pointer); | ||
1145 | return result; | ||
1146 | } | ||
1147 | #else | ||
1148 | static int amdgpu_cgs_acpi_eval_object(struct cgs_device *cgs_device, | ||
1149 | struct cgs_acpi_method_info *info) | ||
1150 | { | ||
1151 | return -EIO; | ||
1152 | } | ||
1153 | #endif | ||
1154 | |||
1155 | static int amdgpu_cgs_call_acpi_method(struct cgs_device *cgs_device, | ||
1156 | uint32_t acpi_method, | ||
1157 | uint32_t acpi_function, | ||
1158 | void *pinput, void *poutput, | ||
1159 | uint32_t output_count, | ||
1160 | uint32_t input_size, | ||
1161 | uint32_t output_size) | ||
1162 | { | ||
1163 | struct cgs_acpi_method_argument acpi_input[2] = { {0}, {0} }; | ||
1164 | struct cgs_acpi_method_argument acpi_output = {0}; | ||
1165 | struct cgs_acpi_method_info info = {0}; | ||
1166 | |||
1167 | acpi_input[0].type = CGS_ACPI_TYPE_INTEGER; | ||
1168 | acpi_input[0].data_length = sizeof(uint32_t); | ||
1169 | acpi_input[0].value = acpi_function; | ||
1170 | |||
1171 | acpi_input[1].type = CGS_ACPI_TYPE_BUFFER; | ||
1172 | acpi_input[1].data_length = input_size; | ||
1173 | acpi_input[1].pointer = pinput; | ||
1174 | |||
1175 | acpi_output.type = CGS_ACPI_TYPE_BUFFER; | ||
1176 | acpi_output.data_length = output_size; | ||
1177 | acpi_output.pointer = poutput; | ||
1178 | |||
1179 | info.size = sizeof(struct cgs_acpi_method_info); | ||
1180 | info.field = CGS_ACPI_FIELD_METHOD_NAME | CGS_ACPI_FIELD_INPUT_ARGUMENT_COUNT; | ||
1181 | info.input_count = 2; | ||
1182 | info.name = acpi_method; | ||
1183 | info.pinput_argument = acpi_input; | ||
1184 | info.output_count = output_count; | ||
1185 | info.poutput_argument = &acpi_output; | ||
1186 | |||
1187 | return amdgpu_cgs_acpi_eval_object(cgs_device, &info); | ||
1188 | } | ||
1189 | |||
1190 | static const struct cgs_ops amdgpu_cgs_ops = { | 674 | static const struct cgs_ops amdgpu_cgs_ops = { |
1191 | .alloc_gpu_mem = amdgpu_cgs_alloc_gpu_mem, | ||
1192 | .free_gpu_mem = amdgpu_cgs_free_gpu_mem, | ||
1193 | .gmap_gpu_mem = amdgpu_cgs_gmap_gpu_mem, | ||
1194 | .gunmap_gpu_mem = amdgpu_cgs_gunmap_gpu_mem, | ||
1195 | .kmap_gpu_mem = amdgpu_cgs_kmap_gpu_mem, | ||
1196 | .kunmap_gpu_mem = amdgpu_cgs_kunmap_gpu_mem, | ||
1197 | .read_register = amdgpu_cgs_read_register, | 675 | .read_register = amdgpu_cgs_read_register, |
1198 | .write_register = amdgpu_cgs_write_register, | 676 | .write_register = amdgpu_cgs_write_register, |
1199 | .read_ind_register = amdgpu_cgs_read_ind_register, | 677 | .read_ind_register = amdgpu_cgs_read_ind_register, |
@@ -1208,18 +686,9 @@ static const struct cgs_ops amdgpu_cgs_ops = { | |||
1208 | .set_clockgating_state = amdgpu_cgs_set_clockgating_state, | 686 | .set_clockgating_state = amdgpu_cgs_set_clockgating_state, |
1209 | .get_active_displays_info = amdgpu_cgs_get_active_displays_info, | 687 | .get_active_displays_info = amdgpu_cgs_get_active_displays_info, |
1210 | .notify_dpm_enabled = amdgpu_cgs_notify_dpm_enabled, | 688 | .notify_dpm_enabled = amdgpu_cgs_notify_dpm_enabled, |
1211 | .call_acpi_method = amdgpu_cgs_call_acpi_method, | ||
1212 | .query_system_info = amdgpu_cgs_query_system_info, | ||
1213 | .is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled, | 689 | .is_virtualization_enabled = amdgpu_cgs_is_virtualization_enabled, |
1214 | .enter_safe_mode = amdgpu_cgs_enter_safe_mode, | 690 | .enter_safe_mode = amdgpu_cgs_enter_safe_mode, |
1215 | .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx, | 691 | .lock_grbm_idx = amdgpu_cgs_lock_grbm_idx, |
1216 | .register_pp_handle = amdgpu_cgs_register_pp_handle, | ||
1217 | }; | ||
1218 | |||
1219 | static const struct cgs_os_ops amdgpu_cgs_os_ops = { | ||
1220 | .add_irq_source = amdgpu_cgs_add_irq_source, | ||
1221 | .irq_get = amdgpu_cgs_irq_get, | ||
1222 | .irq_put = amdgpu_cgs_irq_put | ||
1223 | }; | 692 | }; |
1224 | 693 | ||
1225 | struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev) | 694 | struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev) |
@@ -1233,7 +702,6 @@ struct cgs_device *amdgpu_cgs_create_device(struct amdgpu_device *adev) | |||
1233 | } | 702 | } |
1234 | 703 | ||
1235 | cgs_device->base.ops = &amdgpu_cgs_ops; | 704 | cgs_device->base.ops = &amdgpu_cgs_ops; |
1236 | cgs_device->base.os_ops = &amdgpu_cgs_os_ops; | ||
1237 | cgs_device->adev = adev; | 705 | cgs_device->adev = adev; |
1238 | 706 | ||
1239 | return (struct cgs_device *)cgs_device; | 707 | return (struct cgs_device *)cgs_device; |