mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-01-03 14:00:19 +01:00
initial hotplug work
This commit is contained in:
parent
d69721a14a
commit
34dcf1b8f4
10 changed files with 203 additions and 49 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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++) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
} */
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue