From: Ben Skeggs Date: Thu, 20 Aug 2015 04:54:15 +0000 (+1000) Subject: drm/nouveau/nvif: simplify and tidy library interfaces X-Git-Tag: omap-for-v4.3/fixes-rc1~89^2~11^2~100 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=a01ca78c8f118e5a24f1527ecf078ab56ddd4805;p=pandora-kernel.git 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 --- 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 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 -#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 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 #include -#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 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 -#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; Reading git-diff-tree failed