/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2009, Intel Corporation.
* All Rights Reserved.
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Misc module for AGP master device support
*/
#include <sys/dditypes.h>
/* In 965 1MB GTTMMADR, GTT reside in the latter 512KB */
/* Base address of GTT */
/* Graphics memory base address */
#ifdef DEBUG
#else
#endif
int agpm_debug = 0;
/*
* Whether it is a Intel integrated graphics card
*/
&mod_miscops, "AGP master interfaces"
};
};
};
static int detect_i8xx_device(agp_master_softc_t *);
int
_init(void)
{
int err;
return (err);
return (0);
}
int
_fini(void)
{
int err;
return (err);
return (0);
}
int
{
}
/*
* Minor node is not removed here, since the caller (xx_attach) is
* responsible for removing all nodes.
*/
void
{
/* intel integrated device */
if (IS_IGD(master_softc) &&
/*
* for some chipsets, mmap handle is shared between both mmio
* and GTT table.
*/
}
master_softc = NULL;
return;
}
/*
* 965 has a fixed GTT table size (512KB), so check to see the actual aperture
* size. Aperture size = GTT table size * 1024.
*/
static off_t
{
switch (apersize & GTT_SIZE_MASK) {
case GTT_2MB:
apersize = 2048;
break;
case GTT_1_5MB:
apersize = 1536;
break;
case GTT_1MB:
apersize = 1024;
break;
case GTT_512KB:
apersize = 512;
break;
case GTT_256KB:
apersize = 256;
break;
case GTT_128KB:
apersize = 128;
break;
default:
apersize = 0;
"i965_apersize: invalid GTT size in PGTBL_CTL"));
}
return (apersize);
}
/*
* For Intel 3 series, we need to get GTT size from the GGMS field in GMCH
* Graphics Control Register. Return aperture size in MB.
*/
static off_t
{
/*
* Get the value of configuration register MGGC "Mirror of Dev0 GMCH
* Graphics Control" from Internal Graphics #2 (Device2:Function0).
*/
/* computing aperture size using the pre-allocated GTT size */
switch (value & IX33_GGMS_MASK) {
case IX33_GGMS_1M:
apersize = 1024;
break;
case IX33_GGMS_2M:
apersize = 2048;
break;
default:
apersize = 0; /* no memory pre-allocated */
"i3XX_apersize: no memory allocated for GTT"));
}
return (apersize);
}
if (status != DDI_SUCCESS) { \
AGPM_DEBUG((CE_WARN, \
"set_gtt_mmio: regs_map_setup error")); \
return (-1); \
}
/*
* Set gtt_addr, gtt_mmio_base, igd_apersize, igd_aperbase and igd_devid
* according to chipset.
*/
static int
{
int status;
/* Intel 3 series are similar with 915/945 series */
>T_HANDLE(agpmaster));
&MMIO_HANDLE(agpmaster));
/* Different computing method used in getting aperture size. */
&MMIO_HANDLE(agpmaster));
else
/* I915/945 series */
>T_HANDLE(agpmaster));
&MMIO_HANDLE(agpmaster));
} else {
/* I8XX series */
&MMIO_HANDLE(agpmaster));
}
/*
* If memory size is smaller than a certain value, it means
* the register set number for graphics memory range might
* be wrong
*/
"set_gtt_mmio: error in getting graphics memory"));
return (-1);
}
/* get graphics memory base address from GMADR */
return (0);
}
/*
* Try to initialize agp master.
* 0 is returned if the device is successfully initialized. AGP master soft
* state is returned in master_softcp if needed.
* Otherwise -1 is returned and *master_softcp is set to NULL.
*/
int
{
int instance;
int status;
*master_softcp = NULL;
agpmaster = (agp_master_softc_t *)
if (!detect_i8xx_device(agpmaster)) {
/* Intel 8XX, 915, 945 and 965 series */
goto fail;
/* non IGD or AGP devices, AMD64 gart */
"agpmaster_attach: neither IGD or AGP devices exists"));
return (0);
}
/* create minor node for IGD or AGP device */
DDI_NT_AGP_MASTER, 0);
if (status != DDI_SUCCESS) {
"agpmaster_attach: create agpmaster node failed"));
goto fail;
}
return (0);
fail:
return (-1);
}
/*
* Currently, it handles ioctl requests related with agp master device for
* layered driver (agpgart) only.
*/
/*ARGSUSED*/
int
{
static char kernel_only[] =
"agpmaster_ioctl: %s is a kernel only ioctl";
switch (cmd) {
case DEVICE_DETECT:
return (ENXIO);
}
return (EFAULT);
break;
case AGP_MASTER_SETCMD:
return (ENXIO);
}
return (EFAULT);
command);
break;
case AGP_MASTER_GETINFO:
"AGP_MASTER_GETINFO"));
return (ENXIO);
}
sizeof (agp_info_t), mode))
return (EFAULT);
break;
case I810_SET_GTT_BASE:
return (ENXIO);
}
return (EFAULT);
/* enables page table */
break;
case I8XX_GET_INFO:
return (ENXIO);
}
return (EFAULT);
break;
case I8XX_ADD2GTT:
return (ENXIO);
}
sizeof (igd_gtt_seg_t), mode))
return (EFAULT);
return (EINVAL);
break;
case I8XX_REM_GTT:
return (ENXIO);
}
sizeof (igd_gtt_seg_t), mode))
return (EFAULT);
break;
case I8XX_UNCONFIG:
return (ENXIO);
}
/*
* may need to clear all gtt entries here for i830 series,
* but may not be necessary
*/
break;
}
return (0);
}
/*
* If AGP cap pointer is successfully found, none-zero value is returned.
* Otherwise 0 is returned.
*/
static off_t
{
/* check if this device supports capibility pointer */
if (!value)
return (0);
/* get the offset of the first capability pointer from CAPPTR */
/* check AGP capability from the first capability pointer */
while (nextcap) {
if ((ncapid & PCI_CONF_CAPID_MASK)
== AGP_CAP_ID) /* find AGP cap */
break;
}
return (nextcap);
}
/*
* If i8xx device is successfully detected, 0 is returned.
* Otherwise -1 is returned.
*/
static int
{
switch (master_softc->agpm_id) {
case INTEL_IGD_810:
case INTEL_IGD_810DC:
case INTEL_IGD_810E:
case INTEL_IGD_815:
break;
case INTEL_IGD_830M:
case INTEL_IGD_845G:
case INTEL_IGD_855GM:
case INTEL_IGD_865G:
case INTEL_IGD_915:
case INTEL_IGD_915GM:
case INTEL_IGD_945:
case INTEL_IGD_945GM:
case INTEL_IGD_945GME:
case INTEL_IGD_946GZ:
case INTEL_IGD_965G1:
case INTEL_IGD_965G2:
case INTEL_IGD_965GM:
case INTEL_IGD_965GME:
case INTEL_IGD_965Q:
case INTEL_IGD_Q35:
case INTEL_IGD_G33:
case INTEL_IGD_Q33:
case INTEL_IGD_GM45:
case INTEL_IGD_EL:
case INTEL_IGD_Q45:
case INTEL_IGD_G45:
case INTEL_IGD_G41:
case INTEL_IGD_IGDNG_D:
case INTEL_IGD_IGDNG_M:
case INTEL_IGD_B43:
break;
default: /* unknown id */
return (-1);
}
return (0);
}
/*
* If agp master is successfully detected, 0 is returned.
* Otherwise -1 is returned.
*/
static int
{
if (cap) {
return (0);
} else {
return (-1);
}
}
/*
* Please refer to GART and GTT entry format table in agpdefs.h for
* intel GTT entry format.
*/
static int
{
switch (type) {
case AGP_PHYSICAL:
case AGP_NORMAL:
break;
default:
return (-1);
}
return (0);
}
static int
{
int i;
/* check if gtt max page number is reached */
return (-1);
i++, paddr++) {
return (-1);
entry);
}
return (0);
}
static void
{
int i;
/* check if gtt max page number is reached */
return;
}
}