Skip to content

Commit

Permalink
drm/nouveau/mc: handle irq-related setup ourselves
Browse files Browse the repository at this point in the history
We need to be able to process interrupts before the DRM code is able to
actually enable them, set it up ourselves.  Also, it's less convoluted
to *not* use the DRM wrappers it appears...

Signed-off-by: Ben Skeggs <[email protected]>
  • Loading branch information
Ben Skeggs committed Apr 26, 2013
1 parent 1a64634 commit 0fa9061
Show file tree
Hide file tree
Showing 12 changed files with 75 additions and 127 deletions.
2 changes: 1 addition & 1 deletion drivers/gpu/drm/nouveau/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ nouveau-y += core/engine/vp/nve0.o

# drm/core
nouveau-y += nouveau_drm.o nouveau_chan.o nouveau_dma.o nouveau_fence.o
nouveau-y += nouveau_irq.o nouveau_vga.o nouveau_agp.o
nouveau-y += nouveau_vga.o nouveau_agp.o
nouveau-y += nouveau_ttm.o nouveau_sgdma.o nouveau_bo.o nouveau_gem.o
nouveau-y += nouveau_prime.o nouveau_abi16.o
nouveau-y += nv04_fence.o nv10_fence.o nv17_fence.o
Expand Down
30 changes: 16 additions & 14 deletions drivers/gpu/drm/nouveau/core/include/subdev/mc.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,27 +21,29 @@ nouveau_mc(void *obj)
}

#define nouveau_mc_create(p,e,o,d) \
nouveau_subdev_create_((p), (e), (o), 0, "PMC", "master", \
sizeof(**d), (void **)d)
#define nouveau_mc_destroy(p) \
nouveau_subdev_destroy(&(p)->base)
#define nouveau_mc_init(p) \
nouveau_subdev_init(&(p)->base)
#define nouveau_mc_fini(p,s) \
nouveau_subdev_fini(&(p)->base, (s))

#define _nouveau_mc_dtor _nouveau_subdev_dtor
#define _nouveau_mc_init _nouveau_subdev_init
#define _nouveau_mc_fini _nouveau_subdev_fini
nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d)
#define nouveau_mc_destroy(p) ({ \
struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \
})
#define nouveau_mc_init(p) ({ \
struct nouveau_mc *pmc = (p); _nouveau_mc_init(nv_object(pmc)); \
})
#define nouveau_mc_fini(p,s) ({ \
struct nouveau_mc *pmc = (p); _nouveau_mc_fini(nv_object(pmc), (s)); \
})

int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *,
struct nouveau_oclass *, int, void **);
void _nouveau_mc_dtor(struct nouveau_object *);
int _nouveau_mc_init(struct nouveau_object *);
int _nouveau_mc_fini(struct nouveau_object *, bool);

extern struct nouveau_oclass nv04_mc_oclass;
extern struct nouveau_oclass nv44_mc_oclass;
extern struct nouveau_oclass nv50_mc_oclass;
extern struct nouveau_oclass nv98_mc_oclass;
extern struct nouveau_oclass nvc0_mc_oclass;

void nouveau_mc_intr(struct nouveau_subdev *);

extern const struct nouveau_mc_intr nv04_mc_intr[];
int nv04_mc_init(struct nouveau_object *);
int nv50_mc_init(struct nouveau_object *);
Expand Down
1 change: 1 addition & 0 deletions drivers/gpu/drm/nouveau/core/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
#include <linux/acpi.h>
#include <linux/dmi.h>
#include <linux/reboot.h>
#include <linux/interrupt.h>

#include <asm/unaligned.h>

Expand Down
60 changes: 56 additions & 4 deletions drivers/gpu/drm/nouveau/core/subdev/mc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@

#include <subdev/mc.h>

