18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci 38c2ecf20Sopenharmony_ci/* 48c2ecf20Sopenharmony_ci * Copyright 2016-2019 HabanaLabs, Ltd. 58c2ecf20Sopenharmony_ci * All Rights Reserved. 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci 88c2ecf20Sopenharmony_ci#include "habanalabs.h" 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/slab.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ciint hl_asid_init(struct hl_device *hdev) 138c2ecf20Sopenharmony_ci{ 148c2ecf20Sopenharmony_ci hdev->asid_bitmap = kcalloc(BITS_TO_LONGS(hdev->asic_prop.max_asid), 158c2ecf20Sopenharmony_ci sizeof(*hdev->asid_bitmap), GFP_KERNEL); 168c2ecf20Sopenharmony_ci if (!hdev->asid_bitmap) 178c2ecf20Sopenharmony_ci return -ENOMEM; 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_ci mutex_init(&hdev->asid_mutex); 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci /* ASID 0 is reserved for the kernel driver and device CPU */ 228c2ecf20Sopenharmony_ci set_bit(0, hdev->asid_bitmap); 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci return 0; 258c2ecf20Sopenharmony_ci} 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_civoid hl_asid_fini(struct hl_device *hdev) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci mutex_destroy(&hdev->asid_mutex); 308c2ecf20Sopenharmony_ci kfree(hdev->asid_bitmap); 318c2ecf20Sopenharmony_ci} 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ciunsigned long hl_asid_alloc(struct hl_device *hdev) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci unsigned long found; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci mutex_lock(&hdev->asid_mutex); 388c2ecf20Sopenharmony_ci 398c2ecf20Sopenharmony_ci found = find_first_zero_bit(hdev->asid_bitmap, 408c2ecf20Sopenharmony_ci hdev->asic_prop.max_asid); 418c2ecf20Sopenharmony_ci if (found == hdev->asic_prop.max_asid) 428c2ecf20Sopenharmony_ci found = 0; 438c2ecf20Sopenharmony_ci else 448c2ecf20Sopenharmony_ci set_bit(found, hdev->asid_bitmap); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci mutex_unlock(&hdev->asid_mutex); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci return found; 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_civoid hl_asid_free(struct hl_device *hdev, unsigned long asid) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci if (WARN((asid == 0 || asid >= hdev->asic_prop.max_asid), 548c2ecf20Sopenharmony_ci "Invalid ASID %lu", asid)) 558c2ecf20Sopenharmony_ci return; 568c2ecf20Sopenharmony_ci clear_bit(asid, hdev->asid_bitmap); 578c2ecf20Sopenharmony_ci} 58