Commit 85f6e0f6 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'drm-next-4.15' of git://people.freedesktop.org/~agd5f/linux into drm-next

Some amdgpu/ttm fixes.

* 'drm-next-4.15' of git://people.freedesktop.org/~agd5f/linux:
  drm/amd/powerplay: wrong control mode cause the fan spins faster unnecessarily
  drm/amd/powerplay: fix memory leak of hardcoded pptable
  drm/amdgpu:add fw-vram-usage for atomfirmware
  drm/radeon: fix atombios on big endian
  drm/ttm:fix memory leak due to individualize
  drm/amdgpu: fix error handling in amdgpu_bo_do_create
  drm/ttm: once more fix ttm_buffer_object_transfer
  drm/amd/powerplay: change ASIC temperature reading on Vega10
parents 2ef7a95f 710931c2
...@@ -1766,34 +1766,32 @@ bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev) ...@@ -1766,34 +1766,32 @@ bool amdgpu_atombios_scratch_need_asic_init(struct amdgpu_device *adev)
return true; return true;
} }
/* Atom needs data in little endian format /* Atom needs data in little endian format so swap as appropriate when copying
* so swap as appropriate when copying data to * data to or from atom. Note that atom operates on dw units.
* or from atom. Note that atom operates on *
* dw units. * Use to_le=true when sending data to atom and provide at least
* ALIGN(num_bytes,4) bytes in the dst buffer.
*
* Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
* byes in the src buffer.
*/ */
void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) void amdgpu_atombios_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
{ {
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ u32 src_tmp[5], dst_tmp[5];
u32 *dst32, *src32;
int i; int i;
u8 align_num_bytes = ALIGN(num_bytes, 4);
memcpy(src_tmp, src, num_bytes);
src32 = (u32 *)src_tmp;
dst32 = (u32 *)dst_tmp;
if (to_le) { if (to_le) {
for (i = 0; i < ((num_bytes + 3) / 4); i++) memcpy(src_tmp, src, num_bytes);
dst32[i] = cpu_to_le32(src32[i]); for (i = 0; i < align_num_bytes / 4; i++)
memcpy(dst, dst_tmp, num_bytes); dst_tmp[i] = cpu_to_le32(src_tmp[i]);
memcpy(dst, dst_tmp, align_num_bytes);
} else { } else {
u8 dws = num_bytes & ~3; memcpy(src_tmp, src, align_num_bytes);
for (i = 0; i < ((num_bytes + 3) / 4); i++) for (i = 0; i < align_num_bytes / 4; i++)
dst32[i] = le32_to_cpu(src32[i]); dst_tmp[i] = le32_to_cpu(src_tmp[i]);
memcpy(dst, dst_tmp, dws); memcpy(dst, dst_tmp, num_bytes);
if (num_bytes % 4) {
for (i = 0; i < (num_bytes % 4); i++)
dst[dws+i] = dst_tmp[dws+i];
}
} }
#else #else
memcpy(dst, src, num_bytes); memcpy(dst, src, num_bytes);
......
...@@ -71,19 +71,33 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev) ...@@ -71,19 +71,33 @@ int amdgpu_atomfirmware_allocate_fb_scratch(struct amdgpu_device *adev)
struct atom_context *ctx = adev->mode_info.atom_context; struct atom_context *ctx = adev->mode_info.atom_context;
int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1, int index = get_index_into_master_table(atom_master_list_of_data_tables_v2_1,
vram_usagebyfirmware); vram_usagebyfirmware);
struct vram_usagebyfirmware_v2_1 * firmware_usage;
uint32_t start_addr, size;
uint16_t data_offset; uint16_t data_offset;
int usage_bytes = 0; int usage_bytes = 0;
if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) { if (amdgpu_atom_parse_data_header(ctx, index, NULL, NULL, NULL, &data_offset)) {
struct vram_usagebyfirmware_v2_1 *firmware_usage = firmware_usage = (struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
(struct vram_usagebyfirmware_v2_1 *)(ctx->bios + data_offset);
DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n", DRM_DEBUG("atom firmware requested %08x %dkb fw %dkb drv\n",
le32_to_cpu(firmware_usage->start_address_in_kb), le32_to_cpu(firmware_usage->start_address_in_kb),
le16_to_cpu(firmware_usage->used_by_firmware_in_kb), le16_to_cpu(firmware_usage->used_by_firmware_in_kb),
le16_to_cpu(firmware_usage->used_by_driver_in_kb)); le16_to_cpu(firmware_usage->used_by_driver_in_kb));
usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) * 1024; start_addr = le32_to_cpu(firmware_usage->start_address_in_kb);
size = le16_to_cpu(firmware_usage->used_by_firmware_in_kb);
if ((uint32_t)(start_addr & ATOM_VRAM_OPERATION_FLAGS_MASK) ==
(uint32_t)(ATOM_VRAM_BLOCK_SRIOV_MSG_SHARE_RESERVATION <<
ATOM_VRAM_OPERATION_FLAGS_SHIFT)) {
/* Firmware request VRAM reservation for SR-IOV */
adev->fw_vram_usage.start_offset = (start_addr &
(~ATOM_VRAM_OPERATION_FLAGS_MASK)) << 10;
adev->fw_vram_usage.size = size << 10;
/* Use the default scratch size */
usage_bytes = 0;
} else {
usage_bytes = le16_to_cpu(firmware_usage->used_by_driver_in_kb) << 10;
}
} }
ctx->scratch_size_bytes = 0; ctx->scratch_size_bytes = 0;
if (usage_bytes == 0) if (usage_bytes == 0)
......
...@@ -369,6 +369,9 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, ...@@ -369,6 +369,9 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type, r = ttm_bo_init_reserved(&adev->mman.bdev, &bo->tbo, size, type,
&bo->placement, page_align, !kernel, NULL, &bo->placement, page_align, !kernel, NULL,
acc_size, sg, resv, &amdgpu_ttm_bo_destroy); acc_size, sg, resv, &amdgpu_ttm_bo_destroy);
if (unlikely(r != 0))
return r;
bytes_moved = atomic64_read(&adev->num_bytes_moved) - bytes_moved = atomic64_read(&adev->num_bytes_moved) -
initial_bytes_moved; initial_bytes_moved;
if (adev->mc.visible_vram_size < adev->mc.real_vram_size && if (adev->mc.visible_vram_size < adev->mc.real_vram_size &&
...@@ -378,9 +381,6 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev, ...@@ -378,9 +381,6 @@ static int amdgpu_bo_do_create(struct amdgpu_device *adev,
else else
amdgpu_cs_report_moved_bytes(adev, bytes_moved, 0); amdgpu_cs_report_moved_bytes(adev, bytes_moved, 0);
if (unlikely(r != 0))
return r;
if (kernel) if (kernel)
bo->tbo.priority = 1; bo->tbo.priority = 1;
......
...@@ -78,6 +78,9 @@ static int amd_powerplay_destroy(void *handle) ...@@ -78,6 +78,9 @@ static int amd_powerplay_destroy(void *handle)
{ {
struct pp_instance *instance = (struct pp_instance *)handle; struct pp_instance *instance = (struct pp_instance *)handle;
kfree(instance->hwmgr->hardcode_pp_table);
instance->hwmgr->hardcode_pp_table = NULL;
kfree(instance->hwmgr); kfree(instance->hwmgr);
instance->hwmgr = NULL; instance->hwmgr = NULL;
......
...@@ -4234,7 +4234,7 @@ static void vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode) ...@@ -4234,7 +4234,7 @@ static void vega10_set_fan_control_mode(struct pp_hwmgr *hwmgr, uint32_t mode)
vega10_fan_ctrl_stop_smc_fan_control(hwmgr); vega10_fan_ctrl_stop_smc_fan_control(hwmgr);
break; break;
case AMD_FAN_CTRL_AUTO: case AMD_FAN_CTRL_AUTO:
if (!vega10_fan_ctrl_set_static_mode(hwmgr, mode)) if (PP_CAP(PHM_PlatformCaps_MicrocodeFanControl))
vega10_fan_ctrl_start_smc_fan_control(hwmgr); vega10_fan_ctrl_start_smc_fan_control(hwmgr);
break; break;
default: default:
......
...@@ -365,8 +365,8 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr) ...@@ -365,8 +365,8 @@ int vega10_thermal_get_temperature(struct pp_hwmgr *hwmgr)
temp = cgs_read_register(hwmgr->device, reg); temp = cgs_read_register(hwmgr->device, reg);
temp = (temp & CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP_MASK) >> temp = (temp & CG_MULT_THERMAL_STATUS__CTF_TEMP_MASK) >>
CG_MULT_THERMAL_STATUS__ASIC_MAX_TEMP__SHIFT; CG_MULT_THERMAL_STATUS__CTF_TEMP__SHIFT;
temp = temp & 0x1ff; temp = temp & 0x1ff;
......
...@@ -45,34 +45,32 @@ static char *pre_emph_names[] = { ...@@ -45,34 +45,32 @@ static char *pre_emph_names[] = {
/***** radeon AUX functions *****/ /***** radeon AUX functions *****/
/* Atom needs data in little endian format /* Atom needs data in little endian format so swap as appropriate when copying
* so swap as appropriate when copying data to * data to or from atom. Note that atom operates on dw units.
* or from atom. Note that atom operates on *
* dw units. * Use to_le=true when sending data to atom and provide at least
* ALIGN(num_bytes,4) bytes in the dst buffer.
*
* Use to_le=false when receiving data from atom and provide ALIGN(num_bytes,4)
* byes in the src buffer.
*/ */
void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le) void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le)
{ {
#ifdef __BIG_ENDIAN #ifdef __BIG_ENDIAN
u8 src_tmp[20], dst_tmp[20]; /* used for byteswapping */ u32 src_tmp[5], dst_tmp[5];
u32 *dst32, *src32;
int i; int i;
u8 align_num_bytes = ALIGN(num_bytes, 4);
memcpy(src_tmp, src, num_bytes);
src32 = (u32 *)src_tmp;
dst32 = (u32 *)dst_tmp;
if (to_le) { if (to_le) {
for (i = 0; i < ((num_bytes + 3) / 4); i++) memcpy(src_tmp, src, num_bytes);
dst32[i] = cpu_to_le32(src32[i]); for (i = 0; i < align_num_bytes / 4; i++)
memcpy(dst, dst_tmp, num_bytes); dst_tmp[i] = cpu_to_le32(src_tmp[i]);
memcpy(dst, dst_tmp, align_num_bytes);
} else { } else {
u8 dws = num_bytes & ~3; memcpy(src_tmp, src, align_num_bytes);
for (i = 0; i < ((num_bytes + 3) / 4); i++) for (i = 0; i < align_num_bytes / 4; i++)
dst32[i] = le32_to_cpu(src32[i]); dst_tmp[i] = le32_to_cpu(src_tmp[i]);
memcpy(dst, dst_tmp, dws); memcpy(dst, dst_tmp, num_bytes);
if (num_bytes % 4) {
for (i = 0; i < (num_bytes % 4); i++)
dst[dws+i] = dst_tmp[dws+i];
}
} }
#else #else
memcpy(dst, src, num_bytes); memcpy(dst, src, num_bytes);
......
...@@ -457,8 +457,11 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo) ...@@ -457,8 +457,11 @@ static void ttm_bo_cleanup_refs_or_queue(struct ttm_buffer_object *bo)
if (reservation_object_test_signaled_rcu(&bo->ttm_resv, true)) { if (reservation_object_test_signaled_rcu(&bo->ttm_resv, true)) {
ttm_bo_del_from_lru(bo); ttm_bo_del_from_lru(bo);
spin_unlock(&glob->lru_lock); spin_unlock(&glob->lru_lock);
if (bo->resv != &bo->ttm_resv) if (bo->resv != &bo->ttm_resv) {
reservation_object_unlock(&bo->ttm_resv); reservation_object_unlock(&bo->ttm_resv);
reservation_object_fini(&bo->ttm_resv);
}
ttm_bo_cleanup_memtype_use(bo); ttm_bo_cleanup_memtype_use(bo);
return; return;
} }
......
...@@ -474,6 +474,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, ...@@ -474,6 +474,7 @@ static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
INIT_LIST_HEAD(&fbo->lru); INIT_LIST_HEAD(&fbo->lru);
INIT_LIST_HEAD(&fbo->swap); INIT_LIST_HEAD(&fbo->swap);
INIT_LIST_HEAD(&fbo->io_reserve_lru); INIT_LIST_HEAD(&fbo->io_reserve_lru);
mutex_init(&fbo->wu_mutex);
fbo->moving = NULL; fbo->moving = NULL;
drm_vma_node_reset(&fbo->vma_node); drm_vma_node_reset(&fbo->vma_node);
atomic_set(&fbo->cpu_writers, 0); atomic_set(&fbo->cpu_writers, 0);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment