Skip to content
Browse files

and get bsd support working without kernel panic

Only thing that's guaranteed to work is opening device node.
The memory maps in specific are untested, but the old
libdrm-pscnv might be enough to get things working. YMMV!
  • Loading branch information...
1 parent 5524dd8 commit 06e946467b00a5f2408388891132e410ed1fada8 @mlankhorst mlankhorst committed Apr 17, 2012
Showing with 98 additions and 40 deletions.
  1. +6 −9 pscnv/nouveau_bsddrv.c
  2. +19 −17 pscnv/nouveau_i2c.h
  3. +48 −9 pscnv/nouveau_iic.c
  4. +15 −1 pscnv/nouveau_state.c
  5. +10 −4 pscnv/nv50_display.c
View
15 pscnv/nouveau_bsddrv.c
@@ -39,6 +39,7 @@
#include "drm_pciids.h"
#include "pscnv_ioctl.h"
#include "pscnv_kapi.h"
+#include "device_if.h"
#define MODULE_PARM_DESC(a, b)
#define module_param_named(name, where, type, mode) TUNABLE_INT("drm.pscnv." #name, &where)
@@ -136,10 +137,10 @@ module_param_named(fbpercrtc, nouveau_fbpercrtc, int, 0400);
static drm_pci_id_list_t pciidlist[] = {
{
- /*PCI_VENDOR_ID_NVIDIA*/ 0x10de, 0U
+ /*PCI_VENDOR_ID_NVIDIA*/ 0x10de, 0U, 0, "nVidia graphics card"
},
{
- /*PCI_VENDOR_ID_NVIDIA_SGS*/ 0x12d2, 0U
+ /*PCI_VENDOR_ID_NVIDIA_SGS*/ 0x12d2, 0U, 0, "nVidia SGS graphics card"
},
{}
};
@@ -181,12 +182,12 @@ static device_method_t pscnv_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pscnv_probe),
DEVMETHOD(device_attach, pscnv_attach),
- DEVMETHOD(device_suspend, nouveau_suspend),
- DEVMETHOD(device_resume, nouveau_resume),
- DEVMETHOD(device_detach, drm_detach),
#ifdef DEVICE_AFTER_ATTACH
DEVMETHOD(device_after_attach, drm_after_attach),
#endif
+ DEVMETHOD(device_suspend, nouveau_suspend),
+ DEVMETHOD(device_resume, nouveau_resume),
+ DEVMETHOD(device_detach, drm_detach),
DEVMETHOD_END
};
@@ -313,10 +314,6 @@ static struct drm_driver_info driver = {
.lastclose = nouveau_lastclose,
.unload = nouveau_unload,
.preclose = nouveau_preclose,
-#if defined(CONFIG_DRM_NOUVEAU_DEBUG)
- .debugfs_init = nouveau_debugfs_init,
- .debugfs_cleanup = nouveau_debugfs_takedown,
-#endif
.irq_preinstall = nouveau_irq_preinstall,
.irq_postinstall = nouveau_irq_postinstall,
.irq_uninstall = nouveau_irq_uninstall,
View
36 pscnv/nouveau_i2c.h
@@ -51,9 +51,26 @@ struct i2c_board_info { const char *name; int addr; };
#include "iicbus_if.h"
#include "iicbb_if.h"
+#endif
+
+struct nouveau_i2c_chan {
+#ifdef __linux__
+ struct i2c_adapter adapter;
+#else
+ device_t adapter, bus, iic_dev;
+ char name[32];
+#endif
+ struct drm_device *dev;
+ struct i2c_algo_bit_data bit;
+ unsigned rd;
+ unsigned wr;
+ unsigned data;
+};
+
+#ifndef __linux__
static inline int i2c_transfer(device_t *dev, struct iic_msg *msg, int n) {
- int ret;
- ret = IICBUS_TRANSFER(*dev, msg, n);
+ struct nouveau_i2c_chan *d = (struct nouveau_i2c_chan*)dev;
+ int ret = iicbus_transfer(d->bus, msg, n);
return ret ? -ret : n;
}
@@ -78,23 +95,8 @@ static inline int i2c_smbus_xfer(device_t *dev, uint16_t addr, uint16_t flags,
return i2c_transfer(dev, msg, 2);
}
}
-
#endif
-struct nouveau_i2c_chan {
-#ifdef __linux__
- struct i2c_adapter adapter;
-#else
- device_t adapter, bus, iic_dev;
- char name[32];
-#endif
- struct drm_device *dev;
- struct i2c_algo_bit_data bit;
- unsigned rd;
- unsigned wr;
- unsigned data;
-};
-
#include "drm_dp_helper.h"
struct dcb_i2c_entry;
View
57 pscnv/nouveau_iic.c
@@ -179,6 +179,20 @@ nv50_i2c_setsda(void *data, int state)
i2c->data = state;
}
+static int
+nvd0_i2c_getscl(void *data)
+{
+ struct nouveau_i2c_chan *i2c = data;
+ return !!(nv_rd32(i2c->dev, i2c->rd) & 0x10);
+}
+
+static int
+nvd0_i2c_getsda(void *data)
+{
+ struct nouveau_i2c_chan *i2c = data;
+ return !!(nv_rd32(i2c->dev, i2c->rd) & 0x20);
+}
+
static void
pscnv_iicbb_setsda(device_t idev, int val)
{
@@ -236,13 +250,21 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
} else {
idev = device_add_child(dev->device, "pscnv_gmbus", index);
}
- device_quiet(idev);
+ if (!idev) {
+ return -ENODEV;
+ }
ret = device_probe_and_attach(idev);
if (ret) {
+ NV_ERROR(dev, "Couldn't attach device: %d\n", ret);
device_delete_child(dev->device, idev);
return -ret;
}
+ device_quiet(idev);
i2c = device_get_softc(idev);
+ if (!i2c) {
+ NV_ERROR(dev, "Erp?!\n");
+ return -ENODEV;
+ }
switch (entry->port_type) {
case 0:
@@ -264,9 +286,15 @@ nouveau_i2c_init(struct drm_device *dev, struct dcb_i2c_entry *entry, int index)
case 5:
i2c->bit.setsda = nv50_i2c_setsda;
i2c->bit.setscl = nv50_i2c_setscl;
- i2c->bit.getsda = nv50_i2c_getsda;
- i2c->bit.getscl = nv50_i2c_getscl;
- i2c->rd = nv50_i2c_port[entry->read];
+ if (dev_priv->card_type < NV_D0) {
+ i2c->bit.getsda = nv50_i2c_getsda;
+ i2c->bit.getscl = nv50_i2c_getscl;
+ i2c->rd = nv50_i2c_port[entry->read];
+ } else {
+ i2c->bit.getsda = nvd0_i2c_getsda;
+ i2c->bit.getscl = nvd0_i2c_getscl;
+ i2c->rd = 0x00d014 + (entry->read * 0x20);
+ }
i2c->wr = i2c->rd;
break;
case 6:
@@ -339,7 +367,7 @@ nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
}
};
- return !IICBUS_TRANSFER(i2c->adapter, msgs, 2);
+ return !iicbus_transfer(i2c->bus, msgs, 2);
}
int
@@ -383,8 +411,10 @@ pscnv_gmbus_attach(device_t idev)
/* add bus interface device */
sc->bus = sc->iic_dev = device_add_child(idev, "iicbus", -1);
- if (sc->iic_dev == NULL)
+ if (sc->iic_dev == NULL) {
+ NV_ERROR(sc->dev, "Could not add iicbus to gmbus!\n");
return (ENXIO);
+ }
device_quiet(sc->iic_dev);
bus_generic_attach(idev);
@@ -408,8 +438,10 @@ pscnv_iicbb_attach(device_t idev)
/* add bus interface device */
sc->iic_dev = device_add_child(idev, "iicbb", -1);
- if (sc->iic_dev == NULL)
+ if (sc->iic_dev == NULL) {
+ NV_ERROR(sc->dev, "Could not add iicbb to our bitbanger!\n");
return (ENXIO);
+ }
device_quiet(sc->iic_dev);
bus_generic_attach(idev);
sc->bus = device_find_child(sc->iic_dev, "iicbus", -1);
@@ -474,8 +506,7 @@ pscnv_gmbus_transfer(device_t idev, struct iic_msg *msgs, uint32_t nmsgs)
static int
pscnv_iic_probe(device_t dev)
{
-
- return (BUS_PROBE_DEFAULT);
+ return (BUS_PROBE_SPECIFIC);
}
static int
@@ -492,11 +523,18 @@ pscnv_iic_detach(device_t idev)
return (0);
}
+static int
+pscnv_iicbus_reset(device_t idev, u_char speed, u_char addr, u_char *oldaddr)
+{
+ return (0);
+}
+
/* DP transfer with auxch */
static device_method_t pscnv_gmbus_methods[] = {
DEVMETHOD(device_probe, pscnv_iic_probe),
DEVMETHOD(device_attach, pscnv_gmbus_attach),
DEVMETHOD(device_detach, pscnv_iic_detach),
+ DEVMETHOD(iicbus_reset, pscnv_iicbus_reset),
DEVMETHOD(iicbus_transfer, pscnv_gmbus_transfer),
DEVMETHOD_END
};
@@ -520,6 +558,7 @@ static device_method_t pscnv_iicbb_methods[] = {
DEVMETHOD(bus_print_child, bus_generic_print_child),
DEVMETHOD(iicbb_callback, iicbus_null_callback),
+ DEVMETHOD(iicbus_reset, pscnv_iicbus_reset),
DEVMETHOD(iicbb_setsda, pscnv_iicbb_setsda),
DEVMETHOD(iicbb_setscl, pscnv_iicbb_setscl),
DEVMETHOD(iicbb_getsda, pscnv_iicbb_getsda),
View
16 pscnv/nouveau_state.c
@@ -374,7 +374,14 @@ nouveau_card_init(struct drm_device *dev)
/* this call irq_preinstall, register irq handler and
* call irq_postinstall
*/
+#ifdef __linux__
+ ret = drm_irq_install(dev);
+#else
+ // SIGH
+ DRM_UNLOCK();
ret = drm_irq_install(dev);
+ DRM_LOCK();
+#endif
if (ret)
goto out_display;
@@ -398,7 +405,14 @@ nouveau_card_init(struct drm_device *dev)
dev_priv->init_state = NOUVEAU_CARD_INIT_DONE;
if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+#ifdef __linux__
+ nouveau_fbcon_init(dev);
+#else
+ // SIGH
+ DRM_UNLOCK();
nouveau_fbcon_init(dev);
+ DRM_LOCK();
+#endif
drm_kms_helper_poll_init(dev);
}
@@ -708,7 +722,7 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
/* map larger RAMIN aperture on NV40 cards */
if (dev_priv->card_type >= NV_40) {
int ramin_bar = 2;
- if (drm_get_resource_len(dev, ramin_bar) == 0)
+ if (drm_get_resource_len(dev, ramin_bar) < PAGE_SIZE)
ramin_bar = 3;
dev_priv->ramin_size = drm_get_resource_len(dev, ramin_bar);
View
14 pscnv/nv50_display.c
@@ -1017,7 +1017,7 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
struct drm_device *dev = dev_priv->dev;
struct drm_connector *connector;
uint32_t unplug_mask, plug_mask, change_mask;
- uint32_t hpd0, hpd1 = 0;
+ uint32_t hpd0, hpd1 = 0, changed = 0;
hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050);
if (dev_priv->chipset >= 0x90)
@@ -1034,6 +1034,7 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
struct nouveau_encoder *nv_encoder;
struct dcb_gpio_entry *gpio;
bool plugged;
+ uint32_t mode;
if (!nv_connector->dcb)
continue;
@@ -1056,16 +1057,21 @@ nv50_display_irq_hotplug_bh(struct work_struct *work)
continue;
if (plugged)
- helper->dpms(connector->encoder, DRM_MODE_DPMS_ON);
+ mode = DRM_MODE_DPMS_ON;
else
- helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF);
+ mode = DRM_MODE_DPMS_OFF;
+ if (mode != nv_encoder->last_dpms) {
+ changed = 1;
+ helper->dpms(connector->encoder, mode);
+ }
}
nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054));
if (dev_priv->chipset >= 0x90)
nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074));
- drm_helper_hpd_irq_event(dev);
+ if (changed)
+ drm_helper_hpd_irq_event(dev);
}
void

0 comments on commit 06e9464

Please sign in to comment.
Something went wrong with that request. Please try again.