drm_pci.c revision 60405de4d8688d96dd05157c28db3ade5c9bc234
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Use is subject to license terms.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/* BEGIN CSTYLED */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/**
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * \file drm_pci.h
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * \brief PCI consistent, DMA-accessible memory functions.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * \author Eric Anholt <anholt@FreeBSD.org>
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*-
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Copyright 2003 Eric Anholt.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * All Rights Reserved.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Permission is hereby granted, free of charge, to any person obtaining a
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * copy of this software and associated documentation files (the "Software"),
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * to deal in the Software without restriction, including without limitation
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * the rights to use, copy, modify, merge, publish, distribute, sublicense,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * and/or sell copies of the Software, and to permit persons to whom the
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Software is furnished to do so, subject to the following conditions:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * The above copyright notice and this permission notice (including the next
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * paragraph) shall be included in all copies or substantial portions of the
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * Software.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/**********************************************************************/
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/** \name PCI memory */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*@{*/
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/* END CSTYLED */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#pragma ident "%Z%%M% %I% %E% SMI"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#include "drmP.h"
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#define PCI_DEVICE(x) (((x)>>11) & 0x1f)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#define PCI_FUNCTION(x) (((x) & 0x700) >> 8)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore#define PCI_BUS(x) (((x) & 0xff0000) >> 16)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/* Device info struct */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoretypedef struct drm_device_info {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint16_t drm_venid; /* drm devcie's vendor id */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint16_t drm_devid; /* drm device's device id */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint8_t drm_irq; /* drm device's interrupt line */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore} drm_device_info_t;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoretypedef struct drm_pci_resource {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint_t regnum;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned long offset;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore unsigned long size;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore} drm_pci_resource_t;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/* Get IRQ line */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic int device_get_info(drm_device_info_t *data, ddi_acc_handle_t pch)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint8_t irq;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (!pch)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (DRM_ERR(EINVAL));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore data->drm_venid =
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore pci_config_get16(pch, PCI_CONF_VENID);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore data->drm_devid =
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore pci_config_get16(pch, PCI_CONF_DEVID);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore irq = pci_config_get8(pch, PCI_CONF_IPIN);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_DEBUG("!drm: device_get_info: \
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore venid is %x, devid is %x,irq is %x \n",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore data->drm_venid, data->drm_devid, irq);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (irq)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore irq = pci_config_get8(pch, PCI_CONF_ILINE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore data->drm_irq = irq;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorepci_get_info(drm_softstate_t *softstate, int *bus, int *slot, int *func)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int *regs_list;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint_t nregs = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, softstate->dip,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_PROP_DONTPASS, "reg", (int **)&regs_list, &nregs)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore != DDI_PROP_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_ERROR("pci_get_info: get pci function bus device failed");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto error;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *bus = (int)PCI_BUS(regs_list[0]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *slot = (int)PCI_DEVICE(regs_list[0]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *func = (int)PCI_FUNCTION(regs_list[0]);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (nregs > 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_prop_free(regs_list);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (DDI_SUCCESS);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreerror:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (nregs > 0) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_prop_free(regs_list);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (DDI_FAILURE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorepci_get_irq(drm_softstate_t *softstate)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore drm_device_info_t drm_info;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int ret;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore bzero(&drm_info, sizeof (drm_device_info_t));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ret = device_get_info(&drm_info, softstate->pci_cfg_hdl);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ret)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (-1);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (drm_info.drm_irq);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorepci_get_vendor(drm_softstate_t *softstate)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore drm_device_info_t drm_info;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int ret;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore bzero(&drm_info, sizeof (drm_device_info_t));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ret = device_get_info(&drm_info, softstate->pci_cfg_hdl);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ret)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (DDI_FAILURE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (drm_info.drm_venid);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorepci_get_device(drm_softstate_t *softstate)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore drm_device_info_t drm_info;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int ret;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore bzero(&drm_info, sizeof (drm_device_info_t));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ret = device_get_info(&drm_info, softstate->pci_cfg_hdl);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ret)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (DDI_FAILURE);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (drm_info.drm_devid);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreagp_remap(struct drm_softstate *softstate, struct drm_local_map *map)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_DEBUG(
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "agp_remap: map->handle:%lx map->offset %llx, map->size %lx\n",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long)map->handle, map->offset.off,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long)map->size);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore map->handle = (void *)((softstate->agp_umem_kvaddr) +
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long)(map->offset.off - softstate->agp->base));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore map->dev_addr = (caddr_t)map->handle;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_DEBUG("agp_remap: map->dev_addr is %lx",
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long) map->dev_addr);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*ARGSUSED*/
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreagp_remap_free(struct drm_softstate *softstate, struct drm_local_map *map)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredrm_core_ioremap(struct drm_local_map *map, struct drm_softstate *softstate)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (map->type != _DRM_AGP_UMEM) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) drm_ioremap(softstate, map);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore } else {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) agp_remap(softstate, map);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredrm_core_ioremapfree(struct drm_local_map *map, struct drm_softstate *softstate)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (map->type != _DRM_AGP_UMEM) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (map->handle && map->size)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore drm_ioremapfree(map);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore } else {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) agp_remap_free(softstate, map);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestruct drm_local_map *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredrm_core_findmap(struct drm_softstate *dev, unsigned long offset)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore drm_local_map_t *map;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_SPINLOCK_ASSERT(&dev->dev_lock);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore TAILQ_FOREACH(map, &dev->maplist, link) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((unsigned long)map->offset.off == offset)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (map);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (NULL);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * pci_alloc_consistent()
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic ddi_dma_attr_t hw_dma_attr = {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DMA_ATTR_V0,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long long)0,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long long)0xffffffff,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long long)0xffffffff,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long long)4096,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long long)0xffffffff,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long long)0xffffffff,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 1,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 4,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore 0
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore};
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorestatic ddi_device_acc_attr_t hw_acc_attr = {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DEVICE_ATTR_V0,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_NEVERSWAP_ACC,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_STRICTORDER_ACC
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore};
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid *
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredrm_pci_alloc(drm_softstate_t *dev, uint32_t size,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dma_addr_t *physaddr)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int ret = DDI_FAILURE;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore uint32_t num_cookies;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_dma_cookie_t cookie;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore /* allocat continous physical memory for hw status page */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore hw_dma_attr.dma_attr_sgllen = 1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ret = ddi_dma_alloc_handle(dev->dip,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore &hw_dma_attr,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DMA_SLEEP,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore NULL, &dev->hw_dma_handle)) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_ERROR("drm_pci_alloc:ddi_dma_alloc_handle failed\n");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto err3;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ret = ddi_dma_mem_alloc(dev->hw_dma_handle,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore size,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore &hw_acc_attr,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DMA_CONSISTENT,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DMA_SLEEP, NULL,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore &dev->hw_vbase,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore &dev->hw_size,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore &dev->hw_dma_acc_handle)) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_ERROR("drm_pci_alloc: ddi_dma_mem_alloc failed\n");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto err2;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ret = ddi_dma_addr_bind_handle(dev->hw_dma_handle,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore NULL, dev->hw_vbase,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore size,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DMA_RDWR|DDI_DMA_CONSISTENT,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DMA_SLEEP, NULL,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore &cookie, &num_cookies);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_pbase = cookie.dmac_address;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if ((ret != DDI_DMA_MAPPED) || (num_cookies != 1)) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (num_cookies > 1)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) ddi_dma_unbind_handle(dev->hw_dma_handle);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_ERROR("drm_pci_alloc: alloc contiguous phys memory failed");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore goto err1;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *physaddr = dev->hw_pbase;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (dev->hw_vbase);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreerr1:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_dma_mem_free(&dev->hw_dma_acc_handle);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_dma_acc_handle = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreerr2:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_dma_free_handle(&dev->hw_dma_handle);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_dma_handle = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreerr3:
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_pbase = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_vbase = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_size = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore *physaddr = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (NULL);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore * pci_free_consistent()
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore */
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*ARGSUSED*/
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amorevoid
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredrm_pci_free(drm_softstate_t *dev)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (dev->hw_dma_handle == NULL)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (void) ddi_dma_unbind_handle(dev->hw_dma_handle);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_dma_mem_free(&dev->hw_dma_acc_handle);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_dma_acc_handle = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ddi_dma_free_handle(&dev->hw_dma_handle);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_dma_handle = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_pbase = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_vbase = NULL;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore dev->hw_size = 0;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreint
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredo_get_pci_res(drm_softstate_t *softstate, drm_pci_resource_t *resp)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int length;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore pci_regspec_t *regs;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ddi_getlongprop(
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_DEV_T_ANY, softstate->dip, DDI_PROP_DONTPASS,
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "assigned-addresses", (caddr_t)&regs, &length) !=
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DDI_PROP_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_ERROR("do_get_pci_res: ddi_getlongprop failed!\n");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (DRM_ERR(EFAULT));
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore resp->offset =
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long)regs[resp->regnum].pci_phys_low;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore resp->size =
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore (unsigned long)regs[resp->regnum].pci_size_low;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore kmem_free(regs, (size_t)length);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (DDI_SUCCESS);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*ARGSUSED*/
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreunsigned long
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredrm_get_resource_start(drm_softstate_t *softstate, unsigned int regnum)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore drm_pci_resource_t res;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int ret;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore res.regnum = regnum;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ret = do_get_pci_res(softstate, &res);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ret != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_ERROR(
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "drm_get_resource_start: "
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "DRM_GET_PCI_RESOURCE ioctl failed");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (res.offset);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore/*ARGSUSED*/
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoreunsigned long
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amoredrm_get_resource_len(drm_softstate_t *softstate, unsigned int regnum)
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore{
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore drm_pci_resource_t res;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore int ret;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore res.regnum = regnum;
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore ret = do_get_pci_res(softstate, &res);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore if (ret != DDI_SUCCESS) {
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore DRM_ERROR(
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "drm_get_resource_len: "
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore "DRM_GET_PCI_RESOURCE ioctl failed");
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (0);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore }
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore return (res.size);
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore}
49ef7e0638c8b771d8a136eae78b1c0f99acc8e0Garrett D'Amore