1
0
forked from IQ.Lvbs/IQ.Pilot

IQ.Pilot Release Commit @ 0798119

This commit is contained in:
IQ.Lvbs history cleanup
2026-08-22 23:42:42 -05:00
commit b42569dbca
4529 changed files with 1132125 additions and 0 deletions

View File

@@ -0,0 +1,416 @@
#!/usr/bin/env python3
import time, mmap, sys, shutil, os, glob, subprocess, argparse, collections
from tinygrad.helpers import DEBUG, colored, ansilen
from tinygrad.runtime.autogen import libc
from tinygrad.runtime.autogen.am import am
from tinygrad.runtime.support.hcq import MMIOInterface
from tinygrad.runtime.support.am.amdev import AMDev, AMMemoryManager, AMPageTableEntry
from tinygrad.runtime.support.am.ip import AM_SOC, AM_GMC, AM_IH, AM_PSP, AM_SMU, AM_GFX, AM_SDMA
def bold(s): return f"\033[1m{s}\033[0m"
def trim(s:str, length:int) -> str:
if len(s) > length: return s[:length-3] + "..."
return s
def pad(x:str, length:int) -> str:
if len(x) < length: return x + " " * (length - len(x))
return x
def color_temp(temp):
if temp >= 87: return colored(f"{temp:>3}", "red")
elif temp >= 80: return colored(f"{temp:>3}", "yellow")
return f"{temp:>3}"
def color_voltage(voltage): return colored(f"{voltage/1000:>5.3f}V", "cyan")
def draw_bar(percentage, width=40, fill='|', empty=' ', opt_text='', color='cyan'):
percentage = 0.0 if percentage != percentage else percentage # NaN guard
percentage = max(0.0, min(1.0, float(percentage)))
filled_width = int(width * percentage)
if not opt_text: opt_text = f'{percentage*100:.1f}%'
bar = fill * filled_width + empty * (width - filled_width)
if opt_text and len(opt_text) <= len(bar): bar = (bar[:-len(opt_text)] + opt_text)
bar = colored(bar[:filled_width], color) + bar[filled_width:]
return f'[{bar}]'
def same_line(strs:list[list[str]|None], split=8) -> list[str]:
strs = [s for s in strs if s is not None]
if len(strs) == 0: return []
ret = []
max_width_in_block = [max(ansilen(line) for line in block) for block in strs]
max_height = max(len(block) for block in strs)
for i in range(max_height):
line = []
for bid, block in enumerate(strs):
if i < len(block): line.append(block[i] + (' ' * (split + max_width_in_block[bid] - ansilen(block[i])) if bid != len(strs) - 1 else ''))
else: line.append(' ' * (split + max_width_in_block[bid]))
ret.append(' '.join(line))
return ret
def get_bar0_size(pcibus):
resource_file = f"/sys/bus/pci/devices/{pcibus}/resource"
if not os.path.exists(resource_file): raise FileNotFoundError(f"Resource file not found: {resource_file}")
with open(resource_file, "r") as f: lines = f.readlines()
bar0_info = lines[0].split()
if len(bar0_info) < 3: raise ValueError("Unexpected resource file format for BAR0.")
start_hex, end_hex, _flags = bar0_info
return int(end_hex, 16) - int(start_hex, 16) + 1
class AMSMI(AMDev):
def __init__(self, pcibus, vram_bar:MMIOInterface, doorbell_bar:MMIOInterface, mmio_bar:MMIOInterface):
self.pcibus, self.devfmt = pcibus, pcibus
self.vram, self.doorbell64, self.mmio = vram_bar, doorbell_bar, mmio_bar
self.pci_state = self.read_pci_state()
if self.pci_state == "D0": self._init_from_d0()
def _init_from_d0(self):
self._run_discovery()
self._build_regs()
if self.reg("regSCRATCH_REG7").read() != AMDev.Version:
raise Exception(f"Unsupported AM version: {self.reg('regSCRATCH_REG7').read():x}")
self.is_booting = True
self.init_sw(smi_dev=True)
self.partial_boot = True # do not init anything
def read_pci_state(self):
with open(f"/sys/bus/pci/devices/{self.pcibus}/power_state", "r") as f: return f.read().strip().rstrip()
class SMICtx:
def __init__(self):
self.devs = []
self.opened_pcidevs = []
self.opened_pci_resources = {}
self.prev_lines_cnt = 0
self.prev_terminal_width = 0
self.prev_terminal_height = 0
self.prev_metrics = {}
remove_parts = ["Advanced Micro Devices, Inc. [AMD/ATI]", "VGA compatible controller:", "Processing accelerators:"]
lspci = subprocess.check_output(["lspci"]).decode("utf-8").splitlines()
self.lspci = {l.split()[0]: l.split(" ", 1)[1] for l in lspci}
for k,v in self.lspci.items():
for part in remove_parts: self.lspci[k] = self.lspci[k].replace(part, "").strip().rstrip()
def _smuq10_round(self, v:int) -> int:
v = int(v)
return (v + 512) >> 10 # SMUQ10_ROUND
def _fmt_kb(self, kb:int) -> str:
kb = int(kb)
if kb < 1024: return f"{kb}KB"
mb = kb / 1024.0
if mb < 1024: return f"{mb:.1f}MB"
gb = mb / 1024.0
if gb < 1024: return f"{gb:.2f}GB"
tb = gb / 1024.0
return f"{tb:.2f}TB"
def _open_am_device(self, pcibus):
if pcibus not in self.opened_pci_resources:
bar_fds = {bar: os.open(f"/sys/bus/pci/devices/{pcibus}/resource{bar}", os.O_RDWR | os.O_SYNC) for bar in [0, 2, 5]}
bar_size = {0: get_bar0_size(pcibus), 2: os.fstat(bar_fds[2]).st_size, 5: os.fstat(bar_fds[5]).st_size}
def map_pci_range(bar, fmt='B'):
return MMIOInterface(libc.mmap(0, bar_size[bar], mmap.PROT_READ | mmap.PROT_WRITE, mmap.MAP_SHARED, bar_fds[bar], 0), bar_size[bar], fmt)
self.opened_pci_resources[pcibus] = (map_pci_range(0), None, map_pci_range(5, 'I'))
try:
self.devs.append(AMSMI(pcibus, *self.opened_pci_resources[pcibus]))
except Exception as e:
if DEBUG >= 2: print(f"Failed to open AM device {pcibus}: {e}")
return
self.opened_pcidevs.append(pcibus)
if DEBUG >= 2: print(f"Opened AM device {pcibus}")
def rescan_devs(self):
pattern = os.path.join('/tmp', 'am_*.lock')
for d in [f[8:-5] for f in glob.glob(pattern)]:
if d.startswith("usb"): continue
if d not in self.opened_pcidevs:
self._open_am_device(d)
for d in self.devs:
if d.read_pci_state() != d.pci_state:
d.pci_state = d.read_pci_state()
if d.pci_state == "D0": d._init_from_d0()
os.system('clear')
if d.pci_state == "D0" and d.reg("regSCRATCH_REG7").read() != AMDev.Version:
self.devs.remove(d)
self.opened_pcidevs.remove(d.pcibus)
os.system('clear')
if DEBUG >= 2: print(f"Removed AM device {d.pcibus}")
def collect(self):
tables = {}
for dev in self.devs:
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6): table_t = dev.smu.smu_mod.MetricsTableV0_t
case (13,0,12): table_t = dev.smu.smu_mod.MetricsTable_t
case _: table_t = dev.smu.smu_mod.SmuMetricsExternal_t
tables[dev] = dev.smu.read_table(table_t, dev.smu.smu_mod.SMU_TABLE_SMU_METRICS) if dev.pci_state == "D0" else None
return tables
def _pick_nonzero_avg(self, vals) -> int:
xs = [x for x in vals if x > 0]
return int(sum(xs) / len(xs)) if xs else 0
def get_gfx_activity(self, dev, metrics):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12): return max(0, min(100, self._smuq10_round(metrics.SocketGfxBusy)))
case _: return metrics.SmuMetrics.AverageGfxActivity
def get_mem_activity(self, dev, metrics):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12): return max(0, min(100, self._smuq10_round(metrics.DramBandwidthUtilization)))
case _: return metrics.SmuMetrics.AverageUclkActivity
def get_temps(self, dev, metrics, compact=False):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12):
temps = {
"Hotspot": self._smuq10_round(metrics.MaxSocketTemperature),
"HBM": self._smuq10_round(metrics.MaxHbmTemperature),
"VR": self._smuq10_round(metrics.MaxVrTemperature),
}
if compact: return {k: temps[k] for k in ("Hotspot", "HBM") if temps.get(k, 0) != 0}
return {k: v for k, v in temps.items() if v != 0}
case _:
temps_keys = [(k, name) for k, name in dev.smu.smu_mod.TEMP_e.items()
if k < dev.smu.smu_mod.TEMP_COUNT and metrics.SmuMetrics.AvgTemperature[k] != 0]
if compact: temps_keys = [(k, name) for k, name in temps_keys if k in (dev.smu.smu_mod.TEMP_HOTSPOT, dev.smu.smu_mod.TEMP_MEM)]
return {name: metrics.SmuMetrics.AvgTemperature[k] for k, name in temps_keys}
def get_voltage(self, dev, metrics, compact=False):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12): return {}
case _:
voltage_keys = [(k, name) for k, name in dev.smu.smu_mod.SVI_PLANE_e.items()
if k < dev.smu.smu_mod.SVI_PLANE_COUNT and metrics.SmuMetrics.AvgVoltage[k] != 0]
return {name: metrics.SmuMetrics.AvgVoltage[k] for k, name in voltage_keys}
def get_busy_threshold(self, dev):
match dev.ip_ver[am.MP1_HWIP]:
case (14, 0, 2): return 5
case _: return 15
def get_gfx_freq(self, dev, metrics):
if metrics is None: return 0
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12): return self._smuq10_round(metrics.GfxclkFrequency[0])
case _:
return metrics.SmuMetrics.AverageGfxclkFrequencyPostDs if self.get_gfx_activity(dev, metrics) <= self.get_busy_threshold(dev) else \
metrics.SmuMetrics.AverageGfxclkFrequencyPreDs
def get_mem_freq(self, dev, metrics):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12): return self._smuq10_round(metrics.UclkFrequency)
case _:
return metrics.SmuMetrics.AverageMemclkFrequencyPostDs if self.get_mem_activity(dev, metrics) <= self.get_busy_threshold(dev) else \
metrics.SmuMetrics.AverageMemclkFrequencyPreDs
def get_fckl_freq(self, dev, metrics):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12): return self._smuq10_round(metrics.FclkFrequency)
case _:
return metrics.SmuMetrics.AverageFclkFrequencyPostDs if self.get_mem_activity(dev, metrics) <= self.get_busy_threshold(dev) else \
metrics.SmuMetrics.AverageFclkFrequencyPreDs
def get_fan_rpm_pwm(self, dev, metrics):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12): return None, None
case _: return metrics.SmuMetrics.AvgFanRpm, metrics.SmuMetrics.AvgFanPwm
def get_power(self, dev, metrics):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6): return self._smuq10_round(metrics.SocketPower), self._smuq10_round(metrics.MaxSocketPowerLimit)
case (13,0,12): return self._smuq10_round(metrics.SocketPower), self._smuq10_round(metrics.SocketPowerLimit)
case _: return metrics.SmuMetrics.AverageSocketPower, metrics.SmuMetrics.dGPU_W_MAX
def get_throttle_info(self, dev, metrics):
match dev.ip_ver[am.MP1_HWIP]:
case (13,0,6)|(13,0,12):
throttle_fields = [('ProchotResidencyAcc', 'Prochot'), ('PptResidencyAcc', 'PPT'),
('SocketThmResidencyAcc', 'Socket Thm'), ('VrThmResidencyAcc', 'VR Thm'), ('HbmThmResidencyAcc', 'HBM Thm')]
prev = self.prev_metrics.get(dev.pcibus)
active = []
if prev is not None:
acc_delta = metrics.AccumulationCounter - prev.AccumulationCounter
if acc_delta > 0:
for field, name in throttle_fields:
delta = getattr(metrics, field) - getattr(prev, field)
if delta > 0 and (pct := min(100, (delta * 100 + acc_delta // 2) // acc_delta)) > 0: active.append((name, pct))
return active
case _:
smu_mod = dev.smu.smu_mod
throttler_names = {getattr(smu_mod, a): a[len('THROTTLER_'):-len('_BIT')]
for a in dir(smu_mod) if a.startswith('THROTTLER_') and a.endswith('_BIT')}
active = []
for i, pct in enumerate(metrics.SmuMetrics.ThrottlingPercentage):
if pct > 0: active.append((throttler_names.get(i, f"UNK_{i}"), int(pct)))
return active
def get_mem_usage(self, dev):
usage = 0
pt_stack = [dev.mm.root_page_table]
while len(pt_stack) > 0:
pt = pt_stack.pop()
for i in range(512):
entry = pt.entries[i]
if (entry & am.AMDGPU_PTE_VALID) == 0: continue
if pt.lv < am.AMDGPU_VM_PDB0 and not dev.gmc.is_pte_huge_page(pt.lv, entry):
pt_stack.append(AMPageTableEntry(dev, dev.xgmi2paddr(entry & 0x0000FFFFFFFFF000), lv=pt.lv+1))
continue
if (entry & am.AMDGPU_PTE_SYSTEM) != 0: continue
usage += (1 << ((9 * (3-pt.lv)) + 12))
return usage
def draw(self, once):
terminal_width, terminal_height = shutil.get_terminal_size()
if not once and (self.prev_terminal_width != terminal_width or self.prev_terminal_height != terminal_height):
os.system('clear')
self.prev_terminal_width, self.prev_terminal_height = terminal_width, terminal_height
padding = 8
col_size = (terminal_width) // 2 - padding - 2
activity_line_width = 50 if terminal_width > 170 else \
(30 if terminal_width > 130 else \
(16 if terminal_width > 92 else \
max(0, terminal_width - 77)))
dev_metrics = self.collect()
dev_content = []
for dev, metrics in dev_metrics.items():
if dev.pci_state != "D0":
dev_content.append([f"{colored('(sleep)', 'yellow')} {bold(dev.pcibus)}: {trim(self.lspci[dev.pcibus[5:]], col_size - 20)}"] +
[pad(f"PCI State: {dev.pci_state}", col_size)])
continue
mem_used = self.get_mem_usage(dev)
mem_total = dev.vram_size
mem_fmt = f"{mem_used/1024**3:.1f}/{mem_total/1024**3:.1f}G"
device_line = [f"{bold(dev.pcibus)} {trim(self.lspci[dev.pcibus[5:]], col_size - 20)}"] + [pad("", col_size)]
activity_line = [f"GFX Activity {draw_bar(self.get_gfx_activity(dev, metrics) / 100, activity_line_width)}"] \
+ [f"MEM Activity {draw_bar(self.get_mem_activity(dev, metrics) / 100, activity_line_width)}"] \
+ [f"MEM Usage {draw_bar(mem_used / mem_total, activity_line_width, opt_text=mem_fmt)}"] \
throttle_info = self.get_throttle_info(dev, metrics)
if throttle_info:
throttle_text = colored(', '.join(f"{name} {pct}%" for name, pct in throttle_info), "red")
else:
throttle_text = colored("None", "green")
activity_line += [f"Throttle {throttle_text}" + " " * (activity_line_width + 2)]
temps_data, temps_data_compact = self.get_temps(dev, metrics), self.get_temps(dev, metrics, compact=True)
temps_table = ["=== Temps (°C) ==="] + [f"{name:<16}: {color_temp(val)}" for name, val in temps_data.items()]
temps_table_compact = ["Temps (°C):" + '/'.join([f"{color_temp(val)} {name}" for name, val in temps_data_compact.items()])]
fan_rpm, fan_pwm = self.get_fan_rpm_pwm(dev, metrics)
power_table = ["=== Power ==="]
power_table += ["Fan: N/A"] if fan_rpm is None or fan_pwm is None else [f"Fan Speed: {fan_rpm} RPM", f"Fan Power: {fan_pwm}%"]
total_power, max_power = self.get_power(dev, metrics)
if max_power > 0:
power_line = [f"Power: " + draw_bar(total_power / max_power, 16, opt_text=f"{total_power}/{max_power}W")]
power_line_compact = [f"Power: " + draw_bar(total_power / max_power, activity_line_width, opt_text=f"{total_power}/{max_power}W")]
else:
power_line = ["Power: N/A"]
power_line_compact = ["Power: N/A"]
voltage_data = self.get_voltage(dev, metrics)
voltage_table = None if not voltage_data else (["=== Voltages ==="] + [f"{name:<20}: {color_voltage(voltage)}" for name, voltage in voltage_data.items()])
gfx_freq = self.get_gfx_freq(dev, metrics)
mclk_freq = self.get_mem_freq(dev, metrics)
fclk_freq = self.get_fckl_freq(dev, metrics)
frequency_table = ["=== Frequencies ===", f"GFXCLK: {gfx_freq:>4} MHz", f"FCLK : {fclk_freq:>4} MHz", f"MCLK : {mclk_freq:>4} MHz"]
if self.prev_terminal_width >= 231:
power_table += power_line
if voltage_table is not None: power_table += [""] + voltage_table
activity_line += [""]
elif self.prev_terminal_width >= 171:
power_table += power_line + [""] + frequency_table
activity_line += [""]
frequency_table = None
elif self.prev_terminal_width >= 121:
temps_table = None
activity_line += power_line_compact
else:
temps_table = None
power_table = None
frequency_table = None
activity_line += power_line_compact
dev_content.append(device_line + activity_line + same_line([temps_table, power_table, frequency_table]))
self.prev_metrics = {dev.pcibus: m for dev, m in dev_metrics.items() if m is not None}
raw_text = 'AM Monitor'.center(terminal_width) + "\n" + "=" * terminal_width + "\n\n"
for i in range(0, len(dev_content), 2):
if i + 1 < len(dev_content): raw_text += '\n'.join(same_line([dev_content[i], dev_content[i+1]], split=padding))
else: raw_text += '\n'.join(dev_content[i])
if i + 2 < len(dev_content): raw_text += "\n" + "=" * terminal_width + "\n\n"
sys.stdout.write(f'\033[{self.prev_lines_cnt}A')
sys.stdout.flush()
print(raw_text)
self.prev_lines_cnt = len(raw_text.splitlines()) + 2
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument("--list", action="store_true", help="Run once and exit")
parser.add_argument("--pids", action="store_true", help="Print pids for all AM devices")
parser.add_argument("--kill", action="store_true", help="Kill all pids associated with AM devices. Valid only with --pids")
parser.add_argument("--dev", type=str, default=None, help="PCI bus ID of the AM device to monitor (e.g., 0000:01:00.0)")
args = parser.parse_args()
if args.pids:
for dev in glob.glob('/tmp/am_*.lock'):
if args.dev and not dev.endswith(f"{args.dev}.lock"):
print(f"{dev[8:-5]}: skipping")
continue
try:
if args.kill:
stopped_pids = collections.defaultdict(int)
while True:
try: pid = subprocess.check_output(['sudo', 'lsof', '-t', dev]).decode('utf-8').split('\n')[0]
except subprocess.CalledProcessError: break
if stopped_pids[pid] > 0: time.sleep(0.1)
if stopped_pids[pid] == 64:
print(f"{dev[8:-5]}: can't stop process {pid}, exitting")
exit(1)
print(f"{dev[8:-5]}: killing process {pid}")
os.system(f'sudo pkill -g -9 {pid}')
stopped_pids[pid] += 1
else:
pid = subprocess.check_output(['sudo', 'lsof', dev]).decode('utf-8').strip().split('\n')[1].split()[1]
print(f"{dev[8:-5]}: {pid}")
except subprocess.CalledProcessError:
print(f"{dev[8:-5]}: no process found")
sys.exit(0)
try:
if not args.list: os.system('clear')
smi_ctx = SMICtx()
while True:
smi_ctx.rescan_devs()
smi_ctx.draw(args.list)
if args.list: break
time.sleep(1)
except KeyboardInterrupt:
print("Exiting...")

View File

@@ -0,0 +1,279 @@
/*
* Copyright 2018 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef AMDGPU_DOORBELL_H
#define AMDGPU_DOORBELL_H
enum AMDGPU_DOORBELL_ASSIGNMENT {
AMDGPU_DOORBELL_KIQ = 0x000,
AMDGPU_DOORBELL_HIQ = 0x001,
AMDGPU_DOORBELL_DIQ = 0x002,
AMDGPU_DOORBELL_MEC_RING0 = 0x010,
AMDGPU_DOORBELL_MEC_RING1 = 0x011,
AMDGPU_DOORBELL_MEC_RING2 = 0x012,
AMDGPU_DOORBELL_MEC_RING3 = 0x013,
AMDGPU_DOORBELL_MEC_RING4 = 0x014,
AMDGPU_DOORBELL_MEC_RING5 = 0x015,
AMDGPU_DOORBELL_MEC_RING6 = 0x016,
AMDGPU_DOORBELL_MEC_RING7 = 0x017,
AMDGPU_DOORBELL_GFX_RING0 = 0x020,
AMDGPU_DOORBELL_sDMA_ENGINE0 = 0x1E0,
AMDGPU_DOORBELL_sDMA_ENGINE1 = 0x1E1,
AMDGPU_DOORBELL_IH = 0x1E8,
AMDGPU_DOORBELL_MAX_ASSIGNMENT = 0x3FF,
AMDGPU_DOORBELL_INVALID = 0xFFFF
};
enum AMDGPU_VEGA20_DOORBELL_ASSIGNMENT {
/* Compute + GFX: 0~255 */
AMDGPU_VEGA20_DOORBELL_KIQ = 0x000,
AMDGPU_VEGA20_DOORBELL_HIQ = 0x001,
AMDGPU_VEGA20_DOORBELL_DIQ = 0x002,
AMDGPU_VEGA20_DOORBELL_MEC_RING0 = 0x003,
AMDGPU_VEGA20_DOORBELL_MEC_RING1 = 0x004,
AMDGPU_VEGA20_DOORBELL_MEC_RING2 = 0x005,
AMDGPU_VEGA20_DOORBELL_MEC_RING3 = 0x006,
AMDGPU_VEGA20_DOORBELL_MEC_RING4 = 0x007,
AMDGPU_VEGA20_DOORBELL_MEC_RING5 = 0x008,
AMDGPU_VEGA20_DOORBELL_MEC_RING6 = 0x009,
AMDGPU_VEGA20_DOORBELL_MEC_RING7 = 0x00A,
AMDGPU_VEGA20_DOORBELL_USERQUEUE_START = 0x00B,
AMDGPU_VEGA20_DOORBELL_USERQUEUE_END = 0x08A,
AMDGPU_VEGA20_DOORBELL_GFX_RING0 = 0x08B,
/* SDMA:256~335*/
AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE0 = 0x100,
AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE1 = 0x10A,
AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE2 = 0x114,
AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE3 = 0x11E,
AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE4 = 0x128,
AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE5 = 0x132,
AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE6 = 0x13C,
AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE7 = 0x146,
/* IH: 376~391 */
AMDGPU_VEGA20_DOORBELL_IH = 0x178,
/* MMSCH: 392~407
* overlap the doorbell assignment with VCN as they are mutually exclusive
* VCN engine's doorbell is 32 bit and two VCN ring share one QWORD
*/
AMDGPU_VEGA20_DOORBELL64_VCN0_1 = 0x188, /* VNC0 */
AMDGPU_VEGA20_DOORBELL64_VCN2_3 = 0x189,
AMDGPU_VEGA20_DOORBELL64_VCN4_5 = 0x18A,
AMDGPU_VEGA20_DOORBELL64_VCN6_7 = 0x18B,
AMDGPU_VEGA20_DOORBELL64_VCN8_9 = 0x18C, /* VNC1 */
AMDGPU_VEGA20_DOORBELL64_VCNa_b = 0x18D,
AMDGPU_VEGA20_DOORBELL64_VCNc_d = 0x18E,
AMDGPU_VEGA20_DOORBELL64_VCNe_f = 0x18F,
AMDGPU_VEGA20_DOORBELL64_UVD_RING0_1 = 0x188,
AMDGPU_VEGA20_DOORBELL64_UVD_RING2_3 = 0x189,
AMDGPU_VEGA20_DOORBELL64_UVD_RING4_5 = 0x18A,
AMDGPU_VEGA20_DOORBELL64_UVD_RING6_7 = 0x18B,
AMDGPU_VEGA20_DOORBELL64_VCE_RING0_1 = 0x18C,
AMDGPU_VEGA20_DOORBELL64_VCE_RING2_3 = 0x18D,
AMDGPU_VEGA20_DOORBELL64_VCE_RING4_5 = 0x18E,
AMDGPU_VEGA20_DOORBELL64_VCE_RING6_7 = 0x18F,
AMDGPU_VEGA20_DOORBELL64_FIRST_NON_CP = AMDGPU_VEGA20_DOORBELL_sDMA_ENGINE0,
AMDGPU_VEGA20_DOORBELL64_LAST_NON_CP = AMDGPU_VEGA20_DOORBELL64_VCE_RING6_7,
/* kiq/kcq from second XCD. Max 8 XCDs */
AMDGPU_VEGA20_DOORBELL_XCC1_KIQ_START = 0x190,
/* 8 compute rings per GC. Max to 0x1CE */
AMDGPU_VEGA20_DOORBELL_XCC1_MEC_RING0_START = 0x197,
/* AID1 SDMA: 0x1D0 ~ 0x1F7 */
AMDGPU_VEGA20_DOORBELL_AID1_sDMA_START = 0x1D0,
AMDGPU_VEGA20_DOORBELL_MAX_ASSIGNMENT = 0x1F7,
AMDGPU_VEGA20_DOORBELL_INVALID = 0xFFFF
};
enum AMDGPU_NAVI10_DOORBELL_ASSIGNMENT {
/* Compute + GFX: 0~255 */
AMDGPU_NAVI10_DOORBELL_KIQ = 0x000,
AMDGPU_NAVI10_DOORBELL_HIQ = 0x001,
AMDGPU_NAVI10_DOORBELL_DIQ = 0x002,
AMDGPU_NAVI10_DOORBELL_MEC_RING0 = 0x003,
AMDGPU_NAVI10_DOORBELL_MEC_RING1 = 0x004,
AMDGPU_NAVI10_DOORBELL_MEC_RING2 = 0x005,
AMDGPU_NAVI10_DOORBELL_MEC_RING3 = 0x006,
AMDGPU_NAVI10_DOORBELL_MEC_RING4 = 0x007,
AMDGPU_NAVI10_DOORBELL_MEC_RING5 = 0x008,
AMDGPU_NAVI10_DOORBELL_MEC_RING6 = 0x009,
AMDGPU_NAVI10_DOORBELL_MEC_RING7 = 0x00A,
AMDGPU_NAVI10_DOORBELL_MES_RING0 = 0x00B,
AMDGPU_NAVI10_DOORBELL_MES_RING1 = 0x00C,
AMDGPU_NAVI10_DOORBELL_USERQUEUE_START = 0x00D,
AMDGPU_NAVI10_DOORBELL_USERQUEUE_END = 0x08A,
AMDGPU_NAVI10_DOORBELL_GFX_RING0 = 0x08B,
AMDGPU_NAVI10_DOORBELL_GFX_RING1 = 0x08C,
AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_START = 0x08D,
AMDGPU_NAVI10_DOORBELL_GFX_USERQUEUE_END = 0x0FF,
/* SDMA:256~335*/
AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0 = 0x100,
AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE1 = 0x10A,
AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE2 = 0x114,
AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE3 = 0x11E,
/* IH: 376~391 */
AMDGPU_NAVI10_DOORBELL_IH = 0x178,
/* MMSCH: 392~407
* overlap the doorbell assignment with VCN as they are mutually exclusive
* VCE engine's doorbell is 32 bit and two VCE ring share one QWORD
*/
AMDGPU_NAVI10_DOORBELL64_VCN0_1 = 0x188, /* lower 32 bits for VNC0 and upper 32 bits for VNC1 */
AMDGPU_NAVI10_DOORBELL64_VCN2_3 = 0x189,
AMDGPU_NAVI10_DOORBELL64_VCN4_5 = 0x18A,
AMDGPU_NAVI10_DOORBELL64_VCN6_7 = 0x18B,
AMDGPU_NAVI10_DOORBELL64_VCN8_9 = 0x18C,
AMDGPU_NAVI10_DOORBELL64_VCNa_b = 0x18D,
AMDGPU_NAVI10_DOORBELL64_VCNc_d = 0x18E,
AMDGPU_NAVI10_DOORBELL64_VCNe_f = 0x18F,
AMDGPU_NAVI10_DOORBELL64_VPE = 0x190,
AMDGPU_NAVI10_DOORBELL64_FIRST_NON_CP = AMDGPU_NAVI10_DOORBELL_sDMA_ENGINE0,
AMDGPU_NAVI10_DOORBELL64_LAST_NON_CP = AMDGPU_NAVI10_DOORBELL64_VPE,
AMDGPU_NAVI10_DOORBELL_MAX_ASSIGNMENT = AMDGPU_NAVI10_DOORBELL64_VPE,
AMDGPU_NAVI10_DOORBELL_INVALID = 0xFFFF
};
/*
* 64bit doorbell, offset are in QWORD, occupy 2KB doorbell space
*/
enum AMDGPU_DOORBELL64_ASSIGNMENT {
/*
* All compute related doorbells: kiq, hiq, diq, traditional compute queue, user queue, should locate in
* a continues range so that programming CP_MEC_DOORBELL_RANGE_LOWER/UPPER can cover this range.
* Compute related doorbells are allocated from 0x00 to 0x8a
*/
/* kernel scheduling */
AMDGPU_DOORBELL64_KIQ = 0x00,
/* HSA interface queue and debug queue */
AMDGPU_DOORBELL64_HIQ = 0x01,
AMDGPU_DOORBELL64_DIQ = 0x02,
/* Compute engines */
AMDGPU_DOORBELL64_MEC_RING0 = 0x03,
AMDGPU_DOORBELL64_MEC_RING1 = 0x04,
AMDGPU_DOORBELL64_MEC_RING2 = 0x05,
AMDGPU_DOORBELL64_MEC_RING3 = 0x06,
AMDGPU_DOORBELL64_MEC_RING4 = 0x07,
AMDGPU_DOORBELL64_MEC_RING5 = 0x08,
AMDGPU_DOORBELL64_MEC_RING6 = 0x09,
AMDGPU_DOORBELL64_MEC_RING7 = 0x0a,
/* User queue doorbell range (128 doorbells) */
AMDGPU_DOORBELL64_USERQUEUE_START = 0x0b,
AMDGPU_DOORBELL64_USERQUEUE_END = 0x8a,
/* Graphics engine */
AMDGPU_DOORBELL64_GFX_RING0 = 0x8b,
/*
* Other graphics doorbells can be allocated here: from 0x8c to 0xdf
* Graphics voltage island aperture 1
* default non-graphics QWORD index is 0xe0 - 0xFF inclusive
*/
/* For vega10 sriov, the sdma doorbell must be fixed as follow
* to keep the same setting with host driver, or it will
* happen conflicts
*/
AMDGPU_DOORBELL64_sDMA_ENGINE0 = 0xF0,
AMDGPU_DOORBELL64_sDMA_HI_PRI_ENGINE0 = 0xF1,
AMDGPU_DOORBELL64_sDMA_ENGINE1 = 0xF2,
AMDGPU_DOORBELL64_sDMA_HI_PRI_ENGINE1 = 0xF3,
/* Interrupt handler */
AMDGPU_DOORBELL64_IH = 0xF4, /* For legacy interrupt ring buffer */
AMDGPU_DOORBELL64_IH_RING1 = 0xF5, /* For page migration request log */
AMDGPU_DOORBELL64_IH_RING2 = 0xF6, /* For page migration translation/invalidation log */
/* VCN engine use 32 bits doorbell */
AMDGPU_DOORBELL64_VCN0_1 = 0xF8, /* lower 32 bits for VNC0 and upper 32 bits for VNC1 */
AMDGPU_DOORBELL64_VCN2_3 = 0xF9,
AMDGPU_DOORBELL64_VCN4_5 = 0xFA,
AMDGPU_DOORBELL64_VCN6_7 = 0xFB,
/* overlap the doorbell assignment with VCN as they are mutually exclusive
* VCE engine's doorbell is 32 bit and two VCE ring share one QWORD
*/
AMDGPU_DOORBELL64_UVD_RING0_1 = 0xF8,
AMDGPU_DOORBELL64_UVD_RING2_3 = 0xF9,
AMDGPU_DOORBELL64_UVD_RING4_5 = 0xFA,
AMDGPU_DOORBELL64_UVD_RING6_7 = 0xFB,
AMDGPU_DOORBELL64_VCE_RING0_1 = 0xFC,
AMDGPU_DOORBELL64_VCE_RING2_3 = 0xFD,
AMDGPU_DOORBELL64_VCE_RING4_5 = 0xFE,
AMDGPU_DOORBELL64_VCE_RING6_7 = 0xFF,
AMDGPU_DOORBELL64_FIRST_NON_CP = AMDGPU_DOORBELL64_sDMA_ENGINE0,
AMDGPU_DOORBELL64_LAST_NON_CP = AMDGPU_DOORBELL64_VCE_RING6_7,
AMDGPU_DOORBELL64_MAX_ASSIGNMENT = 0xFF,
AMDGPU_DOORBELL64_INVALID = 0xFFFF
};
enum AMDGPU_DOORBELL_ASSIGNMENT_LAYOUT1 {
/* XCC0: 0x00 ~20, XCC1: 20 ~ 2F ... */
/* KIQ/HIQ/DIQ */
AMDGPU_DOORBELL_LAYOUT1_KIQ_START = 0x000,
AMDGPU_DOORBELL_LAYOUT1_HIQ = 0x001,
AMDGPU_DOORBELL_LAYOUT1_DIQ = 0x002,
/* Compute: 0x08 ~ 0x20 */
AMDGPU_DOORBELL_LAYOUT1_MEC_RING_START = 0x008,
AMDGPU_DOORBELL_LAYOUT1_MEC_RING_END = 0x00F,
AMDGPU_DOORBELL_LAYOUT1_USERQUEUE_START = 0x010,
AMDGPU_DOORBELL_LAYOUT1_USERQUEUE_END = 0x01F,
AMDGPU_DOORBELL_LAYOUT1_XCC_RANGE = 0x020,
/* SDMA: 0x100 ~ 0x19F */
AMDGPU_DOORBELL_LAYOUT1_sDMA_ENGINE_START = 0x100,
AMDGPU_DOORBELL_LAYOUT1_sDMA_ENGINE_END = 0x19F,
/* IH: 0x1A0 ~ 0x1AF */
AMDGPU_DOORBELL_LAYOUT1_IH = 0x1A0,
/* VCN: 0x1B0 ~ 0x1E8 */
AMDGPU_DOORBELL_LAYOUT1_VCN_START = 0x1B0,
AMDGPU_DOORBELL_LAYOUT1_VCN_END = 0x1E8,
AMDGPU_DOORBELL_LAYOUT1_FIRST_NON_CP = AMDGPU_DOORBELL_LAYOUT1_sDMA_ENGINE_START,
AMDGPU_DOORBELL_LAYOUT1_LAST_NON_CP = AMDGPU_DOORBELL_LAYOUT1_VCN_END,
AMDGPU_DOORBELL_LAYOUT1_MAX_ASSIGNMENT = 0x1E8,
AMDGPU_DOORBELL_LAYOUT1_INVALID = 0xFFFF
};
#endif

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2014 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __AMDGPU_IRQ_H__
#define __AMDGPU_IRQ_H__
// #include <linux/irqdomain.h>
// #include "soc15_ih_clientid.h"
// #include "amdgpu_ih.h"
#define bool _Bool
#define AMDGPU_MAX_IRQ_SRC_ID 0x100
#define AMDGPU_MAX_IRQ_CLIENT_ID 0x100
#define AMDGPU_IRQ_CLIENTID_LEGACY 0
#define AMDGPU_IRQ_CLIENTID_MAX SOC15_IH_CLIENTID_MAX
#define AMDGPU_IRQ_SRC_DATA_MAX_SIZE_DW 4
struct amdgpu_device;
enum amdgpu_interrupt_state {
AMDGPU_IRQ_STATE_DISABLE,
AMDGPU_IRQ_STATE_ENABLE,
};
struct amdgpu_iv_entry {
// struct amdgpu_ih_ring *ih;
unsigned client_id;
unsigned src_id;
unsigned ring_id;
unsigned vmid;
unsigned vmid_src;
uint64_t timestamp;
unsigned timestamp_src;
unsigned pasid;
unsigned node_id;
unsigned src_data[AMDGPU_IRQ_SRC_DATA_MAX_SIZE_DW];
const uint32_t *iv_entry;
};
enum interrupt_node_id_per_aid {
AID0_NODEID = 0,
XCD0_NODEID = 1,
XCD1_NODEID = 2,
AID1_NODEID = 4,
XCD2_NODEID = 5,
XCD3_NODEID = 6,
AID2_NODEID = 8,
XCD4_NODEID = 9,
XCD5_NODEID = 10,
AID3_NODEID = 12,
XCD6_NODEID = 13,
XCD7_NODEID = 14,
NODEID_MAX,
};
#endif

View File

@@ -0,0 +1,559 @@
/*
* Copyright 2016 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Author: Huang Rui
*
*/
#ifndef __AMDGPU_PSP_H__
#define __AMDGPU_PSP_H__
// #include "amdgpu.h"
// #include "psp_gfx_if.h"
// #include "ta_xgmi_if.h"
// #include "ta_ras_if.h"
// #include "ta_rap_if.h"
// #include "ta_secureDisplay_if.h"
#define PSP_FENCE_BUFFER_SIZE 0x1000
#define PSP_CMD_BUFFER_SIZE 0x1000
#define PSP_1_MEG 0x100000
#define PSP_TMR_SIZE(adev) ((adev)->asic_type == CHIP_ALDEBARAN ? 0x800000 : 0x400000)
#define PSP_TMR_ALIGNMENT 0x100000
#define PSP_FW_NAME_LEN 0x24
// extern const struct attribute_group amdgpu_flash_attr_group;
enum psp_shared_mem_size {
PSP_ASD_SHARED_MEM_SIZE = 0x0,
PSP_XGMI_SHARED_MEM_SIZE = 0x4000,
PSP_RAS_SHARED_MEM_SIZE = 0x4000,
PSP_HDCP_SHARED_MEM_SIZE = 0x4000,
PSP_DTM_SHARED_MEM_SIZE = 0x4000,
PSP_RAP_SHARED_MEM_SIZE = 0x4000,
PSP_SECUREDISPLAY_SHARED_MEM_SIZE = 0x4000,
};
enum ta_type_id {
TA_TYPE_XGMI = 1,
TA_TYPE_RAS,
TA_TYPE_HDCP,
TA_TYPE_DTM,
TA_TYPE_RAP,
TA_TYPE_SECUREDISPLAY,
TA_TYPE_MAX_INDEX,
};
struct psp_context;
struct psp_xgmi_node_info;
struct psp_xgmi_topology_info;
struct psp_bin_desc;
enum psp_bootloader_cmd {
PSP_BL__LOAD_SYSDRV = 0x10000,
PSP_BL__LOAD_SOSDRV = 0x20000,
PSP_BL__LOAD_KEY_DATABASE = 0x80000,
PSP_BL__LOAD_SOCDRV = 0xB0000,
PSP_BL__LOAD_DBGDRV = 0xC0000,
PSP_BL__LOAD_HADDRV = PSP_BL__LOAD_DBGDRV,
PSP_BL__LOAD_INTFDRV = 0xD0000,
PSP_BL__LOAD_RASDRV = 0xE0000,
PSP_BL__LOAD_IPKEYMGRDRV = 0xF0000,
PSP_BL__DRAM_LONG_TRAIN = 0x100000,
PSP_BL__DRAM_SHORT_TRAIN = 0x200000,
PSP_BL__LOAD_TOS_SPL_TABLE = 0x10000000,
};
enum psp_ring_type {
PSP_RING_TYPE__INVALID = 0,
/*
* These values map to the way the PSP kernel identifies the
* rings.
*/
PSP_RING_TYPE__UM = 1, /* User mode ring (formerly called RBI) */
PSP_RING_TYPE__KM = 2 /* Kernel mode ring (formerly called GPCOM) */
};
// struct psp_ring {
// enum psp_ring_type ring_type;
// struct psp_gfx_rb_frame *ring_mem;
// uint64_t ring_mem_mc_addr;
// void *ring_mem_handle;
// uint32_t ring_size;
// uint32_t ring_wptr;
// };
/* More registers may will be supported */
enum psp_reg_prog_id {
PSP_REG_IH_RB_CNTL = 0, /* register IH_RB_CNTL */
PSP_REG_IH_RB_CNTL_RING1 = 1, /* register IH_RB_CNTL_RING1 */
PSP_REG_IH_RB_CNTL_RING2 = 2, /* register IH_RB_CNTL_RING2 */
PSP_REG_LAST
};
// struct psp_funcs {
// int (*init_microcode)(struct psp_context *psp);
// int (*wait_for_bootloader)(struct psp_context *psp);
// int (*bootloader_load_kdb)(struct psp_context *psp);
// int (*bootloader_load_spl)(struct psp_context *psp);
// int (*bootloader_load_sysdrv)(struct psp_context *psp);
// int (*bootloader_load_soc_drv)(struct psp_context *psp);
// int (*bootloader_load_intf_drv)(struct psp_context *psp);
// int (*bootloader_load_dbg_drv)(struct psp_context *psp);
// int (*bootloader_load_ras_drv)(struct psp_context *psp);
// int (*bootloader_load_ipkeymgr_drv)(struct psp_context *psp);
// int (*bootloader_load_sos)(struct psp_context *psp);
// int (*ring_create)(struct psp_context *psp,
// enum psp_ring_type ring_type);
// int (*ring_stop)(struct psp_context *psp,
// enum psp_ring_type ring_type);
// int (*ring_destroy)(struct psp_context *psp,
// enum psp_ring_type ring_type);
// bool (*smu_reload_quirk)(struct psp_context *psp);
// int (*mode1_reset)(struct psp_context *psp);
// int (*mem_training)(struct psp_context *psp, uint32_t ops);
// uint32_t (*ring_get_wptr)(struct psp_context *psp);
// void (*ring_set_wptr)(struct psp_context *psp, uint32_t value);
// int (*load_usbc_pd_fw)(struct psp_context *psp, uint64_t fw_pri_mc_addr);
// int (*read_usbc_pd_fw)(struct psp_context *psp, uint32_t *fw_ver);
// int (*update_spirom)(struct psp_context *psp, uint64_t fw_pri_mc_addr);
// int (*vbflash_stat)(struct psp_context *psp);
// int (*fatal_error_recovery_quirk)(struct psp_context *psp);
// bool (*get_ras_capability)(struct psp_context *psp);
// bool (*is_aux_sos_load_required)(struct psp_context *psp);
// };
// struct ta_funcs {
// int (*fn_ta_initialize)(struct psp_context *psp);
// int (*fn_ta_invoke)(struct psp_context *psp, uint32_t ta_cmd_id);
// int (*fn_ta_terminate)(struct psp_context *psp);
// };
#define AMDGPU_XGMI_MAX_CONNECTED_NODES 64
// struct psp_xgmi_node_info {
// uint64_t node_id;
// uint8_t num_hops;
// uint8_t is_sharing_enabled;
// enum ta_xgmi_assigned_sdma_engine sdma_engine;
// uint8_t num_links;
// struct xgmi_connected_port_num port_num[TA_XGMI__MAX_PORT_NUM];
// };
// struct psp_xgmi_topology_info {
// uint32_t num_nodes;
// struct psp_xgmi_node_info nodes[AMDGPU_XGMI_MAX_CONNECTED_NODES];
// };
// struct psp_bin_desc {
// uint32_t fw_version;
// uint32_t feature_version;
// uint32_t size_bytes;
// uint8_t *start_addr;
// };
// struct ta_mem_context {
// struct amdgpu_bo *shared_bo;
// uint64_t shared_mc_addr;
// void *shared_buf;
// enum psp_shared_mem_size shared_mem_size;
// };
// struct ta_context {
// bool initialized;
// uint32_t session_id;
// uint32_t resp_status;
// struct ta_mem_context mem_context;
// struct psp_bin_desc bin_desc;
// enum psp_gfx_cmd_id ta_load_type;
// enum ta_type_id ta_type;
// };
// struct ta_cp_context {
// struct ta_context context;
// struct mutex mutex;
// };
// struct psp_xgmi_context {
// struct ta_context context;
// struct psp_xgmi_topology_info top_info;
// bool supports_extended_data;
// uint8_t xgmi_ta_caps;
// };
// struct psp_ras_context {
// struct ta_context context;
// struct amdgpu_ras *ras;
// };
#define MEM_TRAIN_SYSTEM_SIGNATURE 0x54534942
#define GDDR6_MEM_TRAINING_DATA_SIZE_IN_BYTES 0x1000
#define GDDR6_MEM_TRAINING_OFFSET 0x8000
/*Define the VRAM size that will be encroached by BIST training.*/
#define BIST_MEM_TRAINING_ENCROACHED_SIZE 0x2000000
enum psp_memory_training_init_flag {
PSP_MEM_TRAIN_NOT_SUPPORT = 0x0,
PSP_MEM_TRAIN_SUPPORT = 0x1,
PSP_MEM_TRAIN_INIT_FAILED = 0x2,
PSP_MEM_TRAIN_RESERVE_SUCCESS = 0x4,
PSP_MEM_TRAIN_INIT_SUCCESS = 0x8,
};
enum psp_memory_training_ops {
PSP_MEM_TRAIN_SEND_LONG_MSG = 0x1,
PSP_MEM_TRAIN_SAVE = 0x2,
PSP_MEM_TRAIN_RESTORE = 0x4,
PSP_MEM_TRAIN_SEND_SHORT_MSG = 0x8,
PSP_MEM_TRAIN_COLD_BOOT = PSP_MEM_TRAIN_SEND_LONG_MSG,
PSP_MEM_TRAIN_RESUME = PSP_MEM_TRAIN_SEND_SHORT_MSG,
};
// struct psp_memory_training_context {
// /*training data size*/
// u64 train_data_size;
// /*
// * sys_cache
// * cpu virtual address
// * system memory buffer that used to store the training data.
// */
// void *sys_cache;
// /*vram offset of the p2c training data*/
// u64 p2c_train_data_offset;
// /*vram offset of the c2p training data*/
// u64 c2p_train_data_offset;
// struct amdgpu_bo *c2p_bo;
// enum psp_memory_training_init_flag init;
// u32 training_cnt;
// bool enable_mem_training;
// };
/** PSP runtime DB **/
#define PSP_RUNTIME_DB_SIZE_IN_BYTES 0x10000
#define PSP_RUNTIME_DB_OFFSET 0x100000
#define PSP_RUNTIME_DB_COOKIE_ID 0x0ed5
#define PSP_RUNTIME_DB_VER_1 0x0100
#define PSP_RUNTIME_DB_DIAG_ENTRY_MAX_COUNT 0x40
enum psp_runtime_entry_type {
PSP_RUNTIME_ENTRY_TYPE_INVALID = 0x0,
PSP_RUNTIME_ENTRY_TYPE_TEST = 0x1,
PSP_RUNTIME_ENTRY_TYPE_MGPU_COMMON = 0x2, /* Common mGPU runtime data */
PSP_RUNTIME_ENTRY_TYPE_MGPU_WAFL = 0x3, /* WAFL runtime data */
PSP_RUNTIME_ENTRY_TYPE_MGPU_XGMI = 0x4, /* XGMI runtime data */
PSP_RUNTIME_ENTRY_TYPE_BOOT_CONFIG = 0x5, /* Boot Config runtime data */
PSP_RUNTIME_ENTRY_TYPE_PPTABLE_ERR_STATUS = 0x6, /* SCPM validation data */
};
/* PSP runtime DB header */
// struct psp_runtime_data_header {
// /* determine the existence of runtime db */
// uint16_t cookie;
// /* version of runtime db */
// uint16_t version;
// };
// /* PSP runtime DB entry */
// struct psp_runtime_entry {
// /* type of runtime db entry */
// uint32_t entry_type;
// /* offset of entry in bytes */
// uint16_t offset;
// /* size of entry in bytes */
// uint16_t size;
// };
// /* PSP runtime DB directory */
// struct psp_runtime_data_directory {
// /* number of valid entries */
// uint16_t entry_count;
// /* db entries*/
// struct psp_runtime_entry entry_list[PSP_RUNTIME_DB_DIAG_ENTRY_MAX_COUNT];
// };
/* PSP runtime DB boot config feature bitmask */
enum psp_runtime_boot_cfg_feature {
BOOT_CFG_FEATURE_GECC = 0x1,
BOOT_CFG_FEATURE_TWO_STAGE_DRAM_TRAINING = 0x2,
};
/* PSP run time DB SCPM authentication defines */
enum psp_runtime_scpm_authentication {
SCPM_DISABLE = 0x0,
SCPM_ENABLE = 0x1,
SCPM_ENABLE_WITH_SCPM_ERR = 0x2,
};
/* PSP runtime DB boot config entry */
// struct psp_runtime_boot_cfg_entry {
// uint32_t boot_cfg_bitmask;
// uint32_t reserved;
// };
// /* PSP runtime DB SCPM entry */
// struct psp_runtime_scpm_entry {
// enum psp_runtime_scpm_authentication scpm_status;
// };
// struct psp_context {
// struct amdgpu_device *adev;
// struct psp_ring km_ring;
// struct psp_gfx_cmd_resp *cmd;
// const struct psp_funcs *funcs;
// const struct ta_funcs *ta_funcs;
// /* firmware buffer */
// struct amdgpu_bo *fw_pri_bo;
// uint64_t fw_pri_mc_addr;
// void *fw_pri_buf;
// /* sos firmware */
// const struct firmware *sos_fw;
// struct psp_bin_desc sys;
// struct psp_bin_desc sos;
// struct psp_bin_desc toc;
// struct psp_bin_desc kdb;
// struct psp_bin_desc spl;
// struct psp_bin_desc rl;
// struct psp_bin_desc soc_drv;
// struct psp_bin_desc intf_drv;
// struct psp_bin_desc dbg_drv;
// struct psp_bin_desc ras_drv;
// struct psp_bin_desc ipkeymgr_drv;
// /* tmr buffer */
// struct amdgpu_bo *tmr_bo;
// uint64_t tmr_mc_addr;
// /* asd firmware */
// const struct firmware *asd_fw;
// /* toc firmware */
// const struct firmware *toc_fw;
// /* cap firmware */
// const struct firmware *cap_fw;
// /* fence buffer */
// struct amdgpu_bo *fence_buf_bo;
// uint64_t fence_buf_mc_addr;
// void *fence_buf;
// /* cmd buffer */
// struct amdgpu_bo *cmd_buf_bo;
// uint64_t cmd_buf_mc_addr;
// struct psp_gfx_cmd_resp *cmd_buf_mem;
// /* fence value associated with cmd buffer */
// atomic_t fence_value;
// /* flag to mark whether gfx fw autoload is supported or not */
// bool autoload_supported;
// /* flag to mark whether psp use runtime TMR or boottime TMR */
// bool boot_time_tmr;
// /* flag to mark whether df cstate management centralized to PMFW */
// bool pmfw_centralized_cstate_management;
// /* xgmi ta firmware and buffer */
// const struct firmware *ta_fw;
// uint32_t ta_fw_version;
// uint32_t cap_fw_version;
// uint32_t cap_feature_version;
// uint32_t cap_ucode_size;
// struct ta_context asd_context;
// struct psp_xgmi_context xgmi_context;
// struct psp_ras_context ras_context;
// struct ta_cp_context hdcp_context;
// struct ta_cp_context dtm_context;
// struct ta_cp_context rap_context;
// struct ta_cp_context securedisplay_context;
// struct mutex mutex;
// struct psp_memory_training_context mem_train_ctx;
// uint32_t boot_cfg_bitmask;
// /* firmware upgrades supported */
// bool sup_pd_fw_up;
// bool sup_ifwi_up;
// char *vbflash_tmp_buf;
// size_t vbflash_image_size;
// bool vbflash_done;
// };
// struct amdgpu_psp_funcs {
// bool (*check_fw_loading_status)(struct amdgpu_device *adev,
// enum AMDGPU_UCODE_ID);
// };
// #define psp_ring_create(psp, type) (psp)->funcs->ring_create((psp), (type))
// #define psp_ring_stop(psp, type) (psp)->funcs->ring_stop((psp), (type))
// #define psp_ring_destroy(psp, type) ((psp)->funcs->ring_destroy((psp), (type)))
// #define psp_init_microcode(psp) \
// ((psp)->funcs->init_microcode ? (psp)->funcs->init_microcode((psp)) : 0)
// #define psp_bootloader_load_kdb(psp) \
// ((psp)->funcs->bootloader_load_kdb ? (psp)->funcs->bootloader_load_kdb((psp)) : 0)
// #define psp_bootloader_load_spl(psp) \
// ((psp)->funcs->bootloader_load_spl ? (psp)->funcs->bootloader_load_spl((psp)) : 0)
// #define psp_bootloader_load_sysdrv(psp) \
// ((psp)->funcs->bootloader_load_sysdrv ? (psp)->funcs->bootloader_load_sysdrv((psp)) : 0)
// #define psp_bootloader_load_soc_drv(psp) \
// ((psp)->funcs->bootloader_load_soc_drv ? (psp)->funcs->bootloader_load_soc_drv((psp)) : 0)
// #define psp_bootloader_load_intf_drv(psp) \
// ((psp)->funcs->bootloader_load_intf_drv ? (psp)->funcs->bootloader_load_intf_drv((psp)) : 0)
// #define psp_bootloader_load_dbg_drv(psp) \
// ((psp)->funcs->bootloader_load_dbg_drv ? (psp)->funcs->bootloader_load_dbg_drv((psp)) : 0)
// #define psp_bootloader_load_ras_drv(psp) \
// ((psp)->funcs->bootloader_load_ras_drv ? \
// (psp)->funcs->bootloader_load_ras_drv((psp)) : 0)
// #define psp_bootloader_load_ipkeymgr_drv(psp) \
// ((psp)->funcs->bootloader_load_ipkeymgr_drv ? \
// (psp)->funcs->bootloader_load_ipkeymgr_drv((psp)) : 0)
// #define psp_bootloader_load_sos(psp) \
// ((psp)->funcs->bootloader_load_sos ? (psp)->funcs->bootloader_load_sos((psp)) : 0)
// #define psp_smu_reload_quirk(psp) \
// ((psp)->funcs->smu_reload_quirk ? (psp)->funcs->smu_reload_quirk((psp)) : false)
// #define psp_mode1_reset(psp) \
// ((psp)->funcs->mode1_reset ? (psp)->funcs->mode1_reset((psp)) : false)
// #define psp_mem_training(psp, ops) \
// ((psp)->funcs->mem_training ? (psp)->funcs->mem_training((psp), (ops)) : 0)
// #define psp_ring_get_wptr(psp) (psp)->funcs->ring_get_wptr((psp))
// #define psp_ring_set_wptr(psp, value) (psp)->funcs->ring_set_wptr((psp), (value))
// #define psp_load_usbc_pd_fw(psp, fw_pri_mc_addr) \
// ((psp)->funcs->load_usbc_pd_fw ? \
// (psp)->funcs->load_usbc_pd_fw((psp), (fw_pri_mc_addr)) : -EINVAL)
// #define psp_read_usbc_pd_fw(psp, fw_ver) \
// ((psp)->funcs->read_usbc_pd_fw ? \
// (psp)->funcs->read_usbc_pd_fw((psp), fw_ver) : -EINVAL)
// #define psp_update_spirom(psp, fw_pri_mc_addr) \
// ((psp)->funcs->update_spirom ? \
// (psp)->funcs->update_spirom((psp), fw_pri_mc_addr) : -EINVAL)
// #define psp_vbflash_status(psp) \
// ((psp)->funcs->vbflash_stat ? \
// (psp)->funcs->vbflash_stat((psp)) : -EINVAL)
// #define psp_fatal_error_recovery_quirk(psp) \
// ((psp)->funcs->fatal_error_recovery_quirk ? \
// (psp)->funcs->fatal_error_recovery_quirk((psp)) : 0)
// #define psp_is_aux_sos_load_required(psp) \
// ((psp)->funcs->is_aux_sos_load_required ? (psp)->funcs->is_aux_sos_load_required((psp)) : 0)
// extern const struct amd_ip_funcs psp_ip_funcs;
// extern const struct amdgpu_ip_block_version psp_v3_1_ip_block;
// extern const struct amdgpu_ip_block_version psp_v10_0_ip_block;
// extern const struct amdgpu_ip_block_version psp_v11_0_ip_block;
// extern const struct amdgpu_ip_block_version psp_v11_0_8_ip_block;
// extern const struct amdgpu_ip_block_version psp_v12_0_ip_block;
// extern const struct amdgpu_ip_block_version psp_v13_0_ip_block;
// extern const struct amdgpu_ip_block_version psp_v13_0_4_ip_block;
// extern const struct amdgpu_ip_block_version psp_v14_0_ip_block;
// extern int psp_wait_for(struct psp_context *psp, uint32_t reg_index,
// uint32_t field_val, uint32_t mask, bool check_changed);
// extern int psp_wait_for_spirom_update(struct psp_context *psp, uint32_t reg_index,
// uint32_t field_val, uint32_t mask, uint32_t msec_timeout);
// int psp_execute_ip_fw_load(struct psp_context *psp,
// struct amdgpu_firmware_info *ucode);
// int psp_gpu_reset(struct amdgpu_device *adev);
// int psp_ta_init_shared_buf(struct psp_context *psp,
// struct ta_mem_context *mem_ctx);
// void psp_ta_free_shared_buf(struct ta_mem_context *mem_ctx);
// int psp_ta_unload(struct psp_context *psp, struct ta_context *context);
// int psp_ta_load(struct psp_context *psp, struct ta_context *context);
// int psp_ta_invoke(struct psp_context *psp,
// uint32_t ta_cmd_id,
// struct ta_context *context);
// int psp_xgmi_initialize(struct psp_context *psp, bool set_extended_data, bool load_ta);
// int psp_xgmi_terminate(struct psp_context *psp);
// int psp_xgmi_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
// int psp_xgmi_get_hive_id(struct psp_context *psp, uint64_t *hive_id);
// int psp_xgmi_get_node_id(struct psp_context *psp, uint64_t *node_id);
// int psp_xgmi_get_topology_info(struct psp_context *psp,
// int number_devices,
// struct psp_xgmi_topology_info *topology,
// bool get_extended_data);
// int psp_xgmi_set_topology_info(struct psp_context *psp,
// int number_devices,
// struct psp_xgmi_topology_info *topology);
// int psp_ras_initialize(struct psp_context *psp);
// int psp_ras_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
// int psp_ras_enable_features(struct psp_context *psp,
// union ta_ras_cmd_input *info, bool enable);
// int psp_ras_trigger_error(struct psp_context *psp,
// struct ta_ras_trigger_error_input *info, uint32_t instance_mask);
// int psp_ras_terminate(struct psp_context *psp);
// int psp_ras_query_address(struct psp_context *psp,
// struct ta_ras_query_address_input *addr_in,
// struct ta_ras_query_address_output *addr_out);
// int psp_hdcp_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
// int psp_dtm_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
// int psp_rap_invoke(struct psp_context *psp, uint32_t ta_cmd_id, enum ta_rap_status *status);
// int psp_securedisplay_invoke(struct psp_context *psp, uint32_t ta_cmd_id);
// int psp_rlc_autoload_start(struct psp_context *psp);
// int psp_reg_program(struct psp_context *psp, enum psp_reg_prog_id reg,
// uint32_t value);
// int psp_ring_cmd_submit(struct psp_context *psp,
// uint64_t cmd_buf_mc_addr,
// uint64_t fence_mc_addr,
// int index);
// int psp_init_asd_microcode(struct psp_context *psp,
// const char *chip_name);
// int psp_init_toc_microcode(struct psp_context *psp,
// const char *chip_name);
// int psp_init_sos_microcode(struct psp_context *psp,
// const char *chip_name);
// int psp_init_ta_microcode(struct psp_context *psp,
// const char *chip_name);
// int psp_init_cap_microcode(struct psp_context *psp,
// const char *chip_name);
// int psp_get_fw_attestation_records_addr(struct psp_context *psp,
// uint64_t *output_ptr);
// int psp_load_fw_list(struct psp_context *psp,
// struct amdgpu_firmware_info **ucode_list, int ucode_count);
// void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, uint32_t bin_size);
// int psp_spatial_partition(struct psp_context *psp, int mode);
// int is_psp_fw_valid(struct psp_bin_desc bin);
// int amdgpu_psp_wait_for_bootloader(struct amdgpu_device *adev);
// bool amdgpu_psp_get_ras_capability(struct psp_context *psp);
#endif

View File

@@ -0,0 +1,339 @@
/*
* Copyright 2019 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __AMDGPU_SMU_H__
#define __AMDGPU_SMU_H__
#define bool _Bool
#define SMU_THERMAL_MINIMUM_ALERT_TEMP 0
#define SMU_THERMAL_MAXIMUM_ALERT_TEMP 255
#define SMU_TEMPERATURE_UNITS_PER_CENTIGRADES 1000
#define SMU_FW_NAME_LEN 0x24
#define SMU_DPM_USER_PROFILE_RESTORE (1 << 0)
#define SMU_CUSTOM_FAN_SPEED_RPM (1 << 1)
#define SMU_CUSTOM_FAN_SPEED_PWM (1 << 2)
// Power Throttlers
#define SMU_THROTTLER_PPT0_BIT 0
#define SMU_THROTTLER_PPT1_BIT 1
#define SMU_THROTTLER_PPT2_BIT 2
#define SMU_THROTTLER_PPT3_BIT 3
#define SMU_THROTTLER_SPL_BIT 4
#define SMU_THROTTLER_FPPT_BIT 5
#define SMU_THROTTLER_SPPT_BIT 6
#define SMU_THROTTLER_SPPT_APU_BIT 7
// Current Throttlers
#define SMU_THROTTLER_TDC_GFX_BIT 16
#define SMU_THROTTLER_TDC_SOC_BIT 17
#define SMU_THROTTLER_TDC_MEM_BIT 18
#define SMU_THROTTLER_TDC_VDD_BIT 19
#define SMU_THROTTLER_TDC_CVIP_BIT 20
#define SMU_THROTTLER_EDC_CPU_BIT 21
#define SMU_THROTTLER_EDC_GFX_BIT 22
#define SMU_THROTTLER_APCC_BIT 23
// Temperature
#define SMU_THROTTLER_TEMP_GPU_BIT 32
#define SMU_THROTTLER_TEMP_CORE_BIT 33
#define SMU_THROTTLER_TEMP_MEM_BIT 34
#define SMU_THROTTLER_TEMP_EDGE_BIT 35
#define SMU_THROTTLER_TEMP_HOTSPOT_BIT 36
#define SMU_THROTTLER_TEMP_SOC_BIT 37
#define SMU_THROTTLER_TEMP_VR_GFX_BIT 38
#define SMU_THROTTLER_TEMP_VR_SOC_BIT 39
#define SMU_THROTTLER_TEMP_VR_MEM0_BIT 40
#define SMU_THROTTLER_TEMP_VR_MEM1_BIT 41
#define SMU_THROTTLER_TEMP_LIQUID0_BIT 42
#define SMU_THROTTLER_TEMP_LIQUID1_BIT 43
#define SMU_THROTTLER_VRHOT0_BIT 44
#define SMU_THROTTLER_VRHOT1_BIT 45
#define SMU_THROTTLER_PROCHOT_CPU_BIT 46
#define SMU_THROTTLER_PROCHOT_GFX_BIT 47
// Other
#define SMU_THROTTLER_PPM_BIT 56
#define SMU_THROTTLER_FIT_BIT 57
struct smu_hw_power_state {
unsigned int magic;
};
struct smu_power_state;
enum smu_state_ui_label {
SMU_STATE_UI_LABEL_NONE,
SMU_STATE_UI_LABEL_BATTERY,
SMU_STATE_UI_TABEL_MIDDLE_LOW,
SMU_STATE_UI_LABEL_BALLANCED,
SMU_STATE_UI_LABEL_MIDDLE_HIGHT,
SMU_STATE_UI_LABEL_PERFORMANCE,
SMU_STATE_UI_LABEL_BACO,
};
enum smu_state_classification_flag {
SMU_STATE_CLASSIFICATION_FLAG_BOOT = 0x0001,
SMU_STATE_CLASSIFICATION_FLAG_THERMAL = 0x0002,
SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE = 0x0004,
SMU_STATE_CLASSIFICATION_FLAG_RESET = 0x0008,
SMU_STATE_CLASSIFICATION_FLAG_FORCED = 0x0010,
SMU_STATE_CLASSIFICATION_FLAG_USER_3D_PERFORMANCE = 0x0020,
SMU_STATE_CLASSIFICATION_FLAG_USER_2D_PERFORMANCE = 0x0040,
SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE = 0x0080,
SMU_STATE_CLASSIFICATION_FLAG_AC_OVERDIRVER_TEMPLATE = 0x0100,
SMU_STATE_CLASSIFICATION_FLAG_UVD = 0x0200,
SMU_STATE_CLASSIFICATION_FLAG_3D_PERFORMANCE_LOW = 0x0400,
SMU_STATE_CLASSIFICATION_FLAG_ACPI = 0x0800,
SMU_STATE_CLASSIFICATION_FLAG_HD2 = 0x1000,
SMU_STATE_CLASSIFICATION_FLAG_UVD_HD = 0x2000,
SMU_STATE_CLASSIFICATION_FLAG_UVD_SD = 0x4000,
SMU_STATE_CLASSIFICATION_FLAG_USER_DC_PERFORMANCE = 0x8000,
SMU_STATE_CLASSIFICATION_FLAG_DC_OVERDIRVER_TEMPLATE = 0x10000,
SMU_STATE_CLASSIFICATION_FLAG_BACO = 0x20000,
SMU_STATE_CLASSIFICATIN_FLAG_LIMITED_POWER_SOURCE2 = 0x40000,
SMU_STATE_CLASSIFICATION_FLAG_ULV = 0x80000,
SMU_STATE_CLASSIFICATION_FLAG_UVD_MVC = 0x100000,
};
struct smu_state_classification_block {
enum smu_state_ui_label ui_label;
enum smu_state_classification_flag flags;
int bios_index;
bool temporary_state;
bool to_be_deleted;
};
struct smu_state_pcie_block {
unsigned int lanes;
};
enum smu_refreshrate_source {
SMU_REFRESHRATE_SOURCE_EDID,
SMU_REFRESHRATE_SOURCE_EXPLICIT
};
struct smu_state_display_block {
bool disable_frame_modulation;
bool limit_refreshrate;
enum smu_refreshrate_source refreshrate_source;
int explicit_refreshrate;
int edid_refreshrate_index;
bool enable_vari_bright;
};
struct smu_state_memory_block {
bool dll_off;
uint8_t m3arb;
uint8_t unused[3];
};
struct smu_state_software_algorithm_block {
bool disable_load_balancing;
bool enable_sleep_for_timestamps;
};
struct smu_temperature_range {
int min;
int max;
int edge_emergency_max;
int hotspot_min;
int hotspot_crit_max;
int hotspot_emergency_max;
int mem_min;
int mem_crit_max;
int mem_emergency_max;
int software_shutdown_temp;
int software_shutdown_temp_offset;
};
struct smu_state_validation_block {
bool single_display_only;
bool disallow_on_dc;
uint8_t supported_power_levels;
};
struct smu_uvd_clocks {
uint32_t vclk;
uint32_t dclk;
};
/**
* Structure to hold a SMU Power State.
*/
enum smu_power_src_type {
SMU_POWER_SOURCE_AC,
SMU_POWER_SOURCE_DC,
SMU_POWER_SOURCE_COUNT,
};
enum smu_ppt_limit_type {
SMU_DEFAULT_PPT_LIMIT = 0,
SMU_FAST_PPT_LIMIT,
};
enum smu_ppt_limit_level {
SMU_PPT_LIMIT_MIN = -1,
SMU_PPT_LIMIT_CURRENT,
SMU_PPT_LIMIT_DEFAULT,
SMU_PPT_LIMIT_MAX,
};
enum smu_memory_pool_size {
SMU_MEMORY_POOL_SIZE_ZERO = 0,
SMU_MEMORY_POOL_SIZE_256_MB = 0x10000000,
SMU_MEMORY_POOL_SIZE_512_MB = 0x20000000,
SMU_MEMORY_POOL_SIZE_1_GB = 0x40000000,
SMU_MEMORY_POOL_SIZE_2_GB = 0x80000000,
};
enum smu_clk_type {
SMU_GFXCLK,
SMU_VCLK,
SMU_DCLK,
SMU_VCLK1,
SMU_DCLK1,
SMU_ECLK,
SMU_SOCCLK,
SMU_UCLK,
SMU_DCEFCLK,
SMU_DISPCLK,
SMU_PIXCLK,
SMU_PHYCLK,
SMU_FCLK,
SMU_SCLK,
SMU_MCLK,
SMU_PCIE,
SMU_LCLK,
SMU_OD_CCLK,
SMU_OD_SCLK,
SMU_OD_MCLK,
SMU_OD_VDDC_CURVE,
SMU_OD_RANGE,
SMU_OD_VDDGFX_OFFSET,
SMU_OD_FAN_CURVE,
SMU_OD_ACOUSTIC_LIMIT,
SMU_OD_ACOUSTIC_TARGET,
SMU_OD_FAN_TARGET_TEMPERATURE,
SMU_OD_FAN_MINIMUM_PWM,
SMU_CLK_COUNT,
};
struct smu_user_dpm_profile {
uint32_t fan_mode;
uint32_t power_limit;
uint32_t fan_speed_pwm;
uint32_t fan_speed_rpm;
uint32_t flags;
uint32_t user_od;
/* user clock state information */
uint32_t clk_mask[SMU_CLK_COUNT];
uint32_t clk_dependency;
};
#define SMU_TABLE_INIT(tables, table_id, s, a, d) \
do { \
tables[table_id].size = s; \
tables[table_id].align = a; \
tables[table_id].domain = d; \
} while (0)
struct smu_table {
uint64_t size;
uint32_t align;
uint8_t domain;
uint64_t mc_address;
void *cpu_addr;
struct amdgpu_bo *bo;
uint32_t version;
};
enum smu_perf_level_designation {
PERF_LEVEL_ACTIVITY,
PERF_LEVEL_POWER_CONTAINMENT,
};
struct smu_performance_level {
uint32_t core_clock;
uint32_t memory_clock;
uint32_t vddc;
uint32_t vddci;
uint32_t non_local_mem_freq;
uint32_t non_local_mem_width;
};
struct smu_clock_info {
uint32_t min_mem_clk;
uint32_t max_mem_clk;
uint32_t min_eng_clk;
uint32_t max_eng_clk;
uint32_t min_bus_bandwidth;
uint32_t max_bus_bandwidth;
};
struct smu_bios_boot_up_values {
uint32_t revision;
uint32_t gfxclk;
uint32_t uclk;
uint32_t socclk;
uint32_t dcefclk;
uint32_t eclk;
uint32_t vclk;
uint32_t dclk;
uint16_t vddc;
uint16_t vddci;
uint16_t mvddc;
uint16_t vdd_gfx;
uint8_t cooling_id;
uint32_t pp_table_id;
uint32_t format_revision;
uint32_t content_revision;
uint32_t fclk;
uint32_t lclk;
uint32_t firmware_caps;
};
enum smu_table_id {
SMU_TABLE_PPTABLE = 0,
SMU_TABLE_WATERMARKS,
SMU_TABLE_CUSTOM_DPM,
SMU_TABLE_DPMCLOCKS,
SMU_TABLE_AVFS,
SMU_TABLE_AVFS_PSM_DEBUG,
SMU_TABLE_AVFS_FUSE_OVERRIDE,
SMU_TABLE_PMSTATUSLOG,
SMU_TABLE_SMU_METRICS,
SMU_TABLE_DRIVER_SMU_CONFIG,
SMU_TABLE_ACTIVITY_MONITOR_COEFF,
SMU_TABLE_OVERDRIVE,
SMU_TABLE_I2C_COMMANDS,
SMU_TABLE_PACE,
SMU_TABLE_ECCINFO,
SMU_TABLE_COMBO_PPTABLE,
SMU_TABLE_WIFIBAND,
SMU_TABLE_COUNT,
};
#endif

View File

@@ -0,0 +1,626 @@
/*
* Copyright 2012 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef __AMDGPU_UCODE_H__
#define __AMDGPU_UCODE_H__
// #include "amdgpu_socbb.h"
#define bool _Bool
struct common_firmware_header {
uint32_t size_bytes; /* size of the entire header+image(s) in bytes */
uint32_t header_size_bytes; /* size of just the header in bytes */
uint16_t header_version_major; /* header version */
uint16_t header_version_minor; /* header version */
uint16_t ip_version_major; /* IP version */
uint16_t ip_version_minor; /* IP version */
uint32_t ucode_version;
uint32_t ucode_size_bytes; /* size of ucode in bytes */
uint32_t ucode_array_offset_bytes; /* payload offset from the start of the header */
uint32_t crc32; /* crc32 checksum of the payload */
};
/* version_major=1, version_minor=0 */
struct mc_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t io_debug_size_bytes; /* size of debug array in dwords */
uint32_t io_debug_array_offset_bytes; /* payload offset from the start of the header */
};
/* version_major=1, version_minor=0 */
struct smc_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t ucode_start_addr;
};
/* version_major=2, version_minor=0 */
struct smc_firmware_header_v2_0 {
struct smc_firmware_header_v1_0 v1_0;
uint32_t ppt_offset_bytes; /* soft pptable offset */
uint32_t ppt_size_bytes; /* soft pptable size */
};
struct smc_soft_pptable_entry {
uint32_t id;
uint32_t ppt_offset_bytes;
uint32_t ppt_size_bytes;
};
/* version_major=2, version_minor=1 */
struct smc_firmware_header_v2_1 {
struct smc_firmware_header_v1_0 v1_0;
uint32_t pptable_count;
uint32_t pptable_entry_offset;
};
struct psp_fw_legacy_bin_desc {
uint32_t fw_version;
uint32_t offset_bytes;
uint32_t size_bytes;
};
/* version_major=1, version_minor=0 */
struct psp_firmware_header_v1_0 {
struct common_firmware_header header;
struct psp_fw_legacy_bin_desc sos;
};
/* version_major=1, version_minor=1 */
struct psp_firmware_header_v1_1 {
struct psp_firmware_header_v1_0 v1_0;
struct psp_fw_legacy_bin_desc toc;
struct psp_fw_legacy_bin_desc kdb;
};
/* version_major=1, version_minor=2 */
struct psp_firmware_header_v1_2 {
struct psp_firmware_header_v1_0 v1_0;
struct psp_fw_legacy_bin_desc res;
struct psp_fw_legacy_bin_desc kdb;
};
/* version_major=1, version_minor=3 */
struct psp_firmware_header_v1_3 {
struct psp_firmware_header_v1_1 v1_1;
struct psp_fw_legacy_bin_desc spl;
struct psp_fw_legacy_bin_desc rl;
struct psp_fw_legacy_bin_desc sys_drv_aux;
struct psp_fw_legacy_bin_desc sos_aux;
};
struct psp_fw_bin_desc {
uint32_t fw_type;
uint32_t fw_version;
uint32_t offset_bytes;
uint32_t size_bytes;
};
enum psp_fw_type {
PSP_FW_TYPE_UNKOWN,
PSP_FW_TYPE_PSP_SOS,
PSP_FW_TYPE_PSP_SYS_DRV,
PSP_FW_TYPE_PSP_KDB,
PSP_FW_TYPE_PSP_TOC,
PSP_FW_TYPE_PSP_SPL,
PSP_FW_TYPE_PSP_RL,
PSP_FW_TYPE_PSP_SOC_DRV,
PSP_FW_TYPE_PSP_INTF_DRV,
PSP_FW_TYPE_PSP_DBG_DRV,
PSP_FW_TYPE_PSP_RAS_DRV,
PSP_FW_TYPE_PSP_IPKEYMGR_DRV,
PSP_FW_TYPE_MAX_INDEX,
};
/* version_major=2, version_minor=0 */
struct psp_firmware_header_v2_0 {
struct common_firmware_header header;
uint32_t psp_fw_bin_count;
struct psp_fw_bin_desc psp_fw_bin[1];
};
/* version_major=2, version_minor=1 */
struct psp_firmware_header_v2_1 {
struct common_firmware_header header;
uint32_t psp_fw_bin_count;
uint32_t psp_aux_fw_bin_index;
struct psp_fw_bin_desc psp_fw_bin[1];
};
/* version_major=1, version_minor=0 */
struct ta_firmware_header_v1_0 {
struct common_firmware_header header;
struct psp_fw_legacy_bin_desc xgmi;
struct psp_fw_legacy_bin_desc ras;
struct psp_fw_legacy_bin_desc hdcp;
struct psp_fw_legacy_bin_desc dtm;
struct psp_fw_legacy_bin_desc securedisplay;
};
enum ta_fw_type {
TA_FW_TYPE_UNKOWN,
TA_FW_TYPE_PSP_ASD,
TA_FW_TYPE_PSP_XGMI,
TA_FW_TYPE_PSP_RAS,
TA_FW_TYPE_PSP_HDCP,
TA_FW_TYPE_PSP_DTM,
TA_FW_TYPE_PSP_RAP,
TA_FW_TYPE_PSP_SECUREDISPLAY,
TA_FW_TYPE_MAX_INDEX,
};
/* version_major=2, version_minor=0 */
struct ta_firmware_header_v2_0 {
struct common_firmware_header header;
uint32_t ta_fw_bin_count;
struct psp_fw_bin_desc ta_fw_bin[1];
};
/* version_major=1, version_minor=0 */
struct gfx_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t ucode_feature_version;
uint32_t jt_offset; /* jt location */
uint32_t jt_size; /* size of jt */
};
/* version_major=2, version_minor=0 */
struct gfx_firmware_header_v2_0 {
struct common_firmware_header header;
uint32_t ucode_feature_version;
uint32_t ucode_size_bytes;
uint32_t ucode_offset_bytes;
uint32_t data_size_bytes;
uint32_t data_offset_bytes;
uint32_t ucode_start_addr_lo;
uint32_t ucode_start_addr_hi;
};
/* version_major=1, version_minor=0 */
struct mes_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t mes_ucode_version;
uint32_t mes_ucode_size_bytes;
uint32_t mes_ucode_offset_bytes;
uint32_t mes_ucode_data_version;
uint32_t mes_ucode_data_size_bytes;
uint32_t mes_ucode_data_offset_bytes;
uint32_t mes_uc_start_addr_lo;
uint32_t mes_uc_start_addr_hi;
uint32_t mes_data_start_addr_lo;
uint32_t mes_data_start_addr_hi;
};
/* version_major=1, version_minor=0 */
struct rlc_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t ucode_feature_version;
uint32_t save_and_restore_offset;
uint32_t clear_state_descriptor_offset;
uint32_t avail_scratch_ram_locations;
uint32_t master_pkt_description_offset;
};
/* version_major=2, version_minor=0 */
struct rlc_firmware_header_v2_0 {
struct common_firmware_header header;
uint32_t ucode_feature_version;
uint32_t jt_offset; /* jt location */
uint32_t jt_size; /* size of jt */
uint32_t save_and_restore_offset;
uint32_t clear_state_descriptor_offset;
uint32_t avail_scratch_ram_locations;
uint32_t reg_restore_list_size;
uint32_t reg_list_format_start;
uint32_t reg_list_format_separate_start;
uint32_t starting_offsets_start;
uint32_t reg_list_format_size_bytes; /* size of reg list format array in bytes */
uint32_t reg_list_format_array_offset_bytes; /* payload offset from the start of the header */
uint32_t reg_list_size_bytes; /* size of reg list array in bytes */
uint32_t reg_list_array_offset_bytes; /* payload offset from the start of the header */
uint32_t reg_list_format_separate_size_bytes; /* size of reg list format array in bytes */
uint32_t reg_list_format_separate_array_offset_bytes; /* payload offset from the start of the header */
uint32_t reg_list_separate_size_bytes; /* size of reg list array in bytes */
uint32_t reg_list_separate_array_offset_bytes; /* payload offset from the start of the header */
};
/* version_major=2, version_minor=1 */
struct rlc_firmware_header_v2_1 {
struct rlc_firmware_header_v2_0 v2_0;
uint32_t reg_list_format_direct_reg_list_length; /* length of direct reg list format array */
uint32_t save_restore_list_cntl_ucode_ver;
uint32_t save_restore_list_cntl_feature_ver;
uint32_t save_restore_list_cntl_size_bytes;
uint32_t save_restore_list_cntl_offset_bytes;
uint32_t save_restore_list_gpm_ucode_ver;
uint32_t save_restore_list_gpm_feature_ver;
uint32_t save_restore_list_gpm_size_bytes;
uint32_t save_restore_list_gpm_offset_bytes;
uint32_t save_restore_list_srm_ucode_ver;
uint32_t save_restore_list_srm_feature_ver;
uint32_t save_restore_list_srm_size_bytes;
uint32_t save_restore_list_srm_offset_bytes;
};
/* version_major=2, version_minor=2 */
struct rlc_firmware_header_v2_2 {
struct rlc_firmware_header_v2_1 v2_1;
uint32_t rlc_iram_ucode_size_bytes;
uint32_t rlc_iram_ucode_offset_bytes;
uint32_t rlc_dram_ucode_size_bytes;
uint32_t rlc_dram_ucode_offset_bytes;
};
/* version_major=2, version_minor=3 */
struct rlc_firmware_header_v2_3 {
struct rlc_firmware_header_v2_2 v2_2;
uint32_t rlcp_ucode_version;
uint32_t rlcp_ucode_feature_version;
uint32_t rlcp_ucode_size_bytes;
uint32_t rlcp_ucode_offset_bytes;
uint32_t rlcv_ucode_version;
uint32_t rlcv_ucode_feature_version;
uint32_t rlcv_ucode_size_bytes;
uint32_t rlcv_ucode_offset_bytes;
};
/* version_major=2, version_minor=4 */
struct rlc_firmware_header_v2_4 {
struct rlc_firmware_header_v2_3 v2_3;
uint32_t global_tap_delays_ucode_size_bytes;
uint32_t global_tap_delays_ucode_offset_bytes;
uint32_t se0_tap_delays_ucode_size_bytes;
uint32_t se0_tap_delays_ucode_offset_bytes;
uint32_t se1_tap_delays_ucode_size_bytes;
uint32_t se1_tap_delays_ucode_offset_bytes;
uint32_t se2_tap_delays_ucode_size_bytes;
uint32_t se2_tap_delays_ucode_offset_bytes;
uint32_t se3_tap_delays_ucode_size_bytes;
uint32_t se3_tap_delays_ucode_offset_bytes;
};
/* version_major=1, version_minor=0 */
struct sdma_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t ucode_feature_version;
uint32_t ucode_change_version;
uint32_t jt_offset; /* jt location */
uint32_t jt_size; /* size of jt */
};
/* version_major=1, version_minor=1 */
struct sdma_firmware_header_v1_1 {
struct sdma_firmware_header_v1_0 v1_0;
uint32_t digest_size;
};
/* version_major=2, version_minor=0 */
struct sdma_firmware_header_v2_0 {
struct common_firmware_header header;
uint32_t ucode_feature_version;
uint32_t ctx_ucode_size_bytes; /* context thread ucode size */
uint32_t ctx_jt_offset; /* context thread jt location */
uint32_t ctx_jt_size; /* context thread size of jt */
uint32_t ctl_ucode_offset;
uint32_t ctl_ucode_size_bytes; /* control thread ucode size */
uint32_t ctl_jt_offset; /* control thread jt location */
uint32_t ctl_jt_size; /* control thread size of jt */
};
/* version_major=1, version_minor=0 */
struct vpe_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t ucode_feature_version;
uint32_t ctx_ucode_size_bytes; /* context thread ucode size */
uint32_t ctx_jt_offset; /* context thread jt location */
uint32_t ctx_jt_size; /* context thread size of jt */
uint32_t ctl_ucode_offset;
uint32_t ctl_ucode_size_bytes; /* control thread ucode size */
uint32_t ctl_jt_offset; /* control thread jt location */
uint32_t ctl_jt_size; /* control thread size of jt */
};
/* version_major=1, version_minor=0 */
struct umsch_mm_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t umsch_mm_ucode_version;
uint32_t umsch_mm_ucode_size_bytes;
uint32_t umsch_mm_ucode_offset_bytes;
uint32_t umsch_mm_ucode_data_version;
uint32_t umsch_mm_ucode_data_size_bytes;
uint32_t umsch_mm_ucode_data_offset_bytes;
uint32_t umsch_mm_irq_start_addr_lo;
uint32_t umsch_mm_irq_start_addr_hi;
uint32_t umsch_mm_uc_start_addr_lo;
uint32_t umsch_mm_uc_start_addr_hi;
uint32_t umsch_mm_data_start_addr_lo;
uint32_t umsch_mm_data_start_addr_hi;
};
/* version_major=3, version_minor=0 */
struct sdma_firmware_header_v3_0 {
struct common_firmware_header header;
uint32_t ucode_feature_version;
uint32_t ucode_offset_bytes;
uint32_t ucode_size_bytes;
};
/* gpu info payload */
struct gpu_info_firmware_v1_0 {
uint32_t gc_num_se;
uint32_t gc_num_cu_per_sh;
uint32_t gc_num_sh_per_se;
uint32_t gc_num_rb_per_se;
uint32_t gc_num_tccs;
uint32_t gc_num_gprs;
uint32_t gc_num_max_gs_thds;
uint32_t gc_gs_table_depth;
uint32_t gc_gsprim_buff_depth;
uint32_t gc_parameter_cache_depth;
uint32_t gc_double_offchip_lds_buffer;
uint32_t gc_wave_size;
uint32_t gc_max_waves_per_simd;
uint32_t gc_max_scratch_slots_per_cu;
uint32_t gc_lds_size;
};
struct gpu_info_firmware_v1_1 {
struct gpu_info_firmware_v1_0 v1_0;
uint32_t num_sc_per_sh;
uint32_t num_packer_per_sc;
};
/* gpu info payload
* version_major=1, version_minor=1 */
// struct gpu_info_firmware_v1_2 {
// struct gpu_info_firmware_v1_1 v1_1;
// struct gpu_info_soc_bounding_box_v1_0 soc_bounding_box;
// };
/* version_major=1, version_minor=0 */
struct gpu_info_firmware_header_v1_0 {
struct common_firmware_header header;
uint16_t version_major; /* version */
uint16_t version_minor; /* version */
};
/* version_major=1, version_minor=0 */
struct dmcu_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t intv_offset_bytes; /* interrupt vectors offset from end of header, in bytes */
uint32_t intv_size_bytes; /* size of interrupt vectors, in bytes */
};
/* version_major=1, version_minor=0 */
struct dmcub_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t inst_const_bytes; /* size of instruction region, in bytes */
uint32_t bss_data_bytes; /* size of bss/data region, in bytes */
};
/* version_major=1, version_minor=0 */
struct imu_firmware_header_v1_0 {
struct common_firmware_header header;
uint32_t imu_iram_ucode_size_bytes;
uint32_t imu_iram_ucode_offset_bytes;
uint32_t imu_dram_ucode_size_bytes;
uint32_t imu_dram_ucode_offset_bytes;
};
/* header is fixed size */
union amdgpu_firmware_header {
struct common_firmware_header common;
struct mc_firmware_header_v1_0 mc;
struct smc_firmware_header_v1_0 smc;
struct smc_firmware_header_v2_0 smc_v2_0;
struct psp_firmware_header_v1_0 psp;
struct psp_firmware_header_v1_1 psp_v1_1;
struct psp_firmware_header_v1_3 psp_v1_3;
struct psp_firmware_header_v2_0 psp_v2_0;
struct psp_firmware_header_v2_0 psp_v2_1;
struct ta_firmware_header_v1_0 ta;
struct ta_firmware_header_v2_0 ta_v2_0;
struct gfx_firmware_header_v1_0 gfx;
struct gfx_firmware_header_v2_0 gfx_v2_0;
struct rlc_firmware_header_v1_0 rlc;
struct rlc_firmware_header_v2_0 rlc_v2_0;
struct rlc_firmware_header_v2_1 rlc_v2_1;
struct rlc_firmware_header_v2_2 rlc_v2_2;
struct rlc_firmware_header_v2_3 rlc_v2_3;
struct rlc_firmware_header_v2_4 rlc_v2_4;
struct sdma_firmware_header_v1_0 sdma;
struct sdma_firmware_header_v1_1 sdma_v1_1;
struct sdma_firmware_header_v2_0 sdma_v2_0;
struct sdma_firmware_header_v3_0 sdma_v3_0;
struct gpu_info_firmware_header_v1_0 gpu_info;
struct dmcu_firmware_header_v1_0 dmcu;
struct dmcub_firmware_header_v1_0 dmcub;
struct imu_firmware_header_v1_0 imu;
uint8_t raw[0x100];
};
#define UCODE_MAX_PSP_PACKAGING (((sizeof(union amdgpu_firmware_header) - sizeof(struct common_firmware_header) - 4) / sizeof(struct psp_fw_bin_desc)) * 2)
/*
* fw loading support
*/
enum AMDGPU_UCODE_ID {
AMDGPU_UCODE_ID_CAP = 0,
AMDGPU_UCODE_ID_SDMA0,
AMDGPU_UCODE_ID_SDMA1,
AMDGPU_UCODE_ID_SDMA2,
AMDGPU_UCODE_ID_SDMA3,
AMDGPU_UCODE_ID_SDMA4,
AMDGPU_UCODE_ID_SDMA5,
AMDGPU_UCODE_ID_SDMA6,
AMDGPU_UCODE_ID_SDMA7,
AMDGPU_UCODE_ID_SDMA_UCODE_TH0,
AMDGPU_UCODE_ID_SDMA_UCODE_TH1,
AMDGPU_UCODE_ID_SDMA_RS64,
AMDGPU_UCODE_ID_CP_CE,
AMDGPU_UCODE_ID_CP_PFP,
AMDGPU_UCODE_ID_CP_ME,
AMDGPU_UCODE_ID_CP_RS64_PFP,
AMDGPU_UCODE_ID_CP_RS64_ME,
AMDGPU_UCODE_ID_CP_RS64_MEC,
AMDGPU_UCODE_ID_CP_RS64_PFP_P0_STACK,
AMDGPU_UCODE_ID_CP_RS64_PFP_P1_STACK,
AMDGPU_UCODE_ID_CP_RS64_ME_P0_STACK,
AMDGPU_UCODE_ID_CP_RS64_ME_P1_STACK,
AMDGPU_UCODE_ID_CP_RS64_MEC_P0_STACK,
AMDGPU_UCODE_ID_CP_RS64_MEC_P1_STACK,
AMDGPU_UCODE_ID_CP_RS64_MEC_P2_STACK,
AMDGPU_UCODE_ID_CP_RS64_MEC_P3_STACK,
AMDGPU_UCODE_ID_CP_MEC1,
AMDGPU_UCODE_ID_CP_MEC1_JT,
AMDGPU_UCODE_ID_CP_MEC2,
AMDGPU_UCODE_ID_CP_MEC2_JT,
AMDGPU_UCODE_ID_CP_MES,
AMDGPU_UCODE_ID_CP_MES_DATA,
AMDGPU_UCODE_ID_CP_MES1,
AMDGPU_UCODE_ID_CP_MES1_DATA,
AMDGPU_UCODE_ID_IMU_I,
AMDGPU_UCODE_ID_IMU_D,
AMDGPU_UCODE_ID_GLOBAL_TAP_DELAYS,
AMDGPU_UCODE_ID_SE0_TAP_DELAYS,
AMDGPU_UCODE_ID_SE1_TAP_DELAYS,
AMDGPU_UCODE_ID_SE2_TAP_DELAYS,
AMDGPU_UCODE_ID_SE3_TAP_DELAYS,
AMDGPU_UCODE_ID_RLC_RESTORE_LIST_CNTL,
AMDGPU_UCODE_ID_RLC_RESTORE_LIST_GPM_MEM,
AMDGPU_UCODE_ID_RLC_RESTORE_LIST_SRM_MEM,
AMDGPU_UCODE_ID_RLC_IRAM,
AMDGPU_UCODE_ID_RLC_DRAM,
AMDGPU_UCODE_ID_RLC_P,
AMDGPU_UCODE_ID_RLC_V,
AMDGPU_UCODE_ID_RLC_G,
AMDGPU_UCODE_ID_STORAGE,
AMDGPU_UCODE_ID_SMC,
AMDGPU_UCODE_ID_PPTABLE,
AMDGPU_UCODE_ID_UVD,
AMDGPU_UCODE_ID_UVD1,
AMDGPU_UCODE_ID_VCE,
AMDGPU_UCODE_ID_VCN,
AMDGPU_UCODE_ID_VCN1,
AMDGPU_UCODE_ID_DMCU_ERAM,
AMDGPU_UCODE_ID_DMCU_INTV,
AMDGPU_UCODE_ID_VCN0_RAM,
AMDGPU_UCODE_ID_VCN1_RAM,
AMDGPU_UCODE_ID_DMCUB,
AMDGPU_UCODE_ID_VPE_CTX,
AMDGPU_UCODE_ID_VPE_CTL,
AMDGPU_UCODE_ID_VPE,
AMDGPU_UCODE_ID_UMSCH_MM_UCODE,
AMDGPU_UCODE_ID_UMSCH_MM_DATA,
AMDGPU_UCODE_ID_UMSCH_MM_CMD_BUFFER,
AMDGPU_UCODE_ID_P2S_TABLE,
AMDGPU_UCODE_ID_JPEG_RAM,
AMDGPU_UCODE_ID_ISP,
AMDGPU_UCODE_ID_MAXIMUM,
};
/* engine firmware status */
enum AMDGPU_UCODE_STATUS {
AMDGPU_UCODE_STATUS_INVALID,
AMDGPU_UCODE_STATUS_NOT_LOADED,
AMDGPU_UCODE_STATUS_LOADED,
};
enum amdgpu_firmware_load_type {
AMDGPU_FW_LOAD_DIRECT = 0,
AMDGPU_FW_LOAD_PSP,
AMDGPU_FW_LOAD_SMU,
AMDGPU_FW_LOAD_RLC_BACKDOOR_AUTO,
};
/* conform to smu_ucode_xfer_cz.h */
#define AMDGPU_SDMA0_UCODE_LOADED 0x00000001
#define AMDGPU_SDMA1_UCODE_LOADED 0x00000002
#define AMDGPU_CPCE_UCODE_LOADED 0x00000004
#define AMDGPU_CPPFP_UCODE_LOADED 0x00000008
#define AMDGPU_CPME_UCODE_LOADED 0x00000010
#define AMDGPU_CPMEC1_UCODE_LOADED 0x00000020
#define AMDGPU_CPMEC2_UCODE_LOADED 0x00000040
#define AMDGPU_CPRLC_UCODE_LOADED 0x00000100
/* amdgpu firmware info */
struct amdgpu_firmware_info {
/* ucode ID */
enum AMDGPU_UCODE_ID ucode_id;
/* request_firmware */
const struct firmware *fw;
/* starting mc address */
uint64_t mc_addr;
/* kernel linear address */
void *kaddr;
/* ucode_size_bytes */
uint32_t ucode_size;
/* starting tmr mc address */
uint32_t tmr_mc_addr_lo;
uint32_t tmr_mc_addr_hi;
};
// struct amdgpu_firmware {
// struct amdgpu_firmware_info ucode[AMDGPU_UCODE_ID_MAXIMUM];
// enum amdgpu_firmware_load_type load_type;
// struct amdgpu_bo *fw_buf;
// unsigned int fw_size;
// unsigned int max_ucodes;
// /* firmwares are loaded by psp instead of smu from vega10 */
// const struct amdgpu_psp_funcs *funcs;
// struct amdgpu_bo *rbuf;
// struct mutex mutex;
// /* gpu info firmware data pointer */
// const struct firmware *gpu_info_fw;
// void *fw_buf_ptr;
// uint64_t fw_buf_mc;
// };
// void amdgpu_ucode_print_mc_hdr(const struct common_firmware_header *hdr);
// void amdgpu_ucode_print_smc_hdr(const struct common_firmware_header *hdr);
// void amdgpu_ucode_print_imu_hdr(const struct common_firmware_header *hdr);
// void amdgpu_ucode_print_gfx_hdr(const struct common_firmware_header *hdr);
// void amdgpu_ucode_print_rlc_hdr(const struct common_firmware_header *hdr);
// void amdgpu_ucode_print_sdma_hdr(const struct common_firmware_header *hdr);
// void amdgpu_ucode_print_psp_hdr(const struct common_firmware_header *hdr);
// void amdgpu_ucode_print_gpu_info_hdr(const struct common_firmware_header *hdr);
// int amdgpu_ucode_request(struct amdgpu_device *adev, const struct firmware **fw,
// const char *fw_name);
// void amdgpu_ucode_release(const struct firmware **fw);
// bool amdgpu_ucode_hdr_version(union amdgpu_firmware_header *hdr,
// uint16_t hdr_major, uint16_t hdr_minor);
// int amdgpu_ucode_init_bo(struct amdgpu_device *adev);
// int amdgpu_ucode_create_bo(struct amdgpu_device *adev);
// int amdgpu_ucode_sysfs_init(struct amdgpu_device *adev);
// void amdgpu_ucode_free_bo(struct amdgpu_device *adev);
// void amdgpu_ucode_sysfs_fini(struct amdgpu_device *adev);
// enum amdgpu_firmware_load_type
// amdgpu_ucode_get_load_type(struct amdgpu_device *adev, int load_type);
// const char *amdgpu_ucode_name(enum AMDGPU_UCODE_ID ucode_id);
// void amdgpu_ucode_ip_version_decode(struct amdgpu_device *adev, int block_type, char *ucode_prefix, int len);
#endif

