34,8 → 34,14 |
|
#define RADEON_WAIT_IDLE_TIMEOUT 200 |
|
struct radeon_device *main_device; |
#define DRM_IRQ_ARGS void *arg |
|
struct drm_driver { |
irqreturn_t(*irq_handler) (DRM_IRQ_ARGS); |
void (*irq_preinstall) (struct drm_device *dev); |
int (*irq_postinstall) (struct drm_device *dev); |
}; |
|
extern int irq_override; |
|
|
48,9 → 54,12 |
* radeon_irq_process is a macro that points to the per-asic |
* irq handler callback. |
*/ |
void irq_handler_kms() |
irqreturn_t radeon_driver_irq_handler_kms(DRM_IRQ_ARGS) |
{ |
radeon_irq_process(main_device); |
struct drm_device *dev = (struct drm_device *) arg; |
struct radeon_device *rdev = dev->dev_private; |
|
return radeon_irq_process(rdev); |
} |
|
/** |
61,8 → 70,9 |
* Gets the hw ready to enable irqs (all asics). |
* This function disables all interrupt sources on the GPU. |
*/ |
void radeon_irq_preinstall_kms(struct radeon_device *rdev) |
void radeon_driver_irq_preinstall_kms(struct drm_device *dev) |
{ |
struct radeon_device *rdev = dev->dev_private; |
unsigned long irqflags; |
unsigned i; |
|
91,17 → 101,45 |
* Handles stuff to be done after enabling irqs (all asics). |
* Returns 0 on success. |
*/ |
int radeon_driver_irq_postinstall_kms(struct drm_device *dev) |
{ |
dev->max_vblank_count = 0x001fffff; |
return 0; |
} |
|
int radeon_driver_irq_postinstall_kms(struct radeon_device *rdev) |
/** |
* radeon_driver_irq_uninstall_kms - drm irq uninstall callback |
* |
* @dev: drm dev pointer |
* |
* This function disables all interrupt sources on the GPU (all asics). |
*/ |
void radeon_driver_irq_uninstall_kms(struct drm_device *dev) |
{ |
// struct radeon_device *rdev = dev->dev_private; |
struct radeon_device *rdev = dev->dev_private; |
unsigned long irqflags; |
unsigned i; |
|
// dev->max_vblank_count = 0x001fffff; |
|
if (rdev == NULL) { |
return; |
} |
spin_lock_irqsave(&rdev->irq.lock, irqflags); |
/* Disable *all* interrupts */ |
for (i = 0; i < RADEON_NUM_RINGS; i++) |
atomic_set(&rdev->irq.ring_int[i], 0); |
for (i = 0; i < RADEON_MAX_HPD_PINS; i++) |
rdev->irq.hpd[i] = false; |
for (i = 0; i < RADEON_MAX_CRTCS; i++) { |
rdev->irq.crtc_vblank_int[i] = false; |
atomic_set(&rdev->irq.pflip[i], 0); |
rdev->irq.afmt[i] = false; |
} |
radeon_irq_set(rdev); |
return 0; |
spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
} |
|
|
|
/** |
* radeon_irq_kms_init - init driver interrupt info |
* |
117,44 → 155,16 |
|
ENTER(); |
|
// INIT_WORK(&rdev->hotplug_work, radeon_hotplug_work_func); |
// INIT_WORK(&rdev->audio_work, r600_audio_update_hdmi); |
|
spin_lock_init(&rdev->irq.lock); |
// r = drm_vblank_init(rdev->ddev, rdev->num_crtc); |
// if (r) { |
// return r; |
// } |
/* enable msi */ |
rdev->msi_enabled = 0; |
|
// if (radeon_msi_ok(rdev)) { |
// int ret = pci_enable_msi(rdev->pdev); |
// if (!ret) { |
// rdev->msi_enabled = 1; |
// dev_info(rdev->dev, "radeon: using MSI.\n"); |
// } |
// } |
rdev->irq.installed = true; |
main_device = rdev; |
|
radeon_irq_preinstall_kms(rdev); |
|
if (irq_override) |
irq_line = irq_override; |
else |
irq_line = rdev->pdev->irq; |
|
dbgprintf("%s install irq %d\n", __FUNCTION__, irq_line); |
|
AttachIntHandler(irq_line, irq_handler_kms, 2); |
|
// r = drm_irq_install(rdev->ddev); |
|
r = radeon_driver_irq_postinstall_kms(rdev); |
r = drm_irq_install(rdev->ddev); |
if (r) { |
rdev->irq.installed = false; |
LEAVE(); |
FAIL(); |
return r; |
} |
DRM_INFO("radeon: irq initialized.\n"); |
228,4 → 238,99 |
} |
} |
|
/** |
* radeon_irq_kms_enable_hpd - enable hotplug detect interrupt |
* |
* @rdev: radeon device pointer |
* @hpd_mask: mask of hpd pins you want to enable. |
* |
* Enables the hotplug detect interrupt for a specific hpd pin (all asics). |
*/ |
void radeon_irq_kms_enable_hpd(struct radeon_device *rdev, unsigned hpd_mask) |
{ |
unsigned long irqflags; |
int i; |
|
spin_lock_irqsave(&rdev->irq.lock, irqflags); |
for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) |
rdev->irq.hpd[i] |= !!(hpd_mask & (1 << i)); |
radeon_irq_set(rdev); |
spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
} |
|
/** |
* radeon_irq_kms_disable_hpd - disable hotplug detect interrupt |
* |
* @rdev: radeon device pointer |
* @hpd_mask: mask of hpd pins you want to disable. |
* |
* Disables the hotplug detect interrupt for a specific hpd pin (all asics). |
*/ |
void radeon_irq_kms_disable_hpd(struct radeon_device *rdev, unsigned hpd_mask) |
{ |
unsigned long irqflags; |
int i; |
|
spin_lock_irqsave(&rdev->irq.lock, irqflags); |
for (i = 0; i < RADEON_MAX_HPD_PINS; ++i) |
rdev->irq.hpd[i] &= !(hpd_mask & (1 << i)); |
radeon_irq_set(rdev); |
spin_unlock_irqrestore(&rdev->irq.lock, irqflags); |
} |
|
|
static struct drm_driver drm_driver = { |
.irq_preinstall = radeon_driver_irq_preinstall_kms, |
.irq_postinstall = radeon_driver_irq_postinstall_kms, |
.irq_handler = radeon_driver_irq_handler_kms |
}; |
|
static struct drm_driver *driver = &drm_driver; |
|
int drm_irq_install(struct drm_device *dev) |
{ |
unsigned long sh_flags = 0; |
int irq_line; |
int ret = 0; |
|
char *irqname; |
|
mutex_lock(&dev->struct_mutex); |
|
/* Driver must have been initialized */ |
if (!dev->dev_private) { |
mutex_unlock(&dev->struct_mutex); |
return -EINVAL; |
} |
|
if (dev->irq_enabled) { |
mutex_unlock(&dev->struct_mutex); |
return -EBUSY; |
} |
dev->irq_enabled = 1; |
mutex_unlock(&dev->struct_mutex); |
|
irq_line = drm_dev_to_irq(dev); |
|
DRM_DEBUG("irq=%d\n", drm_dev_to_irq(dev)); |
|
/* Before installing handler */ |
if (driver->irq_preinstall) |
driver->irq_preinstall(dev); |
|
ret = AttachIntHandler(irq_line, driver->irq_handler, (u32)dev); |
|
/* After installing handler */ |
if (driver->irq_postinstall) |
ret = driver->irq_postinstall(dev); |
|
if (ret < 0) { |
DRM_ERROR(__FUNCTION__); |
} |
|
u16_t cmd = PciRead16(dev->pdev->busnr, dev->pdev->devfn, 4); |
cmd&= ~(1<<10); |
PciWrite16(dev->pdev->busnr, dev->pdev->devfn, 4, cmd); |
|
return ret; |
} |