Refresh redox-drm and AMD GPU driver

Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent)

Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
This commit is contained in:
2026-04-17 00:03:28 +01:00
parent 6b887e9166
commit 00cda85edd
13 changed files with 737 additions and 399 deletions
@@ -116,12 +116,30 @@ static inline u32 amdgpu_dc_hpd_status(void)
return readl((u8 __iomem *)g_mmio_base + AMDGPU_DC_HPD_STATUS_REG);
}
static void amdgpu_redox_log_irq_expectation(u64 quirk_flags)
{
const char *policy = "MSI-X first, then MSI, then legacy IRQ fallback";
if ((quirk_flags & PCI_QUIRK_FORCE_LEGACY) != 0 ||
((quirk_flags & PCI_QUIRK_NO_MSIX) != 0 &&
(quirk_flags & PCI_QUIRK_NO_MSI) != 0)) {
policy = "legacy IRQ only";
} else if ((quirk_flags & PCI_QUIRK_NO_MSIX) != 0) {
policy = "avoid MSI-X, prefer MSI with legacy fallback";
} else if ((quirk_flags & PCI_QUIRK_NO_MSI) != 0) {
policy = "avoid MSI, prefer MSI-X with legacy fallback";
}
printk("amdgpu_redox: quirk-aware IRQ expectation: %s\n", policy);
}
/* Initialize AMD Display Core */
int amdgpu_dc_init(void *mmio_base, size_t mmio_size)
{
int ret = 0;
u32 gpu_id = 0;
const char *firmware_name = NULL;
u64 quirk_flags = 0;
printk("amdgpu_redox: initializing AMD Display Core\n");
@@ -133,6 +151,28 @@ int amdgpu_dc_init(void *mmio_base, size_t mmio_size)
gpu_id = readl(mmio_base);
printk("amdgpu_redox: GPU ID = %#010x\n", gpu_id);
if (g_pci_dev) {
quirk_flags = pci_get_quirk_flags(g_pci_dev);
printk("amdgpu_redox: PCI %02x:%02x.%u quirk flags = %#llx\n",
g_pci_dev->bus_number,
g_pci_dev->dev_number,
g_pci_dev->func_number,
(unsigned long long)quirk_flags);
if (pci_has_quirk(g_pci_dev, PCI_QUIRK_NO_ASPM)) {
pr_warn("amdgpu_redox: NO_ASPM quirk active; skipping any future ASPM-dependent assumptions\n");
}
if (pci_has_quirk(g_pci_dev, PCI_QUIRK_NEED_IOMMU)) {
pr_warn("amdgpu_redox: NEED_IOMMU quirk active; runtime must provide a functional IOMMU path\n");
}
if (pci_has_quirk(g_pci_dev, PCI_QUIRK_NO_MSIX)) {
pr_warn("amdgpu_redox: NO_MSIX quirk active; IRQ setup must avoid MSI-X\n");
}
if (pci_has_quirk(g_pci_dev, PCI_QUIRK_NO_MSI)) {
pr_warn("amdgpu_redox: NO_MSI quirk active; IRQ setup must avoid MSI\n");
}
amdgpu_redox_log_irq_expectation(quirk_flags);
}
switch (gpu_id) {
case ASIC_FAMILY_NAVI10:
g_asic_family = ASIC_FAMILY_NAVI10;
@@ -182,11 +222,29 @@ int amdgpu_dc_init(void *mmio_base, size_t mmio_size)
{
const struct firmware *fw = NULL;
int fw_ret = request_firmware(&fw, firmware_name, NULL);
bool firmware_required =
g_pci_dev && pci_has_quirk(g_pci_dev, PCI_QUIRK_NEED_FIRMWARE);
if (fw_ret != 0 || !fw) {
pr_warn("amdgpu_redox: firmware %s not available (err=%d), continuing without\n",
firmware_name, fw_ret);
if (firmware_required) {
pr_err("amdgpu_redox: firmware %s is required by quirk policy (flags=%#llx, err=%d)\n",
firmware_name,
(unsigned long long)quirk_flags,
fw_ret);
return fw_ret != 0 ? fw_ret : -ENOENT;
}
pr_warn("amdgpu_redox: firmware %s not available (err=%d), continuing without (quirks=%#llx)\n",
firmware_name,
fw_ret,
(unsigned long long)quirk_flags);
} else {
printk("amdgpu_redox: firmware %s loaded (%zu bytes)\n", firmware_name, fw->size);
if (firmware_required) {
printk("amdgpu_redox: firmware %s loaded (%zu bytes) to satisfy NEED_FIRMWARE quirk\n",
firmware_name,
fw->size);
} else {
printk("amdgpu_redox: firmware %s loaded (%zu bytes)\n", firmware_name, fw->size);
}
release_firmware(fw);
}
}
+28 -11
View File
@@ -204,22 +204,45 @@ extern void redox_dma_free_coherent(size_t size, void *vaddr, dma_addr_t dma_han
#define dma_mapping_error(dev, addr) 0
/* ---- PCI — maps to redox-driver-sys PCI ---- */
struct pci_dev;
struct device_driver {
const char *name;
void *owner;
};
struct device {
struct device_driver *driver;
void *driver_data;
void *platform_data;
void *of_node;
u64 dma_mask;
struct pci_dev *pci_dev;
};
struct pci_dev {
u16 vendor;
u16 device;
u8 bus_number;
u8 dev_number;
u8 func_number;
u8 revision;
u8 irq;
phys_addr_t resource_start[6];
u32 irq;
u64 resource_start[6];
u64 resource_len[6];
u32 resource_flags[6];
void *driver_data;
struct device device_obj;
bool enabled;
u32 resource_flags[6];
void __iomem *mmio_base;
int is_amdgpu;
};
extern struct pci_dev *redox_pci_find_amd_gpu(void);
extern void redox_pci_set_device_info(u16 vendor, u16 device, u8 revision,
u8 irq, u64 bar0_addr, u64 bar0_size,
extern void redox_pci_set_device_info(u16 vendor, u16 device,
u8 bus_number, u8 dev_number,
u8 func_number, u8 revision, u32 irq,
u64 bar0_addr, u64 bar0_size,
u64 bar2_addr, u64 bar2_size);
extern void redox_pci_dev_put(struct pci_dev *pdev);
extern int redox_pci_enable_device(struct pci_dev *pdev);
@@ -255,12 +278,6 @@ extern void redox_release_firmware(const struct firmware *fw);
#define request_firmware(fw, name, dev) redox_request_firmware((fw), (name), (dev))
#define release_firmware(fw) redox_release_firmware((fw))
/* ---- Device model ---- */
struct device {
void *driver_data;
struct pci_dev *pci_dev;
};
#define dev_get_drvdata(dev) ((dev)->driver_data)
#define dev_set_drvdata(dev, data) ((dev)->driver_data = (data))
+11 -3
View File
@@ -222,13 +222,18 @@ void redox_dma_free_coherent(size_t size, void *vaddr, dma_addr_t dma_handle)
static struct pci_dev g_pci_dev;
static int g_pci_dev_populated;
void redox_pci_set_device_info(u16 vendor, u16 device, u8 revision,
u8 irq, u64 bar0_addr, u64 bar0_size,
void redox_pci_set_device_info(u16 vendor, u16 device,
u8 bus_number, u8 dev_number,
u8 func_number, u8 revision, u32 irq,
u64 bar0_addr, u64 bar0_size,
u64 bar2_addr, u64 bar2_size)
{
memset(&g_pci_dev, 0, sizeof(g_pci_dev));
g_pci_dev.vendor = vendor;
g_pci_dev.device = device;
g_pci_dev.bus_number = bus_number;
g_pci_dev.dev_number = dev_number;
g_pci_dev.func_number = func_number;
g_pci_dev.revision = revision;
g_pci_dev.irq = irq;
g_pci_dev.resource_start[0] = (phys_addr_t)bar0_addr;
@@ -238,12 +243,15 @@ void redox_pci_set_device_info(u16 vendor, u16 device, u8 revision,
g_pci_dev.resource_len[2] = bar2_size;
g_pci_dev.resource_flags[2] = IORESOURCE_MEM;
g_pci_dev.driver_data = NULL;
memset(&g_pci_dev.device_obj, 0, sizeof(g_pci_dev.device_obj));
g_pci_dev.enabled = false;
g_pci_dev.mmio_base = NULL;
g_pci_dev.is_amdgpu = 1;
g_pci_dev_populated = 1;
printk("PCI device info set: vendor=%#06x device=%#06x rev=%#04x irq=%u "
printk("PCI device info set: %02x:%02x.%u vendor=%#06x device=%#06x rev=%#04x irq=%u "
"bar0=%#llx+%#llx bar2=%#llx+%#llx\n",
bus_number, dev_number, func_number,
vendor, device, revision, irq,
(unsigned long long)bar0_addr, (unsigned long long)bar0_size,
(unsigned long long)bar2_addr, (unsigned long long)bar2_size);