--- sys/conf/files.orig 2010-05-25 17:53:25.000000000 -0400 +++ sys/conf/files 2010-05-26 17:16:01.000000000 -0400 @@ -890,6 +890,7 @@ dev/drm/radeon_drv.c optional radeondrm dev/drm/radeon_irq.c optional radeondrm dev/drm/radeon_mem.c optional radeondrm dev/drm/radeon_state.c optional radeondrm +dev/drm/radeon_suspend.c optional radeondrm dev/drm/savage_bci.c optional savagedrm dev/drm/savage_drv.c optional savagedrm dev/drm/savage_state.c optional savagedrm --- sys/dev/drm/radeon_drv.c.orig 2009-03-09 03:55:18.000000000 -0400 +++ sys/dev/drm/radeon_drv.c 2010-05-26 17:16:01.000000000 -0400 @@ -111,10 +111,46 @@ radeon_detach(device_t kdev) return ret; } +static int +radeon_suspend(device_t kdev) +{ + struct drm_device *dev = device_get_softc(kdev); + + if (!dev || !dev->dev_private) { + DRM_ERROR("DRM not initialized, aborting suspend.\n"); + return -ENODEV; + } + + DRM_LOCK(); + DRM_DEBUG("starting suspend\n"); + radeon_save_state(dev); + DRM_UNLOCK(); + + return bus_generic_suspend(kdev); +} + +static int +radeon_resume(device_t kdev) +{ + struct drm_device *dev = device_get_softc(kdev); + int error; + + error = bus_generic_resume(kdev); + + DRM_LOCK(); + radeon_restore_state(dev); + DRM_DEBUG("finished resume\n"); + DRM_UNLOCK(); + + return error; +} + static device_method_t radeon_methods[] = { /* Device interface */ DEVMETHOD(device_probe, radeon_probe), DEVMETHOD(device_attach, radeon_attach), + DEVMETHOD(device_suspend, radeon_suspend), + DEVMETHOD(device_resume, radeon_resume), DEVMETHOD(device_detach, radeon_detach), { 0, 0 } --- sys/dev/drm/radeon_drv.h.orig 2009-09-28 18:40:29.000000000 -0400 +++ sys/dev/drm/radeon_drv.h 2010-05-26 17:16:01.000000000 -0400 @@ -364,6 +364,7 @@ typedef struct drm_radeon_private { struct drm_ati_pcigart_info gart_info; u32 scratch_ages[5]; + u32 scratch_regs[8]; /* starting from here on, data is preserved accross an open */ uint32_t flags; /* see radeon_chip_flags */ @@ -549,6 +550,10 @@ r600_blit_swap(struct drm_device *dev, /* radeon_state.c */ extern void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf); +/* radeon_suspend.c */ +extern int radeon_save_state(struct drm_device *dev); +extern int radeon_restore_state(struct drm_device *dev); + /* radeon_cs.c */ extern int radeon_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *fpriv); extern int r600_cs_init(struct drm_device *dev); @@ -1107,6 +1112,10 @@ extern u32 radeon_get_scratch(drm_radeon # define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) # define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) +#define RADEON_BIOS_0_SCRATCH 0x0010 +#define R600_BIOS_0_SCRATCH 0x1724 +#define RADEON_BIOS_NUM_SCRATCH 8 + /* CP registers */ #define RADEON_CP_ME_RAM_ADDR 0x07d4 #define RADEON_CP_ME_RAM_RADDR 0x07d8 --- sys/dev/drm/radeon_suspend.c.orig 2010-05-26 17:55:00.000000000 -0400 +++ sys/dev/drm/radeon_suspend.c 2010-05-26 17:37:34.000000000 -0400 @@ -0,0 +1,113 @@ +/*- + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. + * 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, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (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 + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: + * Gareth Hughes + */ +/* + * Copyright 2008 Advanced Micro Devices, Inc. + * Copyright 2008 Red Hat Inc. + * Copyright 2009 Jerome Glisse. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * Authors: Dave Airlie + * Alex Deucher + * Jerome Glisse + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "dev/drm/drmP.h" +#include "dev/drm/drm.h" +#include "dev/drm/drm_sarea.h" +#include "dev/drm/radeon_drm.h" +#include "dev/drm/radeon_drv.h" + +int radeon_save_state(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + int i; + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++) + dev_priv->scratch_regs[i] = + RADEON_READ(R600_BIOS_0_SCRATCH + i * 4); + return 0; + } + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + RADEON_WRITE(R500_DxMODE_INT_MASK, 0); + RADEON_WRITE(RADEON_GEN_INT_CNTL, 0); + + for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++) + dev_priv->scratch_regs[i] = + RADEON_READ(RADEON_BIOS_0_SCRATCH + i * 4); + + return 0; +} + +int radeon_restore_state(struct drm_device *dev) +{ + struct drm_radeon_private *dev_priv = dev->dev_private; + int error, i; + + error = radeon_cp_resume(dev, NULL, NULL); + if (error != 0) + return error; + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) { + for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++) + RADEON_WRITE(R600_BIOS_0_SCRATCH + i * 4, + dev_priv->scratch_regs[i]); + return 0; + } + + for (i = 0; i < RADEON_BIOS_NUM_SCRATCH; i++) + dev_priv->scratch_regs[i] = + RADEON_READ(RADEON_BIOS_0_SCRATCH + i * 4); + + if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) + RADEON_WRITE(R500_DxMODE_INT_MASK, + dev_priv->r500_disp_irq_reg); + RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg); + + return 0; +} --- sys/modules/drm/radeon/Makefile.orig 2009-08-23 10:55:57.000000000 -0400 +++ sys/modules/drm/radeon/Makefile 2010-05-26 17:16:01.000000000 -0400 @@ -3,7 +3,7 @@ .PATH: ${.CURDIR}/../../../dev/drm KMOD = radeon SRCS = r300_cmdbuf.c r600_blit.c r600_cp.c radeon_cp.c radeon_cs.c \ - radeon_drv.c radeon_irq.c radeon_mem.c radeon_state.c + radeon_drv.c radeon_irq.c radeon_mem.c radeon_state.c radeon_suspend.c SRCS +=device_if.h bus_if.h pci_if.h opt_drm.h .include