initial hotplug work

This commit is contained in:
Jakob Bornecrantz 2007-10-05 16:43:04 +02:00 committed by Jakob Bornecrantz
parent d69721a14a
commit 34dcf1b8f4
10 changed files with 203 additions and 49 deletions

View file

@ -530,7 +530,6 @@ void drm_bo_usage_deref_unlocked(struct drm_buffer_object ** bo)
}
}
EXPORT_SYMBOL(drm_bo_usage_deref_unlocked);
/*
* Note. The caller has to register (if applicable)
* and deregister fence object usage.

View file

@ -197,7 +197,7 @@ static int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
}
static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
static struct page *drm_bo_vm_fault(struct vm_area_struct *vma,
struct fault_data *data)
{
unsigned long address = data->address;

View file

@ -349,6 +349,7 @@ void drm_crtc_probe_output_modes(struct drm_device *dev, int maxX, int maxY)
}
}
}
EXPORT_SYMBOL(drm_crtc_probe_output_modes);
/**
* drm_crtc_set_mode - set a mode
@ -506,7 +507,8 @@ void drm_disable_unused_functions(struct drm_device *dev)
crtc->funcs->dpms(crtc, DPMSModeOff);
}
}
EXPORT_SYMBOL(drm_disable_unused_functions);
/**
* drm_mode_probed_add - add a mode to the specified output's probed mode list
* @output: output the new mode
@ -863,7 +865,7 @@ clone:
}
}
}
EXPORT_SYMBOL(drm_pick_crtcs);
/**
* drm_initial_config - setup a sane initial output configuration
@ -1168,7 +1170,7 @@ int drm_mode_getresources(struct drm_device *dev,
if (card_res->count_modes == 0) {
DRM_DEBUG("probing modes %dx%d\n", dev->mode_config.max_width, dev->mode_config.max_height);
drm_crtc_probe_output_modes(dev, dev->mode_config.max_width, dev->mode_config.max_height);
/* drm_crtc_probe_output_modes(dev, dev->mode_config.max_width, dev->mode_config.max_height); */
mode_count = 0;
list_for_each_entry(output, &dev->mode_config.output_list, head) {
list_for_each(lh, &output->modes)

View file

@ -184,6 +184,7 @@ int drm_lastclose(struct drm_device * dev)
DRM_DEBUG("\n");
/* return 0; */
/*
* We can't do much about this function failing.
*/
@ -198,8 +199,8 @@ int drm_lastclose(struct drm_device * dev)
dev->unique_len=0;
}
if (dev->irq_enabled)
drm_irq_uninstall(dev);
/* if (dev->irq_enabled)
drm_irq_uninstall(dev); */
/* Free drawable information memory */
mutex_lock(&dev->struct_mutex);
@ -253,11 +254,11 @@ int drm_lastclose(struct drm_device * dev)
list_del(&vma->head);
drm_ctl_free(vma, sizeof(*vma), DRM_MEM_VMAS);
}
/*
list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
drm_rmmap_locked(dev, r_list->map);
r_list = NULL;
}
}*/
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
for (i = 0; i < dev->queue_count; i++) {

View file

@ -309,8 +309,6 @@ static struct drm_driver driver = {
DRIVER_IRQ_VBL2,
.load = i915_driver_load,
.unload = i915_driver_unload,
.lastclose = i915_driver_lastclose,
.preclose = i915_driver_preclose,
.device_is_agp = i915_driver_device_is_agp,
.vblank_wait = i915_driver_vblank_wait,
.vblank_wait2 = i915_driver_vblank_wait2,

View file

@ -142,6 +142,7 @@ static bool intel_crt_detect_hotplug(struct drm_output *output)
struct drm_device *dev = output->dev;
struct drm_i915_private *dev_priv = dev->dev_private;
u32 temp;
#if 1
unsigned long timeout = jiffies + msecs_to_jiffies(1000);
temp = I915_READ(PORT_HOTPLUG_EN);
@ -160,6 +161,15 @@ static bool intel_crt_detect_hotplug(struct drm_output *output)
return true;
return false;
#else
temp = I915_READ(PORT_HOTPLUG_STAT);
DRM_DEBUG("HST 0x%08x\n", temp);
if (temp & (1 << 8) && temp & (1 << 9))
return true;
return false;
#endif
}
static bool intel_crt_detect_ddc(struct drm_output *output)

View file

@ -489,8 +489,8 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
}
crtc->fb = fb;
fb->width = crtc->desired_mode->hdisplay;
fb->height = crtc->desired_mode->vdisplay;
fb->width = 2048;//crtc->desired_mode->hdisplay;
fb->height = 2048;//crtc->desired_mode->vdisplay;
fb->bits_per_pixel = 32;
fb->pitch = fb->width * ((fb->bits_per_pixel + 1) / 8);
@ -499,8 +499,8 @@ int intelfb_probe(struct drm_device *dev, struct drm_crtc *crtc)
drm_bo_type_kernel,
DRM_BO_FLAG_READ |
DRM_BO_FLAG_WRITE |
DRM_BO_FLAG_MEM_TT |
DRM_BO_FLAG_MEM_VRAM,
DRM_BO_FLAG_MEM_VRAM | DRM_BO_FLAG_MEM_TT |
DRM_BO_FLAG_NO_MOVE,
0, 0, 0,
&fbo);
if (ret || !fbo) {

View file

@ -129,6 +129,8 @@ struct drm_i915_private {
uint32_t irq_enable_reg;
int irq_enabled;
struct workqueue_struct *wq;
#ifdef I915_HAVE_FENCE
uint32_t flush_sequence;
uint32_t flush_flags;

View file

@ -30,7 +30,7 @@ int i915_probe_agp(struct pci_dev *pdev, unsigned long *aperture_size,
u16 tmp = 0;
unsigned long overhead;
bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
bridge_dev = pci_find_slot(0, PCI_DEVFN(0,0));
if (!bridge_dev) {
DRM_ERROR("bridge device not found\n");
return -1;
@ -254,8 +254,15 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
}
DRM_DEBUG("Enabled hardware status page\n");
dev_priv->wq = create_singlethread_workqueue("i915");
if (dev_priv == 0) {
DRM_DEBUG("Error\n");
}
intel_modeset_init(dev);
drm_initial_config(dev, false);
drm_irq_install(dev);
return 0;
}
@ -264,9 +271,15 @@ int i915_driver_unload(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
I915_WRITE(LP_RING + RING_LEN, 0);
intel_modeset_cleanup(dev);
#if 0
if (dev_priv->ring.virtual_start) {
drm_core_ioremapfree(&dev_priv->ring.map, dev);
}
#endif
if (dev_priv->status_page_dmah) {
drm_pci_free(dev, dev_priv->status_page_dmah);
@ -283,10 +296,6 @@ int i915_driver_unload(struct drm_device *dev)
I915_WRITE(I915REG_HWS_PGA, 0x1ffff000);
}
I915_WRITE(LP_RING + RING_LEN, 0);
intel_modeset_cleanup(dev);
drm_mem_reg_iounmap(dev, &dev_priv->ring_buffer->mem,
dev_priv->ring.virtual_start);
@ -315,20 +324,3 @@ int i915_driver_unload(struct drm_device *dev)
dev->dev_private = NULL;
return 0;
}
void i915_driver_lastclose(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
i915_do_cleanup_pageflip(dev);
//i915_mem_takedown(&(dev_priv->agp_heap));
i915_dma_cleanup(dev);
}
void i915_driver_preclose(struct drm_device *dev, struct drm_file *filp)
{
struct drm_i915_private *dev_priv = dev->dev_private;
//i915_mem_release(dev, filp, dev_priv->agp_heap);
}

View file

@ -31,6 +31,8 @@
#include "i915_drm.h"
#include "i915_drv.h"
#include "intel_drv.h"
#define USER_INT_FLAG (1<<1)
#define VSYNC_PIPEB_FLAG (1<<5)
#define VSYNC_PIPEA_FLAG (1<<7)
@ -301,27 +303,128 @@ static void i915_vblank_tasklet(struct drm_device *dev)
}
}
static drm_device_t *hotplug_dev;
static void i915_hotplug_work_func(struct work_struct *work)
{
drm_device_t *dev = hotplug_dev;
drm_i915_private_t *dev_priv = dev->dev_private;
struct drm_output *output;
struct intel_output *iout;
int has_config = 0;
DRM_DEBUG("starting monkey hunt\n");
mutex_lock(&dev->struct_mutex);
/* find the crt output */
list_for_each_entry(output, &dev->mode_config.output_list, head) {
iout = output->driver_private;
if (iout->type == INTEL_OUTPUT_ANALOG)
break;
}
if (iout == 0) {
DRM_DEBUG("could not find monkey\n");
goto unlock_struct;
}
mutex_lock(&dev->mode_config.mutex);
if (output->crtc && output->crtc->desired_mode) {
DRM_DEBUG("monkey has banana\n");
has_config = 1;
}
DRM_DEBUG("monkey looking for bananas\n");
drm_crtc_probe_output_modes(dev, 2048, 2048);
drm_pick_crtcs(dev);
if (!output->crtc || !output->crtc->desired_mode) {
DRM_DEBUG("monkey had no parent or banana\n");
goto unlock_mode;
}
mutex_unlock(&dev->struct_mutex);
DRM_DEBUG("monkey eating banana\n");
/* We should realy check if there is a fb using this crtc */
if (!has_config)
dev->driver->fb_probe(dev, output->crtc);
else
if (!drm_crtc_set_mode(output->crtc, output->crtc->desired_mode, 0, 0))
DRM_DEBUG("throwing away unused bananas\n");
drm_disable_unused_functions(dev);
mutex_lock(&dev->struct_mutex);
unlock_mode:
mutex_unlock(&dev->mode_config.mutex);
unlock_struct:
mutex_unlock(&dev->struct_mutex);
DRM_DEBUG("monkey hunt done\n");
}
static int i915_run_hotplug_tasklet(drm_device_t *dev)
{
static DECLARE_WORK(hotplug, i915_hotplug_work_func);
drm_i915_private_t *dev_priv = dev->dev_private;
// DRM_DEBUG("%p\n", dev);
// atomic_long_set(&hotplug.data,(unsigned long) dev);
hotplug_dev = dev;
queue_work(dev_priv->wq, &hotplug);
return 0;
}
irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
{
struct drm_device *dev = (struct drm_device *) arg;
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
u16 temp;
u32 temp;
u32 temp2;
u32 pipea_stats, pipeb_stats;
pipea_stats = I915_READ(I915REG_PIPEASTAT);
pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
temp = I915_READ16(I915REG_INT_IDENTITY_R);
/* On i8xx hw the IIR and IER are 16bit on i9xx its 32bit */
/* if (IS_I9XX(dev)) */ {
temp = I915_READ(I915REG_INT_IDENTITY_R);
} /* else {
temp = I915_READ16(I915REG_INT_IDENTITY_R);
} */
temp2 = temp;
temp &= (dev_priv->irq_enable_reg | USER_INT_FLAG);
#if 0
#if 1
/* ugly despamification of pipeb event irq */
if (temp & (0xFFFFFFF ^ ((1 << 5) | (1 << 7)))) {
DRM_DEBUG("IIR %08x\n", temp2);
DRM_DEBUG("MSK %08x\n", dev_priv->irq_enable_reg | USER_INT_FLAG);
DRM_DEBUG("M&I %08x\n", temp);
DRM_DEBUG("HOT %08x\n", I915_READ(PORT_HOTPLUG_STAT));
}
#else
DRM_DEBUG("%s flag=%08x\n", __FUNCTION__, temp);
#endif
if (temp == 0)
return IRQ_NONE;
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
(void) I915_READ16(I915REG_INT_IDENTITY_R);
/* if (IS_I9XX(dev)) */ {
I915_WRITE(I915REG_INT_IDENTITY_R, temp);
(void) I915_READ(I915REG_INT_IDENTITY_R);
} /* else {
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
(void) I915_READ16(I915REG_INT_IDENTITY_R);
} */
DRM_READMEMORYBARRIER();
dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
@ -362,6 +465,23 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
I915_VBLANK_CLEAR);
}
/* for now lest just ack it */
if (temp & (1 << 17)) {
DRM_DEBUG("Hotplug event recived\n");
temp2 = I915_READ(PORT_HOTPLUG_STAT);
if (temp2 & (1 << 11) && temp2 & (1 << 9) && temp2 & (1 << 8)) {
DRM_DEBUG("CRT connected\n");
i915_run_hotplug_tasklet(dev);
}
if (temp2 & (1 << 11) && !(temp2 & ((1 << 9) | (1 << 8))))
DRM_DEBUG("CRT disconnected\n");
I915_WRITE(PORT_HOTPLUG_STAT,temp2);
}
return IRQ_HANDLED;
}
@ -533,8 +653,26 @@ void i915_enable_interrupt (struct drm_device *dev)
if (dev_priv->vblank_pipe & DRM_I915_VBLANK_PIPE_B)
dev_priv->irq_enable_reg |= VSYNC_PIPEB_FLAG;
I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
/* if (dev_priv->mode_setting) */ {
dev_priv->irq_enable_reg |= (1 << 17);
/* Activate the CRT hotplug detection */
I915_WRITE(PORT_HOTPLUG_EN, (1 << 9));
}
/* if (IS_I9XX(dev_priv)) */ {
I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
} /* else {
I915_WRITE16(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
} */
DRM_DEBUG("HEN %08x\n",I915_READ(PORT_HOTPLUG_EN));
DRM_DEBUG("HST %08x\n",I915_READ(PORT_HOTPLUG_STAT));
DRM_DEBUG("IER %08x\n",I915_READ(I915REG_INT_ENABLE_R));
dev_priv->irq_enabled = 1;
DRM_DEBUG("enabled\n");
}
/* Set the vblank monitor pipe
@ -766,15 +904,27 @@ void i915_driver_irq_postinstall(struct drm_device * dev)
void i915_driver_irq_uninstall(struct drm_device * dev)
{
struct drm_i915_private *dev_priv = (struct drm_i915_private *) dev->dev_private;
u16 temp;
u32 temp;
if (!dev_priv)
return;
dev_priv->irq_enabled = 0;
I915_WRITE16(I915REG_HWSTAM, 0xffff);
I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
temp = I915_READ16(I915REG_INT_IDENTITY_R);
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
/* if(IS_I9XX(dev_priv) */ {
I915_WRITE(I915REG_HWSTAM, 0xffffffff);
I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
temp = I915_READ(I915REG_INT_IDENTITY_R);
I915_WRITE(I915REG_INT_IDENTITY_R, temp);
} /* else {
I915_WRITE16(I915REG_HWSTAM, 0xffff);
I915_WRITE16(I915REG_INT_MASK_R, 0xffff);
I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
temp = I915_READ16(I915REG_INT_IDENTITY_R);
I915_WRITE16(I915REG_INT_IDENTITY_R, temp);
} */
}