diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2015-08-20 14:54:15 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2015-08-28 12:40:32 +1000 |
commit | a01ca78c8f118e5a24f1527ecf078ab56ddd4805 (patch) | |
tree | 34ccaf8913fcdf3a9be2794b27a30a52e8449bb0 /drivers | |
parent | 4e7e62d607a711bc8e8576a0fc7d8f242d25c9b3 (diff) | |
download | linux-a01ca78c8f118e5a24f1527ecf078ab56ddd4805.tar.bz2 |
drm/nouveau/nvif: simplify and tidy library interfaces
A variety of tweaks to the NVIF library interfaces, mostly ripping out
things that turned out to be not so useful.
- Removed refcounting from nvif_object, callers are expected to not be
stupid instead.
- nvif_client is directly reachable from anything derived from nvif_object,
removing the need for heuristics to locate it
- _new() versions of interfaces, that allocate memory for the object
they construct, have been removed. The vast majority of callers used
the embedded _init() interfaces.
- No longer storing constructor arguments (and the data returned from
nvkm) inside nvif_object, it's more or less unused and just wastes
memory.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
42 files changed, 365 insertions, 574 deletions
diff --git a/drivers/gpu/drm/nouveau/dispnv04/arb.c b/drivers/gpu/drm/nouveau/dispnv04/arb.c index c6361422a0b2..82bd4658aa58 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/arb.c +++ b/drivers/gpu/drm/nouveau/dispnv04/arb.c @@ -198,7 +198,7 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, int *burst, int *lwm) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; struct nv_fifo_info fifo_data; struct nv_sim_state sim_data; int MClk = nouveau_hw_get_clock(dev, PLL_MEMORY); diff --git a/drivers/gpu/drm/nouveau/dispnv04/dac.c b/drivers/gpu/drm/nouveau/dispnv04/dac.c index 81c1efb8b3b6..71e99cdfc40e 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dac.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dac.c @@ -65,7 +65,8 @@ int nv04_dac_output_offset(struct drm_encoder *encoder) static int sample_load_twice(struct drm_device *dev, bool sense[2]) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvif_object *device = &drm->device.object; int i; for (i = 0; i < 2; i++) { @@ -79,19 +80,19 @@ static int sample_load_twice(struct drm_device *dev, bool sense[2]) * use a 10ms timeout (guards against crtc being inactive, in * which case blank state would never change) */ - if (nvif_msec(device, 10, + if (nvif_msec(&drm->device, 10, if (!(nvif_rd32(device, NV_PRMCIO_INP0__COLOR) & 1)) break; ) < 0) return -EBUSY; - if (nvif_msec(device, 10, + if (nvif_msec(&drm->device, 10, if ( (nvif_rd32(device, NV_PRMCIO_INP0__COLOR) & 1)) break; ) < 0) return -EBUSY; - if (nvif_msec(device, 10, + if (nvif_msec(&drm->device, 10, if (!(nvif_rd32(device, NV_PRMCIO_INP0__COLOR) & 1)) break; ) < 0) @@ -132,7 +133,7 @@ static enum drm_connector_status nv04_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) { struct drm_device *dev = encoder->dev; - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; struct nouveau_drm *drm = nouveau_drm(dev); uint8_t saved_seq1, saved_pi, saved_rpc1, saved_cr_mode; uint8_t saved_palette0[3], saved_palette_mask; @@ -235,8 +236,8 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) { struct drm_device *dev = encoder->dev; struct nouveau_drm *drm = nouveau_drm(dev); - struct nvif_device *device = &nouveau_drm(dev)->device; - struct nvkm_gpio *gpio = nvxx_gpio(device); + struct nvif_object *device = &nouveau_drm(dev)->device.object; + struct nvkm_gpio *gpio = nvxx_gpio(&drm->device); struct dcb_output *dcb = nouveau_encoder(encoder)->dcb; uint32_t sample, testval, regoffset = nv04_dac_output_offset(encoder); uint32_t saved_powerctrl_2 = 0, saved_powerctrl_4 = 0, saved_routput, diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c index a85e7251e0cb..522e91ab5360 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c @@ -281,7 +281,7 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *adjusted_mode) { struct drm_device *dev = encoder->dev; - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nv04_crtc_reg *regp = &nv04_display(dev)->mode_reg.crtc_reg[nv_crtc->index]; diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index 018a4480cfc5..9e650081c357 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -47,7 +47,7 @@ nv04_display_create(struct drm_device *dev) if (!disp) return -ENOMEM; - nvif_object_map(nvif_object(&drm->device)); + nvif_object_map(&drm->device.object); nouveau_display(dev)->priv = disp; nouveau_display(dev)->dtor = nv04_display_destroy; @@ -153,7 +153,7 @@ nv04_display_destroy(struct drm_device *dev) nouveau_display(dev)->priv = NULL; kfree(disp); - nvif_object_unmap(nvif_object(&drm->device)); + nvif_object_unmap(&drm->device.object); } int diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c index 5039bb530523..956a833b8200 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/hw.c +++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c @@ -165,8 +165,8 @@ nouveau_hw_get_pllvals(struct drm_device *dev, enum nvbios_pll_type plltype, struct nvkm_pll_vals *pllvals) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nvif_device *device = &drm->device; - struct nvkm_bios *bios = nvxx_bios(device); + struct nvif_object *device = &drm->device.object; + struct nvkm_bios *bios = nvxx_bios(&drm->device); uint32_t reg1, pll1, pll2 = 0; struct nvbios_pll pll_lim; int ret; @@ -660,7 +660,7 @@ nv_load_state_ext(struct drm_device *dev, int head, struct nv04_mode_state *state) { struct nouveau_drm *drm = nouveau_drm(dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; struct nv04_crtc_reg *regp = &state->crtc_reg[head]; uint32_t reg900; int i; @@ -677,10 +677,10 @@ nv_load_state_ext(struct drm_device *dev, int head, nvif_wr32(device, NV_PVIDEO_INTR_EN, 0); nvif_wr32(device, NV_PVIDEO_OFFSET_BUFF(0), 0); nvif_wr32(device, NV_PVIDEO_OFFSET_BUFF(1), 0); - nvif_wr32(device, NV_PVIDEO_LIMIT(0), device->info.ram_size - 1); - nvif_wr32(device, NV_PVIDEO_LIMIT(1), device->info.ram_size - 1); - nvif_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(0), device->info.ram_size - 1); - nvif_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(1), device->info.ram_size - 1); + nvif_wr32(device, NV_PVIDEO_LIMIT(0), drm->device.info.ram_size - 1); + nvif_wr32(device, NV_PVIDEO_LIMIT(1), drm->device.info.ram_size - 1); + nvif_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(0), drm->device.info.ram_size - 1); + nvif_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(1), drm->device.info.ram_size - 1); nvif_wr32(device, NV_PBUS_POWERCTRL_2, 0); NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg); @@ -740,11 +740,11 @@ nv_load_state_ext(struct drm_device *dev, int head, if (drm->device.info.family < NV_DEVICE_INFO_V0_KELVIN) { /* Not waiting for vertical retrace before modifying CRE_53/CRE_54 causes lockups. */ - nvif_msec(device, 650, + nvif_msec(&drm->device, 650, if ( (nvif_rd32(device, NV_PRMCIO_INP0__COLOR) & 8)) break; ); - nvif_msec(device, 650, + nvif_msec(&drm->device, 650, if (!(nvif_rd32(device, NV_PRMCIO_INP0__COLOR) & 8)) break; ); @@ -770,7 +770,7 @@ static void nv_save_state_palette(struct drm_device *dev, int head, struct nv04_mode_state *state) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; int head_offset = head * NV_PRMDIO_SIZE, i; nvif_wr08(device, NV_PRMDIO_PIXEL_MASK + head_offset, @@ -789,7 +789,7 @@ void nouveau_hw_load_state_palette(struct drm_device *dev, int head, struct nv04_mode_state *state) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; int head_offset = head * NV_PRMDIO_SIZE, i; nvif_wr08(device, NV_PRMDIO_PIXEL_MASK + head_offset, diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.h b/drivers/gpu/drm/nouveau/dispnv04/hw.h index 6c796178bf0c..3bded60c5596 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/hw.h +++ b/drivers/gpu/drm/nouveau/dispnv04/hw.h @@ -60,7 +60,7 @@ extern void nouveau_calc_arb(struct drm_device *, int vclk, int bpp, static inline uint32_t NVReadCRTC(struct drm_device *dev, int head, uint32_t reg) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; uint32_t val; if (head) reg += NV_PCRTC0_SIZE; @@ -71,7 +71,7 @@ static inline uint32_t NVReadCRTC(struct drm_device *dev, static inline void NVWriteCRTC(struct drm_device *dev, int head, uint32_t reg, uint32_t val) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; if (head) reg += NV_PCRTC0_SIZE; nvif_wr32(device, reg, val); @@ -80,7 +80,7 @@ static inline void NVWriteCRTC(struct drm_device *dev, static inline uint32_t NVReadRAMDAC(struct drm_device *dev, int head, uint32_t reg) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; uint32_t val; if (head) reg += NV_PRAMDAC0_SIZE; @@ -91,7 +91,7 @@ static inline uint32_t NVReadRAMDAC(struct drm_device *dev, static inline void NVWriteRAMDAC(struct drm_device *dev, int head, uint32_t reg, uint32_t val) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; if (head) reg += NV_PRAMDAC0_SIZE; nvif_wr32(device, reg, val); @@ -120,7 +120,7 @@ static inline void nv_write_tmds(struct drm_device *dev, static inline void NVWriteVgaCrtc(struct drm_device *dev, int head, uint8_t index, uint8_t value) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; nvif_wr08(device, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); nvif_wr08(device, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE, value); } @@ -128,7 +128,7 @@ static inline void NVWriteVgaCrtc(struct drm_device *dev, static inline uint8_t NVReadVgaCrtc(struct drm_device *dev, int head, uint8_t index) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; uint8_t val; nvif_wr08(device, NV_PRMCIO_CRX__COLOR + head * NV_PRMCIO_SIZE, index); val = nvif_rd08(device, NV_PRMCIO_CR__COLOR + head * NV_PRMCIO_SIZE); @@ -165,7 +165,7 @@ static inline uint8_t NVReadVgaCrtc5758(struct drm_device *dev, int head, uint8_ static inline uint8_t NVReadPRMVIO(struct drm_device *dev, int head, uint32_t reg) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; struct nouveau_drm *drm = nouveau_drm(dev); uint8_t val; @@ -181,7 +181,7 @@ static inline uint8_t NVReadPRMVIO(struct drm_device *dev, static inline void NVWritePRMVIO(struct drm_device *dev, int head, uint32_t reg, uint8_t value) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; struct nouveau_drm *drm = nouveau_drm(dev); /* Only NV4x have two pvio ranges; other twoHeads cards MUST call @@ -194,14 +194,14 @@ static inline void NVWritePRMVIO(struct drm_device *dev, static inline void NVSetEnablePalette(struct drm_device *dev, int head, bool enable) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; nvif_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); nvif_wr08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE, enable ? 0 : 0x20); } static inline bool NVGetEnablePalette(struct drm_device *dev, int head) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; nvif_rd08(device, NV_PRMCIO_INP0__COLOR + head * NV_PRMCIO_SIZE); return !(nvif_rd08(device, NV_PRMCIO_ARX + head * NV_PRMCIO_SIZE) & 0x20); } @@ -209,7 +209,7 @@ static inline bool NVGetEnablePalette(struct drm_device *dev, int head) static inline void NVWriteVgaAttr(struct drm_device *dev, int head, uint8_t index, uint8_t value) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; if (NVGetEnablePalette(dev, head)) index &= ~0x20; else @@ -223,7 +223,7 @@ static inline void NVWriteVgaAttr(struct drm_device *dev, static inline uint8_t NVReadVgaAttr(struct drm_device *dev, int head, uint8_t index) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; uint8_t val; if (NVGetEnablePalette(dev, head)) index &= ~0x20; @@ -259,7 +259,7 @@ static inline void NVVgaProtect(struct drm_device *dev, int head, bool protect) static inline bool nv_heads_tied(struct drm_device *dev) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nvif_object *device = &nouveau_drm(dev)->device.object; struct nouveau_drm *drm = nouveau_drm(dev); if (drm->device.info.chipset == 0x11) diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c index 5f6ea1873f51..aeebdd402478 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ b/drivers/gpu/drm/nouveau/dispnv04/overlay.c @@ -96,7 +96,8 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) { - struct nvif_device *dev = &nouveau_drm(plane->dev)->device; + struct nouveau_drm *drm = nouveau_drm(plane->dev); + struct nvif_object *dev = &drm->device.object; struct nouveau_plane *nv_plane = container_of(plane, struct nouveau_plane, base); struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); @@ -118,7 +119,7 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, if (format > 0xffff) return -ERANGE; - if (dev->info.chipset >= 0x30) { + if (drm->device.info.chipset >= 0x30) { if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1)) return -ERANGE; } else { @@ -173,7 +174,7 @@ nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, static int nv10_disable_plane(struct drm_plane *plane) { - struct nvif_device *dev = &nouveau_drm(plane->dev)->device; + struct nvif_object *dev = &nouveau_drm(plane->dev)->device.object; struct nouveau_plane *nv_plane = container_of(plane, struct nouveau_plane, base); @@ -197,7 +198,7 @@ nv_destroy_plane(struct drm_plane *plane) static void nv10_set_params(struct nouveau_plane *plane) { - struct nvif_device *dev = &nouveau_drm(plane->base.dev)->device; + struct nvif_object *dev = &nouveau_drm(plane->base.dev)->device.object; u32 luma = (plane->brightness - 512) << 16 | plane->contrast; u32 chroma = ((sin_mul(plane->hue, plane->saturation) & 0xffff) << 16) | (cos_mul(plane->hue, plane->saturation) & 0xffff); @@ -346,7 +347,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, uint32_t src_x, uint32_t src_y, uint32_t src_w, uint32_t src_h) { - struct nvif_device *dev = &nouveau_drm(plane->dev)->device; + struct nvif_object *dev = &nouveau_drm(plane->dev)->device.object; struct nouveau_plane *nv_plane = container_of(plane, struct nouveau_plane, base); struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); @@ -426,7 +427,7 @@ nv04_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, static int nv04_disable_plane(struct drm_plane *plane) { - struct nvif_device *dev = &nouveau_drm(plane->dev)->device; + struct nvif_object *dev = &nouveau_drm(plane->dev)->device.object; struct nouveau_plane *nv_plane = container_of(plane, struct nouveau_plane, base); diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h index 225894cdcac2..459910b6bb32 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv17.h @@ -131,13 +131,13 @@ static inline void nv_write_ptv(struct drm_device *dev, uint32_t reg, uint32_t val) { struct nvif_device *device = &nouveau_drm(dev)->device; - nvif_wr32(device, reg, val); + nvif_wr32(&device->object, reg, val); } static inline uint32_t nv_read_ptv(struct drm_device *dev, uint32_t reg) { struct nvif_device *device = &nouveau_drm(dev)->device; - return nvif_rd32(device, reg); + return nvif_rd32(&device->object, reg); } static inline void nv_write_tv_enc(struct drm_device *dev, uint8_t reg, diff --git a/drivers/gpu/drm/nouveau/include/nvif/client.h b/drivers/gpu/drm/nouveau/include/nvif/client.h index eca648ef0f7a..cd6fbfa88762 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/client.h +++ b/drivers/gpu/drm/nouveau/include/nvif/client.h @@ -4,36 +4,24 @@ #include <nvif/object.h> struct nvif_client { - struct nvif_object base; - struct nvif_object *object; /*XXX: hack for nvif_object() */ + struct nvif_object object; const struct nvif_driver *driver; + u8 route; bool super; }; -static inline struct nvif_client * -nvif_client(struct nvif_object *object) -{ - while (object && object->parent != object) - object = object->parent; - return (void *)object; -} - -int nvif_client_init(void (*dtor)(struct nvif_client *), const char *, - const char *, u64, const char *, const char *, +int nvif_client_init(const char *drv, const char *name, u64 device, + const char *cfg, const char *dbg, struct nvif_client *); void nvif_client_fini(struct nvif_client *); -int nvif_client_new(const char *, const char *, u64, const char *, - const char *, struct nvif_client **); -void nvif_client_ref(struct nvif_client *, struct nvif_client **); int nvif_client_ioctl(struct nvif_client *, void *, u32); int nvif_client_suspend(struct nvif_client *); int nvif_client_resume(struct nvif_client *); /*XXX*/ #include <core/client.h> -#define nvxx_client(a) ({ \ - struct nvif_client *_client = nvif_client(nvif_object(a)); \ - nvkm_client(_client->base.priv); \ +#define nvxx_client(a) ({ \ + struct nvif_client *_client = (a); \ + nvkm_client(_client->object.priv); \ }) - #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h index 077651f9b7e9..1973e65f21a6 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/device.h +++ b/drivers/gpu/drm/nouveau/include/nvif/device.h @@ -5,26 +5,13 @@ #include <nvif/class.h> struct nvif_device { - struct nvif_object base; - struct nvif_object *object; /*XXX: hack for nvif_object() */ + struct nvif_object object; struct nv_device_info_v0 info; }; -static inline struct nvif_device * -nvif_device(struct nvif_object *object) -{ - while (object && object->oclass != 0x0080 /*XXX: NV_DEVICE_CLASS*/ ) - object = object->parent; - return (void *)object; -} - -int nvif_device_init(struct nvif_object *, void (*dtor)(struct nvif_device *), - u32 handle, u32 oclass, void *, u32, +int nvif_device_init(struct nvif_object *, u32 handle, u32 oclass, void *, u32, struct nvif_device *); void nvif_device_fini(struct nvif_device *); -int nvif_device_new(struct nvif_object *, u32 handle, u32 oclass, - void *, u32, struct nvif_device **); -void nvif_device_ref(struct nvif_device *, struct nvif_device **); u64 nvif_device_time(struct nvif_device *); /* Delay based on GPU time (ie. PTIMER). @@ -59,7 +46,10 @@ u64 nvif_device_time(struct nvif_device *); #include <subdev/timer.h> #include <subdev/therm.h> -#define nvxx_device(a) nv_device(nvxx_object((a))) +#define nvxx_device(a) ({ \ + struct nvif_device *_device = (a); \ + nv_device(_device->object.priv); \ +}) #define nvxx_bios(a) nvkm_bios(nvxx_device(a)) #define nvxx_fb(a) nvkm_fb(nvxx_device(a)) #define nvxx_mmu(a) nvkm_mmu(nvxx_device(a)) @@ -77,5 +67,5 @@ u64 nvif_device_time(struct nvif_device *); #define nvxx_fifo(a) nvkm_fifo(nvxx_device(a)) #define nvxx_fifo_chan(a) ((struct nvkm_fifo_chan *)nvxx_object(a)) -#define nvxx_gr(a) ((struct nvkm_gr *)nvkm_engine(nvxx_object(a), NVDEV_ENGINE_GR)) +#define nvxx_gr(a) nvkm_gr(nvxx_device(a)) #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/notify.h b/drivers/gpu/drm/nouveau/include/nvif/notify.h index 9ebfa3b45e76..51e2eb580809 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/notify.h +++ b/drivers/gpu/drm/nouveau/include/nvif/notify.h @@ -23,17 +23,11 @@ struct nvif_notify { struct work_struct work; }; -int nvif_notify_init(struct nvif_object *, void (*dtor)(struct nvif_notify *), - int (*func)(struct nvif_notify *), bool work, u8 type, - void *data, u32 size, u32 reply, struct nvif_notify *); +int nvif_notify_init(struct nvif_object *, int (*func)(struct nvif_notify *), + bool work, u8 type, void *data, u32 size, u32 reply, + struct nvif_notify *); int nvif_notify_fini(struct nvif_notify *); int nvif_notify_get(struct nvif_notify *); int nvif_notify_put(struct nvif_notify *); int nvif_notify(const void *, u32, const void *, u32); - -int nvif_notify_new(struct nvif_object *, int (*func)(struct nvif_notify *), - bool work, u8 type, void *data, u32 size, u32 reply, - struct nvif_notify **); -void nvif_notify_ref(struct nvif_notify *, struct nvif_notify **); - #endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h index 04c874707b96..66d94c74b351 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/object.h +++ b/drivers/gpu/drm/nouveau/include/nvif/object.h @@ -4,28 +4,20 @@ #include <nvif/os.h> struct nvif_object { + struct nvif_client *client; struct nvif_object *parent; - struct nvif_object *object; /*XXX: hack for nvif_object() */ - struct kref refcount; u32 handle; u32 oclass; - void *data; - u32 size; void *priv; /*XXX: hack */ - void (*dtor)(struct nvif_object *); struct { void __iomem *ptr; u32 size; } map; }; -int nvif_object_init(struct nvif_object *, void (*dtor)(struct nvif_object *), - u32 handle, u32 oclass, void *, u32, +int nvif_object_init(struct nvif_object *, u32 handle, u32 oclass, void *, u32, struct nvif_object *); void nvif_object_fini(struct nvif_object *); -int nvif_object_new(struct nvif_object *, u32 handle, u32 oclass, - void *, u32, struct nvif_object **); -void nvif_object_ref(struct nvif_object *, struct nvif_object **); int nvif_object_ioctl(struct nvif_object *, void *, u32, void **); int nvif_object_sclass(struct nvif_object *, u32 *, int); u32 nvif_object_rd(struct nvif_object *, int, u64); @@ -36,40 +28,41 @@ void nvif_object_unmap(struct nvif_object *); #define nvif_object(a) (a)->object -#define ioread8_native ioread8 -#define iowrite8_native iowrite8 -#define nvif_rd(a,b,c) ({ \ - struct nvif_object *_object = nvif_object(a); \ +#define nvif_rd(a,f,b,c) ({ \ + struct nvif_object *_object = (a); \ u32 _data; \ if (likely(_object->map.ptr)) \ - _data = ioread##b##_native((u8 __iomem *)_object->map.ptr + (c)); \ + _data = f((u8 __iomem *)_object->map.ptr + (c)); \ else \ - _data = nvif_object_rd(_object, (b) / 8, (c)); \ + _data = nvif_object_rd(_object, (b), (c)); \ _data; \ }) -#define nvif_wr(a,b,c,d) ({ \ - struct nvif_object *_object = nvif_object(a); \ +#define nvif_wr(a,f,b,c,d) ({ \ + struct nvif_object *_object = (a); \ if (likely(_object->map.ptr)) \ - iowrite##b##_native((d), (u8 __iomem *)_object->map.ptr + (c)); \ + f((d), (u8 __iomem *)_object->map.ptr + (c)); \ else \ - nvif_object_wr(_object, (b) / 8, (c), (d)); \ + nvif_object_wr(_object, (b), (c), (d)); \ }) -#define nvif_rd08(a,b) ({ u8 _v = nvif_rd((a), 8, (b)); _v; }) -#define nvif_rd16(a,b) ({ u16 _v = nvif_rd((a), 16, (b)); _v; }) -#define nvif_rd32(a,b) ({ u32 _v = nvif_rd((a), 32, (b)); _v; }) -#define nvif_wr08(a,b,c) nvif_wr((a), 8, (b), (u8)(c)) -#define nvif_wr16(a,b,c) nvif_wr((a), 16, (b), (u16)(c)) -#define nvif_wr32(a,b,c) nvif_wr((a), 32, (b), (u32)(c)) +#define nvif_rd08(a,b) ({ ((u8)nvif_rd((a), ioread8, 1, (b))); }) +#define nvif_rd16(a,b) ({ ((u16)nvif_rd((a), ioread16_native, 2, (b))); }) +#define nvif_rd32(a,b) ({ ((u32)nvif_rd((a), ioread32_native, 4, (b))); }) +#define nvif_wr08(a,b,c) nvif_wr((a), iowrite8, 1, (b), (u8)(c)) +#define nvif_wr16(a,b,c) nvif_wr((a), iowrite16_native, 2, (b), (u16)(c)) +#define nvif_wr32(a,b,c) nvif_wr((a), iowrite32_native, 4, (b), (u32)(c)) #define nvif_mask(a,b,c,d) ({ \ - u32 _v = nvif_rd32(nvif_object(a), (b)); \ - nvif_wr32(nvif_object(a), (b), (_v & ~(c)) | (d)); \ - _v; \ + struct nvif_object *__object = (a); \ + u32 _addr = (b), _data = nvif_rd32(__object, _addr); \ + nvif_wr32(__object, _addr, (_data & ~(c)) | (d)); \ + _data; \ }) -#define nvif_mthd(a,b,c,d) nvif_object_mthd(nvif_object(a), (b), (c), (d)) +#define nvif_mthd(a,b,c,d) nvif_object_mthd((a), (b), (c), (d)) /*XXX*/ #include <core/object.h> -#define nvxx_object(a) ((struct nvkm_object *)nvif_object(a)->priv) - +#define nvxx_object(a) ({ \ + struct nvif_object *_object = (a); \ + (struct nvkm_object *)_object->priv; \ +}) #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 01ffdb37a66b..76c363223e3f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -51,7 +51,7 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) * device (ie. the one that belongs to the fd it * opened) */ - if (nvif_device_init(&cli->base.base, NULL, + if (nvif_device_init(&cli->base.object, NOUVEAU_ABI16_DEVICE, NV_DEVICE, &args, sizeof(args), &abi16->device) == 0) @@ -69,7 +69,7 @@ nouveau_abi16_get(struct drm_file *file_priv, struct drm_device *dev) int nouveau_abi16_put(struct nouveau_abi16 *abi16, int ret) { - struct nouveau_cli *cli = (void *)nvif_client(&abi16->device.base); + struct nouveau_cli *cli = (void *)abi16->device.object.client; mutex_unlock(&cli->mutex); return ret; } @@ -100,6 +100,7 @@ static void nouveau_abi16_ntfy_fini(struct nouveau_abi16_chan *chan, struct nouveau_abi16_ntfy *ntfy) { + nvif_object_fini(&ntfy->object); nvkm_mm_free(&chan->heap, &ntfy->node); list_del(&ntfy->head); kfree(ntfy); @@ -132,7 +133,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, /* destroy channel object, all children will be killed too */ if (chan->chan) { - abi16->handles &= ~(1ULL << (chan->chan->object->handle & 0xffff)); + abi16->handles &= ~(1ULL << (chan->chan->user.handle & 0xffff)); nouveau_channel_del(&chan->chan); } @@ -143,7 +144,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, void nouveau_abi16_fini(struct nouveau_abi16 *abi16) { - struct nouveau_cli *cli = (void *)nvif_client(&abi16->device.base); + struct nouveau_cli *cli = (void *)abi16->device.object.client; struct nouveau_abi16_chan *chan, *temp; /* cleanup channels */ @@ -336,7 +337,7 @@ nouveau_abi16_chan(struct nouveau_abi16 *abi16, int channel) struct nouveau_abi16_chan *chan; list_for_each_entry(chan, &abi16->channels, head) { - if (chan->chan->object->handle == NOUVEAU_ABI16_CHAN(channel)) + if (chan->chan->user.handle == NOUVEAU_ABI16_CHAN(channel)) return chan; } @@ -364,21 +365,9 @@ int nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) { struct drm_nouveau_grobj_alloc *init = data; - struct { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_new_v0 new; - } args = { - .ioctl.owner = NVIF_IOCTL_V0_OWNER_ANY, - .ioctl.type = NVIF_IOCTL_V0_NEW, - .ioctl.path_nr = 3, - .ioctl.path[2] = NOUVEAU_ABI16_CLIENT, - .ioctl.path[1] = NOUVEAU_ABI16_DEVICE, - .ioctl.path[0] = NOUVEAU_ABI16_CHAN(init->channel), - .new.route = NVDRM_OBJECT_ABI16, - .new.handle = init->handle, - .new.oclass = init->class, - }; struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); + struct nouveau_abi16_chan *chan; + struct nouveau_abi16_ntfy *ntfy; struct nouveau_drm *drm = nouveau_drm(dev); struct nvif_client *client; int ret; @@ -388,7 +377,7 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) if (init->handle == ~0) return nouveau_abi16_put(abi16, -EINVAL); - client = nvif_client(nvif_object(&abi16->device)); + client = abi16->device.object.client; /* compatibility with userspace that assumes 506e for all chipsets */ if (init->class == 0x506e) { @@ -397,7 +386,23 @@ nouveau_abi16_ioctl_grobj_alloc(ABI16_IOCTL_ARGS) return nouveau_abi16_put(abi16, 0); } - ret = nvif_client_ioctl(client, &args, sizeof(args)); + chan = nouveau_abi16_chan(abi16, init->channel); + if (!chan) + return nouveau_abi16_put(abi16, -ENOENT); + + ntfy = kzalloc(sizeof(*ntfy), GFP_KERNEL); + if (!ntfy) + return nouveau_abi16_put(abi16, -ENOMEM); + + list_add(&ntfy->head, &chan->notifiers); + + client->route = NVDRM_OBJECT_ABI16; + ret = nvif_object_init(&chan->chan->user, init->handle, init->class, + NULL, 0, &ntfy->object); + client->route = NVDRM_OBJECT_NVIF; + + if (ret) + nouveau_abi16_ntfy_fini(chan, ntfy); return nouveau_abi16_put(abi16, ret); } @@ -405,27 +410,13 @@ int nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) { struct drm_nouveau_notifierobj_alloc *info = data; - struct { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_new_v0 new; - struct nv_dma_v0 ctxdma; - } args = { - .ioctl.owner = NVIF_IOCTL_V0_OWNER_ANY, - .ioctl.type = NVIF_IOCTL_V0_NEW, - .ioctl.path_nr = 3, - .ioctl.path[2] = NOUVEAU_ABI16_CLIENT, - .ioctl.path[1] = NOUVEAU_ABI16_DEVICE, - .ioctl.path[0] = NOUVEAU_ABI16_CHAN(info->channel), - .new.route = NVDRM_OBJECT_ABI16, - .new.handle = info->handle, - .new.oclass = NV_DMA_IN_MEMORY, - }; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16_chan *chan; struct nouveau_abi16_ntfy *ntfy; struct nvif_device *device = &abi16->device; struct nvif_client *client; + struct nv_dma_v0 args = {}; int ret; if (unlikely(!abi16)) @@ -434,7 +425,7 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) /* completely unnecessary for these chipsets... */ if (unlikely(device->info.family >= NV_DEVICE_INFO_V0_FERMI)) return nouveau_abi16_put(abi16, -EINVAL); - client = nvif_client(nvif_object(&abi16->device)); + client = abi16->device.object.client; chan = nouveau_abi16_chan(abi16, info->channel); if (!chan) @@ -445,41 +436,43 @@ nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS) return nouveau_abi16_put(abi16, -ENOMEM); list_add(&ntfy->head, &chan->notifiers); - ntfy->handle = info->handle; ret = nvkm_mm_head(&chan->heap, 0, 1, info->size, info->size, 1, &ntfy->node); if (ret) goto done; - args.ctxdma.start = ntfy->node->offset; - args.ctxdma.limit = ntfy->node->offset + ntfy->node->length - 1; + args.start = ntfy->node->offset; + args.limit = ntfy->node->offset + ntfy->node->length - 1; if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { - args.ctxdma.target = NV_DMA_V0_TARGET_VM; - args.ctxdma.access = NV_DMA_V0_ACCESS_VM; - args.ctxdma.start += chan->ntfy_vma.offset; - args.ctxdma.limit += chan->ntfy_vma.offset; + args.target = NV_DMA_V0_TARGET_VM; + args.access = NV_DMA_V0_ACCESS_VM; + args.start += chan->ntfy_vma.offset; + args.limit += chan->ntfy_vma.offset; } else if (drm->agp.stat == ENABLED) { - args.ctxdma.target = NV_DMA_V0_TARGET_AGP; - args.ctxdma.access = NV_DMA_V0_ACCESS_RDWR; - args.ctxdma.start += drm->agp.base + chan->ntfy->bo.offset; - args.ctxdma.limit += drm->agp.base + chan->ntfy->bo.offset; - client->super = true; + args.target = NV_DMA_V0_TARGET_AGP; + args.access = NV_DMA_V0_ACCESS_RDWR; + args.start += drm->agp.base + chan->ntfy->bo.offset; + args.limit += drm->agp.base + chan->ntfy->bo.offset; } else { - args.ctxdma.target = NV_DMA_V0_TARGET_VM; - args.ctxdma.access = NV_DMA_V0_ACCESS_RDWR; - args.ctxdma.start += chan->ntfy->bo.offset; - args.ctxdma.limit += chan->ntfy->bo.offset; + args.target = NV_DMA_V0_TARGET_VM; + args.access = NV_DMA_V0_ACCESS_RDWR; + args.start += chan->ntfy->bo.offset; + args.limit += chan->ntfy->bo.offset; } - ret = nvif_client_ioctl(client, &args, sizeof(args)); + client->route = NVDRM_OBJECT_ABI16; + client->super = true; + ret = nvif_object_init(&chan->chan->user, info->handle, + NV_DMA_IN_MEMORY, &args, sizeof(args), + &ntfy->object); client->super = false; + client->route = NVDRM_OBJECT_NVIF; if (ret) goto done; info->offset = ntfy->node->offset; - done: if (ret) nouveau_abi16_ntfy_fini(chan, ntfy); @@ -490,47 +483,28 @@ int nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS) { struct drm_nouveau_gpuobj_free *fini = data; - struct { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_del del; - } args = { - .ioctl.owner = NVDRM_OBJECT_ABI16, - .ioctl.type = NVIF_IOCTL_V0_DEL, - .ioctl.path_nr = 4, - .ioctl.path[3] = NOUVEAU_ABI16_CLIENT, - .ioctl.path[2] = NOUVEAU_ABI16_DEVICE, - .ioctl.path[1] = NOUVEAU_ABI16_CHAN(fini->channel), - .ioctl.path[0] = fini->handle, - }; struct nouveau_abi16 *abi16 = nouveau_abi16_get(file_priv, dev); struct nouveau_abi16_chan *chan; struct nouveau_abi16_ntfy *ntfy; - struct nvif_client *client; - int ret; + int ret = -ENOENT; if (unlikely(!abi16)) return -ENOMEM; chan = nouveau_abi16_chan(abi16, fini->channel); if (!chan) - return nouveau_abi16_put(abi16, -ENOENT); - client = nvif_client(nvif_object(&abi16->device)); + return nouveau_abi16_put(abi16, -EINVAL); /* synchronize with the user channel and destroy the gpu object */ nouveau_channel_idle(chan->chan); - ret = nvif_client_ioctl(client, &args, sizeof(args)); - if (ret) - return nouveau_abi16_put(abi16, ret); - - /* cleanup extra state if this object was a notifier */ list_for_each_entry(ntfy, &chan->notifiers, head) { - if (ntfy->handle == fini->handle) { - nvkm_mm_free(&chan->heap, &ntfy->node); - list_del(&ntfy->head); + if (ntfy->object.handle == fini->handle) { + nouveau_abi16_ntfy_fini(chan, ntfy); + ret = 0; break; } } - return nouveau_abi16_put(abi16, 0); + return nouveau_abi16_put(abi16, ret); } diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.h b/drivers/gpu/drm/nouveau/nouveau_abi16.h index 86eb1caf4957..b8acfd787d54 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.h +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.h @@ -13,9 +13,9 @@ int nouveau_abi16_ioctl_notifierobj_alloc(ABI16_IOCTL_ARGS); int nouveau_abi16_ioctl_gpuobj_free(ABI16_IOCTL_ARGS); struct nouveau_abi16_ntfy { + struct nvif_object object; struct list_head head; struct nvkm_mm_node *node; - u32 handle; }; struct nouveau_abi16_chan { diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.c b/drivers/gpu/drm/nouveau/nouveau_agp.c index 0b5970955604..320f48c41fe0 100644 --- a/drivers/gpu/drm/nouveau/nouveau_agp.c +++ b/drivers/gpu/drm/nouveau/nouveau_agp.c @@ -102,7 +102,7 @@ void nouveau_agp_reset(struct nouveau_drm *drm) { #if __OS_HAS_AGP - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; struct drm_device *dev = drm->dev; u32 save[2]; int ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index e566c5b53651..89eb46040b13 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -40,7 +40,7 @@ static int nv40_get_intensity(struct backlight_device *bd) { struct nouveau_drm *drm = bl_get_data(bd); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; int val = (nvif_rd32(device, NV40_PMC_BACKLIGHT) & NV40_PMC_BACKLIGHT_MASK) >> 16; @@ -51,7 +51,7 @@ static int nv40_set_intensity(struct backlight_device *bd) { struct nouveau_drm *drm = bl_get_data(bd); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; int val = bd->props.brightness; int reg = nvif_rd32(device, NV40_PMC_BACKLIGHT); @@ -71,7 +71,7 @@ static int nv40_backlight_init(struct drm_connector *connector) { struct nouveau_drm *drm = nouveau_drm(connector->dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; struct backlight_properties props; struct backlight_device *bd; @@ -97,7 +97,7 @@ nv50_get_intensity(struct backlight_device *bd) { struct nouveau_encoder *nv_encoder = bl_get_data(bd); struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; int or = nv_encoder->or; u32 div = 1025; u32 val; @@ -112,7 +112,7 @@ nv50_set_intensity(struct backlight_device *bd) { struct nouveau_encoder *nv_encoder = bl_get_data(bd); struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; int or = nv_encoder->or; u32 div = 1025; u32 val = (bd->props.brightness * div) / 100; @@ -133,7 +133,7 @@ nva3_get_intensity(struct backlight_device *bd) { struct nouveau_encoder *nv_encoder = bl_get_data(bd); struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; int or = nv_encoder->or; u32 div, val; @@ -151,7 +151,7 @@ nva3_set_intensity(struct backlight_device *bd) { struct nouveau_encoder *nv_encoder = bl_get_data(bd); struct nouveau_drm *drm = nouveau_drm(nv_encoder->base.base.dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; int or = nv_encoder->or; u32 div, val; @@ -177,7 +177,7 @@ static int nv50_backlight_init(struct drm_connector *connector) { struct nouveau_drm *drm = nouveau_drm(connector->dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; struct nouveau_encoder *nv_encoder; struct backlight_properties props; struct backlight_device *bd; @@ -193,9 +193,9 @@ nv50_backlight_init(struct drm_connector *connector) if (!nvif_rd32(device, NV50_PDISP_SOR_PWM_CTL(nv_encoder->or))) return 0; - if (device->info.chipset <= 0xa0 || - device->info.chipset == 0xaa || - device->info.chipset == 0xac) + if (drm->device.info.chipset <= 0xa0 || + drm->device.info.chipset == 0xaa || + drm->device.info.chipset == 0xac) ops = &nv50_bl_ops; else ops = &nva3_bl_ops; diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 3199479ac5b3..4dca65a63b92 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -215,7 +215,7 @@ int call_lvds_script(struct drm_device *dev, struct dcb_output *dcbent, int head */ struct nouveau_drm *drm = nouveau_drm(dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; struct nvbios *bios = &drm->vbios; uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer]; uint32_t sel_clk_binding, sel_clk; @@ -318,7 +318,8 @@ static int parse_lvds_manufacturer_table_header(struct drm_device *dev, struct n static int get_fp_strap(struct drm_device *dev, struct nvbios *bios) { - struct nvif_device *device = &nouveau_drm(dev)->device; + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvif_object *device = &drm->device.object; /* * The fp strap is normally dictated by the "User Strap" in @@ -332,7 +333,7 @@ get_fp_strap(struct drm_device *dev, struct nvbios *bios) if (bios->major_version < 5 && bios->data[0x48] & 0x4) return NVReadVgaCrtc5758(dev, 0, 0xf) & 0xf; - if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) + if (drm->device.info.family >= NV_DEVICE_INFO_V0_TESLA) return (nvif_rd32(device, NV_PEXTDEV_BOOT_0) >> 24) & 0xf; else return (nvif_rd32(device, NV_PEXTDEV_BOOT_0) >> 16) & 0xf; @@ -634,7 +635,7 @@ int run_tmds_table(struct drm_device *dev, struct dcb_output *dcbent, int head, */ struct nouveau_drm *drm = nouveau_drm(dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; struct nvbios *bios = &drm->vbios; int cv = bios->chip_version; uint16_t clktable = 0, scriptptr; @@ -1914,7 +1915,7 @@ static int load_nv17_hwsq_ucode_entry(struct drm_device *dev, struct nvbios *bio */ struct nouveau_drm *drm = nouveau_drm(dev); - struct nvif_device *device = &drm->device; + struct nvif_object *device = &drm->device.object; uint8_t bytes_to_write; uint16_t hwsq_entry_offset; int i; diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 37ed3b250ac5..5529fc479d8a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -1064,7 +1064,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, { struct nouveau_drm *drm = nouveau_bdev(bo->bdev); struct nouveau_channel *chan = drm->ttm.chan; - struct nouveau_cli *cli = (void *)nvif_client(&chan->device->base); + struct nouveau_cli *cli = (void *)chan->user.client; struct nouveau_fence *fence; int ret; @@ -1137,7 +1137,7 @@ nouveau_bo_move_init(struct nouveau_drm *drm) if (chan == NULL) continue; - ret = nvif_object_init(chan->object, NULL, + ret = nvif_object_init(&chan->user, mthd->oclass | (mthd->engine << 16), mthd->oclass, NULL, 0, &drm->ttm.copy); diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 694b135e27c9..302713821f08 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -42,7 +42,7 @@ module_param_named(vram_pushbuf, nouveau_vram_pushbuf, int, 0400); int nouveau_channel_idle(struct nouveau_channel *chan) { - struct nouveau_cli *cli = (void *)nvif_client(chan->object); + struct nouveau_cli *cli = (void *)chan->user.client; struct nouveau_fence *fence = NULL; int ret; @@ -54,7 +54,7 @@ nouveau_channel_idle(struct nouveau_channel *chan) if (ret) NV_PRINTK(err, cli, "failed to idle channel 0x%08x [%s]\n", - chan->object->handle, nvxx_client(&cli->base)->name); + chan->user.handle, nvxx_client(&cli->base)->name); return ret; } @@ -70,14 +70,13 @@ nouveau_channel_del(struct nouveau_channel **pchan) nvif_object_fini(&chan->nvsw); nvif_object_fini(&chan->gart); nvif_object_fini(&chan->vram); - nvif_object_ref(NULL, &chan->object); + nvif_object_fini(&chan->user); nvif_object_fini(&chan->push.ctxdma); nouveau_bo_vma_del(chan->push.buffer, &chan->push.vma); nouveau_bo_unmap(chan->push.buffer); if (chan->push.buffer && chan->push.buffer->pin_refcnt) nouveau_bo_unpin(chan->push.buffer); nouveau_bo_ref(NULL, &chan->push.buffer); - nvif_device_ref(NULL, &chan->device); kfree(chan); } *pchan = NULL; @@ -87,7 +86,7 @@ static int nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, u32 handle, u32 size, struct nouveau_channel **pchan) { - struct nouveau_cli *cli = (void *)nvif_client(&device->base); + struct nouveau_cli *cli = (void *)device->object.client; struct nvkm_mmu *mmu = nvxx_mmu(device); struct nv_dma_v0 args = {}; struct nouveau_channel *chan; @@ -98,7 +97,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, if (!chan) return -ENOMEM; - nvif_device_ref(device, &chan->device); + chan->device = device; chan->drm = drm; /* allocate memory for dma push buffer */ @@ -169,7 +168,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, } } - ret = nvif_object_init(nvif_object(device), NULL, NVDRM_PUSH | + ret = nvif_object_init(&device->object, NVDRM_PUSH | (handle & 0xffff), NV_DMA_FROM_MEMORY, &args, sizeof(args), &chan->push.ctxdma); if (ret) { @@ -194,7 +193,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, union { struct nv50_channel_gpfifo_v0 nv50; struct kepler_channel_gpfifo_a_v0 kepler; - } args, *retn; + } args; struct nouveau_channel *chan; u32 size; int ret; @@ -222,14 +221,13 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, size = sizeof(args.nv50); } - ret = nvif_object_new(nvif_object(device), handle, *oclass++, - &args, size, &chan->object); + ret = nvif_object_init(&device->object, handle, *oclass++, + &args, size, &chan->user); if (ret == 0) { - retn = chan->object->data; - if (chan->object->oclass >= KEPLER_CHANNEL_GPFIFO_A) - chan->chid = retn->kepler.chid; + if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A) + chan->chid = args.kepler.chid; else - chan->chid = retn->nv50.chid; + chan->chid = args.nv50.chid; return ret; } } while (*oclass); @@ -248,7 +246,7 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, NV03_CHANNEL_DMA, 0 }; const u16 *oclass = oclasses; - struct nv03_channel_dma_v0 args, *retn; + struct nv03_channel_dma_v0 args; struct nouveau_channel *chan; int ret; @@ -264,11 +262,10 @@ nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, args.offset = chan->push.vma.offset; do { - ret = nvif_object_new(nvif_object(device), handle, *oclass++, - &args, sizeof(args), &chan->object); + ret = nvif_object_init(&device->object, handle, *oclass++, + &args, sizeof(args), &chan->user); if (ret == 0) { - retn = chan->object->data; - chan->chid = retn->chid; + chan->chid = args.chid; return ret; } } while (ret && *oclass); @@ -281,13 +278,13 @@ static int nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) { struct nvif_device *device = chan->device; - struct nouveau_cli *cli = (void *)nvif_client(&device->base); + struct nouveau_cli *cli = (void *)chan->user.client; struct nvkm_mmu *mmu = nvxx_mmu(device); struct nvkm_sw_chan *swch; struct nv_dma_v0 args = {}; int ret, i; - nvif_object_map(chan->object); + nvif_object_map(&chan->user); /* allocate dma objects to cover all allowed vram, and gart */ if (device->info.family < NV_DEVICE_INFO_V0_FERMI) { @@ -303,9 +300,8 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) args.limit = device->info.ram_user - 1; } - ret = nvif_object_init(chan->object, NULL, vram, - NV_DMA_IN_MEMORY, &args, - sizeof(args), &chan->vram); + ret = nvif_object_init(&chan->user, vram, NV_DMA_IN_MEMORY, + &args, sizeof(args), &chan->vram); if (ret) return ret; @@ -328,15 +324,14 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) args.limit = mmu->limit - 1; } - ret = nvif_object_init(chan->object, NULL, gart, - NV_DMA_IN_MEMORY, &args, - sizeof(args), &chan->gart); + ret = nvif_object_init(&chan->user, gart, NV_DMA_IN_MEMORY, + &args, sizeof(args), &chan->gart); if (ret) return ret; } /* initialise dma tracking parameters */ - switch (chan->object->oclass & 0x00ff) { + switch (chan->user.oclass & 0x00ff) { case 0x006b: case 0x006e: chan->user_put = 0x40; @@ -368,7 +363,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) /* allocate software object class (used for fences on <= nv05) */ if (device->info.family < NV_DEVICE_INFO_V0_CELSIUS) { - ret = nvif_object_init(chan->object, NULL, 0x006e, 0x006e, + ret = nvif_object_init(&chan->user, 0x006e, 0x006e, NULL, 0, &chan->nvsw); if (ret) return ret; @@ -395,7 +390,7 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, u32 handle, u32 arg0, u32 arg1, struct nouveau_channel **pchan) { - struct nouveau_cli *cli = (void *)nvif_client(&device->base); + struct nouveau_cli *cli = (void *)device->object.client; bool super; int ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h index 8b3640f69e4f..2ed32414cb69 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.h +++ b/drivers/gpu/drm/nouveau/nouveau_chan.h @@ -37,7 +37,7 @@ struct nouveau_channel { u32 user_get; u32 user_put; - struct nvif_object *object; + struct nvif_object user; }; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 054f0f25c8be..309c20b086d4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -1256,8 +1256,8 @@ nouveau_connector_create(struct drm_device *dev, int index) break; } - ret = nvif_notify_init(&disp->disp, NULL, nouveau_connector_hotplug, - true, NV04_DISP_NTFY_CONN, + ret = nvif_notify_init(&disp->disp, nouveau_connector_hotplug, true, + NV04_DISP_NTFY_CONN, &(struct nvif_notify_conn_req_v0) { .mask = NVIF_NOTIFY_CONN_V0_ANY, .conn = index, diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 8670d90cdc11..d913074c952f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -185,7 +185,7 @@ nouveau_display_vblank_init(struct drm_device *dev) list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - ret = nvif_notify_init(&disp->disp, NULL, + ret = nvif_notify_init(&disp->disp, nouveau_display_vblank_handler, false, NV04_DISP_NTFY_VBLANK, &(struct nvif_notify_head_req_v0) { @@ -494,7 +494,7 @@ nouveau_display_create(struct drm_device *dev) int i; for (i = 0, ret = -ENODEV; ret && i < ARRAY_SIZE(oclass); i++) { - ret = nvif_object_init(nvif_object(&drm->device), NULL, + ret = nvif_object_init(&drm->device.object, NVDRM_DISPLAY, oclass[i], NULL, 0, &disp->disp); } @@ -711,7 +711,7 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, chan = drm->channel; if (!chan) return -ENODEV; - cli = (void *)nvif_client(&chan->device->base); + cli = (void *)chan->user.client; s = kzalloc(sizeof(*s), GFP_KERNEL); if (!s) diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 6d9245aa81a6..d168c63533c1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c @@ -52,9 +52,9 @@ READ_GET(struct nouveau_channel *chan, uint64_t *prev_get, int *timeout) { uint64_t val; - val = nvif_rd32(chan, chan->user_get); + val = nvif_rd32(&chan->user, chan->user_get); if (chan->user_get_hi) - val |= (uint64_t)nvif_rd32(chan, chan->user_get_hi) << 32; + val |= (uint64_t)nvif_rd32(&chan->user, chan->user_get_hi) << 32; /* reset counter as long as GET is still advancing, this is * to avoid misdetecting a GPU lockup if the GPU happens to @@ -82,7 +82,7 @@ void nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, int delta, int length) { - struct nouveau_cli *cli = (void *)nvif_client(&chan->device->base); + struct nouveau_cli *cli = (void *)chan->user.client; struct nouveau_bo *pb = chan->push.buffer; struct nvkm_vma *vma; int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; @@ -103,7 +103,7 @@ nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, /* Flush writes. */ nouveau_bo_rd32(pb, 0); - nvif_wr32(chan, 0x8c, chan->dma.ib_put); + nvif_wr32(&chan->user, 0x8c, chan->dma.ib_put); chan->dma.ib_free--; } @@ -113,7 +113,7 @@ nv50_dma_push_wait(struct nouveau_channel *chan, int count) uint32_t cnt = 0, prev_get = 0; while (chan->dma.ib_free < count) { - uint32_t get = nvif_rd32(chan, 0x88); + uint32_t get = nvif_rd32(&chan->user, 0x88); if (get != prev_get) { prev_get = get; cnt = 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index 8da0a272c45a..aff3a9d0a1fc 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -140,7 +140,7 @@ BEGIN_IMC0(struct nouveau_channel *chan, int subc, int mthd, u16 data) #define WRITE_PUT(val) do { \ mb(); \ nouveau_bo_rd32(chan->push.buffer, 0); \ - nvif_wr32(chan, chan->user_put, ((val) << 2) + chan->push.vma.offset); \ + nvif_wr32(&chan->user, chan->user_put, ((val) << 2) + chan->push.vma.offset); \ } while (0) static inline void diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 86f567d4e5cd..11cf52a7ff75 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -114,7 +114,7 @@ nouveau_cli_create(struct drm_device *dev, const char *sname, snprintf(cli->name, sizeof(cli->name), "%s", sname); cli->dev = dev; - ret = nvif_client_init(NULL, NULL, cli->name, nouveau_name(dev), + ret = nvif_client_init(NULL, cli->name, nouveau_name(dev), nouveau_config, nouveau_debug, &cli->base); if (ret == 0) { @@ -163,7 +163,7 @@ nouveau_accel_init(struct nouveau_drm *drm) /*XXX: this is crap, but the fence/channel stuff is a little * backwards in some places. this will be fixed. */ - ret = nvif_object_sclass(&device->base, sclass, ARRAY_SIZE(sclass)); + ret = nvif_object_sclass(&device->object, sclass, ARRAY_SIZE(sclass)); if (ret < 0) return; @@ -235,7 +235,7 @@ nouveau_accel_init(struct nouveau_drm *drm) return; } - ret = nvif_object_init(drm->channel->object, NULL, NVDRM_NVSW, + ret = nvif_object_init(&drm->channel->user, NVDRM_NVSW, nouveau_abi16_swclass(drm), NULL, 0, &drm->nvsw); if (ret == 0) { struct nvkm_sw_chan *swch; @@ -262,7 +262,7 @@ nouveau_accel_init(struct nouveau_drm *drm) } if (device->info.family < NV_DEVICE_INFO_V0_FERMI) { - ret = nvkm_gpuobj_new(nvxx_object(&drm->device), NULL, 32, + ret = nvkm_gpuobj_new(nvxx_object(&drm->device.object), NULL, 32, 0, 0, &drm->notify); if (ret) { NV_ERROR(drm, "failed to allocate notifier, %d\n", ret); @@ -270,7 +270,7 @@ nouveau_accel_init(struct nouveau_drm *drm) return; } - ret = nvif_object_init(drm->channel->object, NULL, NvNotify0, + ret = nvif_object_init(&drm->channel->user, NvNotify0, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, @@ -392,8 +392,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) nouveau_get_hdmi_dev(drm); - ret = nvif_device_init(&drm->client.base.base, NULL, NVDRM_DEVICE, - NV_DEVICE, + ret = nvif_device_init(&drm->client.base.object, + NVDRM_DEVICE, NV_DEVICE, &(struct nv_device_v0) { .device = ~0, }, sizeof(struct nv_device_v0), @@ -408,7 +408,7 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) * better fix is found - assuming there is one... */ if (drm->device.info.chipset == 0xc1) - nvif_mask(&drm->device, 0x00088080, 0x00000800, 0x00000000); + nvif_mask(&drm->device.object, 0x00088080, 0x00000800, 0x00000000); nouveau_vga_init(drm); nouveau_agp_init(drm); @@ -736,7 +736,7 @@ nouveau_pmops_runtime_resume(struct device *dev) ret = nouveau_do_resume(drm_dev, true); drm_kms_helper_poll_enable(drm_dev); /* do magic */ - nvif_mask(device, 0x88488, (1 << 25), (1 << 25)); + nvif_mask(&device->object, 0x088488, (1 << 25), (1 << 25)); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index c6d56bef5823..574c36b492ee 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -169,7 +169,7 @@ void nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_chan *fctx) { struct nouveau_fence_priv *priv = (void*)chan->drm->fence; - struct nouveau_cli *cli = (void *)nvif_client(chan->object); + struct nouveau_cli *cli = (void *)chan->user.client; int ret; INIT_LIST_HEAD(&fctx->flip); @@ -188,13 +188,12 @@ nouveau_fence_context_new(struct nouveau_channel *chan, struct nouveau_fence_cha if (!priv->uevent) return; - ret = nvif_notify_init(chan->object, NULL, - nouveau_fence_wait_uevent_handler, false, - G82_CHANNEL_DMA_V0_NTFY_UEVENT, - &(struct nvif_notify_uevent_req) { }, - sizeof(struct nvif_notify_uevent_req), - sizeof(struct nvif_notify_uevent_rep), - &fctx->notify); + ret = nvif_notify_init(&chan->user, nouveau_fence_wait_uevent_handler, + false, G82_CHANNEL_DMA_V0_NTFY_UEVENT, + &(struct nvif_notify_uevent_req) { }, + sizeof(struct nvif_notify_uevent_req), + sizeof(struct nvif_notify_uevent_rep), + &fctx->notify); WARN_ON(ret); } diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index dc5845ee2fa0..dc2378c01b6d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -681,7 +681,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, return -ENOMEM; list_for_each_entry(temp, &abi16->channels, head) { - if (temp->chan->object->handle == (NVDRM_CHAN | req->channel)) { + if (temp->chan->user.handle == (NVDRM_CHAN | req->channel)) { chan = temp->chan; break; } diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c index 1ec8f38ae69a..ce612064fa6a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_sysfs.c @@ -188,9 +188,9 @@ nouveau_sysfs_init(struct drm_device *dev) if (!sysfs) return -ENOMEM; - ret = nvif_object_init(nvif_object(device), NULL, NVDRM_CONTROL, + ret = nvif_object_init(&device->object, NVDRM_CONTROL, NVIF_IOCTL_NEW_V0_CONTROL, NULL, 0, - &sysfs->ctrl); + &sysfs->ctrl); if (ret == 0) device_create_file(nv_device_base(nvxx_device(device)), &dev_attr_pstate); diff --git a/drivers/gpu/drm/nouveau/nouveau_vga.c b/drivers/gpu/drm/nouveau/nouveau_vga.c index c7592ec8ecb8..af89c3665b2a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_vga.c +++ b/drivers/gpu/drm/nouveau/nouveau_vga.c @@ -12,13 +12,14 @@ static unsigned int nouveau_vga_set_decode(void *priv, bool state) { - struct nvif_device *device = &nouveau_drm(priv)->device; + struct nouveau_drm *drm = nouveau_drm(priv); + struct nvif_object *device = &drm->device.object; - if (device->info.family == NV_DEVICE_INFO_V0_CURIE && - device->info.chipset >= 0x4c) + if (drm->device.info.family == NV_DEVICE_INFO_V0_CURIE && + drm->device.info.chipset >= 0x4c) nvif_wr32(device, 0x088060, state); else - if (device->info.chipset >= 0x40) + if (drm->device.info.chipset >= 0x40) nvif_wr32(device, 0x088054, state); else nvif_wr32(device, 0x001854, state); diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 495c57644ced..789dc2993b0d 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -171,33 +171,33 @@ nv04_fbcon_accel_init(struct fb_info *info) return -EINVAL; } - ret = nvif_object_init(chan->object, NULL, 0x0062, + ret = nvif_object_init(&chan->user, 0x0062, device->info.family >= NV_DEVICE_INFO_V0_CELSIUS ? 0x0062 : 0x0042, NULL, 0, &nfbdev->surf2d); if (ret) return ret; - ret = nvif_object_init(chan->object, NULL, 0x0019, 0x0019, NULL, 0, + ret = nvif_object_init(&chan->user, 0x0019, 0x0019, NULL, 0, &nfbdev->clip); if (ret) return ret; - ret = nvif_object_init(chan->object, NULL, 0x0043, 0x0043, NULL, 0, + ret = nvif_object_init(&chan->user, 0x0043, 0x0043, NULL, 0, &nfbdev->rop); if (ret) return ret; - ret = nvif_object_init(chan->object, NULL, 0x0044, 0x0044, NULL, 0, + ret = nvif_object_init(&chan->user, 0x0044, 0x0044, NULL, 0, &nfbdev->patt); if (ret) return ret; - ret = nvif_object_init(chan->object, NULL, 0x004a, 0x004a, NULL, 0, + ret = nvif_object_init(&chan->user, 0x004a, 0x004a, NULL, 0, &nfbdev->gdi); if (ret) return ret; - ret = nvif_object_init(chan->object, NULL, 0x005f, + ret = nvif_object_init(&chan->user, 0x005f, device->info.chipset >= 0x11 ? 0x009f : 0x005f, NULL, 0, &nfbdev->blit); if (ret) diff --git a/drivers/gpu/drm/nouveau/nv04_fence.c b/drivers/gpu/drm/nouveau/nv04_fence.c index c2e05e64cd6f..f4a26224ac68 100644 --- a/drivers/gpu/drm/nouveau/nv04_fence.c +++ b/drivers/gpu/drm/nouveau/nv04_fence.c @@ -57,7 +57,7 @@ nv04_fence_sync(struct nouveau_fence *fence, static u32 nv04_fence_read(struct nouveau_channel *chan) { - struct nvkm_fifo_chan *fifo = nvxx_fifo_chan(chan);; + struct nvkm_fifo_chan *fifo = nvxx_fifo_chan(&chan->user); return atomic_read(&fifo->refcnt); } diff --git a/drivers/gpu/drm/nouveau/nv10_fence.c b/drivers/gpu/drm/nouveau/nv10_fence.c index 5e1ea1cdce75..2c35213da275 100644 --- a/drivers/gpu/drm/nouveau/nv10_fence.c +++ b/drivers/gpu/drm/nouveau/nv10_fence.c @@ -50,7 +50,7 @@ nv10_fence_sync(struct nouveau_fence *fence, u32 nv10_fence_read(struct nouveau_channel *chan) { - return nvif_rd32(chan, 0x0048); + return nvif_rd32(&chan->user, 0x0048); } void diff --git a/drivers/gpu/drm/nouveau/nv17_fence.c b/drivers/gpu/drm/nouveau/nv17_fence.c index 57860cfa1de5..80b6eb8b3d02 100644 --- a/drivers/gpu/drm/nouveau/nv17_fence.c +++ b/drivers/gpu/drm/nouveau/nv17_fence.c @@ -33,7 +33,7 @@ int nv17_fence_sync(struct nouveau_fence *fence, struct nouveau_channel *prev, struct nouveau_channel *chan) { - struct nouveau_cli *cli = (void *)nvif_client(&prev->device->base); + struct nouveau_cli *cli = (void *)prev->user.client; struct nv10_fence_priv *priv = chan->drm->fence; struct nv10_fence_chan *fctx = chan->fence; u32 value; @@ -89,7 +89,7 @@ nv17_fence_context_new(struct nouveau_channel *chan) fctx->base.read = nv10_fence_read; fctx->base.sync = nv17_fence_sync; - ret = nvif_object_init(chan->object, NULL, NvSema, NV_DMA_FROM_MEMORY, + ret = nvif_object_init(&chan->user, NvSema, NV_DMA_FROM_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, .access = NV_DMA_V0_ACCESS_RDWR, diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index c56775f5aff3..794a20ea71fe 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -60,16 +60,20 @@ struct nv50_chan { struct nvif_object user; + struct nvif_device *device; }; static int -nv50_chan_create(struct nvif_object *disp, const u32 *oclass, u8 head, - void *data, u32 size, struct nv50_chan *chan) +nv50_chan_create(struct nvif_device *device, struct nvif_object *disp, + const u32 *oclass, u8 head, void *data, u32 size, + struct nv50_chan *chan) { const u32 handle = (oclass[0] << 16) | head; u32 sclass[8]; int ret, i; + chan->device = device; + ret = nvif_object_sclass(disp, sclass, ARRAY_SIZE(sclass)); WARN_ON(ret > ARRAY_SIZE(sclass)); if (ret < 0) @@ -78,9 +82,8 @@ nv50_chan_create(struct nvif_object *disp, const u32 *oclass, u8 head, while (oclass[0]) { for (i = 0; i < ARRAY_SIZE(sclass); i++) { if (sclass[i] == oclass[0]) { - ret = nvif_object_init(disp, NULL, handle, - oclass[0], data, size, - &chan->user); + ret = nvif_object_init(disp, handle, oclass[0], + data, size, &chan->user); if (ret == 0) nvif_object_map(&chan->user); return ret; @@ -113,10 +116,12 @@ nv50_pioc_destroy(struct nv50_pioc *pioc) } static int -nv50_pioc_create(struct nvif_object *disp, const u32 *oclass, u8 head, - void *data, u32 size, struct nv50_pioc *pioc) +nv50_pioc_create(struct nvif_device *device, struct nvif_object *disp, + const u32 *oclass, u8 head, void *data, u32 size, + struct nv50_pioc *pioc) { - return nv50_chan_create(disp, oclass, head, data, size, &pioc->base); + return nv50_chan_create(device, disp, oclass, head, data, size, + &pioc->base); } /****************************************************************************** @@ -128,7 +133,8 @@ struct nv50_curs { }; static int -nv50_curs_create(struct nvif_object *disp, int head, struct nv50_curs *curs) +nv50_curs_create(struct nvif_device *device, struct nvif_object *disp, + int head, struct nv50_curs *curs) { struct nv50_disp_cursor_v0 args = { .head = head, @@ -142,8 +148,8 @@ nv50_curs_create(struct nvif_object *disp, int head, struct nv50_curs *curs) 0 }; - return nv50_pioc_create(disp, oclass, head, &args, sizeof(args), - &curs->base); + return nv50_pioc_create(device, disp, oclass, head, &args, sizeof(args), + &curs->base); } /****************************************************************************** @@ -155,7 +161,8 @@ struct nv50_oimm { }; static int -nv50_oimm_create(struct nvif_object *disp, int head, struct nv50_oimm *oimm) +nv50_oimm_create(struct nvif_device *device, struct nvif_object *disp, + int head, struct nv50_oimm *oimm) { struct nv50_disp_cursor_v0 args = { .head = head, @@ -169,8 +176,8 @@ nv50_oimm_create(struct nvif_object *disp, int head, struct nv50_oimm *oimm) 0 }; - return nv50_pioc_create(disp, oclass, head, &args, sizeof(args), - &oimm->base); + return nv50_pioc_create(device, disp, oclass, head, &args, sizeof(args), + &oimm->base); } /****************************************************************************** @@ -194,23 +201,24 @@ struct nv50_dmac { static void nv50_dmac_destroy(struct nv50_dmac *dmac, struct nvif_object *disp) { + struct nvif_device *device = dmac->base.device; + nvif_object_fini(&dmac->vram); nvif_object_fini(&dmac->sync); nv50_chan_destroy(&dmac->base); if (dmac->ptr) { - struct pci_dev *pdev = nvxx_device(nvif_device(disp))->pdev; + struct pci_dev *pdev = nvxx_device(device)->pdev; pci_free_consistent(pdev, PAGE_SIZE, dmac->ptr, dmac->handle); } } static int -nv50_dmac_create(struct nvif_object *disp, const u32 *oclass, u8 head, - void *data, u32 size, u64 syncbuf, +nv50_dmac_create(struct nvif_device *device, struct nvif_object *disp, + const u32 *oclass, u8 head, void *data, u32 size, u64 syncbuf, struct nv50_dmac *dmac) { - struct nvif_device *device = nvif_device(disp); struct nv50_disp_core_channel_dma_v0 *args = data; struct nvif_object pushbuf; int ret; @@ -222,9 +230,8 @@ nv50_dmac_create(struct nvif_object *disp, const u32 *oclass, u8 head, if (!dmac->ptr) return -ENOMEM; - ret = nvif_object_init(nvif_object(device), NULL, - args->pushbuf, NV_DMA_FROM_MEMORY, - &(struct nv_dma_v0) { + ret = nvif_object_init(&device->object, args->pushbuf, + NV_DMA_FROM_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_PCI_US, .access = NV_DMA_V0_ACCESS_RD, .start = dmac->handle + 0x0000, @@ -233,13 +240,13 @@ nv50_dmac_create(struct nvif_object *disp, const u32 *oclass, u8 head, if (ret) return ret; - ret = nv50_chan_create(disp, oclass, head, data, size, &dmac->base); + ret = nv50_chan_create(device, disp, oclass, head, data, size, + &dmac->base); nvif_object_fini(&pushbuf); if (ret) return ret; - ret = nvif_object_init(&dmac->base.user, NULL, 0xf0000000, - NV_DMA_IN_MEMORY, + ret = nvif_object_init(&dmac->base.user, 0xf0000000, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, .access = NV_DMA_V0_ACCESS_RDWR, @@ -250,8 +257,7 @@ nv50_dmac_create(struct nvif_object *disp, const u32 *oclass, u8 head, if (ret) return ret; - ret = nvif_object_init(&dmac->base.user, NULL, 0xf0000001, - NV_DMA_IN_MEMORY, + ret = nvif_object_init(&dmac->base.user, 0xf0000001, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, .access = NV_DMA_V0_ACCESS_RDWR, @@ -274,7 +280,8 @@ struct nv50_mast { }; static int -nv50_core_create(struct nvif_object *disp, u64 syncbuf, struct nv50_mast *core) +nv50_core_create(struct nvif_device *device, struct nvif_object *disp, + u64 syncbuf, struct nv50_mast *core) { struct nv50_disp_core_channel_dma_v0 args = { .pushbuf = 0xb0007d00, @@ -293,8 +300,8 @@ nv50_core_create(struct nvif_object *disp, u64 syncbuf, struct nv50_mast *core) 0 }; - return nv50_dmac_create(disp, oclass, 0, &args, sizeof(args), syncbuf, - &core->base); + return nv50_dmac_create(device, disp, oclass, 0, &args, sizeof(args), + syncbuf, &core->base); } /****************************************************************************** @@ -308,8 +315,8 @@ struct nv50_sync { }; static int -nv50_base_create(struct nvif_object *disp, int head, u64 syncbuf, - struct nv50_sync *base) +nv50_base_create(struct nvif_device *device, struct nvif_object *disp, + int head, u64 syncbuf, struct nv50_sync *base) { struct nv50_disp_base_channel_dma_v0 args = { .pushbuf = 0xb0007c00 | head, @@ -326,7 +333,7 @@ nv50_base_create(struct nvif_object *disp, int head, u64 syncbuf, 0 }; - return nv50_dmac_create(disp, oclass, head, &args, sizeof(args), + return nv50_dmac_create(device, disp, oclass, head, &args, sizeof(args), syncbuf, &base->base); } @@ -339,8 +346,8 @@ struct nv50_ovly { }; static int -nv50_ovly_create(struct nvif_object *disp, int head, u64 syncbuf, - struct nv50_ovly *ovly) +nv50_ovly_create(struct nvif_device *device, struct nvif_object *disp, + int head, u64 syncbuf, struct nv50_ovly *ovly) { struct nv50_disp_overlay_channel_dma_v0 args = { .pushbuf = 0xb0007e00 | head, @@ -356,7 +363,7 @@ nv50_ovly_create(struct nvif_object *disp, int head, u64 syncbuf, 0 }; - return nv50_dmac_create(disp, oclass, head, &args, sizeof(args), + return nv50_dmac_create(device, disp, oclass, head, &args, sizeof(args), syncbuf, &ovly->base); } @@ -413,7 +420,7 @@ static u32 * evo_wait(void *evoc, int nr) { struct nv50_dmac *dmac = evoc; - struct nvif_device *device = nvif_device(&dmac->base.user); + struct nvif_device *device = dmac->base.device; u32 put = nvif_rd32(&dmac->base.user, 0x0000) / 4; mutex_lock(&dmac->lock); @@ -573,7 +580,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, if (unlikely(push == NULL)) return -EBUSY; - if (chan && chan->object->oclass < G82_CHANNEL_GPFIFO) { + if (chan && chan->user.oclass < G82_CHANNEL_GPFIFO) { ret = RING_SPACE(chan, 8); if (ret) return ret; @@ -587,7 +594,7 @@ nv50_display_flip_next(struct drm_crtc *crtc, struct drm_framebuffer *fb, OUT_RING (chan, sync->addr); OUT_RING (chan, sync->data); } else - if (chan && chan->object->oclass < FERMI_CHANNEL_GPFIFO) { + if (chan && chan->user.oclass < FERMI_CHANNEL_GPFIFO) { u64 addr = nv84_fence_crtc(chan, nv_crtc->index) + sync->addr; ret = RING_SPACE(chan, 12); if (ret) @@ -1418,6 +1425,8 @@ static const struct drm_crtc_funcs nv50_crtc_func = { static int nv50_crtc_create(struct drm_device *dev, int index) { + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvif_device *device = &drm->device; struct nv50_disp *disp = nv50_disp(dev); struct nv50_head *head; struct drm_crtc *crtc; @@ -1462,13 +1471,13 @@ nv50_crtc_create(struct drm_device *dev, int index) goto out; /* allocate cursor resources */ - ret = nv50_curs_create(disp->disp, index, &head->curs); + ret = nv50_curs_create(device, disp->disp, index, &head->curs); if (ret) goto out; /* allocate page flip / sync resources */ - ret = nv50_base_create(disp->disp, index, disp->sync->bo.offset, - &head->sync); + ret = nv50_base_create(device, disp->disp, index, disp->sync->bo.offset, + &head->sync); if (ret) goto out; @@ -1476,12 +1485,12 @@ nv50_crtc_create(struct drm_device *dev, int index) head->sync.data = 0x00000000; /* allocate overlay resources */ - ret = nv50_oimm_create(disp->disp, index, &head->oimm); + ret = nv50_oimm_create(device, disp->disp, index, &head->oimm); if (ret) goto out; - ret = nv50_ovly_create(disp->disp, index, disp->sync->bo.offset, - &head->ovly); + ret = nv50_ovly_create(device, disp->disp, index, disp->sync->bo.offset, + &head->ovly); if (ret) goto out; @@ -2370,8 +2379,8 @@ nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kin list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nv50_head *head = nv50_head(crtc); - int ret = nvif_object_init(&head->sync.base.base.user, NULL, - name, NV_DMA_IN_MEMORY, &args, size, + int ret = nvif_object_init(&head->sync.base.base.user, name, + NV_DMA_IN_MEMORY, &args, size, &fbdma->base[head->base.index]); if (ret) { nv50_fbdma_fini(fbdma); @@ -2379,9 +2388,8 @@ nv50_fbdma_init(struct drm_device *dev, u32 name, u64 offset, u64 length, u8 kin } } - ret = nvif_object_init(&mast->base.base.user, NULL, name, - NV_DMA_IN_MEMORY, &args, size, - &fbdma->core); + ret = nvif_object_init(&mast->base.base.user, name, NV_DMA_IN_MEMORY, + &args, size, &fbdma->core); if (ret) { nv50_fbdma_fini(fbdma); return ret; @@ -2534,14 +2542,14 @@ nv50_display_create(struct drm_device *dev) goto out; /* allocate master evo channel */ - ret = nv50_core_create(disp->disp, disp->sync->bo.offset, + ret = nv50_core_create(device, disp->disp, disp->sync->bo.offset, &disp->mast); if (ret) goto out; /* create crtc objects to represent the hw heads */ if (disp->disp->oclass >= GF110_DISP) - crtcs = nvif_rd32(device, 0x022448); + crtcs = nvif_rd32(&device->object, 0x022448); else crtcs = 2; diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 901130b06072..e05499d6ed83 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c @@ -183,7 +183,7 @@ nv50_fbcon_accel_init(struct fb_info *info) return -EINVAL; } - ret = nvif_object_init(chan->object, NULL, 0x502d, 0x502d, NULL, 0, + ret = nvif_object_init(&chan->user, 0x502d, 0x502d, NULL, 0, &nfbdev->twod); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nv50_fence.c b/drivers/gpu/drm/nouveau/nv50_fence.c index a82d9ea7c6fd..f0d96e5da6b4 100644 --- a/drivers/gpu/drm/nouveau/nv50_fence.c +++ b/drivers/gpu/drm/nouveau/nv50_fence.c @@ -51,7 +51,7 @@ nv50_fence_context_new(struct nouveau_channel *chan) fctx->base.read = nv10_fence_read; fctx->base.sync = nv17_fence_sync; - ret = nvif_object_init(chan->object, NULL, NvSema, NV_DMA_IN_MEMORY, + ret = nvif_object_init(&chan->user, NvSema, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, .access = NV_DMA_V0_ACCESS_RDWR, @@ -66,7 +66,7 @@ nv50_fence_context_new(struct nouveau_channel *chan) u32 start = bo->bo.mem.start * PAGE_SIZE; u32 limit = start + bo->bo.mem.size - 1; - ret = nvif_object_init(chan->object, NULL, NvEvoSema0 + i, + ret = nvif_object_init(&chan->user, NvEvoSema0 + i, NV_DMA_IN_MEMORY, &(struct nv_dma_v0) { .target = NV_DMA_V0_TARGET_VRAM, .access = NV_DMA_V0_ACCESS_RDWR, diff --git a/drivers/gpu/drm/nouveau/nv84_fence.c b/drivers/gpu/drm/nouveau/nv84_fence.c index 76098a58e2fa..4d7ad6d3fbd4 100644 --- a/drivers/gpu/drm/nouveau/nv84_fence.c +++ b/drivers/gpu/drm/nouveau/nv84_fence.c @@ -131,7 +131,7 @@ nv84_fence_context_del(struct nouveau_channel *chan) int nv84_fence_context_new(struct nouveau_channel *chan) { - struct nouveau_cli *cli = (void *)nvif_client(&chan->device->base); + struct nouveau_cli *cli = (void *)chan->user.client; struct nv84_fence_priv *priv = chan->drm->fence; struct nv84_fence_chan *fctx; int ret, i; diff --git a/drivers/gpu/drm/nouveau/nvc0_fbcon.c b/drivers/gpu/drm/nouveau/nvc0_fbcon.c index fcd2e5f27bb9..c97395b4a312 100644 --- a/drivers/gpu/drm/nouveau/nvc0_fbcon.c +++ b/drivers/gpu/drm/nouveau/nvc0_fbcon.c @@ -156,7 +156,7 @@ nvc0_fbcon_accel_init(struct fb_info *info) struct nouveau_channel *chan = drm->channel; int ret, format; - ret = nvif_object_init(chan->object, NULL, 0x902d, 0x902d, NULL, 0, + ret = nvif_object_init(&chan->user, 0x902d, 0x902d, NULL, 0, &nfbdev->twod); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nvif/client.c b/drivers/gpu/drm/nouveau/nvif/client.c index 80b96844221e..4a830ebf9661 100644 --- a/drivers/gpu/drm/nouveau/nvif/client.c +++ b/drivers/gpu/drm/nouveau/nvif/client.c @@ -29,29 +29,30 @@ int nvif_client_ioctl(struct nvif_client *client, void *data, u32 size) { - return client->driver->ioctl(client->base.priv, client->super, data, size, NULL); + return client->driver->ioctl(client->object.priv, client->super, data, size, NULL); } int nvif_client_suspend(struct nvif_client *client) { - return client->driver->suspend(client->base.priv); + return client->driver->suspend(client->object.priv); } int nvif_client_resume(struct nvif_client *client) { - return client->driver->resume(client->base.priv); + return client->driver->resume(client->object.priv); } void nvif_client_fini(struct nvif_client *client) { if (client->driver) { - client->driver->fini(client->base.priv); + client->driver->fini(client->object.priv); client->driver = NULL; - client->base.parent = NULL; - nvif_object_fini(&client->base); + client->object.parent = NULL; + client->object.client = NULL; + nvif_object_fini(&client->object); } } @@ -68,25 +69,25 @@ nvif_drivers[] = { }; int -nvif_client_init(void (*dtor)(struct nvif_client *), const char *driver, - const char *name, u64 device, const char *cfg, const char *dbg, - struct nvif_client *client) +nvif_client_init(const char *driver, const char *name, u64 device, + const char *cfg, const char *dbg, struct nvif_client *client) { int ret, i; - ret = nvif_object_init(NULL, (void*)dtor, 0, 0, NULL, 0, &client->base); + ret = nvif_object_init(NULL, 0, 0, NULL, 0, &client->object); if (ret) return ret; - client->base.parent = &client->base; - client->base.handle = ~0; - client->object = &client->base; + client->object.client = client; + client->object.parent = &client->object; + client->object.handle = ~0; + client->route = NVIF_IOCTL_V0_ROUTE_NVIF; client->super = true; for (i = 0, ret = -EINVAL; (client->driver = nvif_drivers[i]); i++) { if (!driver || !strcmp(client->driver->name, driver)) { ret = client->driver->init(name, device, cfg, dbg, - &client->base.priv); + &client->object.priv); if (!ret || driver) break; } @@ -96,35 +97,3 @@ nvif_client_init(void (*dtor)(struct nvif_client *), const char *driver, nvif_client_fini(client); return ret; } - -static void -nvif_client_del(struct nvif_client *client) -{ - nvif_client_fini(client); - kfree(client); -} - -int -nvif_client_new(const char *driver, const char *name, u64 device, - const char *cfg, const char *dbg, - struct nvif_client **pclient) -{ - struct nvif_client *client = kzalloc(sizeof(*client), GFP_KERNEL); - if (client) { - int ret = nvif_client_init(nvif_client_del, driver, name, - device, cfg, dbg, client); - if (ret) { - kfree(client); - client = NULL; - } - *pclient = client; - return ret; - } - return -ENOMEM; -} - -void -nvif_client_ref(struct nvif_client *client, struct nvif_client **pclient) -{ - nvif_object_ref(&client->base, (struct nvif_object **)pclient); -} diff --git a/drivers/gpu/drm/nouveau/nvif/device.c b/drivers/gpu/drm/nouveau/nvif/device.c index 837442c69a5d..f15d51a69df2 100644 --- a/drivers/gpu/drm/nouveau/nvif/device.c +++ b/drivers/gpu/drm/nouveau/nvif/device.c @@ -33,52 +33,19 @@ nvif_device_time(struct nvif_device *device) void nvif_device_fini(struct nvif_device *device) { - nvif_object_fini(&device->base); + nvif_object_fini(&device->object); } int -nvif_device_init(struct nvif_object *parent, void (*dtor)(struct nvif_device *), - u32 handle, u32 oclass, void *data, u32 size, - struct nvif_device *device) +nvif_device_init(struct nvif_object *parent, u32 handle, u32 oclass, + void *data, u32 size, struct nvif_device *device) { - int ret = nvif_object_init(parent, (void *)dtor, handle, oclass, - data, size, &device->base); + int ret = nvif_object_init(parent, handle, oclass, data, size, + &device->object); if (ret == 0) { - device->object = &device->base; device->info.version = 0; - ret = nvif_object_mthd(&device->base, NV_DEVICE_V0_INFO, + ret = nvif_object_mthd(&device->object, NV_DEVICE_V0_INFO, &device->info, sizeof(device->info)); } return ret; } - -static void -nvif_device_del(struct nvif_device *device) -{ - nvif_device_fini(device); - kfree(device); -} - -int -nvif_device_new(struct nvif_object *parent, u32 handle, u32 oclass, - void *data, u32 size, struct nvif_device **pdevice) -{ - struct nvif_device *device = kzalloc(sizeof(*device), GFP_KERNEL); - if (device) { - int ret = nvif_device_init(parent, nvif_device_del, handle, - oclass, data, size, device); - if (ret) { - kfree(device); - device = NULL; - } - *pdevice = device; - return ret; - } - return -ENOMEM; -} - -void -nvif_device_ref(struct nvif_device *device, struct nvif_device **pdevice) -{ - nvif_object_ref(&device->base, (struct nvif_object **)pdevice); -} diff --git a/drivers/gpu/drm/nouveau/nvif/notify.c b/drivers/gpu/drm/nouveau/nvif/notify.c index 8e34748709a0..b0787ff833ef 100644 --- a/drivers/gpu/drm/nouveau/nvif/notify.c +++ b/drivers/gpu/drm/nouveau/nvif/notify.c @@ -124,7 +124,7 @@ nvif_notify(const void *header, u32 length, const void *data, u32 size) } if (!WARN_ON(notify == NULL)) { - struct nvif_client *client = nvif_client(notify->object); + struct nvif_client *client = notify->object->client; if (!WARN_ON(notify->size != size)) { atomic_inc(¬ify->putcnt); if (test_bit(NVIF_NOTIFY_WORK, ¬ify->flags)) { @@ -156,7 +156,7 @@ nvif_notify_fini(struct nvif_notify *notify) if (ret >= 0 && object) { ret = nvif_object_ioctl(object, &args, sizeof(args), NULL); if (ret == 0) { - nvif_object_ref(NULL, ¬ify->object); + notify->object = NULL; kfree((void *)notify->data); } } @@ -164,9 +164,9 @@ nvif_notify_fini(struct nvif_notify *notify) } int -nvif_notify_init(struct nvif_object *object, void (*dtor)(struct nvif_notify *), - int (*func)(struct nvif_notify *), bool work, u8 event, - void *data, u32 size, u32 reply, struct nvif_notify *notify) +nvif_notify_init(struct nvif_object *object, int (*func)(struct nvif_notify *), + bool work, u8 event, void *data, u32 size, u32 reply, + struct nvif_notify *notify) { struct { struct nvif_ioctl_v0 ioctl; @@ -175,11 +175,9 @@ nvif_notify_init(struct nvif_object *object, void (*dtor)(struct nvif_notify *), } *args; int ret = -ENOMEM; - notify->object = NULL; - nvif_object_ref(object, ¬ify->object); + notify->object = object; notify->flags = 0; atomic_set(¬ify->putcnt, 1); - notify->dtor = dtor; notify->func = func; notify->data = NULL; notify->size = reply; @@ -211,38 +209,3 @@ done: nvif_notify_fini(notify); return ret; } - -static void -nvif_notify_del(struct nvif_notify *notify) -{ - nvif_notify_fini(notify); - kfree(notify); -} - -void -nvif_notify_ref(struct nvif_notify *notify, struct nvif_notify **pnotify) -{ - BUG_ON(notify != NULL); - if (*pnotify) - (*pnotify)->dtor(*pnotify); - *pnotify = notify; -} - -int -nvif_notify_new(struct nvif_object *object, int (*func)(struct nvif_notify *), - bool work, u8 type, void *data, u32 size, u32 reply, - struct nvif_notify **pnotify) -{ - struct nvif_notify *notify = kzalloc(sizeof(*notify), GFP_KERNEL); - if (notify) { - int ret = nvif_notify_init(object, nvif_notify_del, func, work, - type, data, size, reply, notify); - if (ret) { - kfree(notify); - notify = NULL; - } - *pnotify = notify; - return ret; - } - return -ENOMEM; -} diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index 3ab4e2f8cc12..a727f72ca234 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c @@ -30,7 +30,7 @@ int nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack) { - struct nvif_client *client = nvif_client(object); + struct nvif_client *client = object->client; union { struct nvif_ioctl_v0 v0; } *args = data; @@ -47,7 +47,8 @@ nvif_object_ioctl(struct nvif_object *object, void *data, u32 size, void **hack) } else return -ENOSYS; - return client->driver->ioctl(client->base.priv, client->super, data, size, hack); + return client->driver->ioctl(client->object.priv, client->super, + data, size, hack); } int @@ -145,7 +146,7 @@ void nvif_object_unmap(struct nvif_object *object) { if (object->map.size) { - struct nvif_client *client = nvif_client(object); + struct nvif_client *client = object->client; struct { struct nvif_ioctl_v0 ioctl; struct nvif_ioctl_unmap unmap; @@ -167,7 +168,7 @@ nvif_object_unmap(struct nvif_object *object) int nvif_object_map(struct nvif_object *object) { - struct nvif_client *client = nvif_client(object); + struct nvif_client *client = object->client; struct { struct nvif_ioctl_v0 ioctl; struct nvif_ioctl_map_v0 map; @@ -186,119 +187,65 @@ nvif_object_map(struct nvif_object *object) return ret; } -struct ctor { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_new_v0 new; -}; - void nvif_object_fini(struct nvif_object *object) { - struct ctor *ctor = container_of(object->data, typeof(*ctor), new.data); - if (object->parent) { - struct { - struct nvif_ioctl_v0 ioctl; - struct nvif_ioctl_del del; - } args = { - .ioctl.type = NVIF_IOCTL_V0_DEL, - }; + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_del del; + } args = { + .ioctl.type = NVIF_IOCTL_V0_DEL, + }; - nvif_object_unmap(object); - nvif_object_ioctl(object, &args, sizeof(args), NULL); - if (object->data) { - object->size = 0; - object->data = NULL; - kfree(ctor); - } - nvif_object_ref(NULL, &object->parent); - } + if (!object->client) + return; + + nvif_object_unmap(object); + nvif_object_ioctl(object, &args, sizeof(args), NULL); + object->client = NULL; } int -nvif_object_init(struct nvif_object *parent, void (*dtor)(struct nvif_object *), - u32 handle, u32 oclass, void *data, u32 size, - struct nvif_object *object) +nvif_object_init(struct nvif_object *parent, u32 handle, u32 oclass, + void *data, u32 size, struct nvif_object *object) { - struct ctor *ctor; + struct { + struct nvif_ioctl_v0 ioctl; + struct nvif_ioctl_new_v0 new; + } *args; int ret = 0; - object->parent = NULL; - object->object = object; - nvif_object_ref(parent, &object->parent); - kref_init(&object->refcount); + object->client = NULL; + object->parent = parent; object->handle = handle; object->oclass = oclass; - object->data = NULL; - object->size = 0; - object->dtor = dtor; object->map.ptr = NULL; object->map.size = 0; if (object->parent) { - if (!(ctor = kmalloc(sizeof(*ctor) + size, GFP_KERNEL))) { + if (!(args = kmalloc(sizeof(*args) + size, GFP_KERNEL))) { nvif_object_fini(object); return -ENOMEM; } - object->data = ctor->new.data; - object->size = size; - memcpy(object->data, data, size); - ctor->ioctl.version = 0; - ctor->ioctl.type = NVIF_IOCTL_V0_NEW; - ctor->new.version = 0; - ctor->new.route = NVIF_IOCTL_V0_ROUTE_NVIF; - ctor->new.token = (unsigned long)(void *)object; - ctor->new.handle = handle; - ctor->new.oclass = oclass; - - ret = nvif_object_ioctl(parent, ctor, sizeof(*ctor) + - object->size, &object->priv); + args->ioctl.version = 0; + args->ioctl.type = NVIF_IOCTL_V0_NEW; + args->new.version = 0; + args->new.route = parent->client->route; + args->new.token = (unsigned long)(void *)object; + args->new.handle = handle; + args->new.oclass = oclass; + + memcpy(args->new.data, data, size); + ret = nvif_object_ioctl(parent, args, sizeof(*args) + size, + &object->priv); + memcpy(data, args->new.data, size); + kfree(args); + if (ret == 0) + object->client = parent->client; } if (ret) nvif_object_fini(object); return ret; } - -static void -nvif_object_del(struct nvif_object *object) -{ - nvif_object_fini(object); - kfree(object); -} - -int -nvif_object_new(struct nvif_object *parent, u32 handle, u32 oclass, - void *data, u32 size, struct nvif_object **pobject) -{ - struct nvif_object *object = kzalloc(sizeof(*object), GFP_KERNEL); - if (object) { - int ret = nvif_object_init(parent, nvif_object_del, handle, - oclass, data, size, object); - if (ret) { - kfree(object); - object = NULL; - } - *pobject = object; - return ret; - } - return -ENOMEM; -} - -static void -nvif_object_put(struct kref *kref) -{ - struct nvif_object *object = - container_of(kref, typeof(*object), refcount); - object->dtor(object); -} - -void -nvif_object_ref(struct nvif_object *object, struct nvif_object **pobject) -{ - if (object) - kref_get(&object->refcount); - if (*pobject) - kref_put(&(*pobject)->refcount, nvif_object_put); - *pobject = object; -} |