/* BEGIN CSTYLED */
/*
* i915_drv.c -- Intel i915 driver -*- linux-c -*-
* Created: Wed Feb 14 17:10:04 2001 by gareth@valinux.com
*/
/*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* Copyright (c) 2009, Intel Corporation.
* All Rights Reserved.
*
* 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,
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) 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
* 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:
* Gareth Hughes <gareth@valinux.com>
*
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* Copyright 2014 RackTop Systems.
*/
/*
* I915 DRM Driver for Solaris
*
* This driver provides the hardware 3D acceleration support for Intel
* DRI (Direct Rendering Infrastructure). DRM (Direct Rendering Manager) here
* means the kernel device driver in DRI.
*
* I915 driver is a device dependent driver only, it depends on a misc module
* named drm for generic DRM operations.
*/
#include "drmP.h"
#include "i915_drm.h"
#include "i915_drv.h"
#include "drm_pciids.h"
/*
* copied from vgasubr.h
*/
struct vgaregmap {
};
enum pipe {
PIPE_A = 0,
};
/*
* cb_ops entrypoint
*/
extern struct cb_ops drm_cb_ops;
/*
* module entrypoint
*/
/* drv_PCI_IDs comes from drm_pciids.h */
};
/*
* Local routines
*/
static void i915_configure(drm_driver_t *);
/*
* DRM driver
*/
DEVO_REV, /* devo_rev */
0, /* devo_refcnt */
i915_info, /* devo_getinfo */
nulldev, /* devo_identify */
nulldev, /* devo_probe */
i915_attach, /* devo_attach */
i915_detach, /* devo_detach */
nodev, /* devo_reset */
&drm_cb_ops, /* devo_cb_ops */
NULL, /* devo_bus_ops */
NULL, /* power */
i915_quiesce, /* devo_quiesce */
};
&mod_driverops, /* drv_modops */
"I915 DRM driver", /* drv_linkinfo */
&i915_dev_ops, /* drv_dev_ops */
};
};
DDI_STRICTORDER_ACC /* must be DDI_STRICTORDER_ACC */
};
/*
* softstate head
*/
static void *i915_statep;
int
_init(void)
{
int error;
sizeof (drm_device_t), DRM_MAX_INSTANCES)) != 0)
return (error);
return (error);
}
return (error);
} /* _init() */
int
_fini(void)
{
int error;
return (error);
(void) ddi_soft_state_fini(&i915_statep);
return (0);
} /* _fini() */
int
{
} /* _info() */
/*
* off range: 0x3b0 ~ 0x3ff
*/
static void
{
}
/*
* off range: 0x3b0 ~ 0x3ff
*/
static uint8_t
{
}
static void
{
}
static uint8_t
{
}
static void
{
}
static uint8_t
{
}
static int
{
else
}
static void
{
int i;
return;
else
for(i = 0; i < 256; i++)
}
static void
{
int i;
return;
else
for(i = 0; i < 256; i++)
}
static void
{
int i;
/* VGA color palette registers */
/* DACCRX automatically increments during read */
/* Read 3 bytes of color data from each index */
for (i = 0; i < 256 * 3; i++)
/* MSR bits */
st01 = VGA_ST01_CGA;
} else {
st01 = VGA_ST01_MDA;
}
/* CRT controller regs */
for (i = 0; i <= 0x24; i++)
/* Make sure we don't turn off CR group 0 writes */
/* Attribute controller registers */
for (i = 0; i <= 0x14; i++)
/* Graphics controller registers */
for (i = 0; i < 9; i++)
/* Sequencer registers */
for (i = 0; i < 8; i++)
}
static void
{
int i;
/*
* I/O Address Select. This bit selects 3Bxh or 3Dxh as the
* I/O address for the CRT Controller registers,
* the Feature Control Register (FCR), and Input Status Register
* 1 (ST01). Presently ignored (whole range is claimed), but
* will "ignore" 3Bx for color configuration or 3Dx for monochrome.
* Note that it is typical in AGP chipsets to shadow this bit
* and properly steer I/O cycles to the proper bus for operation
* where a MDA exists on another bus such as ISA.
* 0 = Select 3Bxh I/O address (MDA emulation) (default).
* 1 = Select 3Dxh I/O address (CGA emulation).
*/
st01 = VGA_ST01_CGA;
} else {
st01 = VGA_ST01_MDA;
}
/* Sequencer registers, don't write SR07 */
for (i = 0; i < 7; i++)
/* CRT controller regs */
/* Enable CR group 0 writes */
for (i = 0; i <= 0x24; i++)
/* Graphics controller regs */
for (i = 0; i < 9; i++)
/* Attribute controller registers */
for (i = 0; i <= 0x14; i++)
/* VGA color palette registers */
/* DACCRX automatically increments during read */
/* Read 3 bytes of color data from each index */
for (i = 0; i < 256 * 3; i++)
}
/**
* i915_save_display - save display & mode info
* @dev: DRM device
*
* Save mode timings and display info.
*/
{
/* Display arbitration control */
/*
* Pipe & plane A info.
*/
}
/*
* Pipe & plane B info
*/
}
/*
* CRT state
*/
/*
* LVDS state
*/
/* FIXME: save TV & SDVO state */
/* FBC state */
/* VGA state */
}
{
/*
* Pipe & plane A info
* Prime the clock
*/
drv_usecwait(150);
}
/* Actually enable it */
drv_usecwait(150);
drv_usecwait(150);
/* Restore mode */
/* Restore plane info */
}
/* Enable the plane */
/* Pipe & plane B info */
drv_usecwait(150);
}
/* Actually enable it */
drv_usecwait(150);
drv_usecwait(150);
/* Restore mode */
/* Restore plane info */
}
/* Enable the plane */
/* CRT state */
/* LVDS state */
/* FIXME: restore TV & SDVO state */
/* FBC info */
/* VGA state */
drv_usecwait(150);
}
static int
{
int i;
DRM_ERROR(("i915_resume: pci_config_setup fail"));
return (DDI_FAILURE);
}
/*
* Nexus driver will resume pci config space and set the power state
* for its children. So we needn't resume them explicitly here.
* see pci_pre_resume for detail.
*/
(void) S3_READ(MCHBAR_RENDER_STANDBY);
/* Clock gating state */
/* Cache mode state */
/* Memory arbitration state */
for (i = 0; i < 16; i++) {
}
for (i = 0; i < 3; i++)
(void) pci_config_teardown(&conf_hdl);
return (DDI_SUCCESS);
}
static int
{
int i;
DRM_ERROR(("i915_suspend: pci_config_setup fail"));
return (DDI_FAILURE);
}
/*
* Nexus driver will resume pci config space for its children.
* So pci config registers are not saved here.
*/
/* Hardware status page */
/* Interrupt state */
/* Clock gating state */
/* Cache mode state */
/* Memory Arbitration state */
/* Scratch space */
for (i = 0; i < 16; i++) {
}
for (i = 0; i < 3; i++)
/*
* Save page table control register
*/
(void) pci_config_teardown(&conf_hdl);
return (DDI_SUCCESS);
}
/*
* This funtion check the length of memory mapped IO space to get the right bar. * And There are two possibilities here.
* 1. The MMIO registers is in memory map IO bar with 1M size. The bottom half
* of the 1M space is the MMIO registers.
* 2. The MMIO register is in memory map IO with 512K size. The whole 512K
* space is the MMIO registers.
*/
static int
{
int rnumber;
int nregs;
return (DDI_FAILURE);
}
if ((size == 0x80000) ||
(size == 0x100000) ||
(size == 0x400000))
break;
}
"i915_map_regs: failed to find MMIO registers");
return (DDI_FAILURE);
}
"i915_map_regs: failed to map bar %d", rnumber);
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}
static void
{
}
static int
{
void *handle;
int unit;
switch (cmd) {
case DDI_ATTACH:
break;
case DDI_RESUME:
return (i915_resume(statep));
default:
DRM_ERROR("i915_attach: attach and resume ops are supported");
return (DDI_FAILURE);
}
"i915_attach: failed to alloc softstate");
return (DDI_FAILURE);
}
goto err_exit1;
}
/*
* Map in the mmio register space for s3.
*/
&s3_private->saveHandle)) {
goto err_exit2;
}
/*
* Call drm_supp_register to create minor nodes for us
*/
DRM_ERROR("i915_attach: drm_supp_register failed");
goto err_exit3;
}
/*
* After drm_supp_register, we can call drm_xxx routine
*/
if (
DRM_ERROR("i915_open: "
"DRM current don't support this graphics card");
goto err_exit4;
}
/* call common attach code */
DRM_ERROR("i915_attach: drm_attach failed");
goto err_exit4;
}
return (DDI_SUCCESS);
(void) drm_supp_unregister(handle);
return (DDI_FAILURE);
} /* i915_attach() */
static int
{
int unit;
DRM_ERROR("i915_detach: "
"only detach and resume ops are supported");
return (DDI_FAILURE);
}
DRM_ERROR("i915_detach: can not get soft state");
return (DDI_FAILURE);
}
if (cmd == DDI_SUSPEND)
return (i915_suspend(statep));
/*
* Free the struct for context saving in S3
*/
(void) drm_detach(statep);
return (DDI_SUCCESS);
} /* i915_detach() */
/*ARGSUSED*/
static int
{
int unit;
switch (infocmd) {
case DDI_INFO_DEVT2DEVINFO:
error = DDI_FAILURE;
} else {
error = DDI_SUCCESS;
}
break;
case DDI_INFO_DEVT2INSTANCE:
error = DDI_SUCCESS;
break;
default:
error = DDI_FAILURE;
break;
}
return (error);
} /* i915_info() */
{
}
{
int unit;
return (DDI_FAILURE);
}
return (DDI_SUCCESS);
}