summaryrefslogtreecommitdiff
path: root/shared-core/nouveau_state.c
diff options
context:
space:
mode:
Diffstat (limited to 'shared-core/nouveau_state.c')
-rw-r--r--shared-core/nouveau_state.c57
1 files changed, 54 insertions, 3 deletions
diff --git a/shared-core/nouveau_state.c b/shared-core/nouveau_state.c
index d9c6efe7..3baae6ad 100644
--- a/shared-core/nouveau_state.c
+++ b/shared-core/nouveau_state.c
@@ -27,6 +27,8 @@
#include "drm_sarea.h"
#include "nouveau_drv.h"
#include "nouveau_drm.h"
+#include "nv50_kms_wrapper.h"
+#include "nv50_fbcon.h"
static int nouveau_init_card_mappings(struct drm_device *dev)
{
@@ -362,6 +364,14 @@ nouveau_card_init(struct drm_device *dev)
if (ret) return ret;
dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
+
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ if (dev_priv->card_type >= NV_50) {
+ nv50_kms_init(dev);
+ //nv50_kms_connector_detect_all(dev);
+ nv50_fbcon_init(dev);
+ }
+
return 0;
}
@@ -410,8 +420,7 @@ void nouveau_preclose(struct drm_device *dev, struct drm_file *file_priv)
nouveau_mem_release(file_priv,dev_priv->pci_heap);
}
-/* first module load, setup the mmio/fb mapping */
-int nouveau_firstopen(struct drm_device *dev)
+int nouveau_setup_mappings(struct drm_device *dev)
{
#if defined(__powerpc__)
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -457,6 +466,16 @@ int nouveau_firstopen(struct drm_device *dev)
return 0;
}
+/* first module load, setup the mmio/fb mapping */
+/* KMS: we need mmio at load time, not when the first drm client opens. */
+int nouveau_firstopen(struct drm_device *dev)
+{
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return 0;
+
+ return nouveau_setup_mappings(dev);
+}
+
#define NV40_CHIPSET_MASK 0x00000baf
#define NV44_CHIPSET_MASK 0x00005450
@@ -540,6 +559,10 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
return -EINVAL;
}
+ /* For those who think they want to be funny. */
+ if (dev_priv->card_type < NV_50)
+ dev->driver->driver_features &= ~DRIVER_MODESET;
+
/* Special flags */
if (dev->pci_device == 0x01a0) {
dev_priv->flags |= NV_NFORCE;
@@ -549,10 +572,23 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
dev->dev_private = (void *)dev_priv;
+ /* init card now, otherwise bad things happen */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ int rval = 0;
+
+ rval = nouveau_setup_mappings(dev);
+ if (rval != 0)
+ return rval;
+
+ rval = nouveau_card_init(dev);
+ if (rval != 0)
+ return rval;
+ }
+
return 0;
}
-void nouveau_lastclose(struct drm_device *dev)
+void nouveau_close(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
@@ -568,8 +604,23 @@ void nouveau_lastclose(struct drm_device *dev)
}
}
+/* KMS: we need mmio at load time, not when the first drm client opens. */
+void nouveau_lastclose(struct drm_device *dev)
+{
+ if (drm_core_check_feature(dev, DRIVER_MODESET))
+ return;
+
+ nouveau_close(dev);
+}
+
int nouveau_unload(struct drm_device *dev)
{
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ nv50_kms_destroy(dev);
+ nv50_fbcon_destroy(dev);
+ nouveau_close(dev);
+ }
+
drm_free(dev->dev_private, sizeof(*dev->dev_private), DRM_MEM_DRIVER);
dev->dev_private = NULL;
return 0;