diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-02 19:40:34 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-05-02 19:40:34 -0700 |
commit | 20a2078ce7705a6e0722ef5184336eb8657a58d8 (patch) | |
tree | 5b927c96516380aa0ecd68d8a609f7cd72120ad5 /drivers/gpu/drm/qxl/qxl_irq.c | |
parent | 0279b3c0ada1d78882f24acf94ac4595bd657a89 (diff) | |
parent | 307b9c022720f9de90d58e51743e01e9a42aec59 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie:
"This is the main drm pull request for 3.10.
Wierd bits:
- OMAP drm changes required OMAP dss changes, in drivers/video, so I
took them in here.
- one more fbcon fix for font handover
- VT switch avoidance in pm code
- scatterlist helpers for gpu drivers - have acks from akpm
Highlights:
- qxl kms driver - driver for the spice qxl virtual GPU
Nouveau:
- fermi/kepler VRAM compression
- GK110/nvf0 modesetting support.
Tegra:
- host1x core merged with 2D engine support
i915:
- vt switchless resume
- more valleyview support
- vblank fixes
- modesetting pipe config rework
radeon:
- UVD engine support
- SI chip tiling support
- GPU registers initialisation from golden values.
exynos:
- device tree changes
- fimc block support
Otherwise:
- bunches of fixes all over the place."
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (513 commits)
qxl: update to new idr interfaces.
drm/nouveau: fix build with nv50->nvc0
drm/radeon: fix handling of v6 power tables
drm/radeon: clarify family checks in pm table parsing
drm/radeon: consolidate UVD clock programming
drm/radeon: fix UPLL_REF_DIV_MASK definition
radeon: add bo tracking debugfs
drm/radeon: add new richland pci ids
drm/radeon: add some new SI PCI ids
drm/radeon: fix scratch reg handling for UVD fence
drm/radeon: allocate SA bo in the requested domain
drm/radeon: fix possible segfault when parsing pm tables
drm/radeon: fix endian bugs in atom_allocate_fb_scratch()
OMAPDSS: TFP410: return EPROBE_DEFER if the i2c adapter not found
OMAPDSS: VENC: Add error handling for venc_probe_pdata
OMAPDSS: HDMI: Add error handling for hdmi_probe_pdata
OMAPDSS: RFBI: Add error handling for rfbi_probe_pdata
OMAPDSS: DSI: Add error handling for dsi_probe_pdata
OMAPDSS: SDI: Add error handling for sdi_probe_pdata
OMAPDSS: DPI: Add error handling for dpi_probe_pdata
...
Diffstat (limited to 'drivers/gpu/drm/qxl/qxl_irq.c')
-rw-r--r-- | drivers/gpu/drm/qxl/qxl_irq.c | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/drivers/gpu/drm/qxl/qxl_irq.c b/drivers/gpu/drm/qxl/qxl_irq.c new file mode 100644 index 00000000000..21393dc4700 --- /dev/null +++ b/drivers/gpu/drm/qxl/qxl_irq.c @@ -0,0 +1,97 @@ +/* + * Copyright 2013 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + * Alon Levy + */ + +#include "qxl_drv.h" + +irqreturn_t qxl_irq_handler(DRM_IRQ_ARGS) +{ + struct drm_device *dev = (struct drm_device *) arg; + struct qxl_device *qdev = (struct qxl_device *)dev->dev_private; + uint32_t pending; + + pending = xchg(&qdev->ram_header->int_pending, 0); + + atomic_inc(&qdev->irq_received); + + if (pending & QXL_INTERRUPT_DISPLAY) { + atomic_inc(&qdev->irq_received_display); + wake_up_all(&qdev->display_event); + qxl_queue_garbage_collect(qdev, false); + } + if (pending & QXL_INTERRUPT_CURSOR) { + atomic_inc(&qdev->irq_received_cursor); + wake_up_all(&qdev->cursor_event); + } + if (pending & QXL_INTERRUPT_IO_CMD) { + atomic_inc(&qdev->irq_received_io_cmd); + wake_up_all(&qdev->io_cmd_event); + } + if (pending & QXL_INTERRUPT_ERROR) { + /* TODO: log it, reset device (only way to exit this condition) + * (do it a certain number of times, afterwards admit defeat, + * to avoid endless loops). + */ + qdev->irq_received_error++; + qxl_io_log(qdev, "%s: driver is in bug mode.\n", __func__); + } + if (pending & QXL_INTERRUPT_CLIENT_MONITORS_CONFIG) { + qxl_io_log(qdev, "QXL_INTERRUPT_CLIENT_MONITORS_CONFIG\n"); + schedule_work(&qdev->client_monitors_config_work); + } + qdev->ram_header->int_mask = QXL_INTERRUPT_MASK; + outb(0, qdev->io_base + QXL_IO_UPDATE_IRQ); + return IRQ_HANDLED; +} + +static void qxl_client_monitors_config_work_func(struct work_struct *work) +{ + struct qxl_device *qdev = container_of(work, struct qxl_device, + client_monitors_config_work); + + qxl_display_read_client_monitors_config(qdev); +} + +int qxl_irq_init(struct qxl_device *qdev) +{ + int ret; + + init_waitqueue_head(&qdev->display_event); + init_waitqueue_head(&qdev->cursor_event); + init_waitqueue_head(&qdev->io_cmd_event); + INIT_WORK(&qdev->client_monitors_config_work, + qxl_client_monitors_config_work_func); + atomic_set(&qdev->irq_received, 0); + atomic_set(&qdev->irq_received_display, 0); + atomic_set(&qdev->irq_received_cursor, 0); + atomic_set(&qdev->irq_received_io_cmd, 0); + qdev->irq_received_error = 0; + ret = drm_irq_install(qdev->ddev); + qdev->ram_header->int_mask = QXL_INTERRUPT_MASK; + if (unlikely(ret != 0)) { + DRM_ERROR("Failed installing irq: %d\n", ret); + return 1; + } + return 0; +} |