View File

@@ -0,0 +1,665 @@
/*
* Copyright 2016 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Christian König
*/
#ifndef __AMDGPU_VM_H__
#define __AMDGPU_VM_H__
// #include <linux/idr.h>
// #include <linux/kfifo.h>
// #include <linux/rbtree.h>
// #include <drm/gpu_scheduler.h>
// #include <drm/drm_file.h>
// #include <drm/ttm/ttm_bo.h>
// #include <linux/sched/mm.h>
// #include "amdgpu_sync.h"
// #include "amdgpu_ring.h"
// #include "amdgpu_ids.h"
// struct drm_exec;
// struct amdgpu_bo_va;
// struct amdgpu_job;
// struct amdgpu_bo_list_entry;
// struct amdgpu_bo_vm;
// struct amdgpu_mem_stats;
/*
* GPUVM handling
*/
/* Maximum number of PTEs the hardware can write with one command */
#define AMDGPU_VM_MAX_UPDATE_SIZE 0x3FFFF
/* number of entries in page table */
#define AMDGPU_VM_PTE_COUNT(adev) (1 << (adev)->vm_manager.block_size)
#define AMDGPU_PTE_VALID (1ULL << 0)
#define AMDGPU_PTE_SYSTEM (1ULL << 1)
#define AMDGPU_PTE_SNOOPED (1ULL << 2)
/* RV+ */
#define AMDGPU_PTE_TMZ (1ULL << 3)
/* VI only */
#define AMDGPU_PTE_EXECUTABLE (1ULL << 4)
#define AMDGPU_PTE_READABLE (1ULL << 5)
#define AMDGPU_PTE_WRITEABLE (1ULL << 6)
#define AMDGPU_PTE_FRAG(x) ((x & 0x1fULL) << 7)
/* TILED for VEGA10, reserved for older ASICs */
#define AMDGPU_PTE_PRT (1ULL << 51)
/* PDE is handled as PTE for VEGA10 */
#define AMDGPU_PDE_PTE (1ULL << 54)
#define AMDGPU_PTE_LOG (1ULL << 55)
/* PTE is handled as PDE for VEGA10 (Translate Further) */
#define AMDGPU_PTE_TF (1ULL << 56)
/* MALL noalloc for sienna_cichlid, reserved for older ASICs */
#define AMDGPU_PTE_NOALLOC (1ULL << 58)
/* PDE Block Fragment Size for VEGA10 */
#define AMDGPU_PDE_BFS(a) ((uint64_t)a << 59)
/* Flag combination to set no-retry with TF disabled */
#define AMDGPU_VM_NORETRY_FLAGS (AMDGPU_PTE_EXECUTABLE | AMDGPU_PDE_PTE | \
AMDGPU_PTE_TF)
/* Flag combination to set no-retry with TF enabled */
#define AMDGPU_VM_NORETRY_FLAGS_TF (AMDGPU_PTE_VALID | AMDGPU_PTE_SYSTEM | \
AMDGPU_PTE_PRT)
/* For GFX9 */
#define AMDGPU_PTE_MTYPE_VG10_SHIFT(mtype) ((uint64_t)(mtype) << 57)
#define AMDGPU_PTE_MTYPE_VG10_MASK AMDGPU_PTE_MTYPE_VG10_SHIFT(3ULL)
#define AMDGPU_PTE_MTYPE_VG10(flags, mtype) \
(((uint64_t)(flags) & (~AMDGPU_PTE_MTYPE_VG10_MASK)) | \
AMDGPU_PTE_MTYPE_VG10_SHIFT(mtype))
#define AMDGPU_MTYPE_NC 0
#define AMDGPU_MTYPE_CC 2
#define AMDGPU_PTE_DEFAULT_ATC (AMDGPU_PTE_SYSTEM \
| AMDGPU_PTE_SNOOPED \
| AMDGPU_PTE_EXECUTABLE \
| AMDGPU_PTE_READABLE \
| AMDGPU_PTE_WRITEABLE \
| AMDGPU_PTE_MTYPE_VG10(AMDGPU_MTYPE_CC))
/* gfx10 */
#define AMDGPU_PTE_MTYPE_NV10_SHIFT(mtype) ((uint64_t)(mtype) << 48)
#define AMDGPU_PTE_MTYPE_NV10_MASK AMDGPU_PTE_MTYPE_NV10_SHIFT(7ULL)
#define AMDGPU_PTE_MTYPE_NV10(flags, mtype) \
(((uint64_t)(flags) & (~AMDGPU_PTE_MTYPE_NV10_MASK)) | \
AMDGPU_PTE_MTYPE_NV10_SHIFT(mtype))
/* gfx12 */
#define AMDGPU_PTE_PRT_GFX12 (1ULL << 56)
#define AMDGPU_PTE_PRT_FLAG(adev) \
((amdgpu_ip_version((adev), GC_HWIP, 0) >= IP_VERSION(12, 0, 0)) ? AMDGPU_PTE_PRT_GFX12 : AMDGPU_PTE_PRT)
#define AMDGPU_PTE_MTYPE_GFX12_SHIFT(mtype) ((uint64_t)(mtype) << 54)
#define AMDGPU_PTE_MTYPE_GFX12_MASK AMDGPU_PTE_MTYPE_GFX12_SHIFT(3ULL)
#define AMDGPU_PTE_MTYPE_GFX12(flags, mtype) \
(((uint64_t)(flags) & (~AMDGPU_PTE_MTYPE_GFX12_MASK)) | \
AMDGPU_PTE_MTYPE_GFX12_SHIFT(mtype))
#define AMDGPU_PTE_IS_PTE (1ULL << 63)
/* PDE Block Fragment Size for gfx v12 */
#define AMDGPU_PDE_BFS_GFX12(a) ((uint64_t)((a) & 0x1fULL) << 58)
#define AMDGPU_PDE_BFS_FLAG(adev, a) \
((amdgpu_ip_version((adev), GC_HWIP, 0) >= IP_VERSION(12, 0, 0)) ? AMDGPU_PDE_BFS_GFX12(a) : AMDGPU_PDE_BFS(a))
/* PDE is handled as PTE for gfx v12 */
#define AMDGPU_PDE_PTE_GFX12 (1ULL << 63)
#define AMDGPU_PDE_PTE_FLAG(adev) \
((amdgpu_ip_version((adev), GC_HWIP, 0) >= IP_VERSION(12, 0, 0)) ? AMDGPU_PDE_PTE_GFX12 : AMDGPU_PDE_PTE)
/* How to program VM fault handling */
#define AMDGPU_VM_FAULT_STOP_NEVER 0
#define AMDGPU_VM_FAULT_STOP_FIRST 1
#define AMDGPU_VM_FAULT_STOP_ALWAYS 2
/* How much VRAM be reserved for page tables */
#define AMDGPU_VM_RESERVED_VRAM (8ULL << 20)
/*
* max number of VMHUB
* layout: max 8 GFXHUB + 4 MMHUB0 + 1 MMHUB1
*/
#define AMDGPU_MAX_VMHUBS 13
#define AMDGPU_GFXHUB_START 0
#define AMDGPU_MMHUB0_START 8
#define AMDGPU_MMHUB1_START 12
#define AMDGPU_GFXHUB(x) (AMDGPU_GFXHUB_START + (x))
#define AMDGPU_MMHUB0(x) (AMDGPU_MMHUB0_START + (x))
#define AMDGPU_MMHUB1(x) (AMDGPU_MMHUB1_START + (x))
#define AMDGPU_IS_GFXHUB(x) ((x) >= AMDGPU_GFXHUB_START && (x) < AMDGPU_MMHUB0_START)
#define AMDGPU_IS_MMHUB0(x) ((x) >= AMDGPU_MMHUB0_START && (x) < AMDGPU_MMHUB1_START)
#define AMDGPU_IS_MMHUB1(x) ((x) >= AMDGPU_MMHUB1_START && (x) < AMDGPU_MAX_VMHUBS)
/* Reserve space at top/bottom of address space for kernel use */
#define AMDGPU_VA_RESERVED_CSA_SIZE (2ULL << 20)
#define AMDGPU_VA_RESERVED_CSA_START(adev) (((adev)->vm_manager.max_pfn \
<< AMDGPU_GPU_PAGE_SHIFT) \
- AMDGPU_VA_RESERVED_CSA_SIZE)
#define AMDGPU_VA_RESERVED_SEQ64_SIZE (2ULL << 20)
#define AMDGPU_VA_RESERVED_SEQ64_START(adev) (AMDGPU_VA_RESERVED_CSA_START(adev) \
- AMDGPU_VA_RESERVED_SEQ64_SIZE)
#define AMDGPU_VA_RESERVED_TRAP_SIZE (2ULL << 12)
#define AMDGPU_VA_RESERVED_TRAP_START(adev) (AMDGPU_VA_RESERVED_SEQ64_START(adev) \
- AMDGPU_VA_RESERVED_TRAP_SIZE)
#define AMDGPU_VA_RESERVED_BOTTOM (1ULL << 16)
#define AMDGPU_VA_RESERVED_TOP (AMDGPU_VA_RESERVED_TRAP_SIZE + \
AMDGPU_VA_RESERVED_SEQ64_SIZE + \
AMDGPU_VA_RESERVED_CSA_SIZE)
/* See vm_update_mode */
#define AMDGPU_VM_USE_CPU_FOR_GFX (1 << 0)
#define AMDGPU_VM_USE_CPU_FOR_COMPUTE (1 << 1)
/* VMPT level enumerate, and the hiberachy is:
* PDB2->PDB1->PDB0->PTB
*/
enum amdgpu_vm_level {
AMDGPU_VM_PDB2,
AMDGPU_VM_PDB1,
AMDGPU_VM_PDB0,
AMDGPU_VM_PTB
};
// /* base structure for tracking BO usage in a VM */
// struct amdgpu_vm_bo_base {
// /* constant after initialization */
// struct amdgpu_vm *vm;
// struct amdgpu_bo *bo;
// /* protected by bo being reserved */
// struct amdgpu_vm_bo_base *next;
// /* protected by spinlock */
// struct list_head vm_status;
// /* protected by the BO being reserved */
// bool moved;
// };
// /* provided by hw blocks that can write ptes, e.g., sdma */
// struct amdgpu_vm_pte_funcs {
// /* number of dw to reserve per operation */
// unsigned copy_pte_num_dw;
// /* copy pte entries from GART */
// void (*copy_pte)(struct amdgpu_ib *ib,
// uint64_t pe, uint64_t src,
// unsigned count);
// /* write pte one entry at a time with addr mapping */
// void (*write_pte)(struct amdgpu_ib *ib, uint64_t pe,
// uint64_t value, unsigned count,
// uint32_t incr);
// /* for linear pte/pde updates without addr mapping */
// void (*set_pte_pde)(struct amdgpu_ib *ib,
// uint64_t pe,
// uint64_t addr, unsigned count,
// uint32_t incr, uint64_t flags);
// };
// struct amdgpu_task_info {
// char process_name[TASK_COMM_LEN];
// char task_name[TASK_COMM_LEN];
// pid_t pid;
// pid_t tgid;
// struct kref refcount;
// };
// /**
// * struct amdgpu_vm_update_params
// *
// * Encapsulate some VM table update parameters to reduce
// * the number of function parameters
// *
// */
// struct amdgpu_vm_update_params {
// /**
// * @adev: amdgpu device we do this update for
// */
// struct amdgpu_device *adev;
// /**
// * @vm: optional amdgpu_vm we do this update for
// */
// struct amdgpu_vm *vm;
// /**
// * @immediate: if changes should be made immediately
// */
// bool immediate;
// /**
// * @unlocked: true if the root BO is not locked
// */
// bool unlocked;
// /**
// * @pages_addr:
// *
// * DMA addresses to use for mapping
// */
// dma_addr_t *pages_addr;
// /**
// * @job: job to used for hw submission
// */
// struct amdgpu_job *job;
// /**
// * @num_dw_left: number of dw left for the IB
// */
// unsigned int num_dw_left;
// /**
// * @needs_flush: true whenever we need to invalidate the TLB
// */
// bool needs_flush;
// /**
// * @allow_override: true for memory that is not uncached: allows MTYPE
// * to be overridden for NUMA local memory.
// */
// bool allow_override;
// /**
// * @tlb_flush_waitlist: temporary storage for BOs until tlb_flush
// */
// struct list_head tlb_flush_waitlist;
// };
// struct amdgpu_vm_update_funcs {
// int (*map_table)(struct amdgpu_bo_vm *bo);
// int (*prepare)(struct amdgpu_vm_update_params *p, struct dma_resv *resv,
// enum amdgpu_sync_mode sync_mode);
// int (*update)(struct amdgpu_vm_update_params *p,
// struct amdgpu_bo_vm *bo, uint64_t pe, uint64_t addr,
// unsigned count, uint32_t incr, uint64_t flags);
// int (*commit)(struct amdgpu_vm_update_params *p,
// struct dma_fence **fence);
// };
// struct amdgpu_vm_fault_info {
// /* fault address */
// uint64_t addr;
// /* fault status register */
// uint32_t status;
// /* which vmhub? gfxhub, mmhub, etc. */
// unsigned int vmhub;
// };
// struct amdgpu_vm {
// /* tree of virtual addresses mapped */
// #ifndef HAVE_TREE_INSERT_HAVE_RB_ROOT_CACHED
// struct rb_root va;
// #else
// struct rb_root_cached va;
// #endif
// /* Lock to prevent eviction while we are updating page tables
// * use vm_eviction_lock/unlock(vm)
// */
// struct mutex eviction_lock;
// bool evicting;
// unsigned int saved_flags;
// /* Lock to protect vm_bo add/del/move on all lists of vm */
// spinlock_t status_lock;
// /* Per-VM and PT BOs who needs a validation */
// struct list_head evicted;
// /* BOs for user mode queues that need a validation */
// struct list_head evicted_user;
// /* PT BOs which relocated and their parent need an update */
// struct list_head relocated;
// /* per VM BOs moved, but not yet updated in the PT */
// struct list_head moved;
// /* All BOs of this VM not currently in the state machine */
// struct list_head idle;
// /* regular invalidated BOs, but not yet updated in the PT */
// struct list_head invalidated;
// /* BO mappings freed, but not yet updated in the PT */
// struct list_head freed;
// /* BOs which are invalidated, has been updated in the PTs */
// struct list_head done;
// /* PT BOs scheduled to free and fill with zero if vm_resv is not hold */
// struct list_head pt_freed;
// struct work_struct pt_free_work;
// /* contains the page directory */
// struct amdgpu_vm_bo_base root;
// struct dma_fence *last_update;
// /* Scheduler entities for page table updates */
// struct drm_sched_entity immediate;
// struct drm_sched_entity delayed;
// /* Last finished delayed update */
// atomic64_t tlb_seq;
// struct dma_fence *last_tlb_flush;
// atomic64_t kfd_last_flushed_seq;
// uint64_t tlb_fence_context;
// /* How many times we had to re-generate the page tables */
// uint64_t generation;
// /* Last unlocked submission to the scheduler entities */
// struct dma_fence *last_unlocked;
// unsigned int pasid;
// bool reserved_vmid[AMDGPU_MAX_VMHUBS];
// /* Flag to indicate if VM tables are updated by CPU or GPU (SDMA) */
// bool use_cpu_for_update;
// /* Functions to use for VM table updates */
// const struct amdgpu_vm_update_funcs *update_funcs;
// /* Up to 128 pending retry page faults */
// DECLARE_KFIFO(faults, u64, 128);
// /* Points to the KFD process VM info */
// struct amdkfd_process_info *process_info;
// /* List node in amdkfd_process_info.vm_list_head */
// struct list_head vm_list_node;
// /* Valid while the PD is reserved or fenced */
// uint64_t pd_phys_addr;
// /* Some basic info about the task */
// struct amdgpu_task_info *task_info;
// /* Store positions of group of BOs */
// struct ttm_lru_bulk_move lru_bulk_move;
// /* Flag to indicate if VM is used for compute */
// bool is_compute_context;
// /* Memory partition number, -1 means any partition */
// int8_t mem_id;
// /* cached fault info */
// struct amdgpu_vm_fault_info fault_info;
// };
// struct amdgpu_vm_manager {
// /* Handling of VMIDs */
// struct amdgpu_vmid_mgr id_mgr[AMDGPU_MAX_VMHUBS];
// unsigned int first_kfd_vmid;
// bool concurrent_flush;
// /* Handling of VM fences */
// u64 fence_context;
// unsigned seqno[AMDGPU_MAX_RINGS];
// uint64_t max_pfn;
// uint32_t num_level;
// uint32_t block_size;
// uint32_t fragment_size;
// enum amdgpu_vm_level root_level;
// /* vram base address for page table entry */
// u64 vram_base_offset;
// /* vm pte handling */
// const struct amdgpu_vm_pte_funcs *vm_pte_funcs;
// struct drm_gpu_scheduler *vm_pte_scheds[AMDGPU_MAX_RINGS];
// unsigned vm_pte_num_scheds;
// struct amdgpu_ring *page_fault;
// /* partial resident texture handling */
// spinlock_t prt_lock;
// atomic_t num_prt_users;
// /* controls how VM page tables are updated for Graphics and Compute.
// * BIT0[= 0] Graphics updated by SDMA [= 1] by CPU
// * BIT1[= 0] Compute updated by SDMA [= 1] by CPU
// */
// int vm_update_mode;
// /* PASID to VM mapping, will be used in interrupt context to
// * look up VM of a page fault
// */
// #ifdef HAVE_STRUCT_XARRAY
// struct xarray pasids;
// #else
// struct idr pasid_idr;
// spinlock_t pasid_lock;
// #endif
// /* Global registration of recent page fault information */
// struct amdgpu_vm_fault_info fault_info;
// };
// struct amdgpu_bo_va_mapping;
// #define amdgpu_vm_copy_pte(adev, ib, pe, src, count) ((adev)->vm_manager.vm_pte_funcs->copy_pte((ib), (pe), (src), (count)))
// #define amdgpu_vm_write_pte(adev, ib, pe, value, count, incr) ((adev)->vm_manager.vm_pte_funcs->write_pte((ib), (pe), (value), (count), (incr)))
// #define amdgpu_vm_set_pte_pde(adev, ib, pe, addr, count, incr, flags) ((adev)->vm_manager.vm_pte_funcs->set_pte_pde((ib), (pe), (addr), (count), (incr), (flags)))
// extern const struct amdgpu_vm_update_funcs amdgpu_vm_cpu_funcs;
// extern const struct amdgpu_vm_update_funcs amdgpu_vm_sdma_funcs;
// void amdgpu_vm_manager_init(struct amdgpu_device *adev);
// void amdgpu_vm_manager_fini(struct amdgpu_device *adev);
// int amdgpu_vm_set_pasid(struct amdgpu_device *adev, struct amdgpu_vm *vm,
// u32 pasid);
// long amdgpu_vm_wait_idle(struct amdgpu_vm *vm, long timeout);
// int amdgpu_vm_init(struct amdgpu_device *adev, struct amdgpu_vm *vm, int32_t xcp_id);
// int amdgpu_vm_make_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
// void amdgpu_vm_release_compute(struct amdgpu_device *adev, struct amdgpu_vm *vm);
// void amdgpu_vm_fini(struct amdgpu_device *adev, struct amdgpu_vm *vm);
// int amdgpu_vm_lock_pd(struct amdgpu_vm *vm, struct drm_exec *exec,
// unsigned int num_fences);
// bool amdgpu_vm_ready(struct amdgpu_vm *vm);
// uint64_t amdgpu_vm_generation(struct amdgpu_device *adev, struct amdgpu_vm *vm);
// int amdgpu_vm_validate(struct amdgpu_device *adev, struct amdgpu_vm *vm,
// struct ww_acquire_ctx *ticket,
// int (*callback)(void *p, struct amdgpu_bo *bo),
// void *param);
// int amdgpu_vm_flush(struct amdgpu_ring *ring, struct amdgpu_job *job, bool need_pipe_sync);
// int amdgpu_vm_update_pdes(struct amdgpu_device *adev,
// struct amdgpu_vm *vm, bool immediate);
// int amdgpu_vm_clear_freed(struct amdgpu_device *adev,
// struct amdgpu_vm *vm,
// struct dma_fence **fence);
// int amdgpu_vm_handle_moved(struct amdgpu_device *adev,
// struct amdgpu_vm *vm,
// struct ww_acquire_ctx *ticket);
// int amdgpu_vm_flush_compute_tlb(struct amdgpu_device *adev,
// struct amdgpu_vm *vm,
// uint32_t flush_type,
// uint32_t xcc_mask);
// void amdgpu_vm_bo_base_init(struct amdgpu_vm_bo_base *base,
// struct amdgpu_vm *vm, struct amdgpu_bo *bo);
// int amdgpu_vm_update_range(struct amdgpu_device *adev, struct amdgpu_vm *vm,
// bool immediate, bool unlocked, bool flush_tlb, bool allow_override,
// struct dma_resv *resv, uint64_t start, uint64_t last,
// uint64_t flags, uint64_t offset, uint64_t vram_base,
// struct ttm_resource *res, dma_addr_t *pages_addr,
// struct dma_fence **fence);
// int amdgpu_vm_bo_update(struct amdgpu_device *adev,
// struct amdgpu_bo_va *bo_va,
// bool clear);
// bool amdgpu_vm_evictable(struct amdgpu_bo *bo);
// void amdgpu_vm_bo_invalidate(struct amdgpu_device *adev,
// struct amdgpu_bo *bo, bool evicted);
// uint64_t amdgpu_vm_map_gart(const dma_addr_t *pages_addr, uint64_t addr);
// struct amdgpu_bo_va *amdgpu_vm_bo_find(struct amdgpu_vm *vm,
// struct amdgpu_bo *bo);
// struct amdgpu_bo_va *amdgpu_vm_bo_add(struct amdgpu_device *adev,
// struct amdgpu_vm *vm,
// struct amdgpu_bo *bo);
// int amdgpu_vm_bo_map(struct amdgpu_device *adev,
// struct amdgpu_bo_va *bo_va,
// uint64_t addr, uint64_t offset,
// uint64_t size, uint64_t flags);
// int amdgpu_vm_bo_replace_map(struct amdgpu_device *adev,
// struct amdgpu_bo_va *bo_va,
// uint64_t addr, uint64_t offset,
// uint64_t size, uint64_t flags);
// int amdgpu_vm_bo_unmap(struct amdgpu_device *adev,
// struct amdgpu_bo_va *bo_va,
// uint64_t addr);
// int amdgpu_vm_bo_clear_mappings(struct amdgpu_device *adev,
// struct amdgpu_vm *vm,
// uint64_t saddr, uint64_t size);
// struct amdgpu_bo_va_mapping *amdgpu_vm_bo_lookup_mapping(struct amdgpu_vm *vm,
// uint64_t addr);
// void amdgpu_vm_bo_trace_cs(struct amdgpu_vm *vm, struct ww_acquire_ctx *ticket);
// void amdgpu_vm_bo_del(struct amdgpu_device *adev,
// struct amdgpu_bo_va *bo_va);
// void amdgpu_vm_adjust_size(struct amdgpu_device *adev, uint32_t min_vm_size,
// uint32_t fragment_size_default, unsigned max_level,
// unsigned max_bits);
// int amdgpu_vm_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
// bool amdgpu_vm_need_pipeline_sync(struct amdgpu_ring *ring,
// struct amdgpu_job *job);
// void amdgpu_vm_check_compute_bug(struct amdgpu_device *adev);
// struct amdgpu_task_info *
// amdgpu_vm_get_task_info_pasid(struct amdgpu_device *adev, u32 pasid);
// struct amdgpu_task_info *
// amdgpu_vm_get_task_info_vm(struct amdgpu_vm *vm);
// void amdgpu_vm_put_task_info(struct amdgpu_task_info *task_info);
// bool amdgpu_vm_handle_fault(struct amdgpu_device *adev, u32 pasid,
// u32 vmid, u32 node_id, uint64_t addr,
// bool write_fault);
// void amdgpu_vm_set_task_info(struct amdgpu_vm *vm);
// void amdgpu_vm_move_to_lru_tail(struct amdgpu_device *adev,
// struct amdgpu_vm *vm);
// void amdgpu_vm_get_memory(struct amdgpu_vm *vm,
// struct amdgpu_mem_stats *stats);
// int amdgpu_vm_pt_clear(struct amdgpu_device *adev, struct amdgpu_vm *vm,
// struct amdgpu_bo_vm *vmbo, bool immediate);
// int amdgpu_vm_pt_create(struct amdgpu_device *adev, struct amdgpu_vm *vm,
// int level, bool immediate, struct amdgpu_bo_vm **vmbo,
// int32_t xcp_id);
// void amdgpu_vm_pt_free_root(struct amdgpu_device *adev, struct amdgpu_vm *vm);
// int amdgpu_vm_pde_update(struct amdgpu_vm_update_params *params,
// struct amdgpu_vm_bo_base *entry);
// int amdgpu_vm_ptes_update(struct amdgpu_vm_update_params *params,
// uint64_t start, uint64_t end,
// uint64_t dst, uint64_t flags);
// void amdgpu_vm_pt_free_work(struct work_struct *work);
// void amdgpu_vm_pt_free_list(struct amdgpu_device *adev,
// struct amdgpu_vm_update_params *params);
// #if defined(CONFIG_DEBUG_FS)
// void amdgpu_debugfs_vm_bo_info(struct amdgpu_vm *vm, struct seq_file *m);
// #endif
// int amdgpu_vm_pt_map_tables(struct amdgpu_device *adev, struct amdgpu_vm *vm);
// bool amdgpu_vm_is_bo_always_valid(struct amdgpu_vm *vm, struct amdgpu_bo *bo);
// /**
// * amdgpu_vm_tlb_seq - return tlb flush sequence number
// * @vm: the amdgpu_vm structure to query
// *
// * Returns the tlb flush sequence number which indicates that the VM TLBs needs
// * to be invalidated whenever the sequence number change.
// */
// static inline uint64_t amdgpu_vm_tlb_seq(struct amdgpu_vm *vm)
// {
// unsigned long flags;
// spinlock_t *lock;
// /*
// * Workaround to stop racing between the fence signaling and handling
// * the cb. The lock is static after initially setting it up, just make
// * sure that the dma_fence structure isn't freed up.
// */
// rcu_read_lock();
// lock = vm->last_tlb_flush->lock;
// rcu_read_unlock();
// spin_lock_irqsave(lock, flags);
// spin_unlock_irqrestore(lock, flags);
// return atomic64_read(&vm->tlb_seq);
// }
// /*
// * vm eviction_lock can be taken in MMU notifiers. Make sure no reclaim-FS
// * happens while holding this lock anywhere to prevent deadlocks when
// * an MMU notifier runs in reclaim-FS context.
// */
// static inline void amdgpu_vm_eviction_lock(struct amdgpu_vm *vm)
// {
// mutex_lock(&vm->eviction_lock);
// vm->saved_flags = memalloc_noreclaim_save();
// }
// static inline bool amdgpu_vm_eviction_trylock(struct amdgpu_vm *vm)
// {
// if (mutex_trylock(&vm->eviction_lock)) {
// vm->saved_flags = memalloc_noreclaim_save();
// return true;
// }
// return false;
// }
// static inline void amdgpu_vm_eviction_unlock(struct amdgpu_vm *vm)
// {
// memalloc_noreclaim_restore(vm->saved_flags);
// mutex_unlock(&vm->eviction_lock);
// }
// void amdgpu_vm_update_fault_cache(struct amdgpu_device *adev,
// unsigned int pasid,
// uint64_t addr,
// uint32_t status,
// unsigned int vmhub);
// void amdgpu_vm_tlb_fence_create(struct amdgpu_device *adev,
// struct amdgpu_vm *vm,
// struct dma_fence **fence);
#endif

View File

@@ -0,0 +1,600 @@
/*
* Copyright 2018 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef _DISCOVERY_H_
#define _DISCOVERY_H_
#define PSP_HEADER_SIZE 256
#define BINARY_SIGNATURE 0x28211407
#define DISCOVERY_TABLE_SIGNATURE 0x53445049
#define GC_TABLE_ID 0x4347
#define HARVEST_TABLE_SIGNATURE 0x56524148
#define VCN_INFO_TABLE_ID 0x004E4356
#define MALL_INFO_TABLE_ID 0x4C4C414D
#define NPS_INFO_TABLE_ID 0x0053504E
typedef enum {
IP_DISCOVERY = 0,
GC,
HARVEST_INFO,
VCN_INFO,
MALL_INFO,
NPS_INFO,
TOTAL_TABLES = 6
} table;
#pragma pack(1)
typedef struct table_info
{
uint16_t offset; /* Byte offset */
uint16_t checksum; /* Byte sum of the table */
uint16_t size; /* Table size */
uint16_t padding;
} table_info;
typedef struct binary_header
{
/* psp structure should go at the top of this structure */
uint32_t binary_signature; /* 0x7, 0x14, 0x21, 0x28 */
uint16_t version_major;
uint16_t version_minor;
uint16_t binary_checksum; /* Byte sum of the binary after this field */
uint16_t binary_size; /* Binary Size*/
table_info table_list[TOTAL_TABLES];
} binary_header;
typedef struct die_info
{
uint16_t die_id;
uint16_t die_offset; /* Points to the corresponding die_header structure */
} die_info;
typedef struct ip_discovery_header
{
uint32_t signature; /* Table Signature */
uint16_t version; /* Table Version */
uint16_t size; /* Table Size */
uint32_t id; /* Table ID */
uint16_t num_dies; /* Number of Dies */
die_info die_info[16]; /* list die information for up to 16 dies */
union {
uint16_t padding[1]; /* version <= 3 */
struct { /* version == 4 */
uint8_t base_addr_64_bit : 1; /* ip structures are using 64 bit base address */
uint8_t reserved : 7;
uint8_t reserved2;
};
};
} ip_discovery_header;
typedef struct ip
{
uint16_t hw_id; /* Hardware ID */
uint8_t number_instance; /* instance of the IP */
uint8_t num_base_address; /* Number of Base Addresses */
uint8_t major; /* HCID Major */
uint8_t minor; /* HCID Minor */
uint8_t revision; /* HCID Revision */
#if defined(__BIG_ENDIAN)
uint8_t reserved : 4; /* Placeholder field */
uint8_t harvest : 4; /* Harvest */
#else
uint8_t harvest : 4; /* Harvest */
uint8_t reserved : 4; /* Placeholder field */
#endif
uint32_t base_address[]; /* variable number of Addresses */
} ip;
typedef struct ip_v3
{
uint16_t hw_id; /* Hardware ID */
uint8_t instance_number; /* Instance number for the IP */
uint8_t num_base_address; /* Number of base addresses*/
uint8_t major; /* Hardware ID.major version */
uint8_t minor; /* Hardware ID.minor version */
uint8_t revision; /* Hardware ID.revision version */
#if defined(__BIG_ENDIAN)
uint8_t variant : 4; /* HW variant */
uint8_t sub_revision : 4; /* HCID Sub-Revision */
#else
uint8_t sub_revision : 4; /* HCID Sub-Revision */
uint8_t variant : 4; /* HW variant */
#endif
uint32_t base_address[]; /* Base Address list. Corresponds to the num_base_address field*/
} ip_v3;
typedef struct ip_v4 {
uint16_t hw_id; /* Hardware ID */
uint8_t instance_number; /* Instance number for the IP */
uint8_t num_base_address; /* Number of base addresses*/
uint8_t major; /* Hardware ID.major version */
uint8_t minor; /* Hardware ID.minor version */
uint8_t revision; /* Hardware ID.revision version */
#if defined(LITTLEENDIAN_CPU)
uint8_t sub_revision : 4; /* HCID Sub-Revision */
uint8_t variant : 4; /* HW variant */
#elif defined(BIGENDIAN_CPU)
uint8_t variant : 4; /* HW variant */
uint8_t sub_revision : 4; /* HCID Sub-Revision */
#endif
} ip_v4;
typedef struct die_header
{
uint16_t die_id;
uint16_t num_ips;
} die_header;
typedef struct ip_structure
{
ip_discovery_header* header;
struct die
{
die_header *die_header;
union
{
ip *ip_list;
ip_v3 *ip_v3_list;
ip_v4 *ip_v4_list;
}; /* IP list. Variable size*/
} die;
} ip_structure;
struct gpu_info_header {
uint32_t table_id; /* table ID */
uint16_t version_major; /* table version */
uint16_t version_minor; /* table version */
uint32_t size; /* size of the entire header+data in bytes */
};
struct gc_info_v1_0 {
struct gpu_info_header header;
uint32_t gc_num_se;
uint32_t gc_num_wgp0_per_sa;
uint32_t gc_num_wgp1_per_sa;
uint32_t gc_num_rb_per_se;
uint32_t gc_num_gl2c;
uint32_t gc_num_gprs;
uint32_t gc_num_max_gs_thds;
uint32_t gc_gs_table_depth;
uint32_t gc_gsprim_buff_depth;
uint32_t gc_parameter_cache_depth;
uint32_t gc_double_offchip_lds_buffer;
uint32_t gc_wave_size;
uint32_t gc_max_waves_per_simd;
uint32_t gc_max_scratch_slots_per_cu;
uint32_t gc_lds_size;
uint32_t gc_num_sc_per_se;
uint32_t gc_num_sa_per_se;
uint32_t gc_num_packer_per_sc;
uint32_t gc_num_gl2a;
};
struct gc_info_v1_1 {
struct gpu_info_header header;
uint32_t gc_num_se;
uint32_t gc_num_wgp0_per_sa;
uint32_t gc_num_wgp1_per_sa;
uint32_t gc_num_rb_per_se;
uint32_t gc_num_gl2c;
uint32_t gc_num_gprs;
uint32_t gc_num_max_gs_thds;
uint32_t gc_gs_table_depth;
uint32_t gc_gsprim_buff_depth;
uint32_t gc_parameter_cache_depth;
uint32_t gc_double_offchip_lds_buffer;
uint32_t gc_wave_size;
uint32_t gc_max_waves_per_simd;
uint32_t gc_max_scratch_slots_per_cu;
uint32_t gc_lds_size;
uint32_t gc_num_sc_per_se;
uint32_t gc_num_sa_per_se;
uint32_t gc_num_packer_per_sc;
uint32_t gc_num_gl2a;
uint32_t gc_num_tcp_per_sa;
uint32_t gc_num_sdp_interface;
uint32_t gc_num_tcps;
};
struct gc_info_v1_2 {
struct gpu_info_header header;
uint32_t gc_num_se;
uint32_t gc_num_wgp0_per_sa;
uint32_t gc_num_wgp1_per_sa;
uint32_t gc_num_rb_per_se;
uint32_t gc_num_gl2c;
uint32_t gc_num_gprs;
uint32_t gc_num_max_gs_thds;
uint32_t gc_gs_table_depth;
uint32_t gc_gsprim_buff_depth;
uint32_t gc_parameter_cache_depth;
uint32_t gc_double_offchip_lds_buffer;
uint32_t gc_wave_size;
uint32_t gc_max_waves_per_simd;
uint32_t gc_max_scratch_slots_per_cu;
uint32_t gc_lds_size;
uint32_t gc_num_sc_per_se;
uint32_t gc_num_sa_per_se;
uint32_t gc_num_packer_per_sc;
uint32_t gc_num_gl2a;
uint32_t gc_num_tcp_per_sa;
uint32_t gc_num_sdp_interface;
uint32_t gc_num_tcps;
uint32_t gc_num_tcp_per_wpg;
uint32_t gc_tcp_l1_size;
uint32_t gc_num_sqc_per_wgp;
uint32_t gc_l1_instruction_cache_size_per_sqc;
uint32_t gc_l1_data_cache_size_per_sqc;
uint32_t gc_gl1c_per_sa;
uint32_t gc_gl1c_size_per_instance;
uint32_t gc_gl2c_per_gpu;
};
struct gc_info_v1_3 {
struct gpu_info_header header;
uint32_t gc_num_se;
uint32_t gc_num_wgp0_per_sa;
uint32_t gc_num_wgp1_per_sa;
uint32_t gc_num_rb_per_se;
uint32_t gc_num_gl2c;
uint32_t gc_num_gprs;
uint32_t gc_num_max_gs_thds;
uint32_t gc_gs_table_depth;
uint32_t gc_gsprim_buff_depth;
uint32_t gc_parameter_cache_depth;
uint32_t gc_double_offchip_lds_buffer;
uint32_t gc_wave_size;
uint32_t gc_max_waves_per_simd;
uint32_t gc_max_scratch_slots_per_cu;
uint32_t gc_lds_size;
uint32_t gc_num_sc_per_se;
uint32_t gc_num_sa_per_se;
uint32_t gc_num_packer_per_sc;
uint32_t gc_num_gl2a;
uint32_t gc_num_tcp_per_sa;
uint32_t gc_num_sdp_interface;
uint32_t gc_num_tcps;
uint32_t gc_num_tcp_per_wpg;
uint32_t gc_tcp_l1_size;
uint32_t gc_num_sqc_per_wgp;
uint32_t gc_l1_instruction_cache_size_per_sqc;
uint32_t gc_l1_data_cache_size_per_sqc;
uint32_t gc_gl1c_per_sa;
uint32_t gc_gl1c_size_per_instance;
uint32_t gc_gl2c_per_gpu;
uint32_t gc_tcp_size_per_cu;
uint32_t gc_tcp_cache_line_size;
uint32_t gc_instruction_cache_size_per_sqc;
uint32_t gc_instruction_cache_line_size;
uint32_t gc_scalar_data_cache_size_per_sqc;
uint32_t gc_scalar_data_cache_line_size;
uint32_t gc_tcc_size;
uint32_t gc_tcc_cache_line_size;
};
struct gc_info_v2_0 {
struct gpu_info_header header;
uint32_t gc_num_se;
uint32_t gc_num_cu_per_sh;
uint32_t gc_num_sh_per_se;
uint32_t gc_num_rb_per_se;
uint32_t gc_num_tccs;
uint32_t gc_num_gprs;
uint32_t gc_num_max_gs_thds;
uint32_t gc_gs_table_depth;
uint32_t gc_gsprim_buff_depth;
uint32_t gc_parameter_cache_depth;
uint32_t gc_double_offchip_lds_buffer;
uint32_t gc_wave_size;
uint32_t gc_max_waves_per_simd;
uint32_t gc_max_scratch_slots_per_cu;
uint32_t gc_lds_size;
uint32_t gc_num_sc_per_se;
uint32_t gc_num_packer_per_sc;
};
struct gc_info_v2_1 {
struct gpu_info_header header;
uint32_t gc_num_se;
uint32_t gc_num_cu_per_sh;
uint32_t gc_num_sh_per_se;
uint32_t gc_num_rb_per_se;
uint32_t gc_num_tccs;
uint32_t gc_num_gprs;
uint32_t gc_num_max_gs_thds;
uint32_t gc_gs_table_depth;
uint32_t gc_gsprim_buff_depth;
uint32_t gc_parameter_cache_depth;
uint32_t gc_double_offchip_lds_buffer;
uint32_t gc_wave_size;
uint32_t gc_max_waves_per_simd;
uint32_t gc_max_scratch_slots_per_cu;
uint32_t gc_lds_size;
uint32_t gc_num_sc_per_se;
uint32_t gc_num_packer_per_sc;
/* new for v2_1 */
uint32_t gc_num_tcp_per_sh;
uint32_t gc_tcp_size_per_cu;
uint32_t gc_num_sdp_interface;
uint32_t gc_num_cu_per_sqc;
uint32_t gc_instruction_cache_size_per_sqc;
uint32_t gc_scalar_data_cache_size_per_sqc;
uint32_t gc_tcc_size;
};
typedef struct harvest_info_header {
uint32_t signature; /* Table Signature */
uint32_t version; /* Table Version */
} harvest_info_header;
typedef struct harvest_info {
uint16_t hw_id; /* Hardware ID */
uint8_t number_instance; /* Instance of the IP */
uint8_t reserved; /* Reserved for alignment */
} harvest_info;
typedef struct harvest_table {
harvest_info_header header;
harvest_info list[32];
} harvest_table;
struct mall_info_header {
uint32_t table_id; /* table ID */
uint16_t version_major; /* table version */
uint16_t version_minor; /* table version */
uint32_t size_bytes; /* size of the entire header+data in bytes */
};
struct mall_info_v1_0 {
struct mall_info_header header;
uint32_t mall_size_per_m;
uint32_t m_s_present;
uint32_t m_half_use;
uint32_t m_mall_config;
uint32_t reserved[5];
};
struct mall_info_v2_0 {
struct mall_info_header header;
uint32_t mall_size_per_umc;
uint32_t reserved[8];
};
#define VCN_INFO_TABLE_MAX_NUM_INSTANCES 4
struct vcn_info_header {
uint32_t table_id; /* table ID */
uint16_t version_major; /* table version */
uint16_t version_minor; /* table version */
uint32_t size_bytes; /* size of the entire header+data in bytes */
};
struct vcn_instance_info_v1_0
{
uint32_t instance_num; /* VCN IP instance number. 0 - VCN0; 1 - VCN1 etc*/
union _fuse_data {
struct {
uint32_t av1_disabled : 1;
uint32_t vp9_disabled : 1;
uint32_t hevc_disabled : 1;
uint32_t h264_disabled : 1;
uint32_t reserved : 28;
} bits;
uint32_t all_bits;
} fuse_data;
uint32_t reserved[2];
};
struct vcn_info_v1_0 {
struct vcn_info_header header;
uint32_t num_of_instances; /* number of entries used in instance_info below*/
struct vcn_instance_info_v1_0 instance_info[VCN_INFO_TABLE_MAX_NUM_INSTANCES];
uint32_t reserved[4];
};
#define NPS_INFO_TABLE_MAX_NUM_INSTANCES 12
struct nps_info_header {
uint32_t table_id; /* table ID */
uint16_t version_major; /* table version */
uint16_t version_minor; /* table version */
uint32_t size_bytes; /* size of the entire header+data in bytes = 0x000000D4 (212) */
};
struct nps_instance_info_v1_0 {
uint64_t base_address;
uint64_t limit_address;
};
struct nps_info_v1_0 {
struct nps_info_header header;
uint32_t nps_type;
uint32_t count;
struct nps_instance_info_v1_0
instance_info[NPS_INFO_TABLE_MAX_NUM_INSTANCES];
};
enum amd_hw_ip_block_type {
GC_HWIP = 1,
HDP_HWIP,
SDMA0_HWIP,
SDMA1_HWIP,
SDMA2_HWIP,
SDMA3_HWIP,
SDMA4_HWIP,
SDMA5_HWIP,
SDMA6_HWIP,
SDMA7_HWIP,
LSDMA_HWIP,
MMHUB_HWIP,
ATHUB_HWIP,
NBIO_HWIP,
MP0_HWIP,
MP1_HWIP,
UVD_HWIP,
VCN_HWIP = UVD_HWIP,
JPEG_HWIP = VCN_HWIP,
VCN1_HWIP,
VCE_HWIP,
VPE_HWIP,
DF_HWIP,
DCE_HWIP,
OSSSYS_HWIP,
SMUIO_HWIP,
PWR_HWIP,
NBIF_HWIP,
THM_HWIP,
CLK_HWIP,
UMC_HWIP,
RSMU_HWIP,
XGMI_HWIP,
DCI_HWIP,
PCIE_HWIP,
ISP_HWIP,
MAX_HWIP
};
#define HWIP_MAX_INSTANCE 44
#define HW_ID_MAX 300
// HW ID
#define MP1_HWID 1
#define MP2_HWID 2
#define THM_HWID 3
#define SMUIO_HWID 4
#define FUSE_HWID 5
#define CLKA_HWID 6
#define PWR_HWID 10
#define GC_HWID 11
#define UVD_HWID 12
#define VCN_HWID UVD_HWID
#define AUDIO_AZ_HWID 13
#define ACP_HWID 14
#define DCI_HWID 15
#define DMU_HWID 271
#define DCO_HWID 16
#define DIO_HWID 272
#define XDMA_HWID 17
#define DCEAZ_HWID 18
#define DAZ_HWID 274
#define SDPMUX_HWID 19
#define NTB_HWID 20
#define VPE_HWID 21
#define IOHC_HWID 24
#define L2IMU_HWID 28
#define VCE_HWID 32
#define MMHUB_HWID 34
#define ATHUB_HWID 35
#define DBGU_NBIO_HWID 36
#define DFX_HWID 37
#define DBGU0_HWID 38
#define DBGU1_HWID 39
#define OSSSYS_HWID 40
#define HDP_HWID 41
#define SDMA0_HWID 42
#define SDMA1_HWID 43
#define ISP_HWID 44
#define DBGU_IO_HWID 45
#define DF_HWID 46
#define CLKB_HWID 47
#define FCH_HWID 48
#define DFX_DAP_HWID 49
#define L1IMU_PCIE_HWID 50
#define L1IMU_NBIF_HWID 51
#define L1IMU_IOAGR_HWID 52
#define L1IMU3_HWID 53
#define L1IMU4_HWID 54
#define L1IMU5_HWID 55
#define L1IMU6_HWID 56
#define L1IMU7_HWID 57
#define L1IMU8_HWID 58
#define L1IMU9_HWID 59
#define L1IMU10_HWID 60
#define L1IMU11_HWID 61
#define L1IMU12_HWID 62
#define L1IMU13_HWID 63
#define L1IMU14_HWID 64
#define L1IMU15_HWID 65
#define WAFLC_HWID 66
#define FCH_USB_PD_HWID 67
#define SDMA2_HWID 68
#define SDMA3_HWID 69
#define PCIE_HWID 70
#define PCS_HWID 80
#define DDCL_HWID 89
#define SST_HWID 90
#define LSDMA_HWID 91
#define IOAGR_HWID 100
#define NBIF_HWID 108
#define IOAPIC_HWID 124
#define SYSTEMHUB_HWID 128
#define NTBCCP_HWID 144
#define UMC_HWID 150
#define SATA_HWID 168
#define USB_HWID 170
#define CCXSEC_HWID 176
#define XGMI_HWID 200
#define XGBE_HWID 216
#define MP0_HWID 255
static int hw_id_map[MAX_HWIP] = {
[GC_HWIP] = GC_HWID,
[HDP_HWIP] = HDP_HWID,
[SDMA0_HWIP] = SDMA0_HWID,
[SDMA1_HWIP] = SDMA1_HWID,
[SDMA2_HWIP] = SDMA2_HWID,
[SDMA3_HWIP] = SDMA3_HWID,
[LSDMA_HWIP] = LSDMA_HWID,
[MMHUB_HWIP] = MMHUB_HWID,
[ATHUB_HWIP] = ATHUB_HWID,
[NBIO_HWIP] = NBIF_HWID,
[MP0_HWIP] = MP0_HWID,
[MP1_HWIP] = MP1_HWID,
[UVD_HWIP] = UVD_HWID,
[VCE_HWIP] = VCE_HWID,
[DF_HWIP] = DF_HWID,
[DCE_HWIP] = DMU_HWID,
[OSSSYS_HWIP] = OSSSYS_HWID,
[SMUIO_HWIP] = SMUIO_HWID,
[PWR_HWIP] = PWR_HWID,
[NBIF_HWIP] = NBIF_HWID,
[THM_HWIP] = THM_HWID,
[CLK_HWIP] = CLKA_HWID,
[UMC_HWIP] = UMC_HWID,
[XGMI_HWIP] = XGMI_HWID,
[DCI_HWIP] = DCI_HWID,
[PCIE_HWIP] = PCIE_HWID,
[VPE_HWIP] = VPE_HWID,
[ISP_HWIP] = ISP_HWID,
};
#endif

