60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * drm_irq.c -- IRQ IOCTL and function support
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Created: Fri Oct 18 2003 by anholt@FreeBSD.org
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Copyright 2003 Eric Anholt
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Copyright (c) 2009, Intel Corporation.
60405de4d8688d96dd05157c28db3ade5c9bc234kz * All Rights Reserved.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Permission is hereby granted, free of charge, to any person obtaining a
60405de4d8688d96dd05157c28db3ade5c9bc234kz * copy of this software and associated documentation files (the "Software"),
60405de4d8688d96dd05157c28db3ade5c9bc234kz * to deal in the Software without restriction, including without limitation
60405de4d8688d96dd05157c28db3ade5c9bc234kz * the rights to use, copy, modify, merge, publish, distribute, sublicense,
60405de4d8688d96dd05157c28db3ade5c9bc234kz * and/or sell copies of the Software, and to permit persons to whom the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Software is furnished to do so, subject to the following conditions:
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * The above copyright notice and this permission notice (including the next
60405de4d8688d96dd05157c28db3ade5c9bc234kz * paragraph) shall be included in all copies or substantial portions of the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Software.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
60405de4d8688d96dd05157c28db3ade5c9bc234kz * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60405de4d8688d96dd05157c28db3ade5c9bc234kz * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
60405de4d8688d96dd05157c28db3ade5c9bc234kz * ERIC ANHOLT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
60405de4d8688d96dd05157c28db3ade5c9bc234kz * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
60405de4d8688d96dd05157c28db3ade5c9bc234kz * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Authors:
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Eric Anholt <anholt@FreeBSD.org>
60405de4d8688d96dd05157c28db3ade5c9bc234kz *
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz
e92e3a8694f157faf8a9e44096a70ada86c556bfzw/*
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
e92e3a8694f157faf8a9e44096a70ada86c556bfzw * Use is subject to license terms.
e92e3a8694f157faf8a9e44096a70ada86c556bfzw */
e92e3a8694f157faf8a9e44096a70ada86c556bfzw
60405de4d8688d96dd05157c28db3ade5c9bc234kz#include "drmP.h"
60405de4d8688d96dd05157c28db3ade5c9bc234kz#include "drm.h"
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#include "drm_io32.h"
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_irq_by_busid(DRM_IOCTL_ARGS)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_DEVICE;
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_irq_busid_t irq;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_COPYFROM_WITH_RETURN(&irq, (void *)data, sizeof (irq));
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if ((irq.busnum >> 8) != dev->pci_domain ||
60405de4d8688d96dd05157c28db3ade5c9bc234kz (irq.busnum & 0xff) != dev->pci_bus ||
60405de4d8688d96dd05157c28db3ade5c9bc234kz irq.devnum != dev->pci_slot ||
60405de4d8688d96dd05157c28db3ade5c9bc234kz irq.funcnum != dev->pci_func)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz irq.irq = dev->irq;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_DEBUG("%d:%d:%d => IRQ %d\n",
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China irq.busnum, irq.devnum, irq.funcnum, irq.irq);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_COPYTO_WITH_RETURN((void *)data, &irq, sizeof (irq));
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cgstatic irqreturn_t
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_irq_handler_wrap(DRM_IRQ_ARGS)
d0538f66491267879b7418b21ad78e3dcc2dcc83cg{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_device_t *dev = (void *)arg;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg int ret;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_enter(&dev->irq_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ret = dev->driver->irq_handler(arg);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg mutex_exit(&dev->irq_lock);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ret);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinastatic void vblank_disable_fn(void *arg)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China{
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China struct drm_device *dev = (struct drm_device *)arg;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China int i;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu if (!dev->vblank_disable_allowed)
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu return;
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China for (i = 0; i < dev->num_crtcs; i++) {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_read(&dev->vblank_enabled[i]) == 1) {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->last_vblank[i] =
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->driver->get_vblank_counter(dev, i);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->driver->disable_vblank(dev, i);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_set(&dev->vblank_enabled[i], 0);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_DEBUG("disable vblank");
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China}
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shuvoid
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shudrm_vblank_cleanup(struct drm_device *dev)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China{
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China /* Bail if the driver didn't call drm_vblank_init() */
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (dev->num_crtcs == 0)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China return;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China vblank_disable_fn((void *)dev);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_free(dev->vbl_queues, sizeof (wait_queue_head_t) * dev->num_crtcs,
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_free(dev->vbl_sigs, sizeof (struct drm_vbl_sig) * dev->num_crtcs,
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_free(dev->_vblank_count, sizeof (atomic_t) *
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->num_crtcs, DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_free(dev->vblank_refcount, sizeof (atomic_t) *
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->num_crtcs, DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_free(dev->vblank_enabled, sizeof (int) *
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->num_crtcs, DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_free(dev->last_vblank, sizeof (u32) * dev->num_crtcs,
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_free(dev->vblank_inmodeset, sizeof (*dev->vblank_inmodeset) *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dev->num_crtcs, DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->num_crtcs = 0;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China}
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinaint
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinadrm_vblank_init(struct drm_device *dev, int num_crtcs)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China{
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China int i, ret = ENOMEM;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_set(&dev->vbl_signal_pending, 0);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->num_crtcs = num_crtcs;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->vbl_queues = drm_alloc(sizeof (wait_queue_head_t) * num_crtcs,
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (!dev->vbl_queues)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China goto err;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->vbl_sigs = drm_alloc(sizeof (struct drm_vbl_sig) * num_crtcs,
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (!dev->vbl_sigs)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China goto err;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->_vblank_count = drm_alloc(sizeof (atomic_t) * num_crtcs,
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (!dev->_vblank_count)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China goto err;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->vblank_refcount = drm_alloc(sizeof (atomic_t) * num_crtcs,
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (!dev->vblank_refcount)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China goto err;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->vblank_enabled = drm_alloc(num_crtcs * sizeof (int),
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (!dev->vblank_enabled)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China goto err;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China dev->last_vblank = drm_alloc(num_crtcs * sizeof (u32), DRM_MEM_DRIVER);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (!dev->last_vblank)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China goto err;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dev->vblank_inmodeset = drm_alloc(num_crtcs * sizeof (int),
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_MEM_DRIVER);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!dev->vblank_inmodeset)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto err;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China /* Zero per-crtc vblank stuff */
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China for (i = 0; i < num_crtcs; i++) {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_INIT_WAITQUEUE(&dev->vbl_queues[i], DRM_INTR_PRI(dev));
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China TAILQ_INIT(&dev->vbl_sigs[i]);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_set(&dev->_vblank_count[i], 0);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_set(&dev->vblank_refcount[i], 0);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu dev->vblank_disable_allowed = 1;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China return (0);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinaerr:
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_ERROR("drm_vblank_init: alloc error");
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_vblank_cleanup(dev);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China return (ret);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzstatic int
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_install_irq_handle(drm_device_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dev_info_t *dip = dev->dip;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (dip == NULL) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_install_irq_handle: cannot get vgatext's dip");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ddi_intr_hilevel(dip, 0) != 0) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_install_irq_handle: "
d0538f66491267879b7418b21ad78e3dcc2dcc83cg "high-level interrupts are not supported");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ddi_get_iblock_cookie(dip, (uint_t)0,
60405de4d8688d96dd05157c28db3ade5c9bc234kz &dev->intr_block) != DDI_SUCCESS) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_install_irq_handle: cannot get iblock cookie");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* setup the interrupt handler */
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ddi_add_intr(dip, 0, &dev->intr_block,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (ddi_idevice_cookie_t *)NULL, drm_irq_handler_wrap,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (caddr_t)dev) != DDI_SUCCESS) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_install_irq_handle: ddi_add_intr failed");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_FAILURE);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_SUCCESS);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_irq_install(drm_device_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz int ret;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (dev->dev_private == NULL) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_irq_install: dev_private is NULL");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (dev->irq_enabled) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_irq_install: irq already enabled");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EBUSY);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_DEBUG("drm_irq_install irq=%d\n", dev->irq);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* before installing handler */
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China ret = dev->driver->irq_preinstall(dev);
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China if (ret)
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China return (EINVAL);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* install handler */
60405de4d8688d96dd05157c28db3ade5c9bc234kz ret = drm_install_irq_handle(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz if (ret != DDI_SUCCESS) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_ERROR("drm_irq_install: drm_install_irq_handle failed");
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (ret);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz /* after installing handler */
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dev->driver->irq_postinstall(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China dev->irq_enabled = 1;
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China dev->context_flag = 0;
0f7bfed6285b1bd6a65b05cc5f6ab4687ca999e6miao chen - Sun Microsystems - Beijing China
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (0);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kzstatic void
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_uninstall_irq_handle(drm_device_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz ASSERT(dev->dip);
60405de4d8688d96dd05157c28db3ade5c9bc234kz ddi_remove_intr(dev->dip, 0, dev->intr_block);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
d0538f66491267879b7418b21ad78e3dcc2dcc83cgdrm_irq_uninstall(drm_device_t *dev)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu int i;
e92e3a8694f157faf8a9e44096a70ada86c556bfzw if (!dev->irq_enabled) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
e92e3a8694f157faf8a9e44096a70ada86c556bfzw }
60405de4d8688d96dd05157c28db3ade5c9bc234kz dev->irq_enabled = 0;
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu /*
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu * Wake up any waiters so they don't hang.
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu */
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu DRM_SPINLOCK(&dev->vbl_lock);
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu for (i = 0; i < dev->num_crtcs; i++) {
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu DRM_WAKEUP(&dev->vbl_queues[i]);
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu dev->vblank_enabled[i] = 0;
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu }
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu DRM_SPINUNLOCK(&dev->vbl_lock);
8566479d2f5fd989f537085885d6fa1df55e36e9Edward Shu
d0538f66491267879b7418b21ad78e3dcc2dcc83cg dev->driver->irq_uninstall(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_uninstall_irq_handle(dev);
e92e3a8694f157faf8a9e44096a70ada86c556bfzw dev->locked_tasklet_func = NULL;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (DDI_SUCCESS);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_control(DRM_IOCTL_ARGS)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
60405de4d8688d96dd05157c28db3ade5c9bc234kz DRM_DEVICE;
60405de4d8688d96dd05157c28db3ade5c9bc234kz drm_control_t ctl;
60405de4d8688d96dd05157c28db3ade5c9bc234kz int err;
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_COPYFROM_WITH_RETURN(&ctl, (void *)data, sizeof (ctl));
60405de4d8688d96dd05157c28db3ade5c9bc234kz
60405de4d8688d96dd05157c28db3ade5c9bc234kz switch (ctl.func) {
60405de4d8688d96dd05157c28db3ade5c9bc234kz case DRM_INST_HANDLER:
60405de4d8688d96dd05157c28db3ade5c9bc234kz /*
60405de4d8688d96dd05157c28db3ade5c9bc234kz * Handle drivers whose DRM used to require IRQ setup but the
60405de4d8688d96dd05157c28db3ade5c9bc234kz * no longer does.
60405de4d8688d96dd05157c28db3ade5c9bc234kz */
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (drm_irq_install(dev));
60405de4d8688d96dd05157c28db3ade5c9bc234kz case DRM_UNINST_HANDLER:
60405de4d8688d96dd05157c28db3ade5c9bc234kz err = drm_irq_uninstall(dev);
60405de4d8688d96dd05157c28db3ade5c9bc234kz return (err);
60405de4d8688d96dd05157c28db3ade5c9bc234kz default:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
60405de4d8688d96dd05157c28db3ade5c9bc234kz }
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
60405de4d8688d96dd05157c28db3ade5c9bc234kz
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinau32
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinadrm_vblank_count(struct drm_device *dev, int crtc)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China{
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China return (atomic_read(&dev->_vblank_count[crtc]));
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China}
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinastatic void drm_update_vblank_count(struct drm_device *dev, int crtc)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China{
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China u32 cur_vblank, diff;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China /*
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China * Interrupts were disabled prior to this call, so deal with counter
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China * wrap if needed.
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China * NOTE! It's possible we lost a full dev->max_vblank_count events
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China * here if the register is small or we had vblank interrupts off for
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China * a long time.
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China */
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China diff = cur_vblank - dev->last_vblank[crtc];
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (cur_vblank < dev->last_vblank[crtc]) {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China diff += dev->max_vblank_count;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_DEBUG("last_vblank[%d]=0x%x, cur_vblank=0x%x => diff=0x%x\n",
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China crtc, dev->last_vblank[crtc], cur_vblank, diff);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_add(diff, &dev->_vblank_count[crtc]);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China}
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinastatic timeout_id_t timer_id = NULL;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinaint
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinadrm_vblank_get(struct drm_device *dev, int crtc)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China{
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China int ret = 0;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_SPINLOCK(&dev->vbl_lock);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (timer_id != NULL) {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China (void) untimeout(timer_id);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China timer_id = NULL;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China /* Going from 0->1 means we have to enable interrupts again */
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_add(1, &dev->vblank_refcount[crtc]);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (dev->vblank_refcount[crtc] == 1 &&
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_read(&dev->vblank_enabled[crtc]) == 0) {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China ret = dev->driver->enable_vblank(dev, crtc);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (ret)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_dec(&dev->vblank_refcount[crtc]);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China else {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_set(&dev->vblank_enabled[crtc], 1);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_update_vblank_count(dev, crtc);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_SPINUNLOCK(&dev->vbl_lock);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China return (ret);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China}
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinavoid
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinadrm_vblank_put(struct drm_device *dev, int crtc)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China{
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_SPINLOCK(&dev->vbl_lock);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China /* Last user schedules interrupt disable */
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_dec(&dev->vblank_refcount[crtc]);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (dev->vblank_refcount[crtc] == 0)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China timer_id = timeout(vblank_disable_fn, (void *) dev, 5*DRM_HZ);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_SPINUNLOCK(&dev->vbl_lock);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China}
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * drm_modeset_ctl - handle vblank event counter changes across mode switch
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * @DRM_IOCTL_ARGS: standard ioctl arguments
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * ioctls around modesetting so that any lost vblank events are accounted for.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China *
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * Generally the counter will reset across mode sets. If interrupts are
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * enabled around this call, we don't have to do anything since the counter
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * will have already been incremented.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China/*ARGSUSED*/
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaint
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinadrm_modeset_ctl(DRM_IOCTL_ARGS)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China{
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_DEVICE;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China struct drm_modeset_ctl modeset;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China int crtc, ret = 0;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /* If drm_vblank_init() hasn't been called yet, just no-op */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!dev->num_crtcs)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto out;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_COPYFROM_WITH_RETURN(&modeset, (void *)data,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China sizeof (modeset));
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China crtc = modeset.crtc;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (crtc >= dev->num_crtcs) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = -EINVAL;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China goto out;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China /*
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * To avoid all the problems that might happen if interrupts
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * were enabled/disabled around or between these calls, we just
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * have the kernel take a reference on the CRTC (just once though
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * to avoid corrupting the count if multiple, mismatch calls occur),
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China * so that interrupts remain enabled in the interim.
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China switch (modeset.cmd) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China case _DRM_PRE_MODESET:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (!dev->vblank_inmodeset[crtc]) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dev->vblank_inmodeset[crtc] = 1;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = drm_vblank_get(dev, crtc);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China break;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China case _DRM_POST_MODESET:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (dev->vblank_inmodeset[crtc]) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_SPINLOCK(&dev->vbl_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dev->vblank_disable_allowed = 1;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China dev->vblank_inmodeset[crtc] = 0;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_SPINUNLOCK(&dev->vbl_lock);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China drm_vblank_put(dev, crtc);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China break;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China default:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China ret = -EINVAL;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China break;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing Chinaout:
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China return (ret);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China}
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China
60405de4d8688d96dd05157c28db3ade5c9bc234kz/*ARGSUSED*/
60405de4d8688d96dd05157c28db3ade5c9bc234kzint
60405de4d8688d96dd05157c28db3ade5c9bc234kzdrm_wait_vblank(DRM_IOCTL_ARGS)
60405de4d8688d96dd05157c28db3ade5c9bc234kz{
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_DEVICE;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_wait_vblank_t vblwait;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China int ret, flags, crtc;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg unsigned int sequence;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (!dev->irq_enabled) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("wait vblank, EINVAL");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#ifdef _MULTI_DATAMODEL
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_wait_vblank_32_t vblwait32;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_COPYFROM_WITH_RETURN(&vblwait32, (void *)data,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg sizeof (vblwait32));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait.request.type = vblwait32.request.type;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait.request.sequence = vblwait32.request.sequence;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait.request.signal = vblwait32.request.signal;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg } else {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#endif
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_COPYFROM_WITH_RETURN(&vblwait, (void *)data,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg sizeof (vblwait));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#ifdef _MULTI_DATAMODEL
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#endif
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (vblwait.request.type &
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("drm_wait_vblank: wrong request type 0x%x",
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait.request.type);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China if (crtc >= dev->num_crtcs) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("wait vblank operation not support");
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China return (ENOTSUP);
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China }
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China ret = drm_vblank_get(dev, crtc);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (ret) {
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("can't get drm vblank %d", ret);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China return (ret);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China }
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China sequence = drm_vblank_count(dev, crtc);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China switch (vblwait.request.type & _DRM_VBLANK_TYPES_MASK) {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China case _DRM_VBLANK_RELATIVE:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait.request.sequence += sequence;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China /*FALLTHROUGH*/
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China case _DRM_VBLANK_ABSOLUTE:
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China break;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China default:
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_DEBUG("wait vblank return EINVAL");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (EINVAL);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if ((flags & _DRM_VBLANK_NEXTONMISS) &&
d0538f66491267879b7418b21ad78e3dcc2dcc83cg (sequence - vblwait.request.sequence) <= (1<<23)) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait.request.sequence = sequence + 1;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (flags & _DRM_VBLANK_SIGNAL) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /*
d0538f66491267879b7418b21ad78e3dcc2dcc83cg * Don't block process, send signal when vblank interrupt
d0538f66491267879b7418b21ad78e3dcc2dcc83cg */
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China DRM_ERROR("NOT SUPPORT YET, SHOULD BE ADDED");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg cmn_err(CE_WARN, "NOT SUPPORT YET, SHOULD BE ADDED");
d0538f66491267879b7418b21ad78e3dcc2dcc83cg ret = EINVAL;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China goto done;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg } else {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg /* block until vblank interupt */
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China /* shared code returns -errno */
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_WAIT_ON(ret, &dev->vbl_queues[crtc], 3 * DRM_HZ,
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China (((drm_vblank_count(dev, crtc)
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China - vblwait.request.sequence) <= (1 << 23)) ||
0035d21c77a24d02faf34c10aabc120ca692efb5miao chen - Sun Microsystems - Beijing China !dev->irq_enabled));
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China if (ret != EINTR) {
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China struct timeval now;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China (void) uniqtime(&now);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China vblwait.reply.tval_sec = now.tv_sec;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China vblwait.reply.tval_usec = now.tv_usec;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China vblwait.reply.sequence = drm_vblank_count(dev, crtc);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinadone:
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#ifdef _MULTI_DATAMODEL
d0538f66491267879b7418b21ad78e3dcc2dcc83cg if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg drm_wait_vblank_32_t vblwait32;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait32.reply.type = vblwait.reply.type;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg vblwait32.reply.sequence = vblwait.reply.sequence;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China vblwait32.reply.tval_sec = (int32_t)vblwait.reply.tval_sec;
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China vblwait32.reply.tval_usec = (int32_t)vblwait.reply.tval_usec;
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_COPYTO_WITH_RETURN((void *)data, &vblwait32,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg sizeof (vblwait32));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg } else {
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#endif
d0538f66491267879b7418b21ad78e3dcc2dcc83cg DRM_COPYTO_WITH_RETURN((void *)data, &vblwait,
d0538f66491267879b7418b21ad78e3dcc2dcc83cg sizeof (vblwait));
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#ifdef _MULTI_DATAMODEL
d0538f66491267879b7418b21ad78e3dcc2dcc83cg }
d0538f66491267879b7418b21ad78e3dcc2dcc83cg#endif
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China drm_vblank_put(dev, crtc);
d0538f66491267879b7418b21ad78e3dcc2dcc83cg return (ret);
60405de4d8688d96dd05157c28db3ade5c9bc234kz}
e92e3a8694f157faf8a9e44096a70ada86c556bfzw
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
e92e3a8694f157faf8a9e44096a70ada86c556bfzw/*ARGSUSED*/
e92e3a8694f157faf8a9e44096a70ada86c556bfzwvoid
e92e3a8694f157faf8a9e44096a70ada86c556bfzwdrm_vbl_send_signals(drm_device_t *dev)
e92e3a8694f157faf8a9e44096a70ada86c556bfzw{
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_DEBUG("drm_vbl_send_signals");
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China}
d0538f66491267879b7418b21ad78e3dcc2dcc83cg
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinavoid
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing Chinadrm_handle_vblank(struct drm_device *dev, int crtc)
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China{
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China atomic_inc(&dev->_vblank_count[crtc]);
d02310705313ee2fcefee164a4b26d1fa85e9d22miao chen - Sun Microsystems - Beijing China DRM_WAKEUP(&dev->vbl_queues[crtc]);
e92e3a8694f157faf8a9e44096a70ada86c556bfzw}