40,37 → 40,47 |
|
#include <drm/drm_pciids.h> |
|
#define PCI_VENDOR_ID_ATI 0x1002 |
#define PCI_VENDOR_ID_APPLE 0x106b |
|
int radeon_no_wb = 1; |
int radeon_no_wb; |
int radeon_modeset = -1; |
int radeon_dynclks = -1; |
int radeon_r4xx_atom = 0; |
int radeon_agpmode = 0; |
int radeon_vram_limit = 0; |
int radeon_gart_size = 512; /* default gart size */ |
int radeon_gart_size = -1; /* auto */ |
int radeon_benchmarking = 0; |
int radeon_testing = 0; |
int radeon_connector_table = 0; |
int radeon_tv = 1; |
int radeon_new_pll = -1; |
int radeon_dynpm = -1; |
int radeon_audio = 1; |
int radeon_audio = -1; |
int radeon_disp_priority = 0; |
int radeon_hw_i2c = 0; |
int radeon_pcie_gen2 = 0; |
int radeon_disp_priority = 0; |
int radeon_pcie_gen2 = -1; |
int radeon_msi = -1; |
int radeon_lockup_timeout = 10000; |
int radeon_fastfb = 0; |
|
int radeon_dpm = -1; |
int radeon_aspm = -1; |
int radeon_runtime_pm = -1; |
int radeon_hard_reset = 0; |
int radeon_vm_size = 8; |
int radeon_vm_block_size = -1; |
int radeon_deep_color = 0; |
int radeon_use_pflipirq = 2; |
int irq_override = 0; |
int radeon_bapm = -1; |
|
|
extern display_t *rdisplay; |
struct drm_device *main_drm_device; |
extern display_t *os_display; |
extern struct drm_device *main_device; |
extern videomode_t usermode; |
|
|
void parse_cmdline(char *cmdline, videomode_t *mode, char *log, int *kms); |
int init_display(struct radeon_device *rdev, videomode_t *mode); |
int init_display_kms(struct radeon_device *rdev, videomode_t *mode); |
int init_display_kms(struct drm_device *dev, videomode_t *usermode); |
|
int get_modes(videomode_t *mode, u32_t *count); |
int set_user_mode(videomode_t *mode); |
145,9 → 155,68 |
"VERDE", |
"OLAND", |
"HAINAN", |
"BONAIRE", |
"KAVERI", |
"KABINI", |
"HAWAII", |
"MULLINS", |
"LAST", |
}; |
|
#define RADEON_PX_QUIRK_DISABLE_PX (1 << 0) |
#define RADEON_PX_QUIRK_LONG_WAKEUP (1 << 1) |
|
struct radeon_px_quirk { |
u32 chip_vendor; |
u32 chip_device; |
u32 subsys_vendor; |
u32 subsys_device; |
u32 px_quirk_flags; |
}; |
|
static struct radeon_px_quirk radeon_px_quirk_list[] = { |
/* Acer aspire 5560g (CPU: AMD A4-3305M; GPU: AMD Radeon HD 6480g + 7470m) |
* https://bugzilla.kernel.org/show_bug.cgi?id=74551 |
*/ |
{ PCI_VENDOR_ID_ATI, 0x6760, 0x1025, 0x0672, RADEON_PX_QUIRK_DISABLE_PX }, |
/* Asus K73TA laptop with AMD A6-3400M APU and Radeon 6550 GPU |
* https://bugzilla.kernel.org/show_bug.cgi?id=51381 |
*/ |
{ PCI_VENDOR_ID_ATI, 0x6741, 0x1043, 0x108c, RADEON_PX_QUIRK_DISABLE_PX }, |
/* macbook pro 8.2 */ |
{ PCI_VENDOR_ID_ATI, 0x6741, PCI_VENDOR_ID_APPLE, 0x00e2, RADEON_PX_QUIRK_LONG_WAKEUP }, |
{ 0, 0, 0, 0, 0 }, |
}; |
|
bool radeon_is_px(struct drm_device *dev) |
{ |
struct radeon_device *rdev = dev->dev_private; |
|
if (rdev->flags & RADEON_IS_PX) |
return true; |
return false; |
} |
|
static void radeon_device_handle_px_quirks(struct radeon_device *rdev) |
{ |
struct radeon_px_quirk *p = radeon_px_quirk_list; |
|
/* Apply PX quirks */ |
while (p && p->chip_device != 0) { |
if (rdev->pdev->vendor == p->chip_vendor && |
rdev->pdev->device == p->chip_device && |
rdev->pdev->subsystem_vendor == p->subsys_vendor && |
rdev->pdev->subsystem_device == p->subsys_device) { |
rdev->px_quirk_flags = p->px_quirk_flags; |
break; |
} |
++p; |
} |
|
if (rdev->px_quirk_flags & RADEON_PX_QUIRK_DISABLE_PX) |
rdev->flags &= ~RADEON_IS_PX; |
} |
|
/** |
* radeon_program_register_sequence - program an array of registers. |
* |
184,6 → 253,11 |
} |
} |
|
void radeon_pci_config_reset(struct radeon_device *rdev) |
{ |
pci_write_config_dword(rdev->pdev, 0x7c, RADEON_ASIC_RESET_DATA); |
} |
|
/** |
* radeon_surface_init - Clear GPU surface registers. |
* |
198,6 → 272,9 |
int i; |
|
for (i = 0; i < RADEON_GEM_MAX_SURFACES; i++) { |
if (rdev->surface_regs[i].bo) |
radeon_bo_get_surface_reg(rdev->surface_regs[i].bo); |
else |
radeon_clear_surface_reg(rdev, i); |
} |
/* enable surfaces */ |
276,6 → 353,87 |
} |
|
/* |
* GPU doorbell aperture helpers function. |
*/ |
/** |
* radeon_doorbell_init - Init doorbell driver information. |
* |
* @rdev: radeon_device pointer |
* |
* Init doorbell driver information (CIK) |
* Returns 0 on success, error on failure. |
*/ |
static int radeon_doorbell_init(struct radeon_device *rdev) |
{ |
/* doorbell bar mapping */ |
rdev->doorbell.base = pci_resource_start(rdev->pdev, 2); |
rdev->doorbell.size = pci_resource_len(rdev->pdev, 2); |
|
rdev->doorbell.num_doorbells = min_t(u32, rdev->doorbell.size / sizeof(u32), RADEON_MAX_DOORBELLS); |
if (rdev->doorbell.num_doorbells == 0) |
return -EINVAL; |
|
rdev->doorbell.ptr = ioremap(rdev->doorbell.base, rdev->doorbell.num_doorbells * sizeof(u32)); |
if (rdev->doorbell.ptr == NULL) { |
return -ENOMEM; |
} |
DRM_INFO("doorbell mmio base: 0x%08X\n", (uint32_t)rdev->doorbell.base); |
DRM_INFO("doorbell mmio size: %u\n", (unsigned)rdev->doorbell.size); |
|
memset(&rdev->doorbell.used, 0, sizeof(rdev->doorbell.used)); |
|
return 0; |
} |
|
/** |
* radeon_doorbell_fini - Tear down doorbell driver information. |
* |
* @rdev: radeon_device pointer |
* |
* Tear down doorbell driver information (CIK) |
*/ |
static void radeon_doorbell_fini(struct radeon_device *rdev) |
{ |
iounmap(rdev->doorbell.ptr); |
rdev->doorbell.ptr = NULL; |
} |
|
/** |
* radeon_doorbell_get - Allocate a doorbell entry |
* |
* @rdev: radeon_device pointer |
* @doorbell: doorbell index |
* |
* Allocate a doorbell for use by the driver (all asics). |
* Returns 0 on success or -EINVAL on failure. |
*/ |
int radeon_doorbell_get(struct radeon_device *rdev, u32 *doorbell) |
{ |
unsigned long offset = find_first_zero_bit(rdev->doorbell.used, rdev->doorbell.num_doorbells); |
if (offset < rdev->doorbell.num_doorbells) { |
__set_bit(offset, rdev->doorbell.used); |
*doorbell = offset; |
return 0; |
} else { |
return -EINVAL; |
} |
} |
|
/** |
* radeon_doorbell_free - Free a doorbell entry |
* |
* @rdev: radeon_device pointer |
* @doorbell: doorbell index |
* |
* Free a doorbell allocated for use by the driver (all asics) |
*/ |
void radeon_doorbell_free(struct radeon_device *rdev, u32 doorbell) |
{ |
if (doorbell < rdev->doorbell.num_doorbells) |
__clear_bit(doorbell, rdev->doorbell.used); |
} |
|
/* |
* radeon_wb_*() |
* Writeback is the the method by which the the GPU updates special pages |
* in memory with the status of certain GPU events (fences, ring pointers, |
306,6 → 464,11 |
{ |
radeon_wb_disable(rdev); |
if (rdev->wb.wb_obj) { |
if (!radeon_bo_reserve(rdev->wb.wb_obj, false)) { |
radeon_bo_kunmap(rdev->wb.wb_obj); |
radeon_bo_unpin(rdev->wb.wb_obj); |
radeon_bo_unreserve(rdev->wb.wb_obj); |
} |
radeon_bo_unref(&rdev->wb.wb_obj); |
rdev->wb.wb = NULL; |
rdev->wb.wb_obj = NULL; |
327,7 → 490,8 |
|
if (rdev->wb.wb_obj == NULL) { |
r = radeon_bo_create(rdev, RADEON_GPU_PAGE_SIZE, PAGE_SIZE, true, |
RADEON_GEM_DOMAIN_GTT, NULL, &rdev->wb.wb_obj); |
RADEON_GEM_DOMAIN_GTT, 0, NULL, |
&rdev->wb.wb_obj); |
if (r) { |
dev_warn(rdev->dev, "(%d) create WB bo failed\n", r); |
return r; |
618,15 → 782,11 |
{ |
if (rdev->dummy_page.page) |
return 0; |
rdev->dummy_page.page = (void*)AllocPage(); |
rdev->dummy_page.page = alloc_page(GFP_DMA32 | GFP_KERNEL | __GFP_ZERO); |
if (rdev->dummy_page.page == NULL) |
return -ENOMEM; |
rdev->dummy_page.addr = MapIoMem((addr_t)rdev->dummy_page.page, 4096, 3); |
if (!rdev->dummy_page.addr) { |
// __free_page(rdev->dummy_page.page); |
rdev->dummy_page.page = NULL; |
return -ENOMEM; |
} |
rdev->dummy_page.addr = pci_map_page(rdev->pdev, rdev->dummy_page.page, |
0, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL); |
return 0; |
} |
|
641,7 → 801,7 |
{ |
if (rdev->dummy_page.page == NULL) |
return; |
KernelFree((void*)rdev->dummy_page.addr); |
|
rdev->dummy_page.page = NULL; |
} |
|
944,15 → 1104,27 |
radeon_vram_limit = 0; |
} |
|
if (radeon_gart_size == -1) { |
/* default to a larger gart size on newer asics */ |
if (rdev->family >= CHIP_RV770) |
radeon_gart_size = 1024; |
else |
radeon_gart_size = 512; |
} |
/* gtt size must be power of two and greater or equal to 32M */ |
if (radeon_gart_size < 32) { |
dev_warn(rdev->dev, "gart size (%d) too small forcing to 512M\n", |
dev_warn(rdev->dev, "gart size (%d) too small\n", |
radeon_gart_size); |
if (rdev->family >= CHIP_RV770) |
radeon_gart_size = 1024; |
else |
radeon_gart_size = 512; |
|
} else if (!radeon_check_pot_argument(radeon_gart_size)) { |
dev_warn(rdev->dev, "gart size (%d) must be a power of 2\n", |
radeon_gart_size); |
if (rdev->family >= CHIP_RV770) |
radeon_gart_size = 1024; |
else |
radeon_gart_size = 512; |
} |
rdev->mc.gtt_size = (uint64_t)radeon_gart_size << 20; |
972,8 → 1144,69 |
radeon_agpmode = 0; |
break; |
} |
|
if (!radeon_check_pot_argument(radeon_vm_size)) { |
dev_warn(rdev->dev, "VM size (%d) must be a power of 2\n", |
radeon_vm_size); |
radeon_vm_size = 4; |
} |
|
if (radeon_vm_size < 1) { |
dev_warn(rdev->dev, "VM size (%d) to small, min is 1GB\n", |
radeon_vm_size); |
radeon_vm_size = 4; |
} |
|
/* |
* Max GPUVM size for Cayman, SI and CI are 40 bits. |
*/ |
if (radeon_vm_size > 1024) { |
dev_warn(rdev->dev, "VM size (%d) too large, max is 1TB\n", |
radeon_vm_size); |
radeon_vm_size = 4; |
} |
|
/* defines number of bits in page table versus page directory, |
* a page is 4KB so we have 12 bits offset, minimum 9 bits in the |
* page table and the remaining bits are in the page directory */ |
if (radeon_vm_block_size == -1) { |
|
/* Total bits covered by PD + PTs */ |
unsigned bits = ilog2(radeon_vm_size) + 17; |
|
/* Make sure the PD is 4K in size up to 8GB address space. |
Above that split equal between PD and PTs */ |
if (radeon_vm_size <= 8) |
radeon_vm_block_size = bits - 9; |
else |
radeon_vm_block_size = (bits + 3) / 2; |
|
} else if (radeon_vm_block_size < 9) { |
dev_warn(rdev->dev, "VM page table size (%d) too small\n", |
radeon_vm_block_size); |
radeon_vm_block_size = 9; |
} |
|
if (radeon_vm_block_size > 24 || |
(radeon_vm_size * 1024) < (1ull << radeon_vm_block_size)) { |
dev_warn(rdev->dev, "VM page table size (%d) too large\n", |
radeon_vm_block_size); |
radeon_vm_block_size = 9; |
} |
} |
|
/** |
* radeon_device_init - initialize the driver |
* |
* @rdev: radeon_device pointer |
* @pdev: drm dev pointer |
* @pdev: pci dev pointer |
* @flags: driver flags |
* |
* Initializes the driver info and hw (all asics). |
* Returns 0 for success or an error on failure. |
* Called at driver startup. |
*/ |
int radeon_device_init(struct radeon_device *rdev, |
struct drm_device *ddev, |
struct pci_dev *pdev, |
981,8 → 1214,10 |
{ |
int r, i; |
int dma_bits; |
bool runtime = false; |
|
rdev->shutdown = false; |
rdev->dev = &pdev->dev; |
rdev->ddev = ddev; |
rdev->pdev = pdev; |
rdev->flags = flags; |
989,7 → 1224,7 |
rdev->family = flags & RADEON_FAMILY_MASK; |
rdev->is_atom_bios = false; |
rdev->usec_timeout = RADEON_MAX_USEC_TIMEOUT; |
rdev->mc.gtt_size = radeon_gart_size * 1024 * 1024; |
rdev->mc.gtt_size = 512 * 1024 * 1024; |
rdev->accel_working = false; |
/* set up ring ids */ |
for (i = 0; i < RADEON_NUM_RINGS; i++) { |
1008,6 → 1243,7 |
mutex_init(&rdev->gem.mutex); |
mutex_init(&rdev->pm.mutex); |
mutex_init(&rdev->gpu_clock_mutex); |
mutex_init(&rdev->srbm_mutex); |
// init_rwsem(&rdev->pm.mclk_lock); |
// init_rwsem(&rdev->exclusive_lock); |
init_waitqueue_head(&rdev->irq.vblank_queue); |
1014,20 → 1250,17 |
r = radeon_gem_init(rdev); |
if (r) |
return r; |
/* initialize vm here */ |
mutex_init(&rdev->vm_manager.lock); |
|
radeon_check_arguments(rdev); |
/* Adjust VM size here. |
* Currently set to 4GB ((1 << 20) 4k pages). |
* Max GPUVM size for cayman and SI is 40 bits. |
* Max GPUVM size for cayman+ is 40 bits. |
*/ |
rdev->vm_manager.max_pfn = 1 << 20; |
INIT_LIST_HEAD(&rdev->vm_manager.lru_vm); |
rdev->vm_manager.max_pfn = radeon_vm_size << 18; |
|
/* Set asic functions */ |
r = radeon_asic_init(rdev); |
if (r) |
return r; |
radeon_check_arguments(rdev); |
|
/* all of the newer IGP chips have an internal gart |
* However some rs4xx report as AGP, so remove that here. |
1076,8 → 1309,24 |
/* Registers mapping */ |
/* TODO: block userspace mapping of io register */ |
spin_lock_init(&rdev->mmio_idx_lock); |
spin_lock_init(&rdev->smc_idx_lock); |
spin_lock_init(&rdev->pll_idx_lock); |
spin_lock_init(&rdev->mc_idx_lock); |
spin_lock_init(&rdev->pcie_idx_lock); |
spin_lock_init(&rdev->pciep_idx_lock); |
spin_lock_init(&rdev->pif_idx_lock); |
spin_lock_init(&rdev->cg_idx_lock); |
spin_lock_init(&rdev->uvd_idx_lock); |
spin_lock_init(&rdev->rcu_idx_lock); |
spin_lock_init(&rdev->didt_idx_lock); |
spin_lock_init(&rdev->end_idx_lock); |
if (rdev->family >= CHIP_BONAIRE) { |
rdev->rmmio_base = pci_resource_start(rdev->pdev, 5); |
rdev->rmmio_size = pci_resource_len(rdev->pdev, 5); |
} else { |
rdev->rmmio_base = pci_resource_start(rdev->pdev, 2); |
rdev->rmmio_size = pci_resource_len(rdev->pdev, 2); |
} |
rdev->rmmio = ioremap(rdev->rmmio_base, rdev->rmmio_size); |
if (rdev->rmmio == NULL) { |
return -ENOMEM; |
1085,6 → 1334,10 |
DRM_INFO("register mmio base: 0x%08X\n", (uint32_t)rdev->rmmio_base); |
DRM_INFO("register mmio size: %u\n", (unsigned)rdev->rmmio_size); |
|
/* doorbell bar mapping */ |
if (rdev->family >= CHIP_BONAIRE) |
radeon_doorbell_init(rdev); |
|
/* io port mapping */ |
for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) { |
if (pci_resource_flags(rdev->pdev, i) & IORESOURCE_IO) { |
1096,15 → 1349,20 |
if (rdev->rio_mem == NULL) |
DRM_ERROR("Unable to find PCI I/O BAR\n"); |
|
if (rdev->flags & RADEON_IS_PX) |
radeon_device_handle_px_quirks(rdev); |
if (rdev->flags & RADEON_IS_PX) |
runtime = true; |
|
r = radeon_init(rdev); |
if (r) |
return r; |
|
// r = radeon_ib_ring_tests(rdev); |
// if (r) |
// DRM_ERROR("ib ring test failed (%d).\n", r); |
r = radeon_ib_ring_tests(rdev); |
if (r) |
DRM_ERROR("ib ring test failed (%d).\n", r); |
|
|
if (rdev->flags & RADEON_IS_AGP && !rdev->accel_working) { |
/* Acceleration not working on AGP card try again |
* with fallback to PCI or PCIE GART |
1116,14 → 1374,24 |
if (r) |
return r; |
} |
// if (radeon_testing) { |
// radeon_test_moves(rdev); |
// } |
// if ((radeon_testing & 2)) { |
// radeon_test_syncing(rdev); |
// } |
|
if ((radeon_testing & 1)) { |
if (rdev->accel_working) |
radeon_test_moves(rdev); |
else |
DRM_INFO("radeon: acceleration disabled, skipping move tests\n"); |
} |
if ((radeon_testing & 2)) { |
if (rdev->accel_working) |
radeon_test_syncing(rdev); |
else |
DRM_INFO("radeon: acceleration disabled, skipping sync tests\n"); |
} |
if (radeon_benchmarking) { |
if (rdev->accel_working) |
radeon_benchmark(rdev, radeon_benchmarking); |
else |
DRM_INFO("radeon: acceleration disabled, skipping benchmarks\n"); |
} |
return 0; |
} |
1147,6 → 1415,8 |
int resched; |
|
// down_write(&rdev->exclusive_lock); |
rdev->needs_reset = false; |
|
radeon_save_bios_scratch_regs(rdev); |
/* block TTM */ |
// resched = ttm_bo_lock_delayed_workqueue(&rdev->mman.bdev); |
1245,6 → 1515,8 |
* otherwise it should provide enough functionalities |
* for shadowfb to run |
*/ |
main_device = dev; |
|
if( radeon_modeset ) |
{ |
r = radeon_modeset_init(rdev); |
1251,76 → 1523,16 |
if (r) { |
return r; |
} |
}; |
return 0; |
init_display_kms(dev, &usermode); |
} |
|
videomode_t usermode; |
|
|
int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) |
{ |
static struct drm_device *dev; |
int ret; |
|
dev = kzalloc(sizeof(*dev), 0); |
if (!dev) |
return -ENOMEM; |
|
// ret = pci_enable_device(pdev); |
// if (ret) |
// goto err_g1; |
|
// pci_set_master(pdev); |
|
// if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) { |
// printk(KERN_ERR "DRM: Fill_in_dev failed.\n"); |
// goto err_g2; |
// } |
|
dev->pdev = pdev; |
dev->pci_device = pdev->device; |
dev->pci_vendor = pdev->vendor; |
|
INIT_LIST_HEAD(&dev->filelist); |
INIT_LIST_HEAD(&dev->ctxlist); |
INIT_LIST_HEAD(&dev->vmalist); |
INIT_LIST_HEAD(&dev->maplist); |
|
spin_lock_init(&dev->count_lock); |
mutex_init(&dev->struct_mutex); |
mutex_init(&dev->ctxlist_mutex); |
|
|
ret = radeon_driver_load_kms(dev, ent->driver_data ); |
if (ret) |
goto err_g4; |
|
main_drm_device = dev; |
|
if( radeon_modeset ) |
init_display_kms(dev->dev_private, &usermode); |
else |
init_display(dev->dev_private, &usermode); |
init_display(rdev, &usermode); |
|
|
return 0; |
} |
|
err_g4: |
// drm_put_minor(&dev->primary); |
//err_g3: |
// if (drm_core_check_feature(dev, DRIVER_MODESET)) |
// drm_put_minor(&dev->control); |
//err_g2: |
// pci_disable_device(pdev); |
//err_g1: |
free(dev); |
|
LEAVE(); |
|
return ret; |
} |
|
resource_size_t drm_get_resource_start(struct drm_device *dev, unsigned int resource) |
{ |
return pci_resource_start(dev->pdev, resource); |
1365,181 → 1577,85 |
return rem; |
} |
|
|
static struct pci_device_id pciidlist[] = { |
radeon_PCI_IDS |
}; |
|
void radeon_driver_irq_preinstall_kms(struct drm_device *dev); |
int radeon_driver_irq_postinstall_kms(struct drm_device *dev); |
void radeon_driver_irq_uninstall_kms(struct drm_device *dev); |
irqreturn_t radeon_driver_irq_handler_kms(int irq, void *arg); |
|
#define CURRENT_API 0x0200 /* 2.00 */ |
#define COMPATIBLE_API 0x0100 /* 1.00 */ |
|
#define API_VERSION (COMPATIBLE_API << 16) | CURRENT_API |
static struct drm_driver kms_driver = { |
.driver_features = |
DRIVER_USE_AGP | |
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM | |
DRIVER_PRIME | DRIVER_RENDER, |
.load = radeon_driver_load_kms, |
// .open = radeon_driver_open_kms, |
// .preclose = radeon_driver_preclose_kms, |
// .postclose = radeon_driver_postclose_kms, |
// .lastclose = radeon_driver_lastclose_kms, |
// .unload = radeon_driver_unload_kms, |
// .get_vblank_counter = radeon_get_vblank_counter_kms, |
// .enable_vblank = radeon_enable_vblank_kms, |
// .disable_vblank = radeon_disable_vblank_kms, |
// .get_vblank_timestamp = radeon_get_vblank_timestamp_kms, |
// .get_scanout_position = radeon_get_crtc_scanoutpos, |
#if defined(CONFIG_DEBUG_FS) |
.debugfs_init = radeon_debugfs_init, |
.debugfs_cleanup = radeon_debugfs_cleanup, |
#endif |
.irq_preinstall = radeon_driver_irq_preinstall_kms, |
.irq_postinstall = radeon_driver_irq_postinstall_kms, |
.irq_uninstall = radeon_driver_irq_uninstall_kms, |
.irq_handler = radeon_driver_irq_handler_kms, |
// .ioctls = radeon_ioctls_kms, |
// .gem_free_object = radeon_gem_object_free, |
// .gem_open_object = radeon_gem_object_open, |
// .gem_close_object = radeon_gem_object_close, |
// .dumb_create = radeon_mode_dumb_create, |
// .dumb_map_offset = radeon_mode_dumb_mmap, |
// .dumb_destroy = drm_gem_dumb_destroy, |
// .fops = &radeon_driver_kms_fops, |
|
#define SRV_GETVERSION 0 |
#define SRV_ENUM_MODES 1 |
#define SRV_SET_MODE 2 |
#define SRV_GET_CAPS 3 |
// .prime_handle_to_fd = drm_gem_prime_handle_to_fd, |
// .prime_fd_to_handle = drm_gem_prime_fd_to_handle, |
// .gem_prime_export = drm_gem_prime_export, |
// .gem_prime_import = drm_gem_prime_import, |
// .gem_prime_pin = radeon_gem_prime_pin, |
// .gem_prime_unpin = radeon_gem_prime_unpin, |
// .gem_prime_get_sg_table = radeon_gem_prime_get_sg_table, |
// .gem_prime_import_sg_table = radeon_gem_prime_import_sg_table, |
// .gem_prime_vmap = radeon_gem_prime_vmap, |
// .gem_prime_vunmap = radeon_gem_prime_vunmap, |
|
#define SRV_CREATE_SURFACE 10 |
#define SRV_DESTROY_SURFACE 11 |
#define SRV_LOCK_SURFACE 12 |
#define SRV_UNLOCK_SURFACE 13 |
#define SRV_RESIZE_SURFACE 14 |
#define SRV_BLIT_BITMAP 15 |
#define SRV_BLIT_TEXTURE 16 |
#define SRV_BLIT_VIDEO 17 |
}; |
|
|
|
int r600_video_blit(uint64_t src_offset, int x, int y, |
int w, int h, int pitch); |
|
#define check_input(size) \ |
if( unlikely((inp==NULL)||(io->inp_size != (size))) ) \ |
break; |
|
#define check_output(size) \ |
if( unlikely((outp==NULL)||(io->out_size != (size))) ) \ |
break; |
|
int _stdcall display_handler(ioctl_t *io) |
int ati_init(void) |
{ |
int retval = -1; |
u32_t *inp; |
u32_t *outp; |
|
inp = io->input; |
outp = io->output; |
|
switch(io->io_code) |
{ |
case SRV_GETVERSION: |
check_output(4); |
*outp = API_VERSION; |
retval = 0; |
break; |
|
case SRV_ENUM_MODES: |
dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n", |
inp, io->inp_size, io->out_size ); |
check_output(4); |
if( radeon_modeset) |
retval = get_modes((videomode_t*)inp, outp); |
break; |
|
case SRV_SET_MODE: |
dbgprintf("SRV_SET_MODE inp %x inp_size %x\n", |
inp, io->inp_size); |
check_input(sizeof(videomode_t)); |
if( radeon_modeset ) |
retval = set_user_mode((videomode_t*)inp); |
break; |
/* |
case SRV_GET_CAPS: |
retval = get_driver_caps((hwcaps_t*)inp); |
break; |
|
case SRV_CREATE_SURFACE: |
// check_input(8); |
retval = create_surface(main_drm_device, (struct io_call_10*)inp); |
break; |
|
case SRV_LOCK_SURFACE: |
retval = lock_surface((struct io_call_12*)inp); |
break; |
|
case SRV_BLIT_BITMAP: |
srv_blit_bitmap( inp[0], inp[1], inp[2], |
inp[3], inp[4], inp[5], inp[6]); |
*/ |
}; |
|
return retval; |
} |
|
static char log[256]; |
static pci_dev_t device; |
|
u32_t drvEntry(int action, char *cmdline) |
{ |
struct radeon_device *rdev = NULL; |
|
const struct pci_device_id *ent; |
|
int err; |
u32_t retval = 0; |
|
if(action != 1) |
return 0; |
|
if( GetService("DISPLAY") != 0 ) |
return 0; |
|
if( cmdline && *cmdline ) |
parse_cmdline(cmdline, &usermode, log, &radeon_modeset); |
|
if(!dbg_open(log)) |
{ |
strcpy(log, "/TMP1/1/ati.log"); |
|
if(!dbg_open(log)) |
{ |
printf("Can't open %s\nExit\n", log); |
return 0; |
}; |
} |
dbgprintf("Radeon v3.10 preview-1 cmdline %s\n", cmdline); |
|
cpu_detect(); |
|
enum_pci_devices(); |
|
ent = find_pci_device(&device, pciidlist); |
|
if( unlikely(ent == NULL) ) |
{ |
dbgprintf("device not found\n"); |
return 0; |
return -ENODEV; |
}; |
|
dbgprintf("device %x:%x\n", device.pci_dev.vendor, |
drm_core_init(); |
|
DRM_INFO("device %x:%x\n", device.pci_dev.vendor, |
device.pci_dev.device); |
|
drm_global_init(); |
kms_driver.driver_features |= DRIVER_MODESET; |
|
err = drm_get_dev(&device.pci_dev, ent); |
err = drm_get_pci_dev(&device.pci_dev, ent, &kms_driver); |
|
rdev = rdisplay->ddev->dev_private; |
|
err = RegService("DISPLAY", display_handler); |
|
if( err != 0) |
dbgprintf("Set DISPLAY handler\n"); |
|
return err; |
}; |
} |
|
#define PCI_CLASS_REVISION 0x08 |
#define PCI_CLASS_DISPLAY_VGA 0x0300 |
|
int pci_scan_filter(u32_t id, u32_t busnr, u32_t devfn) |
{ |
u16_t vendor, device; |
u32_t class; |
int ret = 0; |
|
vendor = id & 0xffff; |
device = (id >> 16) & 0xffff; |
|
if(vendor == 0x1002) |
{ |
class = PciRead32(busnr, devfn, PCI_CLASS_REVISION); |
class >>= 16; |
|
if( class == PCI_CLASS_DISPLAY_VGA) |
ret = 1; |
} |
return ret; |
} |
|