View File

@@ -0,0 +1,471 @@
/*
* Copyright 2017 Advanced Micro Devices, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef _PSP_TEE_GFX_IF_H_
#define _PSP_TEE_GFX_IF_H_
#define PSP_GFX_CMD_BUF_VERSION 0x00000001
#define GFX_CMD_STATUS_MASK 0x0000FFFF
#define GFX_CMD_ID_MASK 0x000F0000
#define GFX_CMD_RESERVED_MASK 0x7FF00000
#define GFX_CMD_RESPONSE_MASK 0x80000000
/* USBC PD FW version retrieval command */
#define C2PMSG_CMD_GFX_USB_PD_FW_VER 0x2000000
/* TEE Gfx Command IDs for the register interface.
* Command ID must be between 0x00010000 and 0x000F0000.
*/
enum psp_gfx_crtl_cmd_id
{
GFX_CTRL_CMD_ID_INIT_RBI_RING = 0x00010000, /* initialize RBI ring */
GFX_CTRL_CMD_ID_INIT_GPCOM_RING = 0x00020000, /* initialize GPCOM ring */
GFX_CTRL_CMD_ID_DESTROY_RINGS = 0x00030000, /* destroy rings */
GFX_CTRL_CMD_ID_CAN_INIT_RINGS = 0x00040000, /* is it allowed to initialized the rings */
GFX_CTRL_CMD_ID_ENABLE_INT = 0x00050000, /* enable PSP-to-Gfx interrupt */
GFX_CTRL_CMD_ID_DISABLE_INT = 0x00060000, /* disable PSP-to-Gfx interrupt */
GFX_CTRL_CMD_ID_MODE1_RST = 0x00070000, /* trigger the Mode 1 reset */
GFX_CTRL_CMD_ID_GBR_IH_SET = 0x00080000, /* set Gbr IH_RB_CNTL registers */
GFX_CTRL_CMD_ID_CONSUME_CMD = 0x00090000, /* send interrupt to psp for updating write pointer of vf */
GFX_CTRL_CMD_ID_DESTROY_GPCOM_RING = 0x000C0000, /* destroy GPCOM ring */
GFX_CTRL_CMD_ID_MAX = 0x000F0000, /* max command ID */
};
/*-----------------------------------------------------------------------------
NOTE: All physical addresses used in this interface are actually
GPU Virtual Addresses.
*/
/* Control registers of the TEE Gfx interface. These are located in
* SRBM-to-PSP mailbox registers (total 8 registers).
*/
struct psp_gfx_ctrl
{
volatile unsigned int cmd_resp; /* +0 Command/Response register for Gfx commands */
volatile unsigned int rbi_wptr; /* +4 Write pointer (index) of RBI ring */
volatile unsigned int rbi_rptr; /* +8 Read pointer (index) of RBI ring */
volatile unsigned int gpcom_wptr; /* +12 Write pointer (index) of GPCOM ring */
volatile unsigned int gpcom_rptr; /* +16 Read pointer (index) of GPCOM ring */
volatile unsigned int ring_addr_lo; /* +20 bits [31:0] of GPU Virtual of ring buffer (VMID=0)*/
volatile unsigned int ring_addr_hi; /* +24 bits [63:32] of GPU Virtual of ring buffer (VMID=0) */
volatile unsigned int ring_buf_size; /* +28 Ring buffer size (in bytes) */
};
/* Response flag is set in the command when command is completed by PSP.
* Used in the GFX_CTRL.CmdResp.
* When PSP GFX I/F is initialized, the flag is set.
*/
#define GFX_FLAG_RESPONSE 0x80000000
/* TEE Gfx Command IDs for the ring buffer interface. */
enum psp_gfx_cmd_id
{
GFX_CMD_ID_LOAD_TA = 0x00000001, /* load TA */
GFX_CMD_ID_UNLOAD_TA = 0x00000002, /* unload TA */
GFX_CMD_ID_INVOKE_CMD = 0x00000003, /* send command to TA */
GFX_CMD_ID_LOAD_ASD = 0x00000004, /* load ASD Driver */
GFX_CMD_ID_SETUP_TMR = 0x00000005, /* setup TMR region */
GFX_CMD_ID_LOAD_IP_FW = 0x00000006, /* load HW IP FW */
GFX_CMD_ID_DESTROY_TMR = 0x00000007, /* destroy TMR region */
GFX_CMD_ID_SAVE_RESTORE = 0x00000008, /* save/restore HW IP FW */
GFX_CMD_ID_SETUP_VMR = 0x00000009, /* setup VMR region */
GFX_CMD_ID_DESTROY_VMR = 0x0000000A, /* destroy VMR region */
GFX_CMD_ID_PROG_REG = 0x0000000B, /* program regs */
GFX_CMD_ID_GET_FW_ATTESTATION = 0x0000000F, /* Query GPUVA of the Fw Attestation DB */
/* IDs upto 0x1F are reserved for older programs (Raven, Vega 10/12/20) */
GFX_CMD_ID_LOAD_TOC = 0x00000020, /* Load TOC and obtain TMR size */
GFX_CMD_ID_AUTOLOAD_RLC = 0x00000021, /* Indicates all graphics fw loaded, start RLC autoload */
GFX_CMD_ID_BOOT_CFG = 0x00000022, /* Boot Config */
GFX_CMD_ID_SRIOV_SPATIAL_PART = 0x00000027, /* Configure spatial partitioning mode */
};
/* PSP boot config sub-commands */
enum psp_gfx_boot_config_cmd
{
BOOTCFG_CMD_SET = 1, /* Set boot configuration settings */
BOOTCFG_CMD_GET = 2, /* Get boot configuration settings */
BOOTCFG_CMD_INVALIDATE = 3 /* Reset current boot configuration settings to VBIOS defaults */
};
/* PSP boot config bitmask values */
enum psp_gfx_boot_config
{
BOOT_CONFIG_GECC = 0x1,
};
/* Command to load Trusted Application binary into PSP OS. */
struct psp_gfx_cmd_load_ta
{
unsigned int app_phy_addr_lo; /* bits [31:0] of the GPU Virtual address of the TA binary (must be 4 KB aligned) */
unsigned int app_phy_addr_hi; /* bits [63:32] of the GPU Virtual address of the TA binary */
unsigned int app_len; /* length of the TA binary in bytes */
unsigned int cmd_buf_phy_addr_lo; /* bits [31:0] of the GPU Virtual address of CMD buffer (must be 4 KB aligned) */
unsigned int cmd_buf_phy_addr_hi; /* bits [63:32] of the GPU Virtual address of CMD buffer */
unsigned int cmd_buf_len; /* length of the CMD buffer in bytes; must be multiple of 4 KB */
/* Note: CmdBufLen can be set to 0. In this case no persistent CMD buffer is provided
* for the TA. Each InvokeCommand can have dinamically mapped CMD buffer instead
* of using global persistent buffer.
*/
};
/* Command to Unload Trusted Application binary from PSP OS. */
struct psp_gfx_cmd_unload_ta
{
unsigned int session_id; /* Session ID of the loaded TA to be unloaded */
};
/* Shared buffers for InvokeCommand.
*/
struct psp_gfx_buf_desc
{
unsigned int buf_phy_addr_lo; /* bits [31:0] of GPU Virtual address of the buffer (must be 4 KB aligned) */
unsigned int buf_phy_addr_hi; /* bits [63:32] of GPU Virtual address of the buffer */
unsigned int buf_size; /* buffer size in bytes (must be multiple of 4 KB and no bigger than 64 MB) */
};
/* Max number of descriptors for one shared buffer (in how many different
* physical locations one shared buffer can be stored). If buffer is too much
* fragmented, error will be returned.
*/
#define GFX_BUF_MAX_DESC 64
struct psp_gfx_buf_list
{
unsigned int num_desc; /* number of buffer descriptors in the list */
unsigned int total_size; /* total size of all buffers in the list in bytes (must be multiple of 4 KB) */
struct psp_gfx_buf_desc buf_desc[GFX_BUF_MAX_DESC]; /* list of buffer descriptors */
/* total 776 bytes */
};
/* Command to execute InvokeCommand entry point of the TA. */
struct psp_gfx_cmd_invoke_cmd
{
unsigned int session_id; /* Session ID of the TA to be executed */
unsigned int ta_cmd_id; /* Command ID to be sent to TA */
struct psp_gfx_buf_list buf; /* one indirect buffer (scatter/gather list) */
};
/* Command to setup TMR region. */
struct psp_gfx_cmd_setup_tmr
{
unsigned int buf_phy_addr_lo; /* bits [31:0] of GPU Virtual address of TMR buffer (must be 4 KB aligned) */
unsigned int buf_phy_addr_hi; /* bits [63:32] of GPU Virtual address of TMR buffer */
unsigned int buf_size; /* buffer size in bytes (must be multiple of 4 KB) */
union {
struct {
unsigned int sriov_enabled:1; /* whether the device runs under SR-IOV*/
unsigned int virt_phy_addr:1; /* driver passes both virtual and physical address to PSP*/
unsigned int reserved:30;
} bitfield;
unsigned int tmr_flags;
};
unsigned int system_phy_addr_lo; /* bits [31:0] of system physical address of TMR buffer (must be 4 KB aligned) */
unsigned int system_phy_addr_hi; /* bits [63:32] of system physical address of TMR buffer */
};
/* FW types for GFX_CMD_ID_LOAD_IP_FW command. Limit 31. */
enum psp_gfx_fw_type {
GFX_FW_TYPE_NONE = 0, /* */
GFX_FW_TYPE_CP_ME = 1, /* CP-ME VG + RV */
GFX_FW_TYPE_CP_PFP = 2, /* CP-PFP VG + RV */
GFX_FW_TYPE_CP_CE = 3, /* CP-CE VG + RV */
GFX_FW_TYPE_CP_MEC = 4, /* CP-MEC FW VG + RV */
GFX_FW_TYPE_CP_MEC_ME1 = 5, /* CP-MEC Jump Table 1 VG + RV */
GFX_FW_TYPE_CP_MEC_ME2 = 6, /* CP-MEC Jump Table 2 VG */
GFX_FW_TYPE_RLC_V = 7, /* RLC-V VG */
GFX_FW_TYPE_RLC_G = 8, /* RLC-G VG + RV */
GFX_FW_TYPE_SDMA0 = 9, /* SDMA0 VG + RV */
GFX_FW_TYPE_SDMA1 = 10, /* SDMA1 VG */
GFX_FW_TYPE_DMCU_ERAM = 11, /* DMCU-ERAM VG + RV */
GFX_FW_TYPE_DMCU_ISR = 12, /* DMCU-ISR VG + RV */
GFX_FW_TYPE_VCN = 13, /* VCN RV */
GFX_FW_TYPE_UVD = 14, /* UVD VG */
GFX_FW_TYPE_VCE = 15, /* VCE VG */
GFX_FW_TYPE_ISP = 16, /* ISP RV */
GFX_FW_TYPE_ACP = 17, /* ACP RV */
GFX_FW_TYPE_SMU = 18, /* SMU VG */
GFX_FW_TYPE_MMSCH = 19, /* MMSCH VG */
GFX_FW_TYPE_RLC_RESTORE_LIST_GPM_MEM = 20, /* RLC GPM VG + RV */
GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_MEM = 21, /* RLC SRM VG + RV */
GFX_FW_TYPE_RLC_RESTORE_LIST_SRM_CNTL = 22, /* RLC CNTL VG + RV */
GFX_FW_TYPE_UVD1 = 23, /* UVD1 VG-20 */
GFX_FW_TYPE_TOC = 24, /* TOC NV-10 */
GFX_FW_TYPE_RLC_P = 25, /* RLC P NV */
GFX_FW_TYPE_RLC_IRAM = 26, /* RLC_IRAM NV */
GFX_FW_TYPE_GLOBAL_TAP_DELAYS = 27, /* GLOBAL TAP DELAYS NV */
GFX_FW_TYPE_SE0_TAP_DELAYS = 28, /* SE0 TAP DELAYS NV */
GFX_FW_TYPE_SE1_TAP_DELAYS = 29, /* SE1 TAP DELAYS NV */
GFX_FW_TYPE_GLOBAL_SE0_SE1_SKEW_DELAYS = 30, /* GLOBAL SE0/1 SKEW DELAYS NV */
GFX_FW_TYPE_SDMA0_JT = 31, /* SDMA0 JT NV */
GFX_FW_TYPE_SDMA1_JT = 32, /* SDNA1 JT NV */
GFX_FW_TYPE_CP_MES = 33, /* CP MES NV */
GFX_FW_TYPE_MES_STACK = 34, /* MES STACK NV */
GFX_FW_TYPE_RLC_SRM_DRAM_SR = 35, /* RLC SRM DRAM NV */
GFX_FW_TYPE_RLCG_SCRATCH_SR = 36, /* RLCG SCRATCH NV */
GFX_FW_TYPE_RLCP_SCRATCH_SR = 37, /* RLCP SCRATCH NV */
GFX_FW_TYPE_RLCV_SCRATCH_SR = 38, /* RLCV SCRATCH NV */
GFX_FW_TYPE_RLX6_DRAM_SR = 39, /* RLX6 DRAM NV */
GFX_FW_TYPE_SDMA0_PG_CONTEXT = 40, /* SDMA0 PG CONTEXT NV */
GFX_FW_TYPE_SDMA1_PG_CONTEXT = 41, /* SDMA1 PG CONTEXT NV */
GFX_FW_TYPE_GLOBAL_MUX_SELECT_RAM = 42, /* GLOBAL MUX SEL RAM NV */
GFX_FW_TYPE_SE0_MUX_SELECT_RAM = 43, /* SE0 MUX SEL RAM NV */
GFX_FW_TYPE_SE1_MUX_SELECT_RAM = 44, /* SE1 MUX SEL RAM NV */
GFX_FW_TYPE_ACCUM_CTRL_RAM = 45, /* ACCUM CTRL RAM NV */
GFX_FW_TYPE_RLCP_CAM = 46, /* RLCP CAM NV */
GFX_FW_TYPE_RLC_SPP_CAM_EXT = 47, /* RLC SPP CAM EXT NV */
GFX_FW_TYPE_RLC_DRAM_BOOT = 48, /* RLC DRAM BOOT NV */
GFX_FW_TYPE_VCN0_RAM = 49, /* VCN_RAM NV + RN */
GFX_FW_TYPE_VCN1_RAM = 50, /* VCN_RAM NV + RN */
GFX_FW_TYPE_DMUB = 51, /* DMUB RN */
GFX_FW_TYPE_SDMA2 = 52, /* SDMA2 MI */
GFX_FW_TYPE_SDMA3 = 53, /* SDMA3 MI */
GFX_FW_TYPE_SDMA4 = 54, /* SDMA4 MI */
GFX_FW_TYPE_SDMA5 = 55, /* SDMA5 MI */
GFX_FW_TYPE_SDMA6 = 56, /* SDMA6 MI */
GFX_FW_TYPE_SDMA7 = 57, /* SDMA7 MI */
GFX_FW_TYPE_VCN1 = 58, /* VCN1 MI */
GFX_FW_TYPE_CAP = 62, /* CAP_FW */
GFX_FW_TYPE_SE2_TAP_DELAYS = 65, /* SE2 TAP DELAYS NV */
GFX_FW_TYPE_SE3_TAP_DELAYS = 66, /* SE3 TAP DELAYS NV */
GFX_FW_TYPE_REG_LIST = 67, /* REG_LIST MI */
GFX_FW_TYPE_IMU_I = 68, /* IMU Instruction FW SOC21 */
GFX_FW_TYPE_IMU_D = 69, /* IMU Data FW SOC21 */
GFX_FW_TYPE_LSDMA = 70, /* LSDMA FW SOC21 */
GFX_FW_TYPE_SDMA_UCODE_TH0 = 71, /* SDMA Thread 0/CTX SOC21 */
GFX_FW_TYPE_SDMA_UCODE_TH1 = 72, /* SDMA Thread 1/CTL SOC21 */
GFX_FW_TYPE_PPTABLE = 73, /* PPTABLE SOC21 */
GFX_FW_TYPE_DISCRETE_USB4 = 74, /* dUSB4 FW SOC21 */
GFX_FW_TYPE_TA = 75, /* SRIOV TA FW UUID SOC21 */
GFX_FW_TYPE_RS64_MES = 76, /* RS64 MES ucode SOC21 */
GFX_FW_TYPE_RS64_MES_STACK = 77, /* RS64 MES stack ucode SOC21 */
GFX_FW_TYPE_RS64_KIQ = 78, /* RS64 KIQ ucode SOC21 */
GFX_FW_TYPE_RS64_KIQ_STACK = 79, /* RS64 KIQ Heap stack SOC21 */
GFX_FW_TYPE_ISP_DATA = 80, /* ISP DATA SOC21 */
GFX_FW_TYPE_CP_MES_KIQ = 81, /* MES KIQ ucode SOC21 */
GFX_FW_TYPE_MES_KIQ_STACK = 82, /* MES KIQ stack SOC21 */
GFX_FW_TYPE_UMSCH_DATA = 83, /* User Mode Scheduler Data SOC21 */
GFX_FW_TYPE_UMSCH_UCODE = 84, /* User Mode Scheduler Ucode SOC21 */
GFX_FW_TYPE_UMSCH_CMD_BUFFER = 85, /* User Mode Scheduler Command Buffer SOC21 */
GFX_FW_TYPE_USB_DP_COMBO_PHY = 86, /* USB-Display port Combo SOC21 */
GFX_FW_TYPE_RS64_PFP = 87, /* RS64 PFP SOC21 */
GFX_FW_TYPE_RS64_ME = 88, /* RS64 ME SOC21 */
GFX_FW_TYPE_RS64_MEC = 89, /* RS64 MEC SOC21 */
GFX_FW_TYPE_RS64_PFP_P0_STACK = 90, /* RS64 PFP stack P0 SOC21 */
GFX_FW_TYPE_RS64_PFP_P1_STACK = 91, /* RS64 PFP stack P1 SOC21 */
GFX_FW_TYPE_RS64_ME_P0_STACK = 92, /* RS64 ME stack P0 SOC21 */
GFX_FW_TYPE_RS64_ME_P1_STACK = 93, /* RS64 ME stack P1 SOC21 */
GFX_FW_TYPE_RS64_MEC_P0_STACK = 94, /* RS64 MEC stack P0 SOC21 */
GFX_FW_TYPE_RS64_MEC_P1_STACK = 95, /* RS64 MEC stack P1 SOC21 */
GFX_FW_TYPE_RS64_MEC_P2_STACK = 96, /* RS64 MEC stack P2 SOC21 */
GFX_FW_TYPE_RS64_MEC_P3_STACK = 97, /* RS64 MEC stack P3 SOC21 */
GFX_FW_TYPE_VPEC_FW1 = 100, /* VPEC FW1 To Save VPE */
GFX_FW_TYPE_VPEC_FW2 = 101, /* VPEC FW2 To Save VPE */
GFX_FW_TYPE_VPE = 102,
GFX_FW_TYPE_JPEG_RAM = 128, /**< JPEG Command buffer */
GFX_FW_TYPE_P2S_TABLE = 129,
GFX_FW_TYPE_MAX
};
/* Command to load HW IP FW. */
struct psp_gfx_cmd_load_ip_fw
{
unsigned int fw_phy_addr_lo; /* bits [31:0] of GPU Virtual address of FW location (must be 4 KB aligned) */
unsigned int fw_phy_addr_hi; /* bits [63:32] of GPU Virtual address of FW location */
unsigned int fw_size; /* FW buffer size in bytes */
enum psp_gfx_fw_type fw_type; /* FW type */
};
/* Command to save/restore HW IP FW. */
struct psp_gfx_cmd_save_restore_ip_fw
{
unsigned int save_fw; /* if set, command is used for saving fw otherwise for resetoring*/
unsigned int save_restore_addr_lo; /* bits [31:0] of FB address of GART memory used as save/restore buffer (must be 4 KB aligned) */
unsigned int save_restore_addr_hi; /* bits [63:32] of FB address of GART memory used as save/restore buffer */
unsigned int buf_size; /* Size of the save/restore buffer in bytes */
enum psp_gfx_fw_type fw_type; /* FW type */
};
/* Command to setup register program */
struct psp_gfx_cmd_reg_prog {
unsigned int reg_value;
unsigned int reg_id;
};
/* Command to load TOC */
struct psp_gfx_cmd_load_toc
{
unsigned int toc_phy_addr_lo; /* bits [31:0] of GPU Virtual address of FW location (must be 4 KB aligned) */
unsigned int toc_phy_addr_hi; /* bits [63:32] of GPU Virtual address of FW location */
unsigned int toc_size; /* FW buffer size in bytes */
};
/* Dynamic boot configuration */
struct psp_gfx_cmd_boot_cfg
{
unsigned int timestamp; /* calendar time as number of seconds */
enum psp_gfx_boot_config_cmd sub_cmd; /* sub-command indicating how to process command data */
unsigned int boot_config; /* dynamic boot configuration bitmask */
unsigned int boot_config_valid; /* dynamic boot configuration valid bits bitmask */
};
struct psp_gfx_cmd_sriov_spatial_part {
unsigned int mode;
unsigned int override_ips;
unsigned int override_xcds_avail;
unsigned int override_this_aid;
};
/* All GFX ring buffer commands. */
union psp_gfx_commands
{
struct psp_gfx_cmd_load_ta cmd_load_ta;
struct psp_gfx_cmd_unload_ta cmd_unload_ta;
struct psp_gfx_cmd_invoke_cmd cmd_invoke_cmd;
struct psp_gfx_cmd_setup_tmr cmd_setup_tmr;
struct psp_gfx_cmd_load_ip_fw cmd_load_ip_fw;
struct psp_gfx_cmd_save_restore_ip_fw cmd_save_restore_ip_fw;
struct psp_gfx_cmd_reg_prog cmd_setup_reg_prog;
struct psp_gfx_cmd_setup_tmr cmd_setup_vmr;
struct psp_gfx_cmd_load_toc cmd_load_toc;
struct psp_gfx_cmd_boot_cfg boot_cfg;
struct psp_gfx_cmd_sriov_spatial_part cmd_spatial_part;
};
struct psp_gfx_uresp_reserved
{
unsigned int reserved[8];
};
/* Command-specific response for Fw Attestation Db */
struct psp_gfx_uresp_fwar_db_info
{
unsigned int fwar_db_addr_lo;
unsigned int fwar_db_addr_hi;
};
/* Command-specific response for boot config. */
struct psp_gfx_uresp_bootcfg {
unsigned int boot_cfg; /* boot config data */
};
/* Union of command-specific responses for GPCOM ring. */
union psp_gfx_uresp {
struct psp_gfx_uresp_reserved reserved;
struct psp_gfx_uresp_bootcfg boot_cfg;
struct psp_gfx_uresp_fwar_db_info fwar_db_info;
};
/* Structure of GFX Response buffer.
* For GPCOM I/F it is part of GFX_CMD_RESP buffer, for RBI
* it is separate buffer.
*/
struct psp_gfx_resp
{
unsigned int status; /* +0 status of command execution */
unsigned int session_id; /* +4 session ID in response to LoadTa command */
unsigned int fw_addr_lo; /* +8 bits [31:0] of FW address within TMR (in response to cmd_load_ip_fw command) */
unsigned int fw_addr_hi; /* +12 bits [63:32] of FW address within TMR (in response to cmd_load_ip_fw command) */
unsigned int tmr_size; /* +16 size of the TMR to be reserved including MM fw and Gfx fw in response to cmd_load_toc command */
unsigned int reserved[11];
union psp_gfx_uresp uresp; /* +64 response union containing command-specific responses */
/* total 96 bytes */
};
/* Structure of Command buffer pointed by psp_gfx_rb_frame.cmd_buf_addr_hi
* and psp_gfx_rb_frame.cmd_buf_addr_lo.
*/
struct psp_gfx_cmd_resp
{
unsigned int buf_size; /* +0 total size of the buffer in bytes */
unsigned int buf_version; /* +4 version of the buffer strusture; must be PSP_GFX_CMD_BUF_VERSION */
unsigned int cmd_id; /* +8 command ID */
/* These fields are used for RBI only. They are all 0 in GPCOM commands
*/
unsigned int resp_buf_addr_lo; /* +12 bits [31:0] of GPU Virtual address of response buffer (must be 4 KB aligned) */
unsigned int resp_buf_addr_hi; /* +16 bits [63:32] of GPU Virtual address of response buffer */
unsigned int resp_offset; /* +20 offset within response buffer */
unsigned int resp_buf_size; /* +24 total size of the response buffer in bytes */
union psp_gfx_commands cmd; /* +28 command specific structures */
unsigned char reserved_1[864 - sizeof(union psp_gfx_commands) - 28];
/* Note: Resp is part of this buffer for GPCOM ring. For RBI ring the response
* is separate buffer pointed by resp_buf_addr_hi and resp_buf_addr_lo.
*/
struct psp_gfx_resp resp; /* +864 response */
unsigned char reserved_2[1024 - 864 - sizeof(struct psp_gfx_resp)];
/* total size 1024 bytes */
};
#define FRAME_TYPE_DESTROY 1 /* frame sent by KMD driver when UMD Scheduler context is destroyed*/
/* Structure of the Ring Buffer Frame */
struct psp_gfx_rb_frame
{
unsigned int cmd_buf_addr_lo; /* +0 bits [31:0] of GPU Virtual address of command buffer (must be 4 KB aligned) */
unsigned int cmd_buf_addr_hi; /* +4 bits [63:32] of GPU Virtual address of command buffer */
unsigned int cmd_buf_size; /* +8 command buffer size in bytes */
unsigned int fence_addr_lo; /* +12 bits [31:0] of GPU Virtual address of Fence for this frame */
unsigned int fence_addr_hi; /* +16 bits [63:32] of GPU Virtual address of Fence for this frame */
unsigned int fence_value; /* +20 Fence value */
unsigned int sid_lo; /* +24 bits [31:0] of SID value (used only for RBI frames) */
unsigned int sid_hi; /* +28 bits [63:32] of SID value (used only for RBI frames) */
unsigned char vmid; /* +32 VMID value used for mapping of all addresses for this frame */
unsigned char frame_type; /* +33 1: destory context frame, 0: all other frames; used only for RBI frames */
unsigned char reserved1[2]; /* +34 reserved, must be 0 */
unsigned int reserved2[7]; /* +36 reserved, must be 0 */
/* total 64 bytes */
};
#define PSP_ERR_UNKNOWN_COMMAND 0x00000100
enum tee_error_code {
TEE_SUCCESS = 0x00000000,
TEE_ERROR_NOT_SUPPORTED = 0xFFFF000A,
};
#endif /* _PSP_TEE_GFX_IF_H_ */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
#!/usr/bin/env python3
import os
from tinygrad.helpers import Context
from tinygrad.runtime.support.system import System, PCIDevice
from tinygrad.runtime.support.hcq import FileIOInterface
from tinygrad.runtime.support.am.amdev import AMDev
if __name__ == "__main__":
gpus = System.pci_scan_bus(0x1002, [(0xffff, [0x74a1, 0x75a0])])
for gpu in gpus:
drv_path = f"/sys/bus/pci/devices/{gpu}/driver"
if FileIOInterface.exists(drv_path) and os.path.basename(os.readlink(drv_path)) == "amdgpu":
raise RuntimeError(f"amdgpu is bound to {gpu}. Stopping...")
pcidevs = [PCIDevice("AM", gpu) for gpu in gpus]
amdevs = []
with Context(DEBUG=2):
for pcidev in pcidevs:
amdevs.append(AMDev(pcidev, reset_mode=True))
for amdev in amdevs: amdev.smu.mode1_reset()