void
nouveau_mc_intr(struct nouveau_subdev *subdev)
static irqreturn_t
nouveau_mc_intr(int irq, void *arg)
{
struct nouveau_mc *pmc = nouveau_mc(subdev);
struct nouveau_mc *pmc = arg;
const struct nouveau_mc_intr *map = pmc->intr_map;
struct nouveau_subdev *unit;
u32 stat, intr;

intr = stat = nv_rd32(pmc, 0x000100);
while (stat && map->stat) {
if (stat & map->stat) {
unit = nouveau_subdev(subdev, map->unit);
unit = nouveau_subdev(pmc, map->unit);
if (unit && unit->intr)
unit->intr(unit);
intr &= ~map->stat;
Expand All @@ -46,4 +46,56 @@ nouveau_mc_intr(struct nouveau_subdev *subdev)
if (intr) {
nv_error(pmc, "unknown intr 0x%08x\n", stat);
}

return stat ? IRQ_HANDLED : IRQ_NONE;
}

int
_nouveau_mc_fini(struct nouveau_object *object, bool suspend)
{
struct nouveau_mc *pmc = (void *)object;
nv_wr32(pmc, 0x000140, 0x00000000);
return nouveau_subdev_fini(&pmc->base, suspend);
}

int
_nouveau_mc_init(struct nouveau_object *object)
{
struct nouveau_mc *pmc = (void *)object;
int ret = nouveau_subdev_init(&pmc->base);
if (ret)
return ret;
nv_wr32(pmc, 0x000140, 0x00000001);
return 0;
}

void
_nouveau_mc_dtor(struct nouveau_object *object)
{
struct nouveau_device *device = nv_device(object);
struct nouveau_mc *pmc = (void *)object;
free_irq(device->pdev->irq, pmc);
nouveau_subdev_destroy(&pmc->base);
}

int
nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, int length, void **pobject)
{
struct nouveau_device *device = nv_device(parent);
struct nouveau_mc *pmc;
int ret;

ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMC",
"master", length, pobject);
pmc = *pobject;
if (ret)
return ret;

ret = request_irq(device->pdev->irq, nouveau_mc_intr,
IRQF_SHARED, "nouveau", pmc);
if (ret < 0)
return ret;

return 0;
}
1 change: 0 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;

nv_subdev(priv)->intr = nouveau_mc_intr;
priv->base.intr_map = nv04_mc_intr;
return 0;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;

nv_subdev(priv)->intr = nouveau_mc_intr;
priv->base.intr_map = nv04_mc_intr;
return 0;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;

nv_subdev(priv)->intr = nouveau_mc_intr;
priv->base.intr_map = nv50_mc_intr;
return 0;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,6 @@ nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;

nv_subdev(priv)->intr = nouveau_mc_intr;
priv->base.intr_map = nv98_mc_intr;
return 0;
}
Expand Down
1 change: 0 additions & 1 deletion drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;

nv_subdev(priv)->intr = nouveau_mc_intr;
priv->base.intr_map = nvc0_mc_intr;
return 0;
}
Expand Down
17 changes: 1 addition & 16 deletions drivers/gpu/drm/nouveau/nouveau_drm.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#include <engine/disp.h>

#include "nouveau_drm.h"
#include "nouveau_irq.h"
#include "nouveau_dma.h"
#include "nouveau_ttm.h"
#include "nouveau_gem.h"
Expand Down Expand Up @@ -365,10 +364,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
if (ret)
goto fail_bios;

ret = nouveau_irq_init(dev);
if (ret)
goto fail_irq;

ret = nouveau_display_create(dev);
if (ret)
goto fail_dispctor;
Expand All @@ -388,8 +383,6 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags)
fail_dispinit:
nouveau_display_destroy(dev);
fail_dispctor:
nouveau_irq_fini(dev);
fail_irq:
nouveau_bios_takedown(dev);
fail_bios:
nouveau_ttm_fini(drm);
Expand All @@ -415,7 +408,6 @@ nouveau_drm_unload(struct drm_device *dev)
nouveau_display_fini(dev);
nouveau_display_destroy(dev);

nouveau_irq_fini(dev);
nouveau_bios_takedown(dev);

nouveau_ttm_fini(drm);
Expand Down Expand Up @@ -533,7 +525,6 @@ nouveau_do_resume(struct drm_device *dev)
nouveau_fence(drm)->resume(drm);

nouveau_run_vbios_init(dev);
nouveau_irq_postinstall(dev);
nouveau_pm_resume(dev);

if (dev->mode_config.num_crtc) {
Expand Down Expand Up @@ -669,8 +660,7 @@ static struct drm_driver
driver = {
.driver_features =
DRIVER_USE_AGP | DRIVER_PCI_DMA | DRIVER_SG |
DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_GEM |
DRIVER_MODESET | DRIVER_PRIME,
DRIVER_GEM | DRIVER_MODESET | DRIVER_PRIME,

.load = nouveau_drm_load,
.unload = nouveau_drm_unload,
Expand All @@ -684,11 +674,6 @@ driver = {
.debugfs_cleanup = nouveau_debugfs_takedown,
#endif

.irq_preinstall = nouveau_irq_preinstall,
.irq_postinstall = nouveau_irq_postinstall,
.irq_uninstall = nouveau_irq_uninstall,
.irq_handler = nouveau_irq_handler,

.get_vblank_counter = drm_vblank_count,
.enable_vblank = nouveau_drm_vblank_enable,
.disable_vblank = nouveau_drm_vblank_disable,
Expand Down
76 changes: 0 additions & 76 deletions drivers/gpu/drm/nouveau/nouveau_irq.c

This file was deleted.

11 changes: 0 additions & 11 deletions drivers/gpu/drm/nouveau/nouveau_irq.h

This file was deleted.

0 comments on commit 0fa9061

Please sign in to comment.