# MVGAL Vendor Integration Guide

**Version:** 1.0  
**Date:** May 2026  
**Status:** Implementation Guide

---

## 1. Overview

This guide describes how to integrate a new GPU vendor with MVGAL's vendor backend shim layer. The shim layer provides a standardized interface between MVGAL's core module and vendor-specific driver internals.

---

## 2. Integration Architecture

```
┌─────────────────────────────────────────┐
│         MVGAL Core Module               │
│  (mvgal_core.c, mvgal_main.c, etc.)    │
├─────────────────────────────────────────┤
│         struct mvgal_vendor_ops         │
│    - Standardized function pointers     │
├─────────────────────────────────────────┤
│         Vendor Backend Shim             │
│     (e.g., mvgal_amd.c, mvgal_nvidia.c) │
├─────────────────────────────────────────┤
│      Vendor Driver (amdgpu, nvidia,     │
│       i915, mtgpu, etc.)                │
└─────────────────────────────────────────┘
```

---

## 3. Required Structures

### 3.1 Vendor Operations Structure

Define a `const struct mvgal_vendor_ops` with all required function pointers:

```c
#include "mvgal_core.h"
#include "mvgal_device.h"

const struct mvgal_vendor_ops myvendor_ops = {
    .init = myvendor_init,
    .fini = myvendor_fini,
    .submit_cs = myvendor_submit_cs,
    .alloc_vram = myvendor_alloc_vram,
    .free_vram = myvendor_free_vram,
    .wait_idle = myvendor_wait_idle,
    .set_power_state = myvendor_set_power_state,
    .export_dmabuf = myvendor_export_dmabuf,
    .import_dmabuf = myvendor_import_dmabuf,
    .query_utilization = myvendor_query_utilization,
};
```

### 3.2 Vendor Private Data Structure

Each vendor should define a private data structure to hold vendor-specific state:

```c
struct myvendor_priv {
    struct pci_dev *pdev;
    struct drm_device *drm_dev;
    
    /* DMA-BUF capabilities */
    bool can_export_dmabuf;
    bool can_import_dmabuf;
    
    /* Power management */
    bool has_pm_support;
    
    /* Add vendor-specific fields as needed */
};
```

---

## 4. Required Functions

### 4.1 Initialization: `myvendor_init()`

```c
int myvendor_init(struct mvgal_gpu_device *gpu)
{
    struct myvendor_priv *priv;
    
    if (!gpu)
        return -EINVAL;
    
    priv = kzalloc(sizeof(*priv), GFP_KERNEL);
    if (!priv)
        return -ENOMEM;
    
    priv->pdev = gpu->pdev;
    
    /* Detect vendor-specific capabilities */
    /* Query driver state from sysfs or driver-specific interfaces */
    
    /* Set GPU capabilities */
    gpu->vram_size = <vendor specific>;
    gpu->vram_bandwidth = <vendor specific>;
    gpu->compute_units = <vendor specific>;
    gpu->api_flags = MVGAL_API_VULKAN | MVGAL_API_OPENCL | MVGAL_API_CUDA;
    
    /* Set private data */
    gpu->vendor_priv = priv;
    
    pr_info("MVGAL: MyVendor GPU initialized\n");
    return 0;
}
```

### 4.2 Cleanup: `myvendor_fini()`

```c
void myvendor_fini(struct mvgal_gpu_device *gpu)
{
    struct myvendor_priv *priv = gpu->vendor_priv;
    
    if (!priv)
        return;
    
    /* Free any allocated resources */
    kfree(priv);
    gpu->vendor_priv = NULL;
}
```

### 4.3 Command Submission: `myvendor_submit_cs()`

**Note:** For vendors with proprietary kernel modules (like NVIDIA), actual command submission must happen in user-space. The kernel shim should:
- Validate the workload structure
- Return success immediately for the actual submission to be handled by daemon
- Or hook into vendor-specific DRM ioctls if available