View File

@@ -0,0 +1,7 @@
// From MQD struct
#define regCOMPUTE_CURRENT_LOGIC_XCC_ID 0x0e25
#define regCOMPUTE_CURRENT_LOGIC_XCC_ID_BASE_IDX 0
// Mask is probably not full register, doesn't matter though
#define COMPUTE_CURRENT_LOGIC_XCC_ID__CURRENT_LOGIC_XCC_ID__SHIFT 0x0
#define COMPUTE_CURRENT_LOGIC_XCC_ID__CURRENT_LOGIC_XCC_ID_MASK 0xFFFFFFFFL

View File

@@ -0,0 +1,96 @@
import re, ctypes, sys, importlib
from tinygrad.helpers import getenv
from tinygrad.runtime.support.am.amdev import AMDev, AMRegister
class GFXFake:
def __init__(self): self.xccs = 8
class AMDFake(AMDev):
def __init__(self, pci_dev):
self.pci_dev, self.devfmt = pci_dev, pci_dev.pcibus
self.vram, self.doorbell64, self.mmio = self.pci_dev.map_bar(0), self.pci_dev.map_bar(2, fmt='Q'), self.pci_dev.map_bar(5, fmt='I')
self._run_discovery()
self._build_regs()
self.gfx = GFXFake()
amdev = importlib.import_module("tinygrad.runtime.support.am.amdev")
amdev.AMDev = AMDFake
from tinygrad.runtime.ops_amd import PCIIface
def parse_amdgpu_logs(log_content, register_names=None, register_objects=None, *, only_xcc0: bool = False):
register_map = register_names or {}
register_objs = register_objects or {}
def replace_register(match):
reg = match.group(1)
return f"Reading register {register_map.get(int(reg, 16), reg)}"
processed_log = re.sub(r'Reading register (0x[0-9a-fA-F]+)', replace_register, log_content)
def replace_register_2(match):
reg = match.group(1)
return f"Writing register {register_map.get(int(reg, 16), reg)}"
processed_log = re.sub(r'Writing register (0x[0-9a-fA-F]+)', replace_register_2, processed_log)
# remove timing prefix
processed_log = re.sub(r'^\[\s*\d+(?:\.\d+)?\]\s*', '', processed_log, flags=re.MULTILINE)
# decode register values into field dicts
def decode_value(match):
reg_name = match.group(1)
xcc_part = match.group(2) # "xcc=0 " or ""
val_str = match.group(3)
val = int(val_str, 16)
reg_obj = register_objs.get(reg_name)
if reg_obj is not None and reg_obj.fields:
fields = reg_obj.decode(val)
# show raw for unaccounted bits
accounted = 0
for name, (start, end) in reg_obj.fields.items():
accounted |= (((1 << (end - start + 1)) - 1) << start)
unaccounted = val & ~accounted
parts = {k: v for k, v in fields.items() if v != 0}
if unaccounted: parts['_raw_unaccounted'] = hex(unaccounted)
return f"register {reg_name}, {xcc_part}with value {val_str} {parts}"
return match.group(0)
processed_log = re.sub(r'register (reg\w+), ((?:xcc=\d+ )?)with value (0x[0-9a-fA-F]+)', decode_value, processed_log)
# keep only xcc=0 lines (but keep lines with no xcc at all)
if only_xcc0:
kept = []
for line in processed_log.splitlines(True):
if "xcc=" not in line or re.search(r'\bxcc=0\b', line): kept.append(line)
processed_log = "".join(kept)
return processed_log
def main():
only_xcc0 = bool(getenv("ONLY_XCC0", 0))
reg_names = {}
reg_objs = {}
dev = PCIIface(None, 0)
for x, y in dev.dev_impl.__dict__.items():
if isinstance(y, AMRegister):
for xcc, addr in y.addr.items():
reg_names[addr] = f"{x}, xcc={xcc}"
reg_objs[x] = y
with open(sys.argv[1], 'r') as f:
log_content = f.read()
processed_log = parse_amdgpu_logs(log_content, reg_names, reg_objs, only_xcc0=only_xcc0)
with open(sys.argv[2], 'w') as f:
f.write(processed_log)
if __name__ == '__main__':
if len(sys.argv) != 3:
print("Usage: <input_file_path> <output_file_path>")
sys.exit(1)
main()

View File

@@ -0,0 +1,3 @@
#!/bin/bash
PYTHON_PATH=$(readlink -f $(which python3))
sudo setcap 'cap_dac_override,cap_sys_rawio,cap_sys_admin,cap_ipc_lock=ep' $PYTHON_PATH

View File

@@ -0,0 +1,2 @@
#!/bin/bash
sudo modprobe vfio-pci disable_idle_d3=1