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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user