add nouveau graphic driver, add some patches for radeon graphic driver, add some patches for drm/mesa

This commit is contained in:
Stephan Raue 2009-04-26 04:00:40 +02:00
parent c52480a6b7
commit 7acdaf6ea9
30 changed files with 163340 additions and 9 deletions

View File

@ -119,7 +119,7 @@ WPA_SUPPLICANT=yes
# X.org drivers to use (all/ati/geode/glint/i740/intel/mga/nv/openchrome/
# radeonhd/s3/s3virge/savage/sis/tdfx/trident/vesa/vmware)
# Space separated list is supported, e.g. XORG_DRIVERS="ati s3"
XORG_DRIVERS="ati nv vesa openchrome intel"
XORG_DRIVERS="ati nouveau nv vesa openchrome intel"
# LCD display support (yes/no)

View File

@ -0,0 +1,45 @@
--- configure.ac.mach64 2008-09-05 13:53:24.000000000 +1000
+++ configure.ac 2008-09-05 13:53:39.000000000 +1000
@@ -656,7 +656,7 @@
# because there is no x86-64 system where they could *ever*
# be used.
if test "x$DRI_DIRS" = "xyes"; then
- DRI_DIRS="i915 i965 mach64 mga r128 r200 r300 radeon \
+ DRI_DIRS="i915 i965 mga r128 r200 r300 radeon \
savage tdfx unichrome swrast"
fi
;;
@@ -664,13 +664,13 @@
# Build only the drivers for cards that exist on PowerPC.
# At some point MGA will be added, but not yet.
if test "x$DRI_DIRS" = "xyes"; then
- DRI_DIRS="mach64 r128 r200 r300 radeon tdfx swrast"
+ DRI_DIRS="r128 r200 r300 radeon tdfx swrast"
fi
;;
sparc*)
# Build only the drivers for cards that exist on sparc`
if test "x$DRI_DIRS" = "xyes"; then
- DRI_DIRS="mach64 r128 r200 r300 radeon ffb swrast"
+ DRI_DIRS="r128 r200 r300 radeon ffb swrast"
fi
;;
esac
@@ -689,7 +689,7 @@
# ffb and gamma are missing because they have not been converted
# to use the new interface.
if test "x$DRI_DIRS" = "xyes"; then
- DRI_DIRS="i810 i915 i965 mach64 mga r128 r200 r300 radeon tdfx \
+ DRI_DIRS="i810 i915 i965 mga r128 r200 r300 radeon tdfx \
unichrome savage sis swrast"
fi
;;
@@ -704,7 +704,7 @@
# default drivers
if test "x$DRI_DIRS" = "xyes"; then
- DRI_DIRS="i810 i915 i965 mach64 mga r128 r200 r300 radeon s3v \
+ DRI_DIRS="i810 i915 i965 mga r128 r200 r300 radeon s3v \
savage sis tdfx trident unichrome ffb swrast"
fi

File diff suppressed because it is too large Load Diff

View File

@ -11,9 +11,10 @@ $SCRIPTS/install libXxf86vm
$SCRIPTS/install libX11
mkdir -p $INSTALL/usr/lib
cp -PR $BUILD/$1*/src/mesa/libmesa.so* $INSTALL/usr/lib
#cp -PR $BUILD/$1*/src/mesa/libmesa.so* $INSTALL/usr/lib
#cp -PR $BUILD/$1*/src/mesa/libglapi.so* $INSTALL/usr/lib
cp -PR $BUILD/$1*/lib/libGL.so* $INSTALL/usr/lib
cp -PR $BUILD/$1*/lib/libdricore.so $INSTALL/usr/lib
#cp -PR $BUILD/$1*/lib/libGLU.so* $INSTALL/usr/lib
mkdir -p $INSTALL/usr/lib/dri

View File

