···11+/*22+ * Copyright 2018 Advanced Micro Devices, Inc.33+ *44+ * Permission is hereby granted, free of charge, to any person obtaining a55+ * copy of this software and associated documentation files (the "Software"),66+ * to deal in the Software without restriction, including without limitation77+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,88+ * and/or sell copies of the Software, and to permit persons to whom the99+ * Software is furnished to do so, subject to the following conditions:1010+ *1111+ * The above copyright notice and this permission notice shall be included in1212+ * all copies or substantial portions of the Software.1313+ *1414+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR1515+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,1616+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL1717+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR1818+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,1919+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR2020+ * OTHER DEALINGS IN THE SOFTWARE.2121+ *2222+ * Authors: AMD2323+ *2424+ */2525+2626+#include "vm_helper.h"2727+2828+static void mark_vmid_used(struct vm_helper *vm_helper, unsigned int pos, uint8_t hubp_idx)2929+{3030+ struct vmid_usage vmids = vm_helper->hubp_vmid_usage[hubp_idx];3131+3232+ vmids.vmid_usage[0] = vmids.vmid_usage[1];3333+ vmids.vmid_usage[1] = 1 << pos;3434+}3535+3636+static void add_ptb_to_table(struct vm_helper *vm_helper, unsigned int vmid, uint64_t ptb)3737+{3838+ vm_helper->ptb_assigned_to_vmid[vmid] = ptb;3939+ vm_helper->num_vmids_available--;4040+}4141+4242+static void clear_entry_from_vmid_table(struct vm_helper *vm_helper, unsigned int vmid)4343+{4444+ vm_helper->ptb_assigned_to_vmid[vmid] = 0;4545+ vm_helper->num_vmids_available++;4646+}4747+4848+static void evict_vmids(struct vm_helper *vm_helper)4949+{5050+ int i;5151+ uint16_t ord = 0;5252+5353+ for (i = 0; i < vm_helper->num_vmid; i++)5454+ ord |= vm_helper->hubp_vmid_usage[i].vmid_usage[0] | vm_helper->hubp_vmid_usage[i].vmid_usage[1];5555+5656+ // At this point any positions with value 0 are unused vmids, evict them5757+ for (i = 1; i < vm_helper->num_vmid; i++) {5858+ if (ord & (1u << i))5959+ clear_entry_from_vmid_table(vm_helper, i);6060+ }6161+}6262+6363+// Return value of -1 indicates vmid table unitialized or ptb dne in the table6464+static int get_existing_vmid_for_ptb(struct vm_helper *vm_helper, uint64_t ptb)6565+{6666+ int i;6767+6868+ for (i = 0; i < vm_helper->num_vmid; i++) {6969+ if (vm_helper->ptb_assigned_to_vmid[i] == ptb)7070+ return i;7171+ }7272+7373+ return -1;7474+}7575+7676+// Expected to be called only when there's an available vmid7777+static int get_next_available_vmid(struct vm_helper *vm_helper)7878+{7979+ int i;8080+8181+ for (i = 1; i < vm_helper->num_vmid; i++) {8282+ if (vm_helper->ptb_assigned_to_vmid[i] == 0)8383+ return i;8484+ }8585+8686+ return -1;8787+}8888+8989+uint8_t get_vmid_for_ptb(struct vm_helper *vm_helper, int64_t ptb, uint8_t hubp_idx)9090+{9191+ unsigned int vmid = 0;9292+ int vmid_exists = -1;9393+9494+ // Physical address gets vmid 09595+ if (ptb == 0)9696+ return 0;9797+9898+ vmid_exists = get_existing_vmid_for_ptb(vm_helper, ptb);9999+100100+ if (vmid_exists != -1) {101101+ mark_vmid_used(vm_helper, vmid_exists, hubp_idx);102102+ vmid = vmid_exists;103103+ } else {104104+ if (vm_helper->num_vmids_available == 0)105105+ evict_vmids(vm_helper);106106+107107+ vmid = get_next_available_vmid(vm_helper);108108+ mark_vmid_used(vm_helper, vmid, hubp_idx);109109+ add_ptb_to_table(vm_helper, vmid, ptb);110110+ }111111+112112+ return vmid;113113+}114114+115115+void init_vm_helper(struct vm_helper *vm_helper, unsigned int num_vmid, unsigned int num_hubp)116116+{117117+ vm_helper->num_vmid = num_vmid;118118+ vm_helper->num_hubp = num_hubp;119119+ vm_helper->num_vmids_available = num_vmid - 1;120120+121121+ memset(vm_helper->hubp_vmid_usage, 0, sizeof(vm_helper->hubp_vmid_usage[0]) * MAX_HUBP);122122+ memset(vm_helper->ptb_assigned_to_vmid, 0, sizeof(vm_helper->ptb_assigned_to_vmid[0]) * MAX_VMID);123123+}
-1
drivers/gpu/drm/amd/display/dc/dc.h
···458458};459459460460struct dc *dc_create(const struct dc_init_data *init_params);461461-int dc_get_vmid_use_vector(struct dc *dc);462461void dc_init_callbacks(struct dc *dc,463462 const struct dc_callback_init *init_params);464463void dc_destroy(struct dc **dc);