```c
int myvendor_submit_cs(struct mvgal_gpu_device *gpu, struct mvgal_workload *wl)
{
    struct myvendor_priv *priv = gpu->vendor_priv;
    
    if (!priv || !wl)
        return -EINVAL;
    
    /* 
     * Vendor-specific implementation:
     * 
     * For open-source drivers (AMD, Intel):
     *   - Access DRM device via priv->drm_dev
     *   - Use vendor-specific command submission (DRM_IOCTL_AMDGPU_CS, etc.)
     * 
     * For proprietary drivers (NVIDIA):
     *   - Return success here
     *   - Let userspace daemon handle actual submission
     */
    
    return 0;
}
```

### 4.4 Memory Management

```c
int myvendor_alloc_vram(struct mvgal_gpu_device *gpu, size_t size, uint64_t *gpu_addr)
{
    struct myvendor_priv *priv = gpu->vendor_priv;
    
    if (!priv)
        return -EINVAL;
    
    /*
     * Use vendor-specific memory allocation:
     * - AMD: TTM buffer objects
     * - Intel: i915 GEM or xe buffer objects
     * - For proprietary: return placeholder, handle in userspace
     */
    
    return 0;
}

void myvendor_free_vram(struct mvgal_gpu_device *gpu, uint64_t gpu_addr)
{
    /* Release memory allocation */
}
```

### 4.5 DMA-BUF Operations

```c
struct dma_buf *myvendor_export_dmabuf(struct mvgal_gpu_device *gpu, 
                                        uint64_t gpu_addr, size_t size)
{
    struct myvendor_priv *priv = gpu->vendor_priv;
    
    if (!priv || !priv->can_export_dmabuf)
        return ERR_PTR(-ENOTSUPP);
    
    /*
     * Use vendor-specific DMA-BUF export:
     * - AMD: drm_gem_prime_export()
     * - Intel: drm_gem_prime_export() for i915/xe
     */
    
    return ERR_PTR(-ENOSYS); /* Placeholder */
}

int myvendor_import_dmabuf(struct mvgal_gpu_device *gpu, 
                            struct dma_buf *buf, uint64_t *gpu_addr)
{
    struct myvendor_priv *priv = gpu->vendor_priv;
    
    if (!priv || !buf || !priv->can_import_dmabuf)
        return -ENOTSUPP;
    
    /*
     * Use vendor-specific DMA-BUF import:
     * - AMD: amdgpu_dma_buf_import()
     * - Intel: drm_gem_prime_import()
     */
    
    return 0;
}
```

### 4.6 Telemetry Functions

```c
int myvendor_query_utilization(struct mvgal_gpu_device *gpu, uint32_t *util_percent)
{
    struct myvendor_priv *priv = gpu->vendor_priv;
    
    if (!priv || !util_percent)
        return -EINVAL;
    
    /* 
     * Read utilization from vendor sysfs path:
     * - AMD: /sys/class/drm/cardX/device/gpu_busy_percent
     * - Intel: /sys/class/drm/cardX/gt/gt0/busy_percent
     * - NVIDIA: Use nvidia-smi or NVML (typically in userspace)
     */
    
    *util_percent = 0; /* Default if unavailable */
    return 0;
}
```

---

## 5. Vendor-Specific Considerations

### 5.1 AMD (amdgpu)

**Kernel Module:** `amdgpu.ko`  
**DRM Node:** `/dev/dri/cardX`  
**Sysfs Path:** `/sys/class/drm/cardX/device/`

**Integration Points:**
- Access DRM device via `pci_get_drvdata()`
- Use TTM for memory management
- DMA-BUF via `drm_gem_prime_export/import`
- Utilization via `gpu_busy_percent`

### 5.2 NVIDIA

**Kernel Module:** `nvidia.ko` (proprietary)  
**Device Nodes:** `/dev/nvidia0`, `/dev/nvidiactl`  
**Sysfs Path:** `/proc/driver/nvidia/gpus/`

**Integration Notes:**
- Cannot access kernel internals from kernel space
- Must use user-space daemon for actual operations
- Kernel shim provides topology and coordination only
- DMA-BUF support requires `nvidia-drm.modeset=1`

### 5.3 Intel (i915/xe)

**Kernel Modules:** `i915.ko` or `xe.ko`  
**DRM Node:** `/dev/dri/cardX`  
**Sysfs Path:** `/sys/class/drm/cardX/`