@ -0,0 +1,21 @@
diff -up Mesa-7.1/src/mesa/drivers/osmesa/Makefile.jx Mesa-7.1/src/mesa/drivers/osmesa/Makefile
--- Mesa-7.1/src/mesa/drivers/osmesa/Makefile.jx 2008-08-28 14:05:47.000000000 -0400
+++ Mesa-7.1/src/mesa/drivers/osmesa/Makefile 2008-08-28 14:07:13.000000000 -0400
@@ -46,7 +46,7 @@ osmesa8: $(TOP)/lib/$(OSMESA_LIB_NAME)
$(TOP)/lib/$(OSMESA_LIB_NAME): $(OBJECTS)
$(MKLIB) -o $(OSMESA_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
- -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
+ -major 6 -minor 5 -patch 3 \
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
-id $(INSTALL_LIB_DIR)/lib$(OSMESA_LIB).$(MESA_MAJOR).dylib \
$(OSMESA_LIB_DEPS) $(OBJECTS)
@@ -58,7 +58,7 @@ $(TOP)/lib/$(OSMESA_LIB_NAME): $(OBJECTS
# with all the other Mesa sources (compiled with -DCHAN_BITS=16/32
osmesa16: $(OBJECTS) $(CORE_MESA)
$(MKLIB) -o $(OSMESA_LIB) -linker '$(CC)' -ldflags '$(LDFLAGS)' \
- -major $(MESA_MAJOR) -minor $(MESA_MINOR) -patch $(MESA_TINY) \
+ -major 6 -minor 5 -patch 3 \
-install $(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
-id $(INSTALL_LIB_DIR)/lib$(OSMESA_LIB).$(MESA_MAJOR).dylib \
$(OSMESA_LIB_DEPS) $(OBJECTS) $(CORE_MESA)

View File

@ -0,0 +1,15 @@
diff -up Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c.intel-glthread Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c
--- Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c.intel-glthread 2008-08-25 10:49:40.000000000 -0400
+++ Mesa-7.1/src/mesa/drivers/dri/intel/intel_fbo.c 2008-08-28 14:26:17.000000000 -0400
@@ -633,11 +633,6 @@ intel_render_texture(GLcontext * ctx,
return;
}
- DBG("Begin render texture tid %x tex=%u w=%d h=%d refcount=%d\n",
- _glthread_GetID(),
- att->Texture->Name, newImage->Width, newImage->Height,
- irb->Base.RefCount);
-
/* point the renderbufer's region to the texture image region */
intel_image = intel_texture_image(newImage);
if (irb->region != intel_image->mt->region) {

View File

@ -0,0 +1,102 @@
diff -Naur Mesa-7.4.1/src/mesa/drivers/dri/Makefile Mesa-7.4.1.patch/src/mesa/drivers/dri/Makefile
--- Mesa-7.4.1/src/mesa/drivers/dri/Makefile 2009-03-13 04:28:49.000000000 +0100
+++ Mesa-7.4.1.patch/src/mesa/drivers/dri/Makefile 2009-04-25 22:26:13.000000000 +0200
@@ -6,12 +6,16 @@
-default: $(TOP)/$(LIB_DIR) subdirs
-
+default: $(TOP)/$(LIB_DIR) $(TOP)/$(LIB_DIR)/libdricore.so subdirs
$(TOP)/$(LIB_DIR):
-mkdir $(TOP)/$(LIB_DIR)
+libdricore.so:
+ $(CC) -shared -o libdricore.so -Wl,--whole-archive ../../libmesa.a -Wl,--no-whole-archive -lm -lpthread -lc
+
+$(TOP)/$(LIB_DIR)/libdricore.so: $(TOP)/$(LIB_DIR) libdricore.so
+ $(INSTALL) libdricore.so $(TOP)/$(LIB_DIR)
subdirs:
@for dir in $(DRI_DIRS) ; do \
@@ -32,12 +36,14 @@
$(pcedit) $< > $@
-install: dri.pc
+install: dri.pc $(TOP)/$(LIB_DIR)/libdricore.so
@for dir in $(DRI_DIRS) ; do \
if [ -d $$dir ] ; then \
(cd $$dir && $(MAKE) install) || exit 1 ; \
fi \
done
+ $(INSTALL) -d $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
+ $(INSTALL) -m 755 $(TOP)/$(LIB_DIR)/libdricore.so $(DESTDIR)$(DRI_DRIVER_INSTALL_DIR)
$(INSTALL) -d $(DESTDIR)$(INSTALL_INC_DIR)/GL/internal
$(INSTALL) -m 0644 $(TOP)/include/GL/internal/dri_interface.h \
$(DESTDIR)$(INSTALL_INC_DIR)/GL/internal
@@ -51,5 +57,6 @@
(cd $$dir && $(MAKE) clean) ; \
fi \
done
+ -rm -f libdricore.so $(TOP)/$(LIB_DIR)/libdricore.so
-rm -f common/*.o
-rm -f *.pc
diff -Naur Mesa-7.4.1/src/mesa/drivers/dri/Makefile.template Mesa-7.4.1.patch/src/mesa/drivers/dri/Makefile.template
--- Mesa-7.4.1/src/mesa/drivers/dri/Makefile.template 2009-03-13 04:28:49.000000000 +0100
+++ Mesa-7.4.1.patch/src/mesa/drivers/dri/Makefile.template 2009-04-25 22:22:59.000000000 +0200
@@ -1,6 +1,6 @@
# -*-makefile-*-
-MESA_MODULES = $(TOP)/src/mesa/libmesa.a
+MESA_MODULES = $(TOP)/$(LIB_DIR)/libdricore.so
COMMON_SOURCES = \
../common/utils.c \
@@ -61,7 +61,9 @@
$(LIBNAME): $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile $(TOP)/src/mesa/drivers/dri/Makefile.template
$(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
- $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(DRI_LIB_DEPS)
+ $(OBJECTS) $(WINOBJ) \
+ -L$(TOP)/$(LIB_DIR) -Wl,-R$(DRI_DRIVER_INSTALL_DIR) -ldricore \
+ $(DRI_LIB_DEPS)
$(TOP)/$(LIB_DIR)/$(LIBNAME): $(LIBNAME)
diff -Naur Mesa-7.4.1/src/mesa/x86/read_rgba_span_x86.S Mesa-7.4.1.patch/src/mesa/x86/read_rgba_span_x86.S
--- Mesa-7.4.1/src/mesa/x86/read_rgba_span_x86.S 2008-08-25 16:46:47.000000000 +0200
+++ Mesa-7.4.1.patch/src/mesa/x86/read_rgba_span_x86.S 2009-04-25 22:20:15.000000000 +0200
@@ -77,7 +77,6 @@
*/
.globl _generic_read_RGBA_span_BGRA8888_REV_MMX
-.hidden _generic_read_RGBA_span_BGRA8888_REV_MMX
.type _generic_read_RGBA_span_BGRA8888_REV_MMX, @function
_generic_read_RGBA_span_BGRA8888_REV_MMX:
pushl %ebx
@@ -172,7 +171,6 @@
*/
.globl _generic_read_RGBA_span_BGRA8888_REV_SSE
-.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE
.type _generic_read_RGBA_span_BGRA8888_REV_SSE, @function
_generic_read_RGBA_span_BGRA8888_REV_SSE:
pushl %esi
@@ -335,7 +333,6 @@
.text
.globl _generic_read_RGBA_span_BGRA8888_REV_SSE2
-.hidden _generic_read_RGBA_span_BGRA8888_REV_SSE2
.type _generic_read_RGBA_span_BGRA8888_REV_SSE2, @function
_generic_read_RGBA_span_BGRA8888_REV_SSE2:
pushl %esi
@@ -494,7 +491,6 @@
.text
.globl _generic_read_RGBA_span_RGB565_MMX
- .hidden _generic_read_RGBA_span_RGB565_MMX
.type _generic_read_RGBA_span_RGB565_MMX, @function
_generic_read_RGBA_span_RGB565_MMX:

View File

@ -0,0 +1,21 @@
commit 532d2051245a1d8afe7ca236f1d966d555bb121a
Author: Dave Airlie <airlied@linux.ie>
Date: Fri Sep 12 17:21:25 2008 +1000
Revert "intel: sync to vblank by default"
This reverts commit e9bf3e4cc9a7e4bcd4c45bd707541d26ecdf0409.
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index c193830..f02192d 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -55,7 +55,7 @@ PUBLIC const char __driConfigOptions[] =
DRI_CONF_BEGIN
DRI_CONF_SECTION_PERFORMANCE
DRI_CONF_FTHROTTLE_MODE(DRI_CONF_FTHROTTLE_IRQS)
- DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_ALWAYS_SYNC)
+ DRI_CONF_VBLANK_MODE(DRI_CONF_VBLANK_DEF_INTERVAL_0)
/* Options correspond to DRI_CONF_BO_REUSE_DISABLED,
* DRI_CONF_BO_REUSE_ALL
*/

View File

@ -0,0 +1,15 @@
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index cf09fad..572a28b 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -583,8 +583,8 @@ intel_init_bufmgr(intelScreenPrivate *intelScreen)
if (gem_disable) {
fprintf(stderr, "GEM disabled. Using classic.\n");
} else {
- fprintf(stderr, "Failed to initialize GEM. "
- "Falling back to classic.\n");
+// fprintf(stderr, "Failed to initialize GEM. "
+// "Falling back to classic.\n");
}
if (intelScreen->tex.size == 0) {

View File

@ -0,0 +1,586 @@
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/atombios_crtc.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/atombios_crtc.c
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/atombios_crtc.c.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/atombios_crtc.c 2009-03-03 20:53:05.000000000 +0000
@@ -441,14 +441,23 @@ static bool atombios_crtc_mode_fixup(str
static void atombios_crtc_prepare(struct drm_crtc *crtc)
{
+ struct drm_device *dev = crtc->dev;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev_priv->mode_info.power.pll_mutex);
+
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
atombios_lock_crtc(crtc, 1);
}
static void atombios_crtc_commit(struct drm_crtc *crtc)
{
+ struct drm_device *dev = crtc->dev;
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+
atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON);
atombios_lock_crtc(crtc, 0);
+ mutex_unlock(&dev_priv->mode_info.power.pll_mutex);
}
static const struct drm_crtc_helper_funcs atombios_helper_funcs = {
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_atombios.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_atombios.c
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_atombios.c.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_atombios.c 2009-03-03 20:53:05.000000000 +0000
@@ -620,6 +620,34 @@ void radeon_atom_static_pwrmgt_setup(str
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
+void radeon_atom_get_mc_arb_info(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_mode_info *mode_info = &dev_priv->mode_info;
+ struct atom_context *ctx = mode_info->atom_context;
+ int index = GetIndexIntoMasterTable(DATA, MC_InitParameter);
+ uint8_t frev, crev;
+ uint16_t size, data_offset;
+
+ atom_parse_data_header(ctx, index, &size, &frev, &crev, &data_offset);
+ dev_priv->mode_info.power.mc_arb_init_values =
+ kmalloc(size*sizeof(int), GFP_KERNEL);
+ memcpy(dev_priv->mode_info.power.mc_arb_init_values,
+ ctx->bios + data_offset, size * sizeof(int));
+}
+
+void radeon_atom_get_engine_clock(struct drm_device *dev, int *engine_clock)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_mode_info *mode_info = &dev_priv->mode_info;
+ struct atom_context *ctx = mode_info->atom_context;
+ GET_ENGINE_CLOCK_PS_ALLOCATION args;
+ int index = GetIndexIntoMasterTable(COMMAND, GetEngineClock);
+
+ atom_execute_table(ctx, index, (uint32_t *)&args);
+ *engine_clock = args.ulReturnEngineClock;
+}
+
void radeon_atom_set_engine_clock(struct drm_device *dev, int eng_clock)
{
struct drm_radeon_private *dev_priv = dev->dev_private;
@@ -633,6 +661,18 @@ void radeon_atom_set_engine_clock(struct
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
+void radeon_atom_get_memory_clock(struct drm_device *dev, int *mem_clock)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct radeon_mode_info *mode_info = &dev_priv->mode_info;
+ struct atom_context *ctx = mode_info->atom_context;
+ GET_MEMORY_CLOCK_PS_ALLOCATION args;
+ int index = GetIndexIntoMasterTable(COMMAND, GetMemoryClock);
+
+ atom_execute_table(ctx, index, (uint32_t *)&args);
+ *mem_clock = args.ulReturnMemoryClock;
+}
+
void radeon_atom_set_memory_clock(struct drm_device *dev, int mem_clock)
{
struct drm_radeon_private *dev_priv = dev->dev_private;
@@ -646,6 +686,16 @@ void radeon_atom_set_memory_clock(struct
atom_execute_table(dev_priv->mode_info.atom_context, index, (uint32_t *)&args);
}
+void radeon_atom_initialize_memory_controller(struct drm_device *dev)
+{
+ struct drm_radeon_private *dev_priv = dev->dev_private;
+ struct atom_context *ctx = dev_priv->mode_info.atom_context;
+ int index = GetIndexIntoMasterTable(COMMAND, MemoryDeviceInit);
+ MEMORY_PLLINIT_PS_ALLOCATION args;
+
+ atom_execute_table(ctx, index, (uint32_t *)&args);
+}
+
void radeon_atom_initialize_bios_scratch_regs(struct drm_device *dev)
{
struct drm_radeon_private *dev_priv = dev->dev_private;
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cp.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cp.c
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cp.c.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cp.c 2009-03-03 20:53:05.000000000 +0000
@@ -3223,6 +3223,8 @@ int radeon_driver_load(struct drm_device
if (ret)
goto modeset_fail;
+ mutex_init(&dev_priv->mode_info.power.pll_mutex);
+
radeon_modeset_init(dev);
radeon_modeset_cp_init(dev);
@@ -3231,7 +3233,7 @@ int radeon_driver_load(struct drm_device
drm_irq_install(dev);
}
-
+ radeon_pm_init(dev);
return ret;
modeset_fail:
dev->driver->driver_features &= ~DRIVER_MODESET;
@@ -3303,6 +3305,8 @@ int radeon_driver_unload(struct drm_devi
{
drm_radeon_private_t *dev_priv = dev->dev_private;
+ radeon_pm_exit(dev);
+
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
drm_irq_uninstall(dev);
radeon_modeset_cleanup(dev);
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cs.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cs.c
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cs.c.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_cs.c 2009-03-03 20:53:05.000000000 +0000
@@ -41,6 +41,8 @@ int radeon_cs_ioctl(struct drm_device *d
long size;
int r, i;
+ radeon_pm_timer_reset(dev);
+
mutex_lock(&dev_priv->cs.cs_mutex);
/* set command stream id to 0 which is fake id */
cs_id = 0;
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_drv.h.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_drv.h
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_drv.h.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_drv.h 2009-03-03 20:53:05.000000000 +0000
@@ -612,6 +612,9 @@ extern int radeon_modeset_cp_resume(stru
/* radeon_pm.c */
int radeon_suspend(struct drm_device *dev, pm_message_t state);
int radeon_resume(struct drm_device *dev);
+void radeon_pm_init(struct drm_device *dev);
+void radeon_pm_exit(struct drm_device *dev);
+void radeon_pm_timer_reset(struct drm_device *dev);
/* Flags for stats.boxes
*/
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_irq.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_irq.c
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_irq.c.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_irq.c 2009-03-03 20:53:05.000000000 +0000
@@ -185,8 +185,10 @@ irqreturn_t radeon_driver_irq_handler(DR
struct drm_device *dev = (struct drm_device *) arg;
drm_radeon_private_t *dev_priv =
(drm_radeon_private_t *) dev->dev_private;
+ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power;
u32 stat;
u32 r500_disp_int;
+ unsigned long flags;
/* Only consider the bits we're interested in - others could be used
* outside the DRM
@@ -206,15 +208,47 @@ irqreturn_t radeon_driver_irq_handler(DR
/* VBLANK interrupt */
if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
- if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
+ if (r500_disp_int & R500_D1_VBLANK_INTERRUPT) {
+ spin_lock_irqsave(&power->power_lock, flags);
+ if (power->reclock_head & 1) {
+ power->reclock_head &= ~1;
+ schedule_work(&power->reclock_work);
+ drm_vblank_put(dev, 0);
+ }
+ spin_unlock_irqrestore(&power->power_lock, flags);
drm_handle_vblank(dev, 0);
- if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
+ }
+ if (r500_disp_int & R500_D2_VBLANK_INTERRUPT) {
+ spin_lock_irqsave(&power->power_lock, flags);
+ if (power->reclock_head & 2) {
+ power->reclock_head &= ~2;
+ schedule_work(&power->reclock_work);
+ drm_vblank_put(dev, 1);
+ }
+ spin_unlock_irqrestore(&power->power_lock, flags);
drm_handle_vblank(dev, 1);
+ }
} else {
- if (stat & RADEON_CRTC_VBLANK_STAT)
+ if (stat & RADEON_CRTC_VBLANK_STAT) {
+ spin_lock_irqsave(&power->power_lock, flags);
+ if (power->reclock_head & 1) {
+ power->reclock_head &= ~1;
+ schedule_work(&power->reclock_work);
+ drm_vblank_put(dev, 0);
+ }
+ spin_unlock_irqrestore(&power->power_lock, flags);
drm_handle_vblank(dev, 0);
- if (stat & RADEON_CRTC2_VBLANK_STAT)
+ }
+ if (stat & RADEON_CRTC2_VBLANK_STAT) {
+ spin_lock_irqsave(&power->power_lock, flags);
+ if (power->reclock_head & 2) {
+ power->reclock_head &= ~2;
+ schedule_work(&power->reclock_work);
+ drm_vblank_put(dev, 1);
+ }
+ spin_unlock_irqrestore(&power->power_lock, flags);
drm_handle_vblank(dev, 1);
+ }
}
return IRQ_HANDLED;
}
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_mode.h.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_mode.h
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_mode.h.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_mode.h 2009-03-03 20:53:05.000000000 +0000
@@ -173,6 +173,22 @@ struct radeon_i2c_chan {
struct radeon_i2c_bus_rec rec;
};
+struct radeon_powermanagement_info {
+ struct timer_list idle_power_timer;
+ struct work_struct reclock_work;
+ struct drm_device *dev;
+ uint32_t orig_memory_clock;
+ uint32_t orig_engine_clock;
+ uint32_t *mc_arb_init_values;
+ uint8_t orig_fbdiv;
+ int new_mem_clock;
+ int new_engine_clock;
+ int current_clock_state;
+ int reclock_head;
+ struct mutex pll_mutex;
+ spinlock_t power_lock;
+};
+
struct radeon_mode_info {
struct atom_context *atom_context;
struct radeon_bios_connector bios_connector[RADEON_MAX_BIOS_CONNECTOR];
@@ -182,6 +198,9 @@ struct radeon_mode_info {
struct radeon_pll mpll;
uint32_t mclk;
uint32_t sclk;
+
+ /* power management */
+ struct radeon_powermanagement_info power;
};
struct radeon_crtc {
@@ -307,6 +326,12 @@ extern int radeon_crtc_cursor_move(struc
extern bool radeon_atom_get_clock_info(struct drm_device *dev);
extern bool radeon_combios_get_clock_info(struct drm_device *dev);
+extern void radeon_atom_get_engine_clock(struct drm_device *dev, int *engine_clock);
+extern void radeon_atom_get_memory_clock(struct drm_device *dev, int *memory_clock);
+extern void radeon_atom_set_engine_clock(struct drm_device *dev, int engine_clock);
+extern void radeon_atom_set_memory_clock(struct drm_device *dev, int memory_clock);
+extern void radeon_atom_initialize_memory_controller(struct drm_device *dev);
+extern void radeon_atom_get_mc_arb_info(struct drm_device *dev);
extern void radeon_atombios_get_lvds_info(struct radeon_encoder *encoder);
extern void radeon_atombios_get_tmds_info(struct radeon_encoder *encoder);
extern bool radeon_combios_get_lvds_info(struct radeon_encoder *encoder);
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_pm.c.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_pm.c
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_pm.c.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_pm.c 2009-03-03 20:53:05.000000000 +0000
@@ -31,6 +31,8 @@
#include "drm_crtc_helper.h"
+#define RADEON_DOWNCLOCK_IDLE_MS 30
+
int radeon_suspend(struct drm_device *dev, pm_message_t state)
{
struct drm_radeon_private *dev_priv = dev->dev_private;
@@ -255,3 +257,214 @@ bool radeon_set_pcie_lanes(struct drm_de
return false;
}
+static void radeon_pm_set_engine_clock(struct drm_device *dev, int freq)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ if (dev_priv->is_atom_bios)
+ radeon_atom_set_engine_clock(dev, freq);
+}
+
+static void radeon_pm_set_memory_clock(struct drm_device *dev, int freq)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power;
+
+ mutex_lock(&power->pll_mutex);
+ radeon_do_cp_idle(dev_priv);
+ if (dev_priv->is_atom_bios) {
+ int mpll, spll, hclk, sclk, fbdiv, index, factor;
+ switch (dev_priv->chip_family) {
+ case CHIP_R520:
+ case CHIP_RV530:
+ case CHIP_RV560:
+ case CHIP_RV570:
+ case CHIP_R580:
+ mpll = RADEON_READ_PLL(dev_priv, MPLL_FUNC_CNTL);
+ fbdiv = (mpll & 0x1fe0) >> 5;
+
+ /* Set new fbdiv */
+ factor = power->orig_memory_clock / freq;
+ fbdiv = power->orig_fbdiv / factor;
+
+ mpll &= ~0x1fe0;
+ mpll |= ((fbdiv << 5) | (1 << 24));
+ mpll &= ~(1 << 25);
+
+ spll = RADEON_READ_PLL(dev_priv, SPLL_FUNC_CNTL);
+
+ hclk = fbdiv << 5;
+ hclk += 0x20;
+ hclk *= 8;
+
+ sclk = spll & 0x1fe0;
+ sclk += 0x20;
+ sclk *= 6;
+ sclk = sclk >> 5;
+
+ index = (hclk/sclk);
+
+ R500_WRITE_MCIND(R530_MC_ARB_RATIO_CLK_SEQ,
+ power->mc_arb_init_values[index]);
+ RADEON_WRITE_PLL(dev_priv, MPLL_FUNC_CNTL, mpll);
+ radeon_atom_initialize_memory_controller(dev);
+ break;
+ }
+ }
+
+ mutex_unlock(&power->pll_mutex);
+}
+
+static int radeon_pm_get_active_crtcs(struct drm_device *dev, int *crtcs)
+{
+ struct drm_crtc *crtc;
+ int count = 0;
+ struct radeon_crtc *radeon_crtc;
+
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+ radeon_crtc = to_radeon_crtc(crtc);
+ if (crtc->enabled) {
+ count++;
+ *crtcs |= (1 << radeon_crtc->crtc_id);
+ }
+ }
+ return count;
+}
+
+
+static void radeon_pm_perform_transition(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power;
+ int crtcs = 0, count;
+ unsigned long flags;
+
+ count = radeon_pm_get_active_crtcs(dev, &crtcs);
+
+ spin_lock_irqsave(&power->power_lock, flags);
+ switch (count) {
+ case 0:
+ schedule_work(&power->reclock_work);
+ break;
+ case 1:
+ if (power->reclock_head)
+ break;
+ if (crtcs & 1) {
+ power->reclock_head |= 1;
+ drm_vblank_get(dev, 0);
+ } else {
+ power->reclock_head |= 2;
+ drm_vblank_get(dev, 1);
+ }
+ break;
+ default:
+ /* Too many active heads */
+ break;
+ }
+ spin_unlock_irqrestore(&power->power_lock, flags);
+}
+
+
+static int radeon_pm_set_runtime_power(struct drm_device *dev, int value)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power;
+
+ if (power->current_clock_state == value)
+ return 1;
+
+ switch (value) {
+ case 0:
+ power->new_engine_clock = 100*100;
+ power->new_mem_clock = 100*100;
+ break;
+ case 1:
+ power->new_engine_clock = power->orig_engine_clock;
+ power->new_mem_clock = power->orig_memory_clock;
+ break;
+ }
+
+ power->current_clock_state = value;
+ radeon_pm_perform_transition(dev);
+
+ return 0;
+}
+
+static void radeon_pm_idle_timeout(unsigned long d)
+{
+ struct drm_device *dev = (struct drm_device *)d;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ radeon_pm_set_runtime_power(dev, 0);
+}
+
+static void radeon_pm_reclock_callback(struct work_struct *work)
+{
+ struct radeon_powermanagement_info *power =
+ container_of(work, struct radeon_powermanagement_info,
+ reclock_work);
+ struct drm_device *dev = power->dev;
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+
+ mutex_lock(&dev_priv->cs.cs_mutex);
+ radeon_pm_set_memory_clock(dev, power->new_mem_clock);
+ radeon_pm_set_engine_clock(dev, power->new_engine_clock);
+ mutex_unlock(&dev_priv->cs.cs_mutex);
+}
+
+void radeon_pm_timer_reset(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return;
+
+ radeon_pm_set_runtime_power(dev, 1);
+
+ mod_timer(&power->idle_power_timer,
+ jiffies + msecs_to_jiffies(RADEON_DOWNCLOCK_IDLE_MS));
+}
+
+void radeon_pm_init(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power;
+
+ power->dev = dev;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return;
+
+ if (dev_priv->is_atom_bios) {
+ int mpll;
+ radeon_atom_get_mc_arb_info(dev);
+ radeon_atom_get_engine_clock(dev, &power->orig_engine_clock);
+ radeon_atom_get_memory_clock(dev, &power->orig_memory_clock);
+
+ mpll = RADEON_READ_PLL(dev_priv, MPLL_FUNC_CNTL);
+ dev_priv->mode_info.power.orig_fbdiv = (mpll & 0x1fe0) >> 5;
+ }
+
+ setup_timer(&power->idle_power_timer, radeon_pm_idle_timeout,
+ (unsigned long)dev);
+ INIT_WORK(&power->reclock_work, radeon_pm_reclock_callback);
+
+ spin_lock_init(&power->power_lock);
+
+ power->current_clock_state = 1;
+ power->reclock_head = 0;
+
+ radeon_pm_timer_reset(dev);
+}
+
+void radeon_pm_exit(struct drm_device *dev)
+{
+ drm_radeon_private_t *dev_priv = dev->dev_private;
+ struct radeon_powermanagement_info *power = &dev_priv->mode_info.power;
+
+ if (!drm_core_check_feature(dev, DRIVER_MODESET))
+ return;
+
+ del_timer_sync(&power->idle_power_timer);
+}
diff -up linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_reg.h.mjg linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_reg.h
--- linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_reg.h.mjg 2009-03-03 19:41:48.000000000 +0000
+++ linux-2.6.28.x86_64/drivers/gpu/drm/radeon/radeon_reg.h 2009-03-03 20:53:05.000000000 +0000
@@ -303,6 +303,28 @@
# define RADEON_PLL_WR_EN (1 << 7)
# define RADEON_PLL_DIV_SEL (3 << 8)
# define RADEON_PLL2_DIV_SEL_MASK ~(3 << 8)
+#define SPLL_FUNC_CNTL 0x0000
+#define MPLL_FUNC_CNTL 0x0004
+#define GENERAL_PWRMGT 0x0008
+# define RADEON_GLOBAL_PWRMGT_EN (1 << 0)
+#define SCLK_PWRMGT_CNTL 0x0009
+# define RADEON_SCLK_PWRMGT_OFF (1 << 0)
+#define MCLK_PWRMGT_CNTL 0x000a
+# define RADEON_MCLK_PWRMGT_OFF (1 << 0)
+#define DYN_PWRMGT_SCLK_CNTL 0x000b
+# define RADEON_ENGINE_DYNCLK_MODE (1 << 0)
+# define RADEON_STATIC_SCREEN_EN (1 << 20)
+# define RADEON_CLIENT_SELECT_POWER_EN (1 << 21)
+#define DYN_SCLK_PWMEN_PIPE 0x000d
+# define RADEON_PIPE_3D_NOT_AUTO (1 << 8)
+#define DYN_SCLK_VOL_CNTL 0x000e
+# define RADEON_IO_CG_VOLTAGE_DROP (1 << 0)
+# define RADEON_VOLTAGE_DROP_SYNC (1 << 2)
+#define CP_DYN_CNTL 0x000f
+# define RADEON_CP_FORCEON (1 << 0)
+# define RADEON_CP_LOWER_POWER_IGNORE (1 << 20)
+# define RADEON_CP_NORMAL_POWER_IGNORE (1 << 21)
+# define RADEON_CP_NORMAL_POWER_BUSY (1 << 24)
#define RADEON_CLK_PWRMGT_CNTL 0x0014
# define RADEON_ENGIN_DYNCLK_MODE (1 << 12)
# define RADEON_ACTIVE_HILO_LAT_MASK (3 << 13)
@@ -3961,7 +3983,48 @@
# define AVIVO_I2C_RESET (1 << 8)
#define R600_GENERAL_PWRMGT 0x618
+# define R600_GLOBAL_PWRMGT_EN (1 << 0)
+# define R600_STATIC_PM_EN (1 << 1)
+# define R600_MOBILE_SU (1 << 2)
+# define R600_THERMAL_PROTECTION_DIS (1 << 3)
+# define R600_THERMAL_PROTECTION_TYPE (1 << 4)
+# define R600_ENABLE_GEN2PCIE (1 << 5)
+# define R600_SW_GPIO_INDEX (1 << 6)
+# define R600_LOW_VOLT_D2_ACPI (1 << 8)
+# define R600_LOW_VOLT_D3_ACPI (1 << 9)
+# define R600_VOLT_PWRMGT_EN (1 << 10)
# define R600_OPEN_DRAIN_PADS (1 << 11)
+# define R600_AVP_SCLK_EN (1 << 12)
+# define R600_IDCT_SCLK_EN (1 << 13)
+# define R600_GPU_COUNTER_ACPI (1 << 14)
+# define R600_COUNTER_CLK (1 << 15)
+# define R600_BACKBIAS_PAD_EN (1 << 16)
+# define R600_BACKBIAS_VALUE (1 << 17)
+# define R600_BACKBIAS_DPM_CNTL (1 << 18)
+# define R600_SPREAD_SPECTRUM_INDEX (1 << 19)
+# define R600_DYN_SPREAD_SPECTRUM_EN (1 << 21)
+
+#define R600_SCLK_PWRMGT_CNTL 0x620
+# define R600_SCLK_PWRMGT_OFF (1 << 0)
+# define R600_SCLK_TURNOFF (1 << 1)
+# define R600_SPLL_TURNOFF (1 << 2)
+# define R600_SU_SCLK_USE_BCLK (1 << 3)
+# define R600_DYNAMIC_GFX_ISLAND_PWR_DOWN (1 << 4)
+# define R600_DYNAMIC_GFX_ISLAND_LP (1 << 5)
+# define R600_CLK_TURN_ON_STAGGER (1 << 6)
+# define R600_CLK_TURN_OFF_STAGGER (1 << 7)
+# define R600_FIR_FORCE_TREND_SEL (1 << 8)
+# define R600_FIR_TREND_MODE (1 << 9)
+# define R600_DYN_GFX_CLK_OFF_EN (1 << 10)
+# define R600_VDDC3D_TURNOFF_D1 (1 << 11)
+# define R600_VDDC3D_TURNOFF_D2 (1 << 12)
+# define R600_VDDC3D_TURNOFF_D3 (1 << 13)
+# define R600_SPLL_TURNOFF_D2 (1 << 14)
+# define R600_SCLK_LOW_D1 (1 << 15)
+# define R600_DYN_GFX_CLK_OFF_MC_EN (1 << 16)
+
+#define R600_MCLK_PWRMGT_CNTL 0x624
+# define R600_MPLL_PWRMGT_OFF (1 << 0)
#define R600_LOWER_GPIO_ENABLE 0x710
#define R600_CTXSW_VID_LOWER_GPIO_CNTL 0x718
@@ -5331,5 +5394,6 @@
# define R500_RS_IP_OFFSET_EN (1 << 31)
#define R500_DYN_SCLK_PWMEM_PIPE 0x000d /* PLL */
+#define R530_MC_ARB_RATIO_CLK_SEQ 0x0016 /* MC */
#endif

View File

@ -1196,11 +1196,11 @@ CONFIG_HPET_MMAP=y
# CONFIG_TCG_TPM is not set
# CONFIG_TELCLOCK is not set
CONFIG_DEVPORT=y
CONFIG_I2C=m
CONFIG_I2C=y
CONFIG_I2C_BOARDINFO=y
CONFIG_I2C_CHARDEV=m
CONFIG_I2C_HELPER_AUTO=y
CONFIG_I2C_ALGOBIT=m
CONFIG_I2C_ALGOBIT=y
#
# I2C Hardware Bus support
@ -1386,7 +1386,9 @@ CONFIG_SSB_DRIVER_PCICORE=y
# CONFIG_HTC_PASIC3 is not set
# CONFIG_UCB1400_CORE is not set
# CONFIG_TPS65010 is not set
# CONFIG_TWL4030_CORE is not set
# CONFIG_MFD_TMIO is not set
# CONFIG_PMIC_DA903X is not set
# CONFIG_MFD_WM8400 is not set
# CONFIG_MFD_WM8350_I2C is not set
# CONFIG_MFD_PCF50633 is not set
@ -1711,7 +1713,7 @@ CONFIG_DAB=y
#
# Graphics support
#
CONFIG_AGP=m
CONFIG_AGP=y
CONFIG_AGP_ALI=m
CONFIG_AGP_ATI=m
CONFIG_AGP_AMD=m
@ -1722,18 +1724,21 @@ CONFIG_AGP_SIS=m
CONFIG_AGP_SWORKS=m
CONFIG_AGP_VIA=m
CONFIG_AGP_EFFICEON=m
CONFIG_DRM=m
CONFIG_DRM=y
# CONFIG_DRM_TDFX is not set
# CONFIG_DRM_R128 is not set
CONFIG_DRM_RADEON=m
CONFIG_DRM_RADEON_KMS=y
CONFIG_DRM_I810=m
CONFIG_DRM_I830=m
CONFIG_DRM_I915=m
# CONFIG_DRM_I915_KMS is not set
CONFIG_DRM_I915_KMS=y
# CONFIG_DRM_MGA is not set
CONFIG_DRM_SIS=m
# CONFIG_DRM_SIS is not set
CONFIG_DRM_VIA=m
CONFIG_DRM_SAVAGE=m
# CONFIG_DRM_SAVAGE is not set
CONFIG_DRM_NOUVEAU=m
CONFIG_DRM_NOUVEAU_KMS=y
# CONFIG_VGASTATE is not set
CONFIG_VIDEO_OUTPUT_CONTROL=y
CONFIG_FB=y

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,50 @@
http://lists.freedesktop.org/archives/intel-gfx/2009-February/001313.html
--- a/drivers/gpu/drm/i915/i915_suspend.c.orig 2009-02-18 22:59:19.000000000 -0500
+++ b/drivers/gpu/drm/i915/i915_suspend.c 2009-02-18 22:59:58.000000000 -0500
@@ -28,6 +28,7 @@
#include "drm.h"
#include "i915_drm.h"
#include "i915_drv.h"
+#include <drm/drm_crtc_helper.h>
static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
{
@@ -519,6 +520,8 @@
i915_restore_vga(dev);
+ drm_helper_resume_force_mode(dev);
+
return 0;
}
From f5192bce8be69e5b33d7579bc282fef4d673e2c1 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkundrak@v3.sk>
Date: Sun, 15 Mar 2009 13:55:55 +0100
Subject: [PATCH] Fix i915 nomodeset NULL deref. during PM resume
drm_helper_resume_force_mode() would crash while attempting to
iterate through crtc_list, which is uninitialized when is modesetting
disabled.
---
drivers/gpu/drm/i915/i915_suspend.c | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c
index ef5fb6e..b138032 100644
--- a/drivers/gpu/drm/i915/i915_suspend.c
+++ b/drivers/gpu/drm/i915/i915_suspend.c
@@ -520,7 +520,8 @@ int i915_restore_state(struct drm_device *dev)
i915_restore_vga(dev);
- drm_helper_resume_force_mode(dev);
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ drm_helper_resume_force_mode(dev);
return 0;
}
--
1.6.2

View File

@ -0,0 +1,16 @@
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 37427e4..08af9db 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2553,6 +2553,11 @@ i915_gem_execbuffer(struct drm_device *dev, void *data,
mutex_lock(&dev->struct_mutex);
+ /* We don't get the flushing right for these chipsets, use the
+ * big hamer for now to avoid random crashiness. */
+ if (IS_I855(dev) || IS_I865G(dev))
+ wbinvd();
+
i915_verify_inactive(dev, __FILE__, __LINE__);
if (dev_priv->mm.wedged) {

View File

@ -0,0 +1,95 @@
[PATCH] drm: ignore LVDS on intel graphics systems that lie about having it
There are a number of small form factor desktop systems with Intel mobile
graphics chips that lie and say they have an LVDS. With kernel mode-setting,
this becomes a problem, and makes native resolution boot go haywire -- for
example, my Dell Studio Hybrid, hooked to a 1920x1080 display claims to
have a 1024x768 LVDS, and the resulting graphical boot on the 1920x1080
display uses only the top left 1024x768, and auto-configured X will end
up only 1024x768 as well. With this change, graphical boot and X
both do 1920x1080 as expected.
Nb: one minor issue... Current Fedora rawhide, video playback using Xv
makes X go off into the weeds with this patch added... But that's a bug
elsewhere, still confident this patch DTRT.
Signed-off-by: Jarod Wilson <jarod@redhat.com>
---
drivers/gpu/drm/i915/intel_lvds.c | 46 ++++++++++++++++++++++++++++++------
1 files changed, 38 insertions(+), 8 deletions(-)
diff --git a/drivers/gpu/drm/i915/intel_lvds.c b/drivers/gpu/drm/i915/intel_lvds.c
index 6619f26..4d64686 100644
--- a/drivers/gpu/drm/i915/intel_lvds.c
+++ b/drivers/gpu/drm/i915/intel_lvds.c
@@ -384,7 +384,51 @@ static const struct drm_encoder_funcs intel_lvds_enc_funcs = {
.destroy = intel_lvds_enc_destroy,
};
+static int __init intel_no_lvds_dmi_callback(const struct dmi_system_id *id)
+{
+ DRM_DEBUG("Skipping LVDS initialization for %s\n", id->ident);
+ return 1;
+}
+/* These systems claim to have LVDS, but really don't */
+static const struct dmi_system_id __initdata intel_no_lvds[] = {
+ {
+ .callback = intel_no_lvds_dmi_callback,
+ .ident = "Apple Mac Mini (Core series)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Macmini1,1"),
+ },
+ },
+ {
+ .callback = intel_no_lvds_dmi_callback,
+ .ident = "Apple Mac Mini (Core 2 series)",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Apple Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Macmini2,1"),
+ },
+ },
+ {
+ .callback = intel_no_lvds_dmi_callback,
+ .ident = "MSI IM-945GSE-A",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "MSI"),
+ DMI_MATCH(DMI_PRODUCT_NAME, "A9830IMS"),
+ },
+ },
+ {
+ .callback = intel_no_lvds_dmi_callback,
+ .ident = "Dell Studio Hybrid",
+ .matches = {
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
+ DMI_MATCH(DMI_PRODUCT_NAME, "Studio Hybrid 140g"),
+ },
+ },
+
+ /* FIXME: add a check for the Aopen Mini PC */
+
+ { } /* terminating entry */
+};
/**
* intel_lvds_init - setup LVDS connectors on this device
@@ -404,15 +440,9 @@ void intel_lvds_init(struct drm_device *dev)
u32 lvds;
int pipe;
- /* Blacklist machines that we know falsely report LVDS. */
- /* FIXME: add a check for the Aopen Mini PC */
-
- /* Apple Mac Mini Core Duo and Mac Mini Core 2 Duo */
- if(dmi_match(DMI_PRODUCT_NAME, "Macmini1,1") ||
- dmi_match(DMI_PRODUCT_NAME, "Macmini2,1")) {
- DRM_DEBUG("Skipping LVDS initialization for Apple Mac Mini\n");
+ /* Skip init on machines we know falsely report LVDS */
+ if (dmi_check_system(intel_no_lvds))
return;
- }
intel_output = kzalloc(sizeof(struct intel_output), GFP_KERNEL);
if (!intel_output) {

View File

@ -0,0 +1,14 @@
diff -up linux-2.6.29.noarch/drivers/gpu/drm/i915/intel_display.c.jx linux-2.6.29.noarch/drivers/gpu/drm/i915/intel_display.c
--- linux-2.6.29.noarch/drivers/gpu/drm/i915/intel_display.c.jx 2009-04-09 13:42:51.000000000 -0400
+++ linux-2.6.29.noarch/drivers/gpu/drm/i915/intel_display.c 2009-04-09 13:44:14.000000000 -0400
@@ -2011,8 +2011,8 @@ void intel_modeset_init(struct drm_devic
dev->mode_config.max_width = 8192;
dev->mode_config.max_height = 8192;
} else {
- dev->mode_config.max_width = 2048;
- dev->mode_config.max_height = 2048;
+ dev->mode_config.max_width = 4096;
+ dev->mode_config.max_height = 4096;
}
/* set memory base */

View File

@ -0,0 +1,65 @@
From: Jesse Barnes <jbarnes@virtuousgeek.org>
Date: Tue, 14 Apr 2009 21:17:47 +0000 (-0700)
Subject: drm/i915: allow tiled front buffers on 965+
X-Git-Url: http://git.kernel.org/?p=linux%2Fkernel%2Fgit%2Fanholt%2Fdrm-intel.git;a=commitdiff_plain;h=f544847fbaf099278343f875987a983f2b913134
drm/i915: allow tiled front buffers on 965+
This patch corrects a pretty big oversight in the KMS code for 965+
chips. The current code is missing tiled surface register programming,
so userland can allocate a tiled surface and use it for mode setting,
resulting in corruption. This patch fixes that, allowing for tiled
front buffers on 965+.
Cc: stable@kernel.org
Tested-by: Arkadiusz Miskiewicz <arekm@maven.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Signed-off-by: Eric Anholt <eric@anholt.net>
---
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e805b59..5211947 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -1446,6 +1446,7 @@
#define DISPPLANE_NO_LINE_DOUBLE 0
#define DISPPLANE_STEREO_POLARITY_FIRST 0
#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
+#define DISPPLANE_TILED (1<<10)
#define DSPAADDR 0x70184
#define DSPASTRIDE 0x70188
#define DSPAPOS 0x7018C /* reserved */
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index c2c8e95..bdcda36 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -657,6 +657,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
int dspbase = (pipe == 0 ? DSPAADDR : DSPBADDR);
int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
+ int dsptileoff = (pipe == 0 ? DSPATILEOFF : DSPBTILEOFF);
int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
u32 dspcntr, alignment;
int ret;
@@ -733,6 +734,13 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
mutex_unlock(&dev->struct_mutex);
return -EINVAL;
}
+ if (IS_I965G(dev)) {
+ if (obj_priv->tiling_mode != I915_TILING_NONE)
+ dspcntr |= DISPPLANE_TILED;
+ else
+ dspcntr &= ~DISPPLANE_TILED;
+ }
+
I915_WRITE(dspcntr_reg, dspcntr);
Start = obj_priv->gtt_offset;
@@ -745,6 +753,7 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y,
I915_READ(dspbase);
I915_WRITE(dspsurf, Start);
I915_READ(dspsurf);
+ I915_WRITE(dsptileoff, (y << 16) | x);
} else {
I915_WRITE(dspbase, Start + Offset);
I915_READ(dspbase);

View File

@ -0,0 +1,20 @@
#!/bin/sh
. config/options
$SCRIPTS/build toolchain
$SCRIPTS/build $MESA
$SCRIPTS/build $LIBDRM
cd $BUILD/$1*
./configure --host=$TARGET_NAME \
--build=$HOST_NAME \
--prefix=/usr \
--sysconfdir=/etc \
--disable-static \
--enable-shared \
--with-xorg-module-dir=$XORG_PATH_MODULES
make
$STRIP src/.libs/*.so

View File

@ -0,0 +1,6 @@
#!/bin/sh
. config/options
mkdir -p $INSTALL/$XORG_PATH_MODULES/drivers
cp $BUILD/$1*/src/.libs/*_drv.so $INSTALL/$XORG_PATH_MODULES/drivers

View File

@ -0,0 +1,181 @@
From 98cd8bd95073e6248a0f63a2b5299736e6d097ef Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 19:12:25 +1000
Subject: [PATCH 1/6] kms/f11: hack in transition support without driver pixmaps
---
src/drmmode_display.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 142 insertions(+), 2 deletions(-)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index aa8befe..4909e51 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -185,6 +185,139 @@ drmmode_fb_pixmap(ScrnInfoPtr pScrn, int id, int *w, int *h)
}
static void
+drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id,
+ int src_id, int x, int y)
+{
+ drmModeFBPtr fb;
+ NVPtr pNv = NVPTR(pScrn);
+ char *dst = NULL, *src = NULL;
+ struct drm_nouveau_gem_mmap req;
+ int ret, h;
+
+ /* This is not what this should look like. Until we can do driver
+ * pixmaps, this will be a nasty hack!
+ */
+
+ fb = drmModeGetFB(nouveau_device(pNv->dev)->fd, src_id);
+ if (!fb) {
+ ErrorF("src fb\n");
+ return;
+ }
+
+ req.handle = fb->handle;
+ ret = drmCommandWriteRead(nouveau_device(pNv->dev)->fd,
+ DRM_NOUVEAU_GEM_MMAP, &req, sizeof(req));
+ if (ret) {
+ ErrorF("src bo map: %d\n", ret);
+ drmFree(fb);
+ return;
+ }
+ src = (void *)req.vaddr;
+
+ nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR);
+ dst = pNv->FB->map;
+ dst += (y * fb->pitch) + (x * (fb->bpp >> 3));
+
+ h = fb->height;
+ while (h--) {
+ memcpy(dst, src, fb->width * (fb->bpp >> 3));
+ src += fb->pitch;
+ dst += pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
+ }
+
+ nouveau_bo_unmap(pNv->FB);
+ drmFree(fb);
+}
+
+static void
+drmmode_fb_copy_nv50(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id,
+ int src_id, int x, int y)
+{
+ drmModeFBPtr fb;
+ NVPtr pNv = NVPTR(pScrn);
+ struct nouveau_channel *chan = pNv->chan;
+ struct nouveau_grobj *eng2d = pNv->Nv2D;
+ struct nouveau_bo *src = NULL, *dst = NULL;
+ struct drm_gem_flink req;
+ int ret;
+
+ /* This is not what this should look like. Until we can do driver
+ * pixmaps, this will be a nasty hack!
+ */
+
+ fb = drmModeGetFB(nouveau_device(pNv->dev)->fd, src_id);
+ if (!fb) {
+ ErrorF("src fb\n");
+ return;
+ }
+
+ req.handle = fb->handle;
+ ret = ioctl(nouveau_device(pNv->dev)->fd, DRM_IOCTL_GEM_FLINK, &req);
+ if (ret) {
+ ErrorF("name bo: %d\n", ret);
+ drmFree(fb);
+ return;
+ }
+
+ ret = nouveau_bo_handle_ref(pNv->dev, req.name, &src);
+ if (ret) {
+ ErrorF("src bo: %d\n", ret);
+ drmFree(fb);
+ return;
+ }
+
+ nouveau_bo_ref(pNv->scanout, &dst);
+
+ BEGIN_RING(chan, eng2d, 0x02ac, 1);
+ OUT_RING (chan, 3);
+ BEGIN_RING(chan, eng2d, 0x0200, 2);
+ OUT_RING (chan, pScrn->bitsPerPixel == 16 ? 0xe8 : 0xcf);
+ OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng2d, 0x0214, 5);
+ OUT_RING (chan, pScrn->displayWidth * (pScrn->bitsPerPixel >> 3));
+ OUT_RING (chan, pScrn->virtualX);
+ OUT_RING (chan, pScrn->virtualY);
+ OUT_RELOCh(chan, dst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, dst, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BEGIN_RING(chan, eng2d, 0x0280, 4);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, pScrn->virtualX);
+ OUT_RING (chan, pScrn->virtualY);
+ BEGIN_RING(chan, eng2d, 0x0230, 2);
+ OUT_RING (chan, fb->bpp == 16 ? 0xe8 : 0xcf);
+ OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng2d, 0x0244, 5);
+ OUT_RING (chan, fb->pitch);
+ OUT_RING (chan, fb->width);
+ OUT_RING (chan, fb->height);
+ OUT_RELOCh(chan, src, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, src, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ BEGIN_RING(chan, eng2d, 0x0110, 1);
+ OUT_RING (chan, 0);
+ BEGIN_RING(chan, eng2d, 0x08b0, 12);
+ OUT_RING (chan, x);
+ OUT_RING (chan, y);
+ OUT_RING (chan, fb->width);
+ OUT_RING (chan, fb->height);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ FIRE_RING (chan);
+
+ nouveau_bo_map(dst, NOUVEAU_BO_RD);
+ nouveau_bo_unmap(dst);
+ nouveau_bo_ref(NULL, &dst);
+ nouveau_bo_ref(NULL, &src);
+ drmFree(fb);
+}
+
+static void
drmmode_fb_copy(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, int src_id,
int x, int y)
{
@@ -194,6 +327,14 @@ drmmode_fb_copy(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id, int src_id,
PixmapPtr pspix, pdpix;
int w, h;
+ if (!pNv->exa_driver_pixmaps) {
+ if (pNv->NoAccel)
+ drmmode_fb_copy_sw(pScrn, drmmode, dst_id, src_id, x, y);
+ else
+ drmmode_fb_copy_nv50(pScrn, drmmode, dst_id, src_id, x, y);
+ return;
+ }
+
pspix = drmmode_fb_pixmap(pScrn, src_id, NULL, NULL);
if (!pspix)
return;
@@ -292,8 +433,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
if (drmmode_crtc->rotate_fb_id)
fb_id = drmmode_crtc->rotate_fb_id;
else
- if (fb_id != drmmode_crtc->mode_crtc->buffer_id &&
- pNv->exa_driver_pixmaps) {
+ if (fb_id != drmmode_crtc->mode_crtc->buffer_id) {
drmmode_fb_copy(pScrn, drmmode, fb_id,
drmmode_crtc->mode_crtc->buffer_id, x, y);
}
--
1.6.2.2

View File

@ -0,0 +1,51 @@
From 514eb5a03b8ca223a4d832e1675cda3a6a56b02d Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 19:13:26 +1000
Subject: [PATCH 2/6] bios/f11: store a copy of used vbios image in /var/run
---
src/nv_bios.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/src/nv_bios.c b/src/nv_bios.c
index ebf4027..ad4ff1f 100644
--- a/src/nv_bios.c
+++ b/src/nv_bios.c
@@ -22,6 +22,9 @@
* SOFTWARE.
*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "nv_include.h"
#if defined(__FreeBSD__) || defined(__NetBSD__)
@@ -4492,7 +4495,10 @@ uint8_t * nouveau_bios_embedded_edid(ScrnInfoPtr pScrn)
bool NVInitVBIOS(ScrnInfoPtr pScrn)
{
+ NVPtr pNv = NVPTR(pScrn);
struct nvbios *bios = &NVPTR(pScrn)->VBIOS;
+ char img[128];
+ int fd;
memset(bios, 0, sizeof(struct nvbios));
@@ -4503,6 +4509,13 @@ bool NVInitVBIOS(ScrnInfoPtr pScrn)
if (bios->length > NV_PROM_SIZE)
bios->length = NV_PROM_SIZE;
+ sprintf(img, "/var/run/nv%02x_%04x.rom", pNv->NVArch, pNv->Chipset);
+ fd = open(img, O_CREAT|O_RDWR|O_EXCL, 0700);
+ if (fd >= 0) {
+ write(fd, bios->data, bios->length);
+ close(fd);
+ }
+
return true;
}
--
1.6.2.2

View File

@ -0,0 +1,202 @@
From e278ea7300169355b17b17a785aef938c3fbc1e3 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 19:25:25 +1000
Subject: [PATCH 3/6] f11: hack to support multiple xserver instances
---
src/nv_driver.c | 126 ++++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 98 insertions(+), 28 deletions(-)
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 92232dd..9f4c96f 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -21,6 +21,7 @@
*/
#include <stdio.h>
+#include <sys/ioctl.h>
#include "nv_include.h"
@@ -654,14 +655,27 @@ NV50ReleaseDisplay(ScrnInfoPtr pScrn)
*/
/* Mandatory */
+static void NVMapMemGART(ScrnInfoPtr);
static Bool
NVEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
NVPtr pNv = NVPTR(pScrn);
+ int ret;
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "NVEnterVT is called.\n");
+ if (pNv->dev) {
+ ret = ioctl(nouveau_device(pNv->dev)->fd,
+ DRM_IOCTL_SET_MASTER, NULL);
+ if (ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unable to set master\n");
+ }
+
+ NVMapMemGART(pScrn);
+ }
+
if (!pNv->NoAccel)
NVAccelCommonInit(pScrn);
@@ -718,6 +732,12 @@ NVLeaveVT(int scrnIndex, int flags)
NVSync(pScrn);
+ if (pNv->dev) {
+ nouveau_bo_ref(NULL, &pNv->GART);
+
+ ioctl(nouveau_device(pNv->dev)->fd, DRM_IOCTL_DROP_MASTER, NULL);
+ }
+
if (!pNv->kms_enable) {
if (pNv->Architecture < NV_ARCH_50)
NVRestore(pScrn);
@@ -1629,11 +1649,81 @@ NVMapMemSW(ScrnInfoPtr pScrn)
}
static Bool
+NVMapMemSharedFB(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ uint64_t handle, size;
+ void *map;
+ int ret;
+
+ ret = nouveau_device_get_param(pNv->dev, 0xdeadcafe00000001, &handle);
+ if (ret)
+ return FALSE;
+
+ ret = nouveau_device_get_param(pNv->dev, 0xdeadcafe00000002, &size);
+ if (ret)
+ return FALSE;
+
+ if (nouveau_device(pNv->dev)->mm_enabled) {
+ ret = nouveau_bo_handle_ref(pNv->dev, handle, &pNv->FB);
+ if (ret) {
+ ErrorF("%d\n", ret);
+ return FALSE;
+ }
+
+ pNv->FB->size = size;
+ pNv->FB->tiled = (pNv->Architecture == NV_ARCH_50);
+ return TRUE;
+ }
+
+ ret = drmMap(nouveau_device(pNv->dev)->fd, handle >> 32, size, &map);
+ if (ret)
+ return FALSE;
+
+ ret = nouveau_bo_fake(pNv->dev, handle & 0xffffffff, NOUVEAU_BO_VRAM |
+ NOUVEAU_BO_PIN, size, map, &pNv->FB);
+ if (ret)
+ return FALSE;
+
+ pNv->FB->tiled = (pNv->Architecture == NV_ARCH_50);
+ return TRUE;
+}
+
+static void
+NVMapMemGART(ScrnInfoPtr pScrn) {
+ NVPtr pNv = NVPTR(pScrn);
+ int size;
+
+ if (pNv->AGPSize) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "AGPGART: %dMiB available\n",
+ (unsigned int)(pNv->AGPSize >> 20));
+ if (pNv->AGPSize > (16*1024*1024))
+ size = 16*1024*1024;
+ else
+ /* always leave 512kb for other things like the fifos */
+ size = pNv->AGPSize - 512*1024;
+ } else {
+ size = (4 << 20) - (1 << 18) ;
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "GART: PCI DMA - using %dKiB\n",
+ size >> 10);
+ }
+
+ if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_PIN, 0,
+ size, &pNv->GART)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unable to allocate GART memory\n");
+ }
+}
+
+static Bool
NVMapMem(ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
uint64_t res;
int size;
+ uint32_t flags;
if (!pNv->dev)
return NVMapMemSW(pScrn);
@@ -1650,46 +1740,26 @@ NVMapMem(ScrnInfoPtr pScrn)
size = size * (pScrn->bitsPerPixel >> 3);
size = size * pScrn->virtualY;
} else {
+ if (NVMapMemSharedFB(pScrn))
+ goto skip_fb;
size = pNv->VRAMPhysicalSize / 2;
}
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
- 0, size, &pNv->FB)) {
+ flags = NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN;
+ if (pNv->Architecture >= NV_ARCH_50)
+ flags |= NOUVEAU_BO_TILED;
+
+ if (nouveau_bo_new(pNv->dev, flags, 0, size, &pNv->FB)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to allocate framebuffer memory\n");
return FALSE;
}
+skip_fb:
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"Allocated %dMiB VRAM for framebuffer + offscreen pixmaps, "
"at offset 0x%X\n",
(uint32_t)(pNv->FB->size >> 20), (uint32_t) pNv->FB->offset);
- if (pNv->AGPSize) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "AGPGART: %dMiB available\n",
- (unsigned int)(pNv->AGPSize >> 20));
- if (pNv->AGPSize > (16*1024*1024))
- size = 16*1024*1024;
- else
- /* always leave 512kb for other things like the fifos */
- size = pNv->AGPSize - 512*1024;
- } else {
- size = (4 << 20) - (1 << 18) ;
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "GART: PCI DMA - using %dKiB\n",
- size >> 10);
- }
-
- if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_GART | NOUVEAU_BO_PIN, 0,
- size, &pNv->GART)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Unable to allocate GART memory\n");
- }
- if (pNv->GART) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "GART: Allocated %dMiB as a scratch buffer\n",
- (unsigned int)(pNv->GART->size >> 20));
- }
/* We don't need to allocate cursors / lut here if we're using
* kernel modesetting
--
1.6.2.2

View File

@ -0,0 +1,644 @@
From e31aa5217c97dfd1e2c678ce7391fcd255abb0bf Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 19:30:38 +1000
Subject: [PATCH 4/6] nv50/f11: accelerate front-buffer rendering, linear shadow for scanout
---
src/Makefile.am | 1 +
src/drmmode_display.c | 8 +-
src/nouveau_exa.c | 37 ++++--
src/nv50_randr.c | 2 +-
src/nv50_shadow_damage.c | 306 ++++++++++++++++++++++++++++++++++++++++++++++
src/nv_dri.c | 2 +-
src/nv_driver.c | 38 +++++-
src/nv_proto.h | 4 +
src/nv_shadow.c | 8 +-
src/nv_type.h | 4 +
10 files changed, 387 insertions(+), 23 deletions(-)
create mode 100644 src/nv50_shadow_damage.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 29253a6..0c9e4e9 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -81,6 +81,7 @@ nouveau_drv_la_SOURCES = \
nv50_xv.c \
nv50_texture.h \
nv50reg.h \
+ nv50_shadow_damage.c \
nouveau_crtc.h \
nouveau_output.h \
nouveau_connector.h \
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 4909e51..ca1a60b 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -214,8 +214,8 @@ drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id,
}
src = (void *)req.vaddr;
- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR);
- dst = pNv->FB->map;
+ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR);
+ dst = pNv->scanout->map;
dst += (y * fb->pitch) + (x * (fb->bpp >> 3));
h = fb->height;
@@ -225,7 +225,7 @@ drmmode_fb_copy_sw(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int dst_id,
dst += pScrn->displayWidth * (pScrn->bitsPerPixel / 8);
}
- nouveau_bo_unmap(pNv->FB);
+ nouveau_bo_unmap(pNv->scanout);
drmFree(fb);
}
@@ -380,7 +380,7 @@ drmmode_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
ret = drmModeAddFB(drmmode->fd,
pScrn->virtualX, pScrn->virtualY,
pScrn->depth, pScrn->bitsPerPixel,
- pitch, pNv->FB->handle, &drmmode->fb_id);
+ pitch, pNv->scanout->handle, &drmmode->fb_id);
if (ret < 0) {
ErrorF("failed to add fb\n");
return FALSE;
diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index b7bcc87..aee2794 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -265,7 +265,8 @@ nouveau_exa_wait_marker(ScreenPtr pScreen, int marker)
static Bool
nouveau_exa_prepare_access(PixmapPtr ppix, int index)
{
- ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+ ScreenPtr pScreen = ppix->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
if (pNv->exa_driver_pixmaps) {
@@ -275,20 +276,33 @@ nouveau_exa_prepare_access(PixmapPtr ppix, int index)
return FALSE;
ppix->devPrivate.ptr = map;
- return TRUE;
+ } else
+ if (ppix == pScreen->GetScreenPixmap(pScreen)) {
+ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR);
+ ppix->devPrivate.ptr = pNv->scanout->map;
+ } else {
+ /* force migration */
+ return FALSE;
}
- return FALSE;
+ return TRUE;
}
static void
nouveau_exa_finish_access(PixmapPtr ppix, int index)
{
- ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+ ScreenPtr pScreen = ppix->drawable.pScreen;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
- if (pNv->exa_driver_pixmaps)
+ if (pNv->exa_driver_pixmaps) {
nouveau_exa_pixmap_unmap(ppix);
+ } else
+ if (ppix == pScreen->GetScreenPixmap(pScreen)) {
+ ppix->devPrivate.ptr = NULL;
+ nouveau_bo_unmap(pNv->scanout);
+ nv50_shadow_damage_frontbuffer_fallback(pScrn);
+ }
}
static Bool
@@ -393,8 +407,7 @@ nouveau_exa_pixmap_is_tiled(PixmapPtr ppix)
if (!nouveau_pixmap_bo(ppix)->tiled)
return false;
} else
- if (pNv->Architecture < NV_ARCH_50 ||
- exaGetPixmapOffset(ppix) < pNv->EXADriverPtr->offScreenBase)
+ if (pNv->Architecture < NV_ARCH_50)
return false;
return true;
@@ -406,7 +419,7 @@ nouveau_exa_pixmap_map(PixmapPtr ppix)
struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
unsigned delta = nouveau_pixmap_offset(ppix);
- if (bo->tiled) {
+ if (NVPTR(xf86Screens[ppix->drawable.pScreen->myNum])->GART && bo->tiled) {
struct nouveau_pixmap *nvpix = nouveau_pixmap(ppix);
nvpix->map_refcount++;
@@ -432,7 +445,7 @@ nouveau_exa_pixmap_unmap(PixmapPtr ppix)
{
struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
- if (bo->tiled) {
+ if (NVPTR(xf86Screens[ppix->drawable.pScreen->myNum])->GART && bo->tiled) {
struct nouveau_pixmap *nvpix = nouveau_pixmap(ppix);
if (--nvpix->map_refcount)
@@ -616,6 +629,12 @@ nouveau_exa_init(ScreenPtr pScreen)
exa->maxY = 2048;
}
+ /* Needed for frontbuffer fallbacks (to ensure it accesses the linear fb). */
+ if (pNv->Architecture >= NV_ARCH_50) {
+ exa->PrepareAccess = nouveau_exa_prepare_access;
+ exa->FinishAccess = nouveau_exa_finish_access;
+ }
+
exa->MarkSync = nouveau_exa_mark_sync;
exa->WaitMarker = nouveau_exa_wait_marker;
diff --git a/src/nv50_randr.c b/src/nv50_randr.c
index 8a9281b..538c883 100644
--- a/src/nv50_randr.c
+++ b/src/nv50_randr.c
@@ -99,7 +99,7 @@ nv50_crtc_mode_set(xf86CrtcPtr crtc, DisplayModePtr mode, DisplayModePtr adjuste
nv_crtc->crtc->SetFB(nv_crtc->crtc, nv_crtc->shadow);
nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, 0, 0);
} else {
- nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->FB);
+ nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->scanout);
nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, x, y);
}
nv_crtc->crtc->ModeSet(nv_crtc->crtc, mode);
diff --git a/src/nv50_shadow_damage.c b/src/nv50_shadow_damage.c
new file mode 100644
index 0000000..790b09c
--- /dev/null
+++ b/src/nv50_shadow_damage.c
@@ -0,0 +1,306 @@
+/*
+ * Copyright 2009 Maarten Maathuis
+ *
+ * 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 AUTHORS 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.
+ */
+
+/**
+ * This file serves to process all damage to the frontbuffer pixmap.
+ * This is needed until we can/have:
+ * - Tiled frontbufffer support.
+ * - Working wfb support.
+ * - Widespread wfb exa support.
+ */
+
+#include "nv_include.h"
+#include "damagestr.h"
+
+/* When driver allocated pixmaps are used we can easily fold this back into exa code. */
+
+static void
+nv50_shadow_damage_blit_state_emit(struct nouveau_channel *chan)
+{
+ ScrnInfoPtr pScrn = chan->user_private;
+ NVPtr pNv = NVPTR(pScrn);
+ PixmapPtr ppix = pNv->pspix;
+ struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
+ struct nouveau_grobj *eng2d = pNv->Nv2D;
+ unsigned delta = nouveau_pixmap_offset(ppix), fmt;
+
+ WAIT_RING (chan, 27 + 13);
+
+ switch (ppix->drawable.depth) {
+ case 8 : fmt = NV50_2D_SRC_FORMAT_8BPP; break;
+ case 15: fmt = NV50_2D_SRC_FORMAT_15BPP; break;
+ case 16: fmt = NV50_2D_SRC_FORMAT_16BPP; break;
+ case 24: fmt = NV50_2D_SRC_FORMAT_24BPP; break;
+ case 32: fmt = NV50_2D_SRC_FORMAT_32BPP; break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unknown surface format for bpp=%d\n",
+ ppix->drawable.depth);
+ return;
+ }
+
+ /* tiled source */
+ BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 5);
+ OUT_RING (chan, fmt);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+
+ BEGIN_RING(chan, eng2d, NV50_2D_SRC_WIDTH, 4);
+ OUT_RING (chan, ppix->drawable.width);
+ OUT_RING (chan, ppix->drawable.height);
+ OUT_RELOCh(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ /* untiled destination */
+ BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 2);
+ OUT_RING (chan, fmt);
+ OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng2d, NV50_2D_DST_PITCH, 5);
+ OUT_RING (chan, NOUVEAU_ALIGN(pScrn->virtualX, 64) *
+ (pScrn->bitsPerPixel >> 3));
+ OUT_RING (chan, ppix->drawable.width);
+ OUT_RING (chan, ppix->drawable.height);
+ OUT_RELOCh(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, ppix->drawable.width);
+ OUT_RING (chan, ppix->drawable.height);
+ BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1);
+ OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY);
+}
+
+static void
+nv50_shadow_damage_blit(PixmapPtr ppix, RegionPtr pRegion)
+{
+ ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ struct nouveau_channel *chan = pNv->chan;
+ struct nouveau_grobj *eng2d = pNv->Nv2D;
+ BoxPtr pbox;
+ int nbox;
+
+ pbox = REGION_RECTS(pRegion);
+ nbox = REGION_NUM_RECTS(pRegion);
+ if (!nbox)
+ return;
+
+ pNv->pspix = ppix;
+ chan->flush_notify = nv50_shadow_damage_blit_state_emit;
+ chan->flush_notify(chan);
+ while (nbox--) {
+ WAIT_RING (chan, 13);
+ BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12);
+ OUT_RING (chan, pbox->x1);
+ OUT_RING (chan, pbox->y1);
+ OUT_RING (chan, pbox->x2 - pbox->x1);
+ OUT_RING (chan, pbox->y2 - pbox->y1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, pbox->x1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, pbox->y1);
+
+ pbox++;
+ }
+ chan->flush_notify = NULL;
+}
+
+/* For frontbuffer fallbacks. */
+static void
+nv50_shadow_damage_blit_back_state_emit(struct nouveau_channel *chan)
+{
+ ScrnInfoPtr pScrn = chan->user_private;
+ NVPtr pNv = NVPTR(pScrn);
+ PixmapPtr ppix = pNv->pdpix;
+ struct nouveau_grobj *eng2d = pNv->Nv2D;
+ struct nouveau_bo *bo = nouveau_pixmap_bo(ppix);
+ unsigned delta = nouveau_pixmap_offset(ppix), fmt;
+
+ WAIT_RING (chan, 27 + 13);
+
+ switch (ppix->drawable.depth) {
+ case 8 : fmt = NV50_2D_SRC_FORMAT_8BPP; break;
+ case 15: fmt = NV50_2D_SRC_FORMAT_15BPP; break;
+ case 16: fmt = NV50_2D_SRC_FORMAT_16BPP; break;
+ case 24: fmt = NV50_2D_SRC_FORMAT_24BPP; break;
+ case 32: fmt = NV50_2D_SRC_FORMAT_32BPP; break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Unknown surface format for bpp=%d\n",
+ ppix->drawable.depth);
+ return;
+ }
+
+ /* untiled source */
+ BEGIN_RING(chan, eng2d, NV50_2D_SRC_FORMAT, 2);
+ OUT_RING (chan, fmt);
+ OUT_RING (chan, 1);
+ BEGIN_RING(chan, eng2d, NV50_2D_SRC_PITCH, 5);
+ OUT_RING (chan, NOUVEAU_ALIGN(pScrn->virtualX, 64) *
+ (pScrn->bitsPerPixel >> 3));
+ OUT_RING (chan, ppix->drawable.width);
+ OUT_RING (chan, ppix->drawable.height);
+ OUT_RELOCh(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, pNv->scanout, 0, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ /* tiled destination */
+ BEGIN_RING(chan, eng2d, NV50_2D_DST_FORMAT, 5);
+ OUT_RING (chan, fmt);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+
+ BEGIN_RING(chan, eng2d, NV50_2D_DST_WIDTH, 4);
+ OUT_RING (chan, ppix->drawable.width);
+ OUT_RING (chan, ppix->drawable.height);
+ OUT_RELOCh(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+ OUT_RELOCl(chan, bo, delta, NOUVEAU_BO_VRAM | NOUVEAU_BO_WR);
+
+ BEGIN_RING(chan, eng2d, NV50_2D_CLIP_X, 4);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, ppix->drawable.width);
+ OUT_RING (chan, ppix->drawable.height);
+ BEGIN_RING(chan, eng2d, NV50_2D_OPERATION, 1);
+ OUT_RING (chan, NV50_2D_OPERATION_SRCCOPY);
+}
+
+static void
+nv50_shadow_damage_blit_back(PixmapPtr ppix, RegionPtr pRegion)
+{
+ ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+ struct nouveau_channel *chan = pNv->chan;
+ struct nouveau_grobj *eng2d = pNv->Nv2D;
+ BoxPtr pbox;
+ int nbox;
+
+ pbox = REGION_RECTS(pRegion);
+ nbox = REGION_NUM_RECTS(pRegion);
+ if (!nbox)
+ return;
+
+ pNv->pdpix = ppix;
+ chan->flush_notify = nv50_shadow_damage_blit_back_state_emit;
+ chan->flush_notify(chan);
+ while (nbox--) {
+ WAIT_RING (chan, 13);
+ BEGIN_RING(chan, eng2d, NV50_2D_BLIT_DST_X, 12);
+ OUT_RING (chan, pbox->x1);
+ OUT_RING (chan, pbox->y1);
+ OUT_RING (chan, pbox->x2 - pbox->x1);
+ OUT_RING (chan, pbox->y2 - pbox->y1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, 1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, pbox->x1);
+ OUT_RING (chan, 0);
+ OUT_RING (chan, pbox->y1);
+
+ pbox++;
+ }
+ chan->flush_notify = NULL;
+}
+
+static void
+nv50_shadow_damage_report(DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+ PixmapPtr ppix = closure;
+
+ nv50_shadow_damage_blit(ppix, pRegion);
+}
+
+void
+nv50_shadow_damage_frontbuffer_fallback(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr ppix = NULL;
+ DamagePtr pDamage = pNv->screen_damage;
+
+ if (pNv->Architecture < NV_ARCH_50)
+ return;
+
+ ppix = pScreen->GetScreenPixmap(pScreen);
+ if (!ppix) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No screen pixmap.\n");
+ return;
+ }
+
+ /* Pending damage reflects the rendering currently being done. */
+ /* When exa calls finish access, damage hasn't flushed it yet. */
+ nv50_shadow_damage_blit_back(ppix, &pDamage->pendingDamage);
+}
+
+static void
+nv50_shadow_damage_destroy(DamagePtr pDamage, void *closure)
+{
+ PixmapPtr ppix = closure;
+ ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
+ NVPtr pNv = NVPTR(pScrn);
+
+ pNv->screen_damage = NULL;
+}
+
+bool
+nv50_shadow_damage_create(ScrnInfoPtr pScrn)
+{
+ NVPtr pNv = NVPTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ PixmapPtr ppix = NULL;
+
+ if (pNv->Architecture < NV_ARCH_50)
+ return false;
+
+ ppix = pScreen->GetScreenPixmap(pScreen);
+ if (!ppix) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No screen pixmap.\n");
+ return false;
+ }
+
+ pNv->screen_damage = DamageCreate(nv50_shadow_damage_report, nv50_shadow_damage_destroy, DamageReportRawRegion, true, pScreen, ppix);
+ if (!pNv->screen_damage) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "No screen damage\n");
+ return false;
+ }
+
+ /* We want the notification after submission. */
+ DamageSetReportAfterOp(pNv->screen_damage, true);
+
+ DamageRegister(&ppix->drawable, pNv->screen_damage);
+
+ return true;
+}
diff --git a/src/nv_dri.c b/src/nv_dri.c
index bd3e5a9..dca6a40 100644
--- a/src/nv_dri.c
+++ b/src/nv_dri.c
@@ -337,7 +337,7 @@ Bool NVDRIFinishScreenInit(ScrnInfoPtr pScrn)
pNOUVEAUDRI->depth = pScrn->depth;
pNOUVEAUDRI->bpp = pScrn->bitsPerPixel;
- ret = nouveau_bo_handle_get(pNv->FB, &pNOUVEAUDRI->front_offset);
+ ret = nouveau_bo_handle_get(pNv->scanout, &pNOUVEAUDRI->front_offset);
if (ret) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[dri] unable to reference front buffer: %d\n", ret);
diff --git a/src/nv_driver.c b/src/nv_driver.c
index 9f4c96f..a280257 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -686,10 +686,11 @@ NVEnterVT(int scrnIndex, int flags)
/* Clear the framebuffer, we don't want to see garbage
* on-screen up until X decides to draw something
*/
- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR);
- memset(pNv->FB->map, 0, NOUVEAU_ALIGN(pScrn->virtualX, 64) *
- pScrn->virtualY * (pScrn->bitsPerPixel >> 3));
- nouveau_bo_unmap(pNv->FB);
+ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR);
+ memset(pNv->scanout->map, 0,
+ NOUVEAU_ALIGN(pScrn->virtualX, 64) * pScrn->virtualY *
+ (pScrn->bitsPerPixel >> 3));
+ nouveau_bo_unmap(pNv->scanout);
if (pNv->Architecture == NV_ARCH_50) {
if (!NV50AcquireDisplay(pScrn))
@@ -1609,6 +1610,8 @@ NVMapMemSW(ScrnInfoPtr pScrn)
return FALSE;
pNv->GART = NULL;
+ nouveau_bo_ref(pNv->FB, &pNv->scanout);
+
ret = nouveau_bo_fake(&dev, Cursor0Offset,
NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
64 * 64 * 4, pNv->VRAMMap + Cursor0Offset,
@@ -1760,6 +1763,23 @@ skip_fb:
"at offset 0x%X\n",
(uint32_t)(pNv->FB->size >> 20), (uint32_t) pNv->FB->offset);
+ /* Allocate linear scanout. */
+ if (!pNv->NoAccel && pNv->Architecture >= NV_ARCH_50) {
+ unsigned scanout_size;
+
+ scanout_size = NOUVEAU_ALIGN(pScrn->virtualX, 64);
+ scanout_size *= (pScrn->bitsPerPixel >> 3);
+ scanout_size *= pScrn->virtualY;
+
+ if (nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
+ 0, scanout_size, &pNv->scanout)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Failed to allocate scanout buffer\n");
+ return FALSE;
+ }
+ } else {
+ nouveau_bo_ref(pNv->FB, &pNv->scanout);
+ }
/* We don't need to allocate cursors / lut here if we're using
* kernel modesetting
@@ -1832,6 +1852,7 @@ NVUnmapMem(ScrnInfoPtr pScrn)
}
nouveau_bo_ref(NULL, &pNv->FB);
+ nouveau_bo_ref(NULL, &pNv->scanout);
nouveau_bo_ref(NULL, &pNv->GART);
nouveau_bo_ref(NULL, &pNv->Cursor);
nouveau_bo_ref(NULL, &pNv->Cursor2);
@@ -2347,6 +2368,15 @@ NVSaveScreen(ScreenPtr pScreen, int mode)
bool on = xf86IsUnblank(mode);
int i;
+ /* This might seem strange, but we need an entry point after CreateScreenResources.
+ * This happens to one of the few, if not the only place.
+ * When we move to driver allocated pixmaps, we can move this.
+ */
+ if (mode == SCREEN_SAVER_FORCER && pNv->Architecture == NV_ARCH_50 &&
+ !pNv->NoAccel && !pNv->screen_damage &&
+ !nv50_shadow_damage_create(pScrn))
+ return FALSE;
+
if (!pNv->randr12_enable)
return vgaHWSaveScreen(pScreen, mode);
diff --git a/src/nv_proto.h b/src/nv_proto.h
index 072c7c4..4e9b65c 100644
--- a/src/nv_proto.h
+++ b/src/nv_proto.h
@@ -267,6 +267,10 @@ void nv50_xv_video_stop(ScrnInfoPtr, pointer, Bool);
int nv50_xv_port_attribute_set(ScrnInfoPtr, Atom, INT32, pointer);
int nv50_xv_port_attribute_get(ScrnInfoPtr, Atom, INT32 *, pointer);
+/* nv50_shadow_damage.c */
+bool nv50_shadow_damage_create(ScrnInfoPtr pScrn);
+void nv50_shadow_damage_frontbuffer_fallback(ScrnInfoPtr pScrn);
+
/* To support EXA 2.0, 2.1 has this in the header */
#ifndef exaMoveInPixmap
extern void exaMoveInPixmap(PixmapPtr pPixmap);
diff --git a/src/nv_shadow.c b/src/nv_shadow.c
index ea1ba35..e15051c 100644
--- a/src/nv_shadow.c
+++ b/src/nv_shadow.c
@@ -38,9 +38,9 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
cpp = pScrn->bitsPerPixel >> 3;
FBPitch = pScrn->displayWidth * cpp;
- max_height = pNv->FB->size/FBPitch;
+ max_height = pNv->scanout->size/FBPitch;
- nouveau_bo_map(pNv->FB, NOUVEAU_BO_WR);
+ nouveau_bo_map(pNv->scanout, NOUVEAU_BO_WR);
while(num--) {
x1 = MAX(pbox->x1, 0);
y1 = MAX(pbox->y1, 0);
@@ -51,7 +51,7 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
if (width > 0 && height > 0) {
src = pNv->ShadowPtr + (y1 * pNv->ShadowPitch) + (x1 * cpp);
- dst = pNv->FB->map + (y1 * FBPitch) + (x1 * cpp);
+ dst = pNv->scanout->map + (y1 * FBPitch) + (x1 * cpp);
while(height--) {
memcpy(dst, src, width);
@@ -62,5 +62,5 @@ NVRefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
pbox++;
}
- nouveau_bo_unmap(pNv->FB);
+ nouveau_bo_unmap(pNv->scanout);
}
diff --git a/src/nv_type.h b/src/nv_type.h
index 2ec4fba..5396cc8 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -270,6 +270,7 @@ typedef struct _NVRec {
/* Various pinned memory regions */
struct nouveau_bo * FB;
void * FBMap;
+ struct nouveau_bo * scanout;
//struct nouveau_bo * FB_old; /* for KMS */
struct nouveau_bo * shadow[2]; /* for easy acces by exa */
struct nouveau_bo * Cursor;
@@ -278,6 +279,9 @@ typedef struct _NVRec {
struct nvbios VBIOS;
struct nouveau_bios_info *vbios;
+
+ DamagePtr screen_damage; /* for NV50+ */
+
Bool NoAccel;
Bool HWCursor;
Bool FpScale;
--
1.6.2.2

View File

@ -0,0 +1,31 @@
From 7460d8ebca84bd5e7c26e88143f14f4909598b68 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@gmail.com>
Date: Mon, 13 Apr 2009 20:20:39 +1000
Subject: [PATCH 5/6] nv50/f11: disable acceleration on NVAx chipsets
---
src/nv_driver.c | 8 ++++++++
1 files changed, 8 insertions(+), 0 deletions(-)
diff --git a/src/nv_driver.c b/src/nv_driver.c
index a280257..f097fb9 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -1144,6 +1144,14 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
pNv->ShadowFB = TRUE;
}
+ if ((pNv->NVArch & 0xf0) == 0xa0) {
+ xf86DrvMsg(pScrn->scrnIndex, X_NOTICE,
+ "Acceleration disabled, currently non-functional "
+ "on this chipset\n");
+ pNv->NoAccel = TRUE;
+ pNv->ShadowFB = TRUE;
+ }
+
/* Save current console video mode */
if (pNv->Architecture >= NV_ARCH_50 && pNv->pInt10 && !pNv->kms_enable) {
const xf86Int10InfoPtr pInt10 = pNv->pInt10;
--
1.6.2.2

View File

@ -0,0 +1,13 @@
diff --git a/src/nv_bios.c b/src/nv_bios.c
index fe6368e..7b56148 100644
--- a/src/nv_bios.c
+++ b/src/nv_bios.c
@@ -4104,6 +4104,8 @@ parse_dcb20_entry(ScrnInfoPtr pScrn, struct bios_parsed_dcb *bdcb,
mask = ~0x5;
if (conf & 0x4)
entry->lvdsconf.use_power_scripts = true;
+ if ((conf & 0xf0) == 0x60)
+ mask &= ~0xf0;
}
if (conf & mask) {
/* I'm bored of getting this reported; left as a reminder for someone to fix it */

View File

@ -0,0 +1,395 @@
From 7e4b7775589cff4433de1f3dfa1416c66cdfe060 Mon Sep 17 00:00:00 2001
From: Ben Skeggs <skeggsb@caspar.localdomain>
Date: Tue, 14 Apr 2009 09:23:07 +1000
Subject: [PATCH 6/6] f11: support framebuffer resize without driver pixmaps
---
src/drmmode_display.c | 75 +++++++++++++++++++++++++++++++--
src/nouveau_exa.c | 17 ++++----
src/nv50_randr.c | 6 +++
src/nv_crtc.c | 16 ++++++-
src/nv_driver.c | 108 ++++++++++++++++++++++++++++++++++++++++++++++---
src/nv_type.h | 9 ++++-
6 files changed, 209 insertions(+), 22 deletions(-)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index ca1a60b..c666c9f 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -1069,6 +1069,59 @@ drmmode_output_init(ScrnInfoPtr pScrn, drmmode_ptr drmmode, int num)
}
static Bool
+nv_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ NVPtr pNv = NVPTR(pScrn);
+ const int cpp = pScrn->bitsPerPixel >> 3;
+ int pitch = NOUVEAU_ALIGN(width * cpp, 256);
+ int ret = 0;
+ PixmapPtr ppix;
+
+ if (pScrn->virtualX == width && pScrn->virtualY == height &&
+ (pNv->NoAccel || pNv->exa_onscreen))
+ return TRUE;
+
+ if (!pNv->dev)
+ goto out_done;
+
+ nouveau_fb_free(pScrn);
+
+ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp);
+ if (ret) {
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ pitch = (*pScreen->GetScreenPixmap)(pScreen)->devKind;
+
+ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp);
+ /* famous last words: "this should never happen!" */
+ if (ret)
+ FatalError("couldn't allocate framebuffer!\n");
+
+ ret = -ENOMEM;
+ }
+
+out_done:
+ if (!ret && pNv->ShadowFB) {
+ xfree(pNv->ShadowPtr);
+ pNv->ShadowPtr = xalloc(pitch * height);
+ pNv->ShadowPitch = pitch;
+ }
+
+ ppix = (*pScreen->GetScreenPixmap)(pScreen);
+
+ (*pScreen->ModifyPixmapHeader)(ppix, width, height, -1, -1, pitch,
+ (!pNv->NoAccel || pNv->ShadowFB) ?
+ pNv->ShadowPtr : pNv->FBMap);
+ pScrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
+
+ pScrn->virtualX = width;
+ pScrn->virtualY = height;
+ pScrn->displayWidth = pitch / cpp;
+ return ret == 0;
+}
+
+static Bool
drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -1083,10 +1136,23 @@ drmmode_xf86crtc_resize (ScrnInfoPtr scrn, int width, int height)
ErrorF("resize called %d %d\n", width, height);
if (!pNv->exa_driver_pixmaps) {
- if (width > scrn->virtualX || height > scrn->virtualY)
+ if (!nv_xf86crtc_resize(scrn, width, height))
return FALSE;
- scrn->displayWidth = NOUVEAU_ALIGN(width, 64);
+ if (drmmode->fb_id)
+ drmModeRmFB(drmmode->fd, drmmode->fb_id);
+ drmmode->fb_id = 0;
+
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+
+ if (!crtc->enabled)
+ continue;
+
+ xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation,
+ crtc->x, crtc->y);
+ }
+
return TRUE;
}
@@ -1149,7 +1215,7 @@ static const xf86CrtcConfigFuncsRec drmmode_xf86crtc_config_funcs = {
Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
{
- xf86CrtcConfigPtr xf86_config;
+ xf86CrtcConfigPtr xf86_config;
drmmode_ptr drmmode;
int i;
@@ -1173,8 +1239,7 @@ Bool drmmode_pre_init(ScrnInfoPtr pScrn, int fd, int cpp)
for (i = 0; i < drmmode->mode_res->count_connectors; i++)
drmmode_output_init(pScrn, drmmode, i);
- xf86InitialConfiguration(pScrn, NVPTR(pScrn)->exa_driver_pixmaps);
-
+ xf86InitialConfiguration(pScrn, TRUE);
return TRUE;
}
diff --git a/src/nouveau_exa.c b/src/nouveau_exa.c
index aee2794..41e3f85 100644
--- a/src/nouveau_exa.c
+++ b/src/nouveau_exa.c
@@ -279,7 +279,10 @@ nouveau_exa_prepare_access(PixmapPtr ppix, int index)
} else
if (ppix == pScreen->GetScreenPixmap(pScreen)) {
nouveau_bo_map(pNv->scanout, NOUVEAU_BO_RDWR);
- ppix->devPrivate.ptr = pNv->scanout->map;
+ if (pNv->scanout != pNv->FB)
+ ppix->devPrivate.ptr = pNv->scanout->map;
+ else
+ ppix->devPrivate.ptr = pNv->FB->map + pNv->exa_onscreen->offset;
} else {
/* force migration */
return FALSE;
@@ -301,7 +304,8 @@ nouveau_exa_finish_access(PixmapPtr ppix, int index)
if (ppix == pScreen->GetScreenPixmap(pScreen)) {
ppix->devPrivate.ptr = NULL;
nouveau_bo_unmap(pNv->scanout);
- nv50_shadow_damage_frontbuffer_fallback(pScrn);
+ if (pNv->Architecture == NV_ARCH_50)
+ nv50_shadow_damage_frontbuffer_fallback(pScrn);
}
}
@@ -543,10 +547,9 @@ Bool
nouveau_exa_pixmap_is_onscreen(PixmapPtr ppix)
{
ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
- NVPtr pNv = NVPTR(pScrn);
unsigned long offset = exaGetPixmapOffset(ppix);
- if (offset < pNv->EXADriverPtr->offScreenBase)
+ if (offset == 0)
return TRUE;
return FALSE;
@@ -630,10 +633,8 @@ nouveau_exa_init(ScreenPtr pScreen)
}
/* Needed for frontbuffer fallbacks (to ensure it accesses the linear fb). */
- if (pNv->Architecture >= NV_ARCH_50) {
- exa->PrepareAccess = nouveau_exa_prepare_access;
- exa->FinishAccess = nouveau_exa_finish_access;
- }
+ exa->PrepareAccess = nouveau_exa_prepare_access;
+ exa->FinishAccess = nouveau_exa_finish_access;
exa->MarkSync = nouveau_exa_mark_sync;
exa->WaitMarker = nouveau_exa_wait_marker;
diff --git a/src/nv50_randr.c b/src/nv50_randr.c
index 538c883..c451ba3 100644
--- a/src/nv50_randr.c
+++ b/src/nv50_randr.c
@@ -289,8 +289,14 @@ nv50_crtc_set_origin(xf86CrtcPtr crtc, int x, int y)
{
ScrnInfoPtr pScrn = crtc->scrn;
NV50CrtcPrivatePtr nv_crtc = crtc->driver_private;
+ NVPtr pNv = NVPTR(pScrn);
nv_crtc->crtc->SetFBOffset(nv_crtc->crtc, x, y);
+ if (nv_crtc->crtc->front_buffer &&
+ nv_crtc->crtc->front_buffer != pNv->scanout) {
+ nv_crtc->crtc->SetFB(nv_crtc->crtc, pNv->scanout);
+ nv_crtc->crtc->ModeSet(nv_crtc->crtc, &crtc->mode);
+ }
NV50DisplayCommand(pScrn, NV50_UPDATE_DISPLAY, 0);
}
diff --git a/src/nv_crtc.c b/src/nv_crtc.c
index 1d50874..cfa06e1 100644
--- a/src/nv_crtc.c
+++ b/src/nv_crtc.c
@@ -1154,7 +1154,10 @@ void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y)
ScrnInfoPtr pScrn = crtc->scrn;
NVPtr pNv = NVPTR(pScrn);
struct nouveau_crtc *nv_crtc = to_nouveau_crtc(crtc);
- uint32_t start = (y * pScrn->displayWidth + x) * pScrn->bitsPerPixel / 8;
+ uint32_t cpp = pScrn->bitsPerPixel / 8;
+ uint32_t start = (y * pScrn->displayWidth + x) * cpp;
+ uint32_t pitch = pScrn->displayWidth * cpp;
+ NVCrtcRegPtr regp = &pNv->ModeReg.crtc_reg[nv_crtc->head];
if (crtc->rotatedData != NULL) /* we do not exist on the real framebuffer */
#if NOUVEAU_EXA_PIXMAPS
@@ -1162,8 +1165,17 @@ void NVCrtcSetBase(xf86CrtcPtr crtc, int x, int y)
#else
start = pNv->FB->offset + nv_crtc->shadow->offset; /* We do exist relative to the framebuffer */
#endif
- else
+ else {
+ if (pNv->exa_onscreen)
+ start += pNv->exa_onscreen->offset;
start += pNv->FB->offset;
+ }
+
+ regp->CRTC[NV_CIO_CR_OFFSET_INDEX] = pitch >> 3;
+ regp->CRTC[NV_CIO_CRE_RPC0_INDEX] =
+ XLATE(pitch >> 3, 8, NV_CIO_CRE_RPC0_OFFSET_10_8);
+ crtc_wr_cio_state(crtc, regp, NV_CIO_CRE_RPC0_INDEX);
+ crtc_wr_cio_state(crtc, regp, NV_CIO_CR_OFFSET_INDEX);
start &= ~3;
pNv->ModeReg.crtc_reg[nv_crtc->head].fb_start = start;
diff --git a/src/nv_driver.c b/src/nv_driver.c
index f097fb9..0cc81ae 100644
--- a/src/nv_driver.c
+++ b/src/nv_driver.c
@@ -900,16 +900,112 @@ Bool NVI2CInit(ScrnInfoPtr pScrn)
return TRUE;
}
+void
+nouveau_fb_free(ScrnInfoPtr pScrn)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ NVPtr pNv = NVPTR(pScrn);
+
+ if (!pNv->NoAccel && pNv->exa_onscreen) {
+ exaOffscreenFree(pScreen, pNv->exa_onscreen);
+ pNv->exa_onscreen = NULL;
+ }
+
+ if (pNv->scanout && pNv->FB != pNv->scanout)
+ nouveau_bo_ref(NULL, &pNv->scanout);
+}
+
+int
+nouveau_fb_alloc(ScrnInfoPtr pScrn, int pitch, int height, int cpp)
+{
+ ScreenPtr pScreen = pScrn->pScreen;
+ NVPtr pNv = NVPTR(pScrn);
+ int ret;
+
+ if (!pNv->NoAccel) {
+ pNv->exa_onscreen = exaOffscreenAlloc(pScreen, pitch * height,
+ 256, TRUE, NULL, NULL);
+ if (!pNv->exa_onscreen)
+ return -ENOMEM;
+ }
+
+ if (!pNv->scanout) {
+ ret = nouveau_bo_new(pNv->dev, NOUVEAU_BO_VRAM | NOUVEAU_BO_PIN,
+ 256, pitch * height, &pNv->scanout);
+ if (ret) {
+ nouveau_fb_free(pScrn);
+ return ret;
+ }
+ }
+
+
+ return 0;
+}
+
static Bool
nv_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
-#if 0
- do not change virtual* for now, as it breaks multihead server regeneration
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "nv_xf86crtc_resize is called with %dx%d resolution.\n", width, height);
+ xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
+ ScreenPtr pScreen = pScrn->pScreen;
+ NVPtr pNv = NVPTR(pScrn);
+ const int cpp = pScrn->bitsPerPixel >> 3;
+ int pitch = NOUVEAU_ALIGN(width * cpp, 256);
+ int ret = 0, i;
+ PixmapPtr ppix;
+
+ if (pScrn->virtualX == width && pScrn->virtualY == height &&
+ (pNv->NoAccel || pNv->exa_onscreen))
+ return TRUE;
+
+ if (!pNv->dev)
+ goto out_done;
+
+ nouveau_fb_free(pScrn);
+
+ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp);
+ if (ret) {
+ width = pScrn->virtualX;
+ height = pScrn->virtualY;
+ pitch = (*pScreen->GetScreenPixmap)(pScreen)->devKind;
+
+ ret = nouveau_fb_alloc(pScrn, pitch, height, cpp);
+ /* famous last words: "this should never happen!" */
+ if (ret)
+ FatalError("couldn't allocate framebuffer!\n");
+
+ ret = -ENOMEM;
+ }
+
+out_done:
+
+ if (!ret && pNv->ShadowFB) {
+ xfree(pNv->ShadowPtr);
+ pNv->ShadowPtr = xalloc(pitch * height);
+ pNv->ShadowPitch = pitch;
+ }
+
+ ppix = pScreen->GetScreenPixmap(pScreen);
+
+ (*pScreen->ModifyPixmapHeader)(ppix, width, height, -1, -1, pitch,
+ (!pNv->NoAccel || pNv->ShadowFB) ?
+ pNv->ShadowPtr : pNv->FBMap);
+ pScrn->pixmapPrivate.ptr = ppix->devPrivate.ptr;
+
pScrn->virtualX = width;
pScrn->virtualY = height;
-#endif
- return TRUE;
+ pScrn->displayWidth = pitch / cpp;
+
+ for (i = 0; i < config->num_crtc; i++) {
+ xf86CrtcPtr crtc = config->crtc[i];
+
+ if (!crtc->enabled)
+ continue;
+
+ xf86CrtcSetMode(crtc, &crtc->mode, crtc->rotation,
+ crtc->x, crtc->y);
+ }
+
+ return ret == 0;
}
static const xf86CrtcConfigFuncsRec nv_xf86crtc_config_funcs = {
@@ -1423,7 +1519,7 @@ NVPreInit(ScrnInfoPtr pScrn, int flags)
} else
nv50_output_create(pScrn); /* create randr-1.2 "outputs". */
- if (!xf86InitialConfiguration(pScrn, FALSE))
+ if (!xf86InitialConfiguration(pScrn, TRUE))
NVPreInitFail("No valid modes.\n");
}
diff --git a/src/nv_type.h b/src/nv_type.h
index 5396cc8..1a9b9ed 100644
--- a/src/nv_type.h
+++ b/src/nv_type.h
@@ -304,8 +304,11 @@ typedef struct _NVRec {
volatile CARD8 *PDIO1;
uint8_t cur_head;
+
ExaDriverPtr EXADriverPtr;
Bool exa_driver_pixmaps;
+ ExaOffscreenArea * exa_onscreen;
+
ScreenBlockHandlerProcPtr BlockHandler;
CloseScreenProcPtr CloseScreen;
/* Cursor */
@@ -494,11 +497,15 @@ nouveau_pixmap_offset(PixmapPtr ppix)
{
ScrnInfoPtr pScrn = xf86Screens[ppix->drawable.pScreen->myNum];
NVPtr pNv = NVPTR(pScrn);
+ unsigned offset;
if (pNv->exa_driver_pixmaps)
return 0;
- return exaGetPixmapOffset(ppix);
+ offset = exaGetPixmapOffset(ppix);
+ if (offset == 0)
+ offset = pNv->exa_onscreen->offset;
+ return offset;
}
#endif /* __NV_STRUCT_H__ */
--
1.6.2.2

View File

@ -0,0 +1 @@
http://sources.openelec.tv/svn/xf86-video-nouveau-master-20090425.tar.bz2