**Integration Points:**
- Use DRM GEM interface
- i915: `drm_i915_gem_execbuffer2`
- xe: `xe_exec` interface
- DMA-BUF via standard DRM

### 5.4 Moore Threads (mtgpu)

**Kernel Module:** `mtgpu.ko` (community driver)  
**DRM Node:** `/dev/dri/cardX`  
**Status:** Experimental

**Integration Notes:**
- Support is optional and capability-probed
- Graceful degradation required
- Check for driver at runtime

---

## 6. Build System Integration

### 6.1 Kernel Module Build

Add to `kernel/vendors/Makefile`:

```makefile
# mvgal-{vendor}.o
mvgal-y += vendors/mvgal_{vendor}.o

# Optional vendor support
ccflags-y += -DMVGAL_VENDOR_{VENDOR}=1
```

### 6.2 Kconfig Option (Optional)

```kconfig
config MVGAL_VENDOR_MYENDOR
    tristate "MVGAL MyVendor GPU support"
    depends on PCI
    default y
    help
      Support for MyVendor GPUs in MVGAL.
```

---

## 7. Capabilities Detection

### 7.1 API Support Flags

```c
/* At init time, detect supported APIs */
gpu->api_flags = 0;

/* Check what the GPU supports */
if (vulkan_supported)
    gpu->api_flags |= MVGAL_API_VULKAN;
if (opencl_supported)
    gpu->api_flags |= MVGAL_API_OPENCL;
if (cuda_supported)  /* NVIDIA only */
    gpu->api_flags |= MVGAL_API_CUDA;
```

### 7.2 VRAM Size Detection

```c
/* Method 1: From PCI BAR */
gpu->vram_size = pci_resource_len(gpu->pdev, 0);

/* Method 2: From sysfs */
/* Read /sys/class/drm/cardX/device/mem_info_vram_total */

/* Method 3: Estimate from device ID (fallback) */
```

### 7.3 P2P Detection

```c
int mvgal_detect_p2p_support(struct mvgal_gpu_device *gpu1, 
                              struct mvgal_gpu_device *gpu2)
{
    /* Same NUMA node is a good heuristic */
    if (gpu1->numa_node != U32_MAX && 
        gpu1->numa_node == gpu2->numa_node)
        return MVGAL_UAPI_P2P_P2P;
    
    return MVGAL_UAPI_P2P_DMA;
}
```

---

## 8. Testing Integration

### 8.1 Module Load Test

```bash
# Load the module
insmod mvgal.ko

# Check kernel log
dmesg | grep mvgal

# Check sysfs
ls /sys/class/mvgal/
cat /sys/class/mvgal/mvgal0/gpu_count
```

### 8.2 Device Enumeration Test

```c
int fd = open("/dev/mvgal0", O_RDWR);
struct mvgal_uapi_gpu_count count = {0};
ioctl(fd, MVGAL_IOC_GET_GPU_COUNT, &count);
printf("Found %u GPUs\n", count.gpu_count);
```

### 8.3 DMA-BUF Test

```bash
# Check DMA-BUF capabilities
cat /sys/kernel/debug/dma_buf/bufinfo
```

---

## 9. Troubleshooting

### 9.1 Common Issues

| Issue | Cause | Solution |
|-------|-------|----------|
| GPU not detected | Driver not loaded | Load vendor driver module |
| DMA-BUF export fails | Driver lacks support | Use host staging fallback |
| Utilization always 0 | Sysfs path wrong | Check vendor sysfs interface |
| VRAM size incorrect | BAR sizing | Use sysfs or estimate |

### 9.2 Debug Output

Enable verbose logging:
```bash
echo 1 > /sys/module/mvgal/parameters/enable_debug
dmesg -w
```

---

## 10. Contribution Guidelines

1. **Code Style:** Follow kernel coding style
2. **License:** GPL-2.0-only for kernel code
3. **Documentation:** Update this guide with new integration steps
4. **Testing:** Include test results for new hardware combinations

---

## 11. References

- Linux DMA-BUF Documentation: `Documentation/driver-api/dma-buf.rst`
- DRM UAPI Header: `include/uapi/drm/drm.h`
- Vendor driver source trees for implementation details