Commit 71f4e45a authored by Dave Airlie's avatar Dave Airlie

Merge branch 'linux-5.1' of git://github.com/skeggsb/linux into drm-next

Various fixes/cleanups, along with initial support for SVM features
utilising HMM address-space mirroring and device memory migration.
There's a lot more work to do in these areas, both in terms of
features and efficiency, but these can slowly trickle in later down
the track.
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Ben Skeggs <skeggsb@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv5bsB4rRY1Gqa_Bp_KAd-v_q1rGZ4nYmOAQhceL0Nr-Xg@mail.gmail.com
parents c06de561 a788ade4
...@@ -30,6 +30,8 @@ nouveau-y += nouveau_vga.o ...@@ -30,6 +30,8 @@ nouveau-y += nouveau_vga.o
# DRM - memory management # DRM - memory management
nouveau-y += nouveau_bo.o nouveau-y += nouveau_bo.o
nouveau-y += nouveau_gem.o nouveau-y += nouveau_gem.o
nouveau-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_svm.o
nouveau-$(CONFIG_DRM_NOUVEAU_SVM) += nouveau_dmem.o
nouveau-y += nouveau_mem.o nouveau-y += nouveau_mem.o
nouveau-y += nouveau_prime.o nouveau-y += nouveau_prime.o
nouveau-y += nouveau_sgdma.o nouveau-y += nouveau_sgdma.o
......
...@@ -71,3 +71,15 @@ config DRM_NOUVEAU_BACKLIGHT ...@@ -71,3 +71,15 @@ config DRM_NOUVEAU_BACKLIGHT
help help
Say Y here if you want to control the backlight of your display Say Y here if you want to control the backlight of your display
(e.g. a laptop panel). (e.g. a laptop panel).
config DRM_NOUVEAU_SVM
bool "(EXPERIMENTAL) Enable SVM (Shared Virtual Memory) support"
depends on ARCH_HAS_HMM
depends on DRM_NOUVEAU
depends on STAGING
select HMM_MIRROR
select DEVICE_PRIVATE
default n
help
Say Y here if you want to enable experimental support for
Shared Virtual Memory (SVM).
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "nvreg.h" #include "nvreg.h"
#include "nouveau_fbcon.h" #include "nouveau_fbcon.h"
#include "disp.h" #include "disp.h"
#include "nouveau_dma.h"
#include <subdev/bios/pll.h> #include <subdev/bios/pll.h>
#include <subdev/clk.h> #include <subdev/clk.h>
...@@ -1077,12 +1078,223 @@ nouveau_crtc_set_config(struct drm_mode_set *set, ...@@ -1077,12 +1078,223 @@ nouveau_crtc_set_config(struct drm_mode_set *set,
return ret; return ret;
} }
struct nv04_page_flip_state {
struct list_head head;
struct drm_pending_vblank_event *event;
struct drm_crtc *crtc;
int bpp, pitch;
u64 offset;
};
static int
nv04_finish_page_flip(struct nouveau_channel *chan,
struct nv04_page_flip_state *ps)
{
struct nouveau_fence_chan *fctx = chan->fence;
struct nouveau_drm *drm = chan->drm;
struct drm_device *dev = drm->dev;
struct nv04_page_flip_state *s;
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
if (list_empty(&fctx->flip)) {
NV_ERROR(drm, "unexpected pageflip\n");
spin_unlock_irqrestore(&dev->event_lock, flags);
return -EINVAL;
}
s = list_first_entry(&fctx->flip, struct nv04_page_flip_state, head);
if (s->event) {
drm_crtc_arm_vblank_event(s->crtc, s->event);
} else {
/* Give up ownership of vblank for page-flipped crtc */
drm_crtc_vblank_put(s->crtc);
}
list_del(&s->head);
if (ps)
*ps = *s;
kfree(s);
spin_unlock_irqrestore(&dev->event_lock, flags);
return 0;
}
int
nv04_flip_complete(struct nvif_notify *notify)
{
struct nouveau_cli *cli = (void *)notify->object->client;
struct nouveau_drm *drm = cli->drm;
struct nouveau_channel *chan = drm->channel;
struct nv04_page_flip_state state;
if (!nv04_finish_page_flip(chan, &state)) {
nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc),
state.offset + state.crtc->y *
state.pitch + state.crtc->x *
state.bpp / 8);
}
return NVIF_NOTIFY_KEEP;
}
static int
nv04_page_flip_emit(struct nouveau_channel *chan,
struct nouveau_bo *old_bo,
struct nouveau_bo *new_bo,
struct nv04_page_flip_state *s,
struct nouveau_fence **pfence)
{
struct nouveau_fence_chan *fctx = chan->fence;
struct nouveau_drm *drm = chan->drm;
struct drm_device *dev = drm->dev;
unsigned long flags;
int ret;
/* Queue it to the pending list */
spin_lock_irqsave(&dev->event_lock, flags);
list_add_tail(&s->head, &fctx->flip);
spin_unlock_irqrestore(&dev->event_lock, flags);
/* Synchronize with the old framebuffer */
ret = nouveau_fence_sync(old_bo, chan, false, false);
if (ret)
goto fail;
/* Emit the pageflip */
ret = RING_SPACE(chan, 2);
if (ret)
goto fail;
BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
OUT_RING (chan, 0x00000000);
FIRE_RING (chan);
ret = nouveau_fence_new(chan, false, pfence);
if (ret)
goto fail;
return 0;
fail:
spin_lock_irqsave(&dev->event_lock, flags);
list_del(&s->head);
spin_unlock_irqrestore(&dev->event_lock, flags);
return ret;
}
static int
nv04_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event, u32 flags,
struct drm_modeset_acquire_ctx *ctx)
{
const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1;
struct drm_device *dev = crtc->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo;
struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
struct nv04_page_flip_state *s;
struct nouveau_channel *chan;
struct nouveau_cli *cli;
struct nouveau_fence *fence;
struct nv04_display *dispnv04 = nv04_display(dev);
int head = nouveau_crtc(crtc)->index;
int ret;
chan = drm->channel;
if (!chan)
return -ENODEV;
cli = (void *)chan->user.client;
s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
return -ENOMEM;
if (new_bo != old_bo) {
ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM, true);
if (ret)
goto fail_free;
}
mutex_lock(&cli->mutex);
ret = ttm_bo_reserve(&new_bo->bo, true, false, NULL);
if (ret)
goto fail_unpin;
/* synchronise rendering channel with the kernel's channel */
ret = nouveau_fence_sync(new_bo, chan, false, true);
if (ret) {
ttm_bo_unreserve(&new_bo->bo);
goto fail_unpin;
}
if (new_bo != old_bo) {
ttm_bo_unreserve(&new_bo->bo);
ret = ttm_bo_reserve(&old_bo->bo, true, false, NULL);
if (ret)
goto fail_unpin;
}
/* Initialize a page flip struct */
*s = (struct nv04_page_flip_state)
{ { }, event, crtc, fb->format->cpp[0] * 8, fb->pitches[0],
new_bo->bo.offset };
/* Keep vblanks on during flip, for the target crtc of this flip */
drm_crtc_vblank_get(crtc);
/* Emit a page flip */
if (swap_interval) {
ret = RING_SPACE(chan, 8);
if (ret)
goto fail_unreserve;
BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1);
OUT_RING (chan, 0);
BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1);
OUT_RING (chan, head);
BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
OUT_RING (chan, 0);
BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
OUT_RING (chan, 0);
}
nouveau_bo_ref(new_bo, &dispnv04->image[head]);
ret = nv04_page_flip_emit(chan, old_bo, new_bo, s, &fence);
if (ret)
goto fail_unreserve;
mutex_unlock(&cli->mutex);
/* Update the crtc struct and cleanup */
crtc->primary->fb = fb;
nouveau_bo_fence(old_bo, fence, false);
ttm_bo_unreserve(&old_bo->bo);
if (old_bo != new_bo)
nouveau_bo_unpin(old_bo);
nouveau_fence_unref(&fence);
return 0;
fail_unreserve:
drm_crtc_vblank_put(crtc);
ttm_bo_unreserve(&old_bo->bo);
fail_unpin:
mutex_unlock(&cli->mutex);
if (old_bo != new_bo)
nouveau_bo_unpin(new_bo);
fail_free:
kfree(s);
return ret;
}
static const struct drm_crtc_funcs nv04_crtc_funcs = { static const struct drm_crtc_funcs nv04_crtc_funcs = {
.cursor_set = nv04_crtc_cursor_set, .cursor_set = nv04_crtc_cursor_set,
.cursor_move = nv04_crtc_cursor_move, .cursor_move = nv04_crtc_cursor_move,
.gamma_set = nv_crtc_gamma_set, .gamma_set = nv_crtc_gamma_set,
.set_config = nouveau_crtc_set_config, .set_config = nouveau_crtc_set_config,
.page_flip = nouveau_crtc_page_flip, .page_flip = nv04_crtc_page_flip,
.destroy = nv_crtc_destroy, .destroy = nv_crtc_destroy,
}; };
......
...@@ -30,6 +30,160 @@ ...@@ -30,6 +30,160 @@
#include "hw.h" #include "hw.h"
#include "nouveau_encoder.h" #include "nouveau_encoder.h"
#include "nouveau_connector.h" #include "nouveau_connector.h"
#include "nouveau_bo.h"
#include <nvif/if0004.h>
static void
nv04_display_fini(struct drm_device *dev, bool suspend)
{
struct nv04_display *disp = nv04_display(dev);
struct drm_crtc *crtc;
/* Disable flip completion events. */
nvif_notify_put(&disp->flip);
/* Disable vblank interrupts. */
NVWriteCRTC(dev, 0, NV_PCRTC_INTR_EN_0, 0);
if (nv_two_heads(dev))
NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
if (!suspend)
return;
/* Un-pin FB and cursors so they'll be evicted to system memory. */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb;
nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
if (!nouveau_fb || !nouveau_fb->nvbo)
continue;
nouveau_bo_unpin(nouveau_fb->nvbo);
}
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (nv_crtc->cursor.nvbo) {
if (nv_crtc->cursor.set_offset)
nouveau_bo_unmap(nv_crtc->cursor.nvbo);
nouveau_bo_unpin(nv_crtc->cursor.nvbo);
}
}
}
static int
nv04_display_init(struct drm_device *dev, bool resume, bool runtime)
{
struct nv04_display *disp = nv04_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_encoder *encoder;
struct drm_crtc *crtc;
int ret;
/* meh.. modeset apparently doesn't setup all the regs and depends
* on pre-existing state, for now load the state of the card *before*
* nouveau was loaded, and then do a modeset.
*
* best thing to do probably is to make save/restore routines not
* save/restore "pre-load" state, but more general so we can save
* on suspend too.
*/
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
nv_crtc->save(&nv_crtc->base);
}
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
encoder->enc_save(&encoder->base.base);
/* Enable flip completion events. */
nvif_notify_get(&disp->flip);
if (!resume)
return 0;
/* Re-pin FB/cursors. */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb;
nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
if (!nouveau_fb || !nouveau_fb->nvbo)
continue;
ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM, true);
if (ret)
NV_ERROR(drm, "Could not pin framebuffer\n");
}
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (!nv_crtc->cursor.nvbo)
continue;
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
if (!ret && nv_crtc->cursor.set_offset)
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
if (ret)
NV_ERROR(drm, "Could not pin/map cursor.\n");
}
/* Force CLUT to get re-loaded during modeset. */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
nv_crtc->lut.depth = 0;
}
/* This should ensure we don't hit a locking problem when someone
* wakes us up via a connector. We should never go into suspend
* while the display is on anyways.
*/
if (runtime)
return 0;
/* Restore mode. */
drm_helper_resume_force_mode(dev);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (!nv_crtc->cursor.nvbo)
continue;
if (nv_crtc->cursor.set_offset)
nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
nv_crtc->cursor_saved_y);
}
return 0;
}
static void
nv04_display_destroy(struct drm_device *dev)
{
struct nv04_display *disp = nv04_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_encoder *encoder;
struct nouveau_crtc *nv_crtc;
/* Restore state */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
encoder->enc_restore(&encoder->base.base);
list_for_each_entry(nv_crtc, &dev->mode_config.crtc_list, base.head)
nv_crtc->restore(&nv_crtc->base);
nouveau_hw_save_vga_fonts(dev, 0);
nvif_notify_fini(&disp->flip);
nouveau_display(dev)->priv = NULL;
kfree(disp);
nvif_object_unmap(&drm->client.device.object);
}
int int
nv04_display_create(struct drm_device *dev) nv04_display_create(struct drm_device *dev)
...@@ -58,6 +212,13 @@ nv04_display_create(struct drm_device *dev) ...@@ -58,6 +212,13 @@ nv04_display_create(struct drm_device *dev)
/* Pre-nv50 doesn't support atomic, so don't expose the ioctls */ /* Pre-nv50 doesn't support atomic, so don't expose the ioctls */
dev->driver->driver_features &= ~DRIVER_ATOMIC; dev->driver->driver_features &= ~DRIVER_ATOMIC;
/* Request page flip completion event. */
if (drm->nvsw.client) {
nvif_notify_init(&drm->nvsw, nv04_flip_complete,
false, NV04_NVSW_NTFY_UEVENT,
NULL, 0, 0, &disp->flip);
}
nouveau_hw_save_vga_fonts(dev, 1); nouveau_hw_save_vga_fonts(dev, 1);
nv04_crtc_create(dev, 0); nv04_crtc_create(dev, 0);
...@@ -121,58 +282,3 @@ nv04_display_create(struct drm_device *dev) ...@@ -121,58 +282,3 @@ nv04_display_create(struct drm_device *dev)
return 0; return 0;
} }
void
nv04_display_destroy(struct drm_device *dev)
{
struct nv04_display *disp = nv04_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_encoder *encoder;
struct nouveau_crtc *nv_crtc;
/* Restore state */
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
encoder->enc_restore(&encoder->base.base);
list_for_each_entry(nv_crtc, &dev->mode_config.crtc_list, base.head)
nv_crtc->restore(&nv_crtc->base);
nouveau_hw_save_vga_fonts(dev, 0);
nouveau_display(dev)->priv = NULL;
kfree(disp);
nvif_object_unmap(&drm->client.device.object);
}
int
nv04_display_init(struct drm_device *dev)
{
struct nouveau_encoder *encoder;
struct nouveau_crtc *crtc;
/* meh.. modeset apparently doesn't setup all the regs and depends
* on pre-existing state, for now load the state of the card *before*
* nouveau was loaded, and then do a modeset.
*
* best thing to do probably is to make save/restore routines not
* save/restore "pre-load" state, but more general so we can save
* on suspend too.
*/
list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
crtc->save(&crtc->base);
list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
encoder->enc_save(&encoder->base.base);
return 0;
}
void
nv04_display_fini(struct drm_device *dev)
{
/* disable vblank interrupts */
NVWriteCRTC(dev, 0, NV_PCRTC_INTR_EN_0, 0);
if (nv_two_heads(dev))
NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
}
...@@ -82,6 +82,7 @@ struct nv04_display { ...@@ -82,6 +82,7 @@ struct nv04_display {
uint32_t saved_vga_font[4][16384]; uint32_t saved_vga_font[4][16384];
uint32_t dac_users[4]; uint32_t dac_users[4];
struct nouveau_bo *image[2]; struct nouveau_bo *image[2];
struct nvif_notify flip;
}; };
static inline struct nv04_display * static inline struct nv04_display *
...@@ -92,9 +93,6 @@ nv04_display(struct drm_device *dev) ...@@ -92,9 +93,6 @@ nv04_display(struct drm_device *dev)
/* nv04_display.c */ /* nv04_display.c */
int nv04_display_create(struct drm_device *); int nv04_display_create(struct drm_device *);
void nv04_display_destroy(struct drm_device *);
int nv04_display_init(struct drm_device *);
void nv04_display_fini(struct drm_device *);
/* nv04_crtc.c */ /* nv04_crtc.c */
int nv04_crtc_create(struct drm_device *, int index); int nv04_crtc_create(struct drm_device *, int index);
...@@ -176,4 +174,5 @@ nouveau_bios_run_init_table(struct drm_device *dev, u16 table, ...@@ -176,4 +174,5 @@ nouveau_bios_run_init_table(struct drm_device *dev, u16 table,
); );
} }
int nv04_flip_complete(struct nvif_notify *);
#endif #endif
...@@ -42,7 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore) ...@@ -42,7 +42,7 @@ nv50_core_new(struct nouveau_drm *drm, struct nv50_core **pcore)
int version; int version;
int (*new)(struct nouveau_drm *, s32, struct nv50_core **); int (*new)(struct nouveau_drm *, s32, struct nv50_core **);
} cores[] = { } cores[] = {
{ TU104_DISP_CORE_CHANNEL_DMA, 0, corec57d_new }, { TU102_DISP_CORE_CHANNEL_DMA, 0, corec57d_new },
{ GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new }, { GV100_DISP_CORE_CHANNEL_DMA, 0, corec37d_new },
{ GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, { GP102_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
{ GP100_DISP_CORE_CHANNEL_DMA, 0, core917d_new }, { GP100_DISP_CORE_CHANNEL_DMA, 0, core917d_new },
......
...@@ -31,7 +31,7 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw) ...@@ -31,7 +31,7 @@ nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
int version; int version;
int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **); int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
} curses[] = { } curses[] = {
{ TU104_DISP_CURSOR, 0, cursc37a_new }, { TU102_DISP_CURSOR, 0, cursc37a_new },
{ GV100_DISP_CURSOR, 0, cursc37a_new }, { GV100_DISP_CURSOR, 0, cursc37a_new },
{ GK104_DISP_CURSOR, 0, curs907a_new }, { GK104_DISP_CURSOR, 0, curs907a_new },
{ GF110_DISP_CURSOR, 0, curs907a_new }, { GF110_DISP_CURSOR, 0, curs907a_new },
......
...@@ -817,7 +817,8 @@ nv50_msto_enable(struct drm_encoder *encoder) ...@@ -817,7 +817,8 @@ nv50_msto_enable(struct drm_encoder *encoder)
r = drm_dp_mst_allocate_vcpi(&mstm->mgr, mstc->port, armh->dp.pbn, r = drm_dp_mst_allocate_vcpi(&mstm->mgr, mstc->port, armh->dp.pbn,
armh->dp.tu); armh->dp.tu);
WARN_ON(!r); if (!r)
DRM_DEBUG_KMS("Failed to allocate VCPI\n");
if (!mstm->links++) if (!mstm->links++)
nv50_outp_acquire(mstm->outp); nv50_outp_acquire(mstm->outp);
...@@ -2220,8 +2221,8 @@ nv50_disp_func = { ...@@ -2220,8 +2221,8 @@ nv50_disp_func = {
* Init * Init
*****************************************************************************/ *****************************************************************************/
void static void
nv50_display_fini(struct drm_device *dev) nv50_display_fini(struct drm_device *dev, bool suspend)
{ {
struct nouveau_encoder *nv_encoder; struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -2242,8 +2243,8 @@ nv50_display_fini(struct drm_device *dev) ...@@ -2242,8 +2243,8 @@ nv50_display_fini(struct drm_device *dev)
} }
} }
int static int
nv50_display_init(struct drm_device *dev) nv50_display_init(struct drm_device *dev, bool resume, bool runtime)
{ {
struct nv50_core *core = nv50_disp(dev)->core; struct nv50_core *core = nv50_disp(dev)->core;
struct drm_encoder *encoder; struct drm_encoder *encoder;
...@@ -2269,7 +2270,7 @@ nv50_display_init(struct drm_device *dev) ...@@ -2269,7 +2270,7 @@ nv50_display_init(struct drm_device *dev)
return 0; return 0;
} }
void static void
nv50_display_destroy(struct drm_device *dev) nv50_display_destroy(struct drm_device *dev)
{ {
struct nv50_disp *disp = nv50_disp(dev); struct nv50_disp *disp = nv50_disp(dev);
......
...@@ -31,7 +31,7 @@ nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw) ...@@ -31,7 +31,7 @@ nv50_wimm_init(struct nouveau_drm *drm, struct nv50_wndw *wndw)
int version; int version;
int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *); int (*init)(struct nouveau_drm *, s32, struct nv50_wndw *);
} wimms[] = { } wimms[] = {
{ TU104_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, { TU102_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init },
{ GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init }, { GV100_DISP_WINDOW_IMM_CHANNEL_DMA, 0, wimmc37b_init },
{} {}
}; };
......
...@@ -626,7 +626,7 @@ nv50_wndw_new(struct nouveau_drm *drm, enum drm_plane_type type, int index, ...@@ -626,7 +626,7 @@ nv50_wndw_new(struct nouveau_drm *drm, enum drm_plane_type type, int index,
int (*new)(struct nouveau_drm *, enum drm_plane_type, int (*new)(struct nouveau_drm *, enum drm_plane_type,
int, s32, struct nv50_wndw **); int, s32, struct nv50_wndw **);
} wndws[] = { } wndws[] = {
{ TU104_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new }, { TU102_DISP_WINDOW_CHANNEL_DMA, 0, wndwc57e_new },
{ GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new }, { GV100_DISP_WINDOW_CHANNEL_DMA, 0, wndwc37e_new },
{} {}
}; };
......
...@@ -54,6 +54,9 @@ ...@@ -54,6 +54,9 @@
#define VOLTA_USERMODE_A 0x0000c361 #define VOLTA_USERMODE_A 0x0000c361
#define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069
#define VOLTA_FAULT_BUFFER_A /* clb069.h */ 0x0000c369
#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b #define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b
#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e #define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e
#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e #define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e
...@@ -84,7 +87,7 @@ ...@@ -84,7 +87,7 @@
#define GP100_DISP /* cl5070.h */ 0x00009770 #define GP100_DISP /* cl5070.h */ 0x00009770
#define GP102_DISP /* cl5070.h */ 0x00009870 #define GP102_DISP /* cl5070.h */ 0x00009870
#define GV100_DISP /* cl5070.h */ 0x0000c370 #define GV100_DISP /* cl5070.h */ 0x0000c370
#define TU104_DISP /* cl5070.h */ 0x0000c570 #define TU102_DISP /* cl5070.h */ 0x0000c570
#define NV31_MPEG 0x00003174 #define NV31_MPEG 0x00003174
#define G82_MPEG 0x00008274 #define G82_MPEG 0x00008274
...@@ -97,7 +100,7 @@ ...@@ -97,7 +100,7 @@
#define GF110_DISP_CURSOR /* cl507a.h */ 0x0000907a #define GF110_DISP_CURSOR /* cl507a.h */ 0x0000907a
#define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a #define GK104_DISP_CURSOR /* cl507a.h */ 0x0000917a
#define GV100_DISP_CURSOR /* cl507a.h */ 0x0000c37a #define GV100_DISP_CURSOR /* cl507a.h */ 0x0000c37a
#define TU104_DISP_CURSOR /* cl507a.h */ 0x0000c57a #define TU102_DISP_CURSOR /* cl507a.h */ 0x0000c57a
#define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b #define NV50_DISP_OVERLAY /* cl507b.h */ 0x0000507b
#define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b #define G82_DISP_OVERLAY /* cl507b.h */ 0x0000827b
...@@ -106,7 +109,7 @@ ...@@ -106,7 +109,7 @@
#define GK104_DISP_OVERLAY /* cl507b.h */ 0x0000917b #define GK104_DISP_OVERLAY /* cl507b.h */ 0x0000917b
#define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c37b #define GV100_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c37b
#define TU104_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c57b #define TU102_DISP_WINDOW_IMM_CHANNEL_DMA /* clc37b.h */ 0x0000c57b
#define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c #define NV50_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000507c
#define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c #define G82_DISP_BASE_CHANNEL_DMA /* cl507c.h */ 0x0000827c
...@@ -129,7 +132,7 @@ ...@@ -129,7 +132,7 @@
#define GP100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000977d #define GP100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000977d
#define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d #define GP102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000987d
#define GV100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c37d #define GV100_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c37d
#define TU104_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c57d #define TU102_DISP_CORE_CHANNEL_DMA /* cl507d.h */ 0x0000c57d
#define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e #define NV50_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000507e
#define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e #define G82_DISP_OVERLAY_CHANNEL_DMA /* cl507e.h */ 0x0000827e
...@@ -139,7 +142,7 @@ ...@@ -139,7 +142,7 @@
#define GK104_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000917e #define GK104_DISP_OVERLAY_CONTROL_DMA /* cl507e.h */ 0x0000917e
#define GV100_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c37e #define GV100_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c37e
#define TU104_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c57e #define TU102_DISP_WINDOW_CHANNEL_DMA /* clc37e.h */ 0x0000c57e
#define NV50_TESLA 0x00005097 #define NV50_TESLA 0x00005097
#define G82_TESLA 0x00008297 #define G82_TESLA 0x00008297
......
#ifndef __NVIF_CLB069_H__
#define __NVIF_CLB069_H__
struct nvif_clb069_v0 {
__u8 version;
__u8 pad01[3];
__u32 entries;
__u32 get;
__u32 put;
};
#define NVB069_V0_NTFY_FAULT 0x00
#endif
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
struct nvif_vmm_v0 { struct nvif_vmm_v0 {
__u8 version; __u8 version;
__u8 page_nr; __u8 page_nr;
__u8 pad02[6]; __u8 managed;
__u8 pad03[5];
__u64 addr; __u64 addr;
__u64 size; __u64 size;
__u8 data[]; __u8 data[];
...@@ -14,6 +15,9 @@ struct nvif_vmm_v0 { ...@@ -14,6 +15,9 @@ struct nvif_vmm_v0 {
#define NVIF_VMM_V0_PUT 0x02 #define NVIF_VMM_V0_PUT 0x02
#define NVIF_VMM_V0_MAP 0x03 #define NVIF_VMM_V0_MAP 0x03
#define NVIF_VMM_V0_UNMAP 0x04 #define NVIF_VMM_V0_UNMAP 0x04
#define NVIF_VMM_V0_PFNMAP 0x05
#define NVIF_VMM_V0_PFNCLR 0x06
#define NVIF_VMM_V0_MTHD(i) ((i) + 0x80)
struct nvif_vmm_page_v0 { struct nvif_vmm_page_v0 {
__u8 version; __u8 version;
...@@ -61,4 +65,28 @@ struct nvif_vmm_unmap_v0 { ...@@ -61,4 +65,28 @@ struct nvif_vmm_unmap_v0 {
__u8 pad01[7]; __u8 pad01[7];
__u64 addr; __u64 addr;
}; };
struct nvif_vmm_pfnmap_v0 {
__u8 version;
__u8 page;
__u8 pad02[6];
__u64 addr;
__u64 size;
#define NVIF_VMM_PFNMAP_V0_ADDR 0xfffffffffffff000ULL
#define NVIF_VMM_PFNMAP_V0_ADDR_SHIFT 12
#define NVIF_VMM_PFNMAP_V0_APER 0x00000000000000f0ULL
#define NVIF_VMM_PFNMAP_V0_HOST 0x0000000000000000ULL
#define NVIF_VMM_PFNMAP_V0_VRAM 0x0000000000000010ULL
#define NVIF_VMM_PFNMAP_V0_W 0x0000000000000002ULL
#define NVIF_VMM_PFNMAP_V0_V 0x0000000000000001ULL
#define NVIF_VMM_PFNMAP_V0_NONE 0x0000000000000000ULL
__u64 phys[];
};
struct nvif_vmm_pfnclr_v0 {
__u8 version;
__u8 pad01[7];
__u64 addr;
__u64 size;
};
#endif #endif
...@@ -6,6 +6,12 @@ struct gp100_vmm_vn { ...@@ -6,6 +6,12 @@ struct gp100_vmm_vn {
/* nvif_vmm_vX ... */ /* nvif_vmm_vX ... */
}; };
struct gp100_vmm_v0 {
/* nvif_vmm_vX ... */
__u8 version;
__u8 fault_replay;
};
struct gp100_vmm_map_vn { struct gp100_vmm_map_vn {
/* nvif_vmm_map_vX ... */ /* nvif_vmm_map_vX ... */
}; };
...@@ -18,4 +24,19 @@ struct gp100_vmm_map_v0 { ...@@ -18,4 +24,19 @@ struct gp100_vmm_map_v0 {
__u8 priv; __u8 priv;
__u8 kind; __u8 kind;
}; };
#define GP100_VMM_VN_FAULT_REPLAY NVIF_VMM_V0_MTHD(0x00)
#define GP100_VMM_VN_FAULT_CANCEL NVIF_VMM_V0_MTHD(0x01)
struct gp100_vmm_fault_replay_vn {
};
struct gp100_vmm_fault_cancel_v0 {
__u8 version;
__u8 hub;
__u8 gpc;
__u8 client;
__u8 pad04[4];
__u64 inst;
};
#endif #endif
...@@ -30,8 +30,8 @@ struct nvif_vmm { ...@@ -30,8 +30,8 @@ struct nvif_vmm {
int page_nr; int page_nr;
}; };
int nvif_vmm_init(struct nvif_mmu *, s32 oclass, u64 addr, u64 size, int nvif_vmm_init(struct nvif_mmu *, s32 oclass, bool managed, u64 addr,
void *argv, u32 argc, struct nvif_vmm *); u64 size, void *argv, u32 argc, struct nvif_vmm *);
void nvif_vmm_fini(struct nvif_vmm *); void nvif_vmm_fini(struct nvif_vmm *);
int nvif_vmm_get(struct nvif_vmm *, enum nvif_vmm_get, bool sparse, int nvif_vmm_get(struct nvif_vmm *, enum nvif_vmm_get, bool sparse,
u8 page, u8 align, u64 size, struct nvif_vma *); u8 page, u8 align, u64 size, struct nvif_vma *);
......
...@@ -28,6 +28,7 @@ enum nvkm_devidx { ...@@ -28,6 +28,7 @@ enum nvkm_devidx {
NVKM_SUBDEV_ICCSENSE, NVKM_SUBDEV_ICCSENSE,
NVKM_SUBDEV_THERM, NVKM_SUBDEV_THERM,
NVKM_SUBDEV_CLK, NVKM_SUBDEV_CLK,
NVKM_SUBDEV_GSP,
NVKM_SUBDEV_SECBOOT, NVKM_SUBDEV_SECBOOT,
NVKM_ENGINE_BSP, NVKM_ENGINE_BSP,
...@@ -137,6 +138,7 @@ struct nvkm_device { ...@@ -137,6 +138,7 @@ struct nvkm_device {
struct nvkm_fb *fb; struct nvkm_fb *fb;
struct nvkm_fuse *fuse; struct nvkm_fuse *fuse;
struct nvkm_gpio *gpio; struct nvkm_gpio *gpio;
struct nvkm_gsp *gsp;
struct nvkm_i2c *i2c; struct nvkm_i2c *i2c;
struct nvkm_subdev *ibus; struct nvkm_subdev *ibus;
struct nvkm_iccsense *iccsense; struct nvkm_iccsense *iccsense;
...@@ -209,6 +211,7 @@ struct nvkm_device_chip { ...@@ -209,6 +211,7 @@ struct nvkm_device_chip {
int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **); int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **);
int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **); int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **);
int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **); int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **);
int (*gsp )(struct nvkm_device *, int idx, struct nvkm_gsp **);
int (*i2c )(struct nvkm_device *, int idx, struct nvkm_i2c **); int (*i2c )(struct nvkm_device *, int idx, struct nvkm_i2c **);
int (*ibus )(struct nvkm_device *, int idx, struct nvkm_subdev **); int (*ibus )(struct nvkm_device *, int idx, struct nvkm_subdev **);
int (*iccsense)(struct nvkm_device *, int idx, struct nvkm_iccsense **); int (*iccsense)(struct nvkm_device *, int idx, struct nvkm_iccsense **);
......
...@@ -11,5 +11,5 @@ int gm200_ce_new(struct nvkm_device *, int, struct nvkm_engine **); ...@@ -11,5 +11,5 @@ int gm200_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int gp100_ce_new(struct nvkm_device *, int, struct nvkm_engine **); int gp100_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int gp102_ce_new(struct nvkm_device *, int, struct nvkm_engine **); int gp102_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int gv100_ce_new(struct nvkm_device *, int, struct nvkm_engine **); int gv100_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
int tu104_ce_new(struct nvkm_device *, int, struct nvkm_engine **); int tu102_ce_new(struct nvkm_device *, int, struct nvkm_engine **);
#endif #endif
...@@ -36,5 +36,5 @@ int gm200_disp_new(struct nvkm_device *, int, struct nvkm_disp **); ...@@ -36,5 +36,5 @@ int gm200_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); int gp100_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **); int gp102_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int gv100_disp_new(struct nvkm_device *, int, struct nvkm_disp **); int gv100_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
int tu104_disp_new(struct nvkm_device *, int, struct nvkm_disp **); int tu102_disp_new(struct nvkm_device *, int, struct nvkm_disp **);
#endif #endif
...@@ -74,5 +74,5 @@ int gm20b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); ...@@ -74,5 +74,5 @@ int gm20b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gp100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); int gp100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gp10b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); int gp10b_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int gv100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); int gv100_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
int tu104_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **); int tu102_fifo_new(struct nvkm_device *, int, struct nvkm_fifo **);
#endif #endif
...@@ -10,6 +10,9 @@ struct nvkm_gr { ...@@ -10,6 +10,9 @@ struct nvkm_gr {
u64 nvkm_gr_units(struct nvkm_gr *); u64 nvkm_gr_units(struct nvkm_gr *);
int nvkm_gr_tlb_flush(struct nvkm_gr *); int nvkm_gr_tlb_flush(struct nvkm_gr *);
int nvkm_gr_ctxsw_pause(struct nvkm_device *);
int nvkm_gr_ctxsw_resume(struct nvkm_device *);
u32 nvkm_gr_ctxsw_inst(struct nvkm_device *);
int nv04_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int nv04_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int nv10_gr_new(struct nvkm_device *, int, struct nvkm_gr **); int nv10_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
struct nvkm_nvdec { struct nvkm_nvdec {
struct nvkm_engine engine; struct nvkm_engine engine;
u32 addr;
struct nvkm_falcon *falcon; struct nvkm_falcon *falcon;
}; };
......
...@@ -5,10 +5,13 @@ ...@@ -5,10 +5,13 @@
struct nvkm_sec2 { struct nvkm_sec2 {
struct nvkm_engine engine; struct nvkm_engine engine;
u32 addr;
struct nvkm_falcon *falcon; struct nvkm_falcon *falcon;
struct nvkm_msgqueue *queue; struct nvkm_msgqueue *queue;
struct work_struct work; struct work_struct work;
}; };
int gp102_sec2_new(struct nvkm_device *, int, struct nvkm_sec2 **); int gp102_sec2_new(struct nvkm_device *, int, struct nvkm_sec2 **);
int tu102_sec2_new(struct nvkm_device *, int, struct nvkm_sec2 **);
#endif #endif
...@@ -29,5 +29,5 @@ int gf100_bar_new(struct nvkm_device *, int, struct nvkm_bar **); ...@@ -29,5 +29,5 @@ int gf100_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
int gk20a_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int gk20a_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
int gm107_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int gm107_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
int gm20b_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int gm20b_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
int tu104_bar_new(struct nvkm_device *, int, struct nvkm_bar **); int tu102_bar_new(struct nvkm_device *, int, struct nvkm_bar **);
#endif #endif
...@@ -31,5 +31,5 @@ int gf100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); ...@@ -31,5 +31,5 @@ int gf100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int gm107_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); int gm107_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); int gm200_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int gv100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); int gv100_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
int tu104_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **); int tu102_devinit_new(struct nvkm_device *, int, struct nvkm_devinit **);
#endif #endif
...@@ -13,6 +13,8 @@ struct nvkm_fault { ...@@ -13,6 +13,8 @@ struct nvkm_fault {
struct nvkm_event event; struct nvkm_event event;
struct nvkm_notify nrpfb; struct nvkm_notify nrpfb;
struct nvkm_device_oclass user;
}; };
struct nvkm_fault_data { struct nvkm_fault_data {
...@@ -30,5 +32,5 @@ struct nvkm_fault_data { ...@@ -30,5 +32,5 @@ struct nvkm_fault_data {
int gp100_fault_new(struct nvkm_device *, int, struct nvkm_fault **); int gp100_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
int gv100_fault_new(struct nvkm_device *, int, struct nvkm_fault **); int gv100_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
int tu104_fault_new(struct nvkm_device *, int, struct nvkm_fault **); int tu102_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
#endif #endif
#ifndef __NVKM_GSP_H__
#define __NVKM_GSP_H__
#define nvkm_gsp(p) container_of((p), struct nvkm_gsp, subdev)
#include <core/subdev.h>
struct nvkm_gsp {
struct nvkm_subdev subdev;
u32 addr;
struct nvkm_falcon *falcon;
};
int gv100_gsp_new(struct nvkm_device *, int, struct nvkm_gsp **);
#endif
...@@ -31,5 +31,5 @@ int gk104_mc_new(struct nvkm_device *, int, struct nvkm_mc **); ...@@ -31,5 +31,5 @@ int gk104_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int gk20a_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
int gp100_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int gp100_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
int gp10b_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int gp10b_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
int tu104_mc_new(struct nvkm_device *, int, struct nvkm_mc **); int tu102_mc_new(struct nvkm_device *, int, struct nvkm_mc **);
#endif #endif
...@@ -17,6 +17,7 @@ struct nvkm_vma { ...@@ -17,6 +17,7 @@ struct nvkm_vma {
bool part:1; /* Region was split from an allocated region by map(). */ bool part:1; /* Region was split from an allocated region by map(). */
bool user:1; /* Region user-allocated. */ bool user:1; /* Region user-allocated. */
bool busy:1; /* Region busy (for temporarily preventing user access). */ bool busy:1; /* Region busy (for temporarily preventing user access). */
bool mapped:1; /* Region contains valid pages. */
struct nvkm_memory *memory; /* Memory currently mapped into VMA. */ struct nvkm_memory *memory; /* Memory currently mapped into VMA. */
struct nvkm_tags *tags; /* Compression tag reference. */ struct nvkm_tags *tags; /* Compression tag reference. */
}; };
...@@ -44,6 +45,8 @@ struct nvkm_vmm { ...@@ -44,6 +45,8 @@ struct nvkm_vmm {
dma_addr_t null; dma_addr_t null;
void *nullp; void *nullp;
bool replay;
}; };
int nvkm_vmm_new(struct nvkm_device *, u64 addr, u64 size, void *argv, u32 argc, int nvkm_vmm_new(struct nvkm_device *, u64 addr, u64 size, void *argv, u32 argc,
...@@ -63,6 +66,7 @@ struct nvkm_vmm_map { ...@@ -63,6 +66,7 @@ struct nvkm_vmm_map {
struct nvkm_mm_node *mem; struct nvkm_mm_node *mem;
struct scatterlist *sgl; struct scatterlist *sgl;
dma_addr_t *dma; dma_addr_t *dma;
u64 *pfn;
u64 off; u64 off;
const struct nvkm_vmm_page *page; const struct nvkm_vmm_page *page;
...@@ -130,5 +134,5 @@ int gm20b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); ...@@ -130,5 +134,5 @@ int gm20b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
int gp100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gp100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
int gp10b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gp10b_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
int gv100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int gv100_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
int tu104_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **); int tu102_mmu_new(struct nvkm_device *, int, struct nvkm_mmu **);
#endif #endif
...@@ -9,6 +9,7 @@ struct nvkm_top { ...@@ -9,6 +9,7 @@ struct nvkm_top {
struct list_head device; struct list_head device;
}; };
u32 nvkm_top_addr(struct nvkm_device *, enum nvkm_devidx);
u32 nvkm_top_reset(struct nvkm_device *, enum nvkm_devidx); u32 nvkm_top_reset(struct nvkm_device *, enum nvkm_devidx);
u32 nvkm_top_intr(struct nvkm_device *, u32 intr, u64 *subdevs); u32 nvkm_top_intr(struct nvkm_device *, u32 intr, u64 *subdevs);
u32 nvkm_top_intr_mask(struct nvkm_device *, enum nvkm_devidx); u32 nvkm_top_intr_mask(struct nvkm_device *, enum nvkm_devidx);
......
...@@ -38,6 +38,7 @@ int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, u8 temp, ...@@ -38,6 +38,7 @@ int nvkm_volt_set_id(struct nvkm_volt *, u8 id, u8 min_id, u8 temp,
int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int nv40_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gf100_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gf100_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gf117_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gk104_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gk20a_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gk20a_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
int gm20b_volt_new(struct nvkm_device *, int, struct nvkm_volt **); int gm20b_volt_new(struct nvkm_device *, int, struct nvkm_volt **);
......
...@@ -214,6 +214,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) ...@@ -214,6 +214,7 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS)
WARN_ON(1); WARN_ON(1);
break; break;
} }
break;
case NOUVEAU_GETPARAM_FB_SIZE: case NOUVEAU_GETPARAM_FB_SIZE:
getparam->value = drm->gem.vram_available; getparam->value = drm->gem.vram_available;
break; break;
...@@ -338,7 +339,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) ...@@ -338,7 +339,8 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
goto done; goto done;
if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
ret = nouveau_vma_new(chan->ntfy, &cli->vmm, &chan->ntfy_vma); ret = nouveau_vma_new(chan->ntfy, chan->chan->vmm,
&chan->ntfy_vma);
if (ret) if (ret)
goto done; goto done;
} }
......
...@@ -194,7 +194,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align, ...@@ -194,7 +194,7 @@ nouveau_bo_new(struct nouveau_cli *cli, u64 size, int align,
struct nouveau_drm *drm = cli->drm; struct nouveau_drm *drm = cli->drm;
struct nouveau_bo *nvbo; struct nouveau_bo *nvbo;
struct nvif_mmu *mmu = &cli->mmu; struct nvif_mmu *mmu = &cli->mmu;
struct nvif_vmm *vmm = &cli->vmm.vmm; struct nvif_vmm *vmm = cli->svm.cli ? &cli->svm.vmm : &cli->vmm.vmm;
size_t acc_size; size_t acc_size;
int type = ttm_bo_type_device; int type = ttm_bo_type_device;
int ret, i, pi = -1; int ret, i, pi = -1;
...@@ -1434,7 +1434,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg) ...@@ -1434,7 +1434,7 @@ nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *reg)
if (drm->client.mem->oclass < NVIF_CLASS_MEM_NV50 || !mem->kind) if (drm->client.mem->oclass < NVIF_CLASS_MEM_NV50 || !mem->kind)
/* untiled */ /* untiled */
break; break;
/* fallthrough, tiled memory */ /* fall through - tiled memory */
case TTM_PL_VRAM: case TTM_PL_VRAM:
reg->bus.offset = reg->start << PAGE_SHIFT; reg->bus.offset = reg->start << PAGE_SHIFT;
reg->bus.base = device->func->resource_addr(device, 1); reg->bus.base = device->func->resource_addr(device, 1);
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "nouveau_fence.h" #include "nouveau_fence.h"
#include "nouveau_abi16.h" #include "nouveau_abi16.h"
#include "nouveau_vmm.h" #include "nouveau_vmm.h"
#include "nouveau_svm.h"
MODULE_PARM_DESC(vram_pushbuf, "Create DMA push buffers in VRAM"); MODULE_PARM_DESC(vram_pushbuf, "Create DMA push buffers in VRAM");
int nouveau_vram_pushbuf; int nouveau_vram_pushbuf;
...@@ -95,6 +96,10 @@ nouveau_channel_del(struct nouveau_channel **pchan) ...@@ -95,6 +96,10 @@ nouveau_channel_del(struct nouveau_channel **pchan)
if (chan->fence) if (chan->fence)
nouveau_fence(chan->drm)->context_del(chan); nouveau_fence(chan->drm)->context_del(chan);
if (cli)
nouveau_svmm_part(chan->vmm->svmm, chan->inst);
nvif_object_fini(&chan->nvsw); nvif_object_fini(&chan->nvsw);
nvif_object_fini(&chan->gart); nvif_object_fini(&chan->gart);
nvif_object_fini(&chan->vram); nvif_object_fini(&chan->vram);
...@@ -130,6 +135,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -130,6 +135,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
chan->device = device; chan->device = device;
chan->drm = drm; chan->drm = drm;
chan->vmm = cli->svm.cli ? &cli->svm : &cli->vmm;
atomic_set(&chan->killed, 0); atomic_set(&chan->killed, 0);
/* allocate memory for dma push buffer */ /* allocate memory for dma push buffer */
...@@ -157,7 +163,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -157,7 +163,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
chan->push.addr = chan->push.buffer->bo.offset; chan->push.addr = chan->push.buffer->bo.offset;
if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) { if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
ret = nouveau_vma_new(chan->push.buffer, &cli->vmm, ret = nouveau_vma_new(chan->push.buffer, chan->vmm,
&chan->push.vma); &chan->push.vma);
if (ret) { if (ret) {
nouveau_channel_del(pchan); nouveau_channel_del(pchan);
...@@ -172,7 +178,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -172,7 +178,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
args.target = NV_DMA_V0_TARGET_VM; args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_VM; args.access = NV_DMA_V0_ACCESS_VM;
args.start = 0; args.start = 0;
args.limit = cli->vmm.vmm.limit - 1; args.limit = chan->vmm->vmm.limit - 1;
} else } else
if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) { if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) {
if (device->info.family == NV_DEVICE_INFO_V0_TNT) { if (device->info.family == NV_DEVICE_INFO_V0_TNT) {
...@@ -202,7 +208,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -202,7 +208,7 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device,
args.target = NV_DMA_V0_TARGET_VM; args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_RDWR; args.access = NV_DMA_V0_ACCESS_RDWR;
args.start = 0; args.start = 0;
args.limit = cli->vmm.vmm.limit - 1; args.limit = chan->vmm->vmm.limit - 1;
} }
} }
...@@ -220,7 +226,6 @@ static int ...@@ -220,7 +226,6 @@ static int
nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
u64 runlist, bool priv, struct nouveau_channel **pchan) u64 runlist, bool priv, struct nouveau_channel **pchan)
{ {
struct nouveau_cli *cli = (void *)device->object.client;
static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A, static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A,
VOLTA_CHANNEL_GPFIFO_A, VOLTA_CHANNEL_GPFIFO_A,
PASCAL_CHANNEL_GPFIFO_A, PASCAL_CHANNEL_GPFIFO_A,
...@@ -255,7 +260,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -255,7 +260,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
args.volta.ilength = 0x02000; args.volta.ilength = 0x02000;
args.volta.ioffset = 0x10000 + chan->push.addr; args.volta.ioffset = 0x10000 + chan->push.addr;
args.volta.runlist = runlist; args.volta.runlist = runlist;
args.volta.vmm = nvif_handle(&cli->vmm.vmm.object); args.volta.vmm = nvif_handle(&chan->vmm->vmm.object);
args.volta.priv = priv; args.volta.priv = priv;
size = sizeof(args.volta); size = sizeof(args.volta);
} else } else
...@@ -264,7 +269,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -264,7 +269,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
args.kepler.ilength = 0x02000; args.kepler.ilength = 0x02000;
args.kepler.ioffset = 0x10000 + chan->push.addr; args.kepler.ioffset = 0x10000 + chan->push.addr;
args.kepler.runlist = runlist; args.kepler.runlist = runlist;
args.kepler.vmm = nvif_handle(&cli->vmm.vmm.object); args.kepler.vmm = nvif_handle(&chan->vmm->vmm.object);
args.kepler.priv = priv; args.kepler.priv = priv;
size = sizeof(args.kepler); size = sizeof(args.kepler);
} else } else
...@@ -272,14 +277,14 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -272,14 +277,14 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
args.fermi.version = 0; args.fermi.version = 0;
args.fermi.ilength = 0x02000; args.fermi.ilength = 0x02000;
args.fermi.ioffset = 0x10000 + chan->push.addr; args.fermi.ioffset = 0x10000 + chan->push.addr;
args.fermi.vmm = nvif_handle(&cli->vmm.vmm.object); args.fermi.vmm = nvif_handle(&chan->vmm->vmm.object);
size = sizeof(args.fermi); size = sizeof(args.fermi);
} else { } else {
args.nv50.version = 0; args.nv50.version = 0;
args.nv50.ilength = 0x02000; args.nv50.ilength = 0x02000;
args.nv50.ioffset = 0x10000 + chan->push.addr; args.nv50.ioffset = 0x10000 + chan->push.addr;
args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma); args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma);
args.nv50.vmm = nvif_handle(&cli->vmm.vmm.object); args.nv50.vmm = nvif_handle(&chan->vmm->vmm.object);
size = sizeof(args.nv50); size = sizeof(args.nv50);
} }
...@@ -350,7 +355,6 @@ static int ...@@ -350,7 +355,6 @@ static int
nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
{ {
struct nvif_device *device = chan->device; struct nvif_device *device = chan->device;
struct nouveau_cli *cli = (void *)chan->user.client;
struct nouveau_drm *drm = chan->drm; struct nouveau_drm *drm = chan->drm;
struct nv_dma_v0 args = {}; struct nv_dma_v0 args = {};
int ret, i; int ret, i;
...@@ -376,7 +380,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) ...@@ -376,7 +380,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
args.target = NV_DMA_V0_TARGET_VM; args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_VM; args.access = NV_DMA_V0_ACCESS_VM;
args.start = 0; args.start = 0;
args.limit = cli->vmm.vmm.limit - 1; args.limit = chan->vmm->vmm.limit - 1;
} else { } else {
args.target = NV_DMA_V0_TARGET_VRAM; args.target = NV_DMA_V0_TARGET_VRAM;
args.access = NV_DMA_V0_ACCESS_RDWR; args.access = NV_DMA_V0_ACCESS_RDWR;
...@@ -393,7 +397,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) ...@@ -393,7 +397,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
args.target = NV_DMA_V0_TARGET_VM; args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_VM; args.access = NV_DMA_V0_ACCESS_VM;
args.start = 0; args.start = 0;
args.limit = cli->vmm.vmm.limit - 1; args.limit = chan->vmm->vmm.limit - 1;
} else } else
if (chan->drm->agp.bridge) { if (chan->drm->agp.bridge) {
args.target = NV_DMA_V0_TARGET_AGP; args.target = NV_DMA_V0_TARGET_AGP;
...@@ -405,7 +409,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) ...@@ -405,7 +409,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
args.target = NV_DMA_V0_TARGET_VM; args.target = NV_DMA_V0_TARGET_VM;
args.access = NV_DMA_V0_ACCESS_RDWR; args.access = NV_DMA_V0_ACCESS_RDWR;
args.start = 0; args.start = 0;
args.limit = cli->vmm.vmm.limit - 1; args.limit = chan->vmm->vmm.limit - 1;
} }
ret = nvif_object_init(&chan->user, gart, NV_DMA_IN_MEMORY, ret = nvif_object_init(&chan->user, gart, NV_DMA_IN_MEMORY,
...@@ -495,6 +499,10 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device, ...@@ -495,6 +499,10 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
nouveau_channel_del(pchan); nouveau_channel_del(pchan);
} }
ret = nouveau_svmm_join((*pchan)->vmm->svmm, (*pchan)->inst);
if (ret)
nouveau_channel_del(pchan);
done: done:
cli->base.super = super; cli->base.super = super;
return ret; return ret;
......
...@@ -8,6 +8,7 @@ struct nvif_device; ...@@ -8,6 +8,7 @@ struct nvif_device;
struct nouveau_channel { struct nouveau_channel {
struct nvif_device *device; struct nvif_device *device;
struct nouveau_drm *drm; struct nouveau_drm *drm;
struct nouveau_vmm *vmm;
int chid; int chid;
u64 inst; u64 inst;
......
...@@ -32,18 +32,13 @@ ...@@ -32,18 +32,13 @@
#include <drm/drm_fb_helper.h> #include <drm/drm_fb_helper.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
#include <nvif/class.h>
#include "nouveau_fbcon.h" #include "nouveau_fbcon.h"
#include "dispnv04/hw.h"
#include "nouveau_crtc.h" #include "nouveau_crtc.h"
#include "nouveau_dma.h"
#include "nouveau_gem.h" #include "nouveau_gem.h"
#include "nouveau_connector.h" #include "nouveau_connector.h"
#include "nv50_display.h" #include "nv50_display.h"
#include "nouveau_fence.h" #include <nvif/class.h>
#include <nvif/cl0046.h> #include <nvif/cl0046.h>
#include <nvif/event.h> #include <nvif/event.h>
...@@ -412,15 +407,14 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val, ...@@ -412,15 +407,14 @@ nouveau_display_acpi_ntfy(struct notifier_block *nb, unsigned long val,
#endif #endif
int int
nouveau_display_init(struct drm_device *dev) nouveau_display_init(struct drm_device *dev, bool resume, bool runtime)
{ {
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter; struct drm_connector_list_iter conn_iter;
int ret; int ret;
ret = disp->init(dev); ret = disp->init(dev, resume, runtime);
if (ret) if (ret)
return ret; return ret;
...@@ -437,8 +431,6 @@ nouveau_display_init(struct drm_device *dev) ...@@ -437,8 +431,6 @@ nouveau_display_init(struct drm_device *dev)
} }
drm_connector_list_iter_end(&conn_iter); drm_connector_list_iter_end(&conn_iter);
/* enable flip completion events */
nvif_notify_get(&drm->flip);
return ret; return ret;
} }
...@@ -457,9 +449,6 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime) ...@@ -457,9 +449,6 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
drm_helper_force_disable_all(dev); drm_helper_force_disable_all(dev);
} }
/* disable flip completion events */
nvif_notify_put(&drm->flip);
/* disable hotplug interrupts */ /* disable hotplug interrupts */
drm_connector_list_iter_begin(dev, &conn_iter); drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) { nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
...@@ -472,7 +461,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime) ...@@ -472,7 +461,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime)
cancel_work_sync(&drm->hpd_work); cancel_work_sync(&drm->hpd_work);
drm_kms_helper_poll_disable(dev); drm_kms_helper_poll_disable(dev);
disp->fini(dev); disp->fini(dev, suspend);
} }
static void static void
...@@ -625,7 +614,6 @@ int ...@@ -625,7 +614,6 @@ int
nouveau_display_suspend(struct drm_device *dev, bool runtime) nouveau_display_suspend(struct drm_device *dev, bool runtime)
{ {
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct drm_crtc *crtc;
if (drm_drv_uses_atomic_modeset(dev)) { if (drm_drv_uses_atomic_modeset(dev)) {
if (!runtime) { if (!runtime) {
...@@ -636,32 +624,9 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime) ...@@ -636,32 +624,9 @@ nouveau_display_suspend(struct drm_device *dev, bool runtime)
return ret; return ret;
} }
} }
nouveau_display_fini(dev, true, runtime);
return 0;
} }
nouveau_display_fini(dev, true, runtime); nouveau_display_fini(dev, true, runtime);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb;
nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
if (!nouveau_fb || !nouveau_fb->nvbo)
continue;
nouveau_bo_unpin(nouveau_fb->nvbo);
}
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (nv_crtc->cursor.nvbo) {
if (nv_crtc->cursor.set_offset)
nouveau_bo_unmap(nv_crtc->cursor.nvbo);
nouveau_bo_unpin(nv_crtc->cursor.nvbo);
}
}
return 0; return 0;
} }
...@@ -669,275 +634,16 @@ void ...@@ -669,275 +634,16 @@ void
nouveau_display_resume(struct drm_device *dev, bool runtime) nouveau_display_resume(struct drm_device *dev, bool runtime)
{ {
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_crtc *crtc; nouveau_display_init(dev, true, runtime);
int ret;
if (drm_drv_uses_atomic_modeset(dev)) { if (drm_drv_uses_atomic_modeset(dev)) {
nouveau_display_init(dev);
if (disp->suspend) { if (disp->suspend) {
drm_atomic_helper_resume(dev, disp->suspend); drm_atomic_helper_resume(dev, disp->suspend);
disp->suspend = NULL; disp->suspend = NULL;
} }
return; return;
} }
/* re-pin fb/cursors */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_framebuffer *nouveau_fb;
nouveau_fb = nouveau_framebuffer(crtc->primary->fb);
if (!nouveau_fb || !nouveau_fb->nvbo)
continue;
ret = nouveau_bo_pin(nouveau_fb->nvbo, TTM_PL_FLAG_VRAM, true);
if (ret)
NV_ERROR(drm, "Could not pin framebuffer\n");
}
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (!nv_crtc->cursor.nvbo)
continue;
ret = nouveau_bo_pin(nv_crtc->cursor.nvbo, TTM_PL_FLAG_VRAM, true);
if (!ret && nv_crtc->cursor.set_offset)
ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
if (ret)
NV_ERROR(drm, "Could not pin/map cursor.\n");
}
nouveau_display_init(dev);
/* Force CLUT to get re-loaded during modeset */
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
nv_crtc->lut.depth = 0;
}
/* This should ensure we don't hit a locking problem when someone
* wakes us up via a connector. We should never go into suspend
* while the display is on anyways.
*/
if (runtime)
return;
drm_helper_resume_force_mode(dev);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
if (!nv_crtc->cursor.nvbo)
continue;
if (nv_crtc->cursor.set_offset)
nv_crtc->cursor.set_offset(nv_crtc, nv_crtc->cursor.nvbo->bo.offset);
nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
nv_crtc->cursor_saved_y);
}
}
static int
nouveau_page_flip_emit(struct nouveau_channel *chan,
struct nouveau_bo *old_bo,
struct nouveau_bo *new_bo,
struct nouveau_page_flip_state *s,
struct nouveau_fence **pfence)
{
struct nouveau_fence_chan *fctx = chan->fence;
struct nouveau_drm *drm = chan->drm;
struct drm_device *dev = drm->dev;
unsigned long flags;
int ret;
/* Queue it to the pending list */
spin_lock_irqsave(&dev->event_lock, flags);
list_add_tail(&s->head, &fctx->flip);
spin_unlock_irqrestore(&dev->event_lock, flags);
/* Synchronize with the old framebuffer */
ret = nouveau_fence_sync(old_bo, chan, false, false);
if (ret)
goto fail;
/* Emit the pageflip */
ret = RING_SPACE(chan, 2);
if (ret)
goto fail;
BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1);
OUT_RING (chan, 0x00000000);
FIRE_RING (chan);
ret = nouveau_fence_new(chan, false, pfence);
if (ret)
goto fail;
return 0;
fail:
spin_lock_irqsave(&dev->event_lock, flags);
list_del(&s->head);
spin_unlock_irqrestore(&dev->event_lock, flags);
return ret;
}
int
nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event, u32 flags,
struct drm_modeset_acquire_ctx *ctx)
{
const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1;
struct drm_device *dev = crtc->dev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->primary->fb)->nvbo;
struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo;
struct nouveau_page_flip_state *s;
struct nouveau_channel *chan;
struct nouveau_cli *cli;
struct nouveau_fence *fence;
struct nv04_display *dispnv04 = nv04_display(dev);
int head = nouveau_crtc(crtc)->index;
int ret;
chan = drm->channel;
if (!chan)
return -ENODEV;
cli = (void *)chan->user.client;
s = kzalloc(sizeof(*s), GFP_KERNEL);
if (!s)
return -ENOMEM;
if (new_bo != old_bo) {
ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM, true);
if (ret)
goto fail_free;
}
mutex_lock(&cli->mutex);
ret = ttm_bo_reserve(&new_bo->bo, true, false, NULL);
if (ret)
goto fail_unpin;
/* synchronise rendering channel with the kernel's channel */
ret = nouveau_fence_sync(new_bo, chan, false, true);
if (ret) {
ttm_bo_unreserve(&new_bo->bo);
goto fail_unpin;
}
if (new_bo != old_bo) {
ttm_bo_unreserve(&new_bo->bo);
ret = ttm_bo_reserve(&old_bo->bo, true, false, NULL);
if (ret)
goto fail_unpin;
}
/* Initialize a page flip struct */
*s = (struct nouveau_page_flip_state)
{ { }, event, crtc, fb->format->cpp[0] * 8, fb->pitches[0],
new_bo->bo.offset };
/* Keep vblanks on during flip, for the target crtc of this flip */
drm_crtc_vblank_get(crtc);
/* Emit a page flip */
if (swap_interval) {
ret = RING_SPACE(chan, 8);
if (ret)
goto fail_unreserve;
BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1);
OUT_RING (chan, 0);
BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1);
OUT_RING (chan, head);
BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1);
OUT_RING (chan, 0);
BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1);
OUT_RING (chan, 0);
}
nouveau_bo_ref(new_bo, &dispnv04->image[head]);
ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence);
if (ret)
goto fail_unreserve;
mutex_unlock(&cli->mutex);
/* Update the crtc struct and cleanup */
crtc->primary->fb = fb;
nouveau_bo_fence(old_bo, fence, false);
ttm_bo_unreserve(&old_bo->bo);
if (old_bo != new_bo)
nouveau_bo_unpin(old_bo);
nouveau_fence_unref(&fence);
return 0;
fail_unreserve:
drm_crtc_vblank_put(crtc);
ttm_bo_unreserve(&old_bo->bo);
fail_unpin:
mutex_unlock(&cli->mutex);
if (old_bo != new_bo)
nouveau_bo_unpin(new_bo);
fail_free:
kfree(s);
return ret;
}
int
nouveau_finish_page_flip(struct nouveau_channel *chan,
struct nouveau_page_flip_state *ps)
{
struct nouveau_fence_chan *fctx = chan->fence;
struct nouveau_drm *drm = chan->drm;
struct drm_device *dev = drm->dev;
struct nouveau_page_flip_state *s;
unsigned long flags;
spin_lock_irqsave(&dev->event_lock, flags);
if (list_empty(&fctx->flip)) {
NV_ERROR(drm, "unexpected pageflip\n");
spin_unlock_irqrestore(&dev->event_lock, flags);
return -EINVAL;
}
s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
if (s->event) {
drm_crtc_arm_vblank_event(s->crtc, s->event);
} else {
/* Give up ownership of vblank for page-flipped crtc */
drm_crtc_vblank_put(s->crtc);
}
list_del(&s->head);
if (ps)
*ps = *s;
kfree(s);
spin_unlock_irqrestore(&dev->event_lock, flags);
return 0;
}
int
nouveau_flip_complete(struct nvif_notify *notify)
{
struct nouveau_drm *drm = container_of(notify, typeof(*drm), flip);
struct nouveau_channel *chan = drm->channel;
struct nouveau_page_flip_state state;
if (!nouveau_finish_page_flip(chan, &state)) {
nv_set_crtc_base(drm->dev, drm_crtc_index(state.crtc),
state.offset + state.crtc->y *
state.pitch + state.crtc->x *
state.bpp / 8);
}
return NVIF_NOTIFY_KEEP;
} }
int int
......
...@@ -25,19 +25,11 @@ int nouveau_framebuffer_new(struct drm_device *, ...@@ -25,19 +25,11 @@ int nouveau_framebuffer_new(struct drm_device *,
const struct drm_mode_fb_cmd2 *, const struct drm_mode_fb_cmd2 *,
struct nouveau_bo *, struct nouveau_framebuffer **); struct nouveau_bo *, struct nouveau_framebuffer **);
struct nouveau_page_flip_state {
struct list_head head;
struct drm_pending_vblank_event *event;
struct drm_crtc *crtc;
int bpp, pitch;
u64 offset;
};
struct nouveau_display { struct nouveau_display {
void *priv; void *priv;
void (*dtor)(struct drm_device *); void (*dtor)(struct drm_device *);
int (*init)(struct drm_device *); int (*init)(struct drm_device *, bool resume, bool runtime);
void (*fini)(struct drm_device *); void (*fini)(struct drm_device *, bool suspend);
struct nvif_disp disp; struct nvif_disp disp;
...@@ -61,7 +53,7 @@ nouveau_display(struct drm_device *dev) ...@@ -61,7 +53,7 @@ nouveau_display(struct drm_device *dev)
int nouveau_display_create(struct drm_device *dev); int nouveau_display_create(struct drm_device *dev);
void nouveau_display_destroy(struct drm_device *dev); void nouveau_display_destroy(struct drm_device *dev);
int nouveau_display_init(struct drm_device *dev); int nouveau_display_init(struct drm_device *dev, bool resume, bool runtime);
void nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime); void nouveau_display_fini(struct drm_device *dev, bool suspend, bool runtime);
int nouveau_display_suspend(struct drm_device *dev, bool runtime); int nouveau_display_suspend(struct drm_device *dev, bool runtime);
void nouveau_display_resume(struct drm_device *dev, bool runtime); void nouveau_display_resume(struct drm_device *dev, bool runtime);
...@@ -71,13 +63,6 @@ bool nouveau_display_scanoutpos(struct drm_device *, unsigned int, ...@@ -71,13 +63,6 @@ bool nouveau_display_scanoutpos(struct drm_device *, unsigned int,
bool, int *, int *, ktime_t *, bool, int *, int *, ktime_t *,
ktime_t *, const struct drm_display_mode *); ktime_t *, const struct drm_display_mode *);
int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb,
struct drm_pending_vblank_event *event,
uint32_t page_flip_flags,
struct drm_modeset_acquire_ctx *ctx);
int nouveau_finish_page_flip(struct nouveau_channel *,
struct nouveau_page_flip_state *);
int nouveau_display_dumb_create(struct drm_file *, struct drm_device *, int nouveau_display_dumb_create(struct drm_file *, struct drm_device *,
struct drm_mode_create_dumb *args); struct drm_mode_create_dumb *args);
int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *, int nouveau_display_dumb_map_offset(struct drm_file *, struct drm_device *,
......
This diff is collapsed.
/*
* Copyright 2018 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef __NOUVEAU_DMEM_H__
#define __NOUVEAU_DMEM_H__
#include <nvif/os.h>
struct drm_device;
struct drm_file;
struct nouveau_drm;
struct hmm_range;
#if IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM)
void nouveau_dmem_init(struct nouveau_drm *);
void nouveau_dmem_fini(struct nouveau_drm *);
void nouveau_dmem_suspend(struct nouveau_drm *);
void nouveau_dmem_resume(struct nouveau_drm *);
int nouveau_dmem_migrate_vma(struct nouveau_drm *drm,
struct vm_area_struct *vma,
unsigned long start,
unsigned long end);
void nouveau_dmem_convert_pfn(struct nouveau_drm *drm,
struct hmm_range *range);
#else /* IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM) */
static inline void nouveau_dmem_init(struct nouveau_drm *drm) {}
static inline void nouveau_dmem_fini(struct nouveau_drm *drm) {}
static inline void nouveau_dmem_suspend(struct nouveau_drm *drm) {}
static inline void nouveau_dmem_resume(struct nouveau_drm *drm) {}
static inline int nouveau_dmem_migrate_vma(struct nouveau_drm *drm,
struct vm_area_struct *vma,
unsigned long start,
unsigned long end)
{
return 0;
}
static inline void nouveau_dmem_convert_pfn(struct nouveau_drm *drm,
struct hmm_range *range) {}
#endif /* IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM) */
#endif
This diff is collapsed.
...@@ -96,6 +96,7 @@ struct nouveau_cli { ...@@ -96,6 +96,7 @@ struct nouveau_cli {
struct nvif_device device; struct nvif_device device;
struct nvif_mmu mmu; struct nvif_mmu mmu;
struct nouveau_vmm vmm; struct nouveau_vmm vmm;
struct nouveau_vmm svm;
const struct nvif_mclass *mem; const struct nvif_mclass *mem;
struct list_head head; struct list_head head;
...@@ -181,7 +182,6 @@ struct nouveau_drm { ...@@ -181,7 +182,6 @@ struct nouveau_drm {
struct nouveau_fbdev *fbcon; struct nouveau_fbdev *fbcon;
struct nvif_object nvsw; struct nvif_object nvsw;
struct nvif_object ntfy; struct nvif_object ntfy;
struct nvif_notify flip;
/* nv10-nv40 tiling regions */ /* nv10-nv40 tiling regions */
struct { struct {
...@@ -210,6 +210,10 @@ struct nouveau_drm { ...@@ -210,6 +210,10 @@ struct nouveau_drm {
bool have_disp_power_ref; bool have_disp_power_ref;
struct dev_pm_domain vga_pm_domain; struct dev_pm_domain vga_pm_domain;
struct nouveau_svm *svm;
struct nouveau_dmem *dmem;
}; };
static inline struct nouveau_drm * static inline struct nouveau_drm *
......
...@@ -353,7 +353,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper, ...@@ -353,7 +353,7 @@ nouveau_fbcon_create(struct drm_fb_helper *helper,
chan = nouveau_nofbaccel ? NULL : drm->channel; chan = nouveau_nofbaccel ? NULL : drm->channel;
if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) { if (chan && device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
ret = nouveau_vma_new(nvbo, &drm->client.vmm, &fb->vma); ret = nouveau_vma_new(nvbo, chan->vmm, &fb->vma);
if (ret) { if (ret) {
NV_ERROR(drm, "failed to map fb into chan: %d\n", ret); NV_ERROR(drm, "failed to map fb into chan: %d\n", ret);
chan = NULL; chan = NULL;
......
...@@ -82,8 +82,6 @@ int nv50_fence_create(struct nouveau_drm *); ...@@ -82,8 +82,6 @@ int nv50_fence_create(struct nouveau_drm *);
int nv84_fence_create(struct nouveau_drm *); int nv84_fence_create(struct nouveau_drm *);
int nvc0_fence_create(struct nouveau_drm *); int nvc0_fence_create(struct nouveau_drm *);
int nouveau_flip_complete(struct nvif_notify *);
struct nv84_fence_chan { struct nv84_fence_chan {
struct nouveau_fence_chan base; struct nouveau_fence_chan base;
struct nouveau_vma *vma; struct nouveau_vma *vma;
......
...@@ -68,10 +68,11 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) ...@@ -68,10 +68,11 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct device *dev = drm->dev->dev; struct device *dev = drm->dev->dev;
struct nouveau_vmm *vmm = cli->svm.cli ? &cli->svm : &cli->vmm;
struct nouveau_vma *vma; struct nouveau_vma *vma;
int ret; int ret;
if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50) if (vmm->vmm.object.oclass < NVIF_CLASS_VMM_NV50)
return 0; return 0;
ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL); ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
...@@ -82,7 +83,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) ...@@ -82,7 +83,7 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
if (ret < 0 && ret != -EACCES) if (ret < 0 && ret != -EACCES)
goto out; goto out;
ret = nouveau_vma_new(nvbo, &cli->vmm, &vma); ret = nouveau_vma_new(nvbo, vmm, &vma);
pm_runtime_mark_last_busy(dev); pm_runtime_mark_last_busy(dev);
pm_runtime_put_autosuspend(dev); pm_runtime_put_autosuspend(dev);
out: out:
...@@ -142,17 +143,18 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) ...@@ -142,17 +143,18 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct device *dev = drm->dev->dev; struct device *dev = drm->dev->dev;
struct nouveau_vmm *vmm = cli->svm.cli ? &cli->svm : & cli->vmm;
struct nouveau_vma *vma; struct nouveau_vma *vma;
int ret; int ret;
if (cli->vmm.vmm.object.oclass < NVIF_CLASS_VMM_NV50) if (vmm->vmm.object.oclass < NVIF_CLASS_VMM_NV50)
return; return;
ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL); ret = ttm_bo_reserve(&nvbo->bo, false, false, NULL);
if (ret) if (ret)
return; return;
vma = nouveau_vma_find(nvbo, &cli->vmm); vma = nouveau_vma_find(nvbo, vmm);
if (vma) { if (vma) {
if (--vma->refs == 0) { if (--vma->refs == 0) {
ret = pm_runtime_get_sync(dev); ret = pm_runtime_get_sync(dev);
...@@ -219,6 +221,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, ...@@ -219,6 +221,7 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
{ {
struct nouveau_cli *cli = nouveau_cli(file_priv); struct nouveau_cli *cli = nouveau_cli(file_priv);
struct nouveau_bo *nvbo = nouveau_gem_object(gem); struct nouveau_bo *nvbo = nouveau_gem_object(gem);
struct nouveau_vmm *vmm = cli->svm.cli ? &cli->svm : &cli->vmm;
struct nouveau_vma *vma; struct nouveau_vma *vma;
if (is_power_of_2(nvbo->valid_domains)) if (is_power_of_2(nvbo->valid_domains))
...@@ -228,8 +231,8 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem, ...@@ -228,8 +231,8 @@ nouveau_gem_info(struct drm_file *file_priv, struct drm_gem_object *gem,
else else
rep->domain = NOUVEAU_GEM_DOMAIN_VRAM; rep->domain = NOUVEAU_GEM_DOMAIN_VRAM;
rep->offset = nvbo->bo.offset; rep->offset = nvbo->bo.offset;
if (cli->vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) { if (vmm->vmm.object.oclass >= NVIF_CLASS_VMM_NV50) {
vma = nouveau_vma_find(nvbo, &cli->vmm); vma = nouveau_vma_find(nvbo, vmm);
if (!vma) if (!vma)
return -EINVAL; return -EINVAL;
...@@ -321,7 +324,8 @@ struct validate_op { ...@@ -321,7 +324,8 @@ struct validate_op {
}; };
static void static void
validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence, validate_fini_no_ticket(struct validate_op *op, struct nouveau_channel *chan,
struct nouveau_fence *fence,
struct drm_nouveau_gem_pushbuf_bo *pbbo) struct drm_nouveau_gem_pushbuf_bo *pbbo)
{ {
struct nouveau_bo *nvbo; struct nouveau_bo *nvbo;
...@@ -332,13 +336,11 @@ validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence, ...@@ -332,13 +336,11 @@ validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence,
b = &pbbo[nvbo->pbbo_index]; b = &pbbo[nvbo->pbbo_index];
if (likely(fence)) { if (likely(fence)) {
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct nouveau_vma *vma;
nouveau_bo_fence(nvbo, fence, !!b->write_domains); nouveau_bo_fence(nvbo, fence, !!b->write_domains);
if (drm->client.vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) { if (chan->vmm->vmm.object.oclass >= NVIF_CLASS_VMM_NV50) {
vma = (void *)(unsigned long)b->user_priv; struct nouveau_vma *vma =
(void *)(unsigned long)b->user_priv;
nouveau_fence_unref(&vma->fence); nouveau_fence_unref(&vma->fence);
dma_fence_get(&fence->base); dma_fence_get(&fence->base);
vma->fence = fence; vma->fence = fence;
...@@ -358,10 +360,11 @@ validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence, ...@@ -358,10 +360,11 @@ validate_fini_no_ticket(struct validate_op *op, struct nouveau_fence *fence,
} }
static void static void
validate_fini(struct validate_op *op, struct nouveau_fence *fence, validate_fini(struct validate_op *op, struct nouveau_channel *chan,
struct nouveau_fence *fence,
struct drm_nouveau_gem_pushbuf_bo *pbbo) struct drm_nouveau_gem_pushbuf_bo *pbbo)
{ {
validate_fini_no_ticket(op, fence, pbbo); validate_fini_no_ticket(op, chan, fence, pbbo);
ww_acquire_fini(&op->ticket); ww_acquire_fini(&op->ticket);
} }
...@@ -416,7 +419,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -416,7 +419,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
list_splice_tail_init(&vram_list, &op->list); list_splice_tail_init(&vram_list, &op->list);
list_splice_tail_init(&gart_list, &op->list); list_splice_tail_init(&gart_list, &op->list);
list_splice_tail_init(&both_list, &op->list); list_splice_tail_init(&both_list, &op->list);
validate_fini_no_ticket(op, NULL, NULL); validate_fini_no_ticket(op, chan, NULL, NULL);
if (unlikely(ret == -EDEADLK)) { if (unlikely(ret == -EDEADLK)) {
ret = ttm_bo_reserve_slowpath(&nvbo->bo, true, ret = ttm_bo_reserve_slowpath(&nvbo->bo, true,
&op->ticket); &op->ticket);
...@@ -430,8 +433,8 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -430,8 +433,8 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
} }
} }
if (cli->vmm.vmm.object.oclass >= NVIF_CLASS_VMM_NV50) { if (chan->vmm->vmm.object.oclass >= NVIF_CLASS_VMM_NV50) {
struct nouveau_vmm *vmm = &cli->vmm; struct nouveau_vmm *vmm = chan->vmm;
struct nouveau_vma *vma = nouveau_vma_find(nvbo, vmm); struct nouveau_vma *vma = nouveau_vma_find(nvbo, vmm);
if (!vma) { if (!vma) {
NV_PRINTK(err, cli, "vma not found!\n"); NV_PRINTK(err, cli, "vma not found!\n");
...@@ -471,7 +474,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv, ...@@ -471,7 +474,7 @@ validate_init(struct nouveau_channel *chan, struct drm_file *file_priv,
list_splice_tail(&gart_list, &op->list); list_splice_tail(&gart_list, &op->list);
list_splice_tail(&both_list, &op->list); list_splice_tail(&both_list, &op->list);
if (ret) if (ret)
validate_fini(op, NULL, NULL); validate_fini(op, chan, NULL, NULL);
return ret; return ret;
} }
...@@ -563,7 +566,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, ...@@ -563,7 +566,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
if (unlikely(ret < 0)) { if (unlikely(ret < 0)) {
if (ret != -ERESTARTSYS) if (ret != -ERESTARTSYS)
NV_PRINTK(err, cli, "validating bo list\n"); NV_PRINTK(err, cli, "validating bo list\n");
validate_fini(op, NULL, NULL); validate_fini(op, chan, NULL, NULL);
return ret; return ret;
} }
*apply_relocs = ret; *apply_relocs = ret;
...@@ -842,7 +845,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, ...@@ -842,7 +845,7 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
} }
out: out:
validate_fini(&op, fence, bo); validate_fini(&op, chan, fence, bo);
nouveau_fence_unref(&fence); nouveau_fence_unref(&fence);
out_prevalid: out_prevalid:
......
This diff is collapsed.
#ifndef __NOUVEAU_SVM_H__
#define __NOUVEAU_SVM_H__
#include <nvif/os.h>
struct drm_device;
struct drm_file;
struct nouveau_drm;
struct nouveau_svmm;
#if IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM)
void nouveau_svm_init(struct nouveau_drm *);
void nouveau_svm_fini(struct nouveau_drm *);
void nouveau_svm_suspend(struct nouveau_drm *);
void nouveau_svm_resume(struct nouveau_drm *);
int nouveau_svmm_init(struct drm_device *, void *, struct drm_file *);
void nouveau_svmm_fini(struct nouveau_svmm **);
int nouveau_svmm_join(struct nouveau_svmm *, u64 inst);
void nouveau_svmm_part(struct nouveau_svmm *, u64 inst);
int nouveau_svmm_bind(struct drm_device *, void *, struct drm_file *);
#else /* IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM) */
static inline void nouveau_svm_init(struct nouveau_drm *drm) {}
static inline void nouveau_svm_fini(struct nouveau_drm *drm) {}
static inline void nouveau_svm_suspend(struct nouveau_drm *drm) {}
static inline void nouveau_svm_resume(struct nouveau_drm *drm) {}
static inline int nouveau_svmm_init(struct drm_device *device, void *p,
struct drm_file *file)
{
return -ENOSYS;
}
static inline void nouveau_svmm_fini(struct nouveau_svmm **svmmp) {}
static inline int nouveau_svmm_join(struct nouveau_svmm *svmm, u64 inst)
{
return 0;
}
static inline void nouveau_svmm_part(struct nouveau_svmm *svmm, u64 inst) {}
static inline int nouveau_svmm_bind(struct drm_device *device, void *p,
struct drm_file *file)
{
return -ENOSYS;
}
#endif /* IS_ENABLED(CONFIG_DRM_NOUVEAU_SVM) */
#endif
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "nouveau_vmm.h" #include "nouveau_vmm.h"
#include "nouveau_drv.h" #include "nouveau_drv.h"
#include "nouveau_bo.h" #include "nouveau_bo.h"
#include "nouveau_svm.h"
#include "nouveau_mem.h" #include "nouveau_mem.h"
void void
...@@ -119,6 +120,7 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm, ...@@ -119,6 +120,7 @@ nouveau_vma_new(struct nouveau_bo *nvbo, struct nouveau_vmm *vmm,
void void
nouveau_vmm_fini(struct nouveau_vmm *vmm) nouveau_vmm_fini(struct nouveau_vmm *vmm)
{ {
nouveau_svmm_fini(&vmm->svmm);
nvif_vmm_fini(&vmm->vmm); nvif_vmm_fini(&vmm->vmm);
vmm->cli = NULL; vmm->cli = NULL;
} }
...@@ -126,7 +128,7 @@ nouveau_vmm_fini(struct nouveau_vmm *vmm) ...@@ -126,7 +128,7 @@ nouveau_vmm_fini(struct nouveau_vmm *vmm)
int int
nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm) nouveau_vmm_init(struct nouveau_cli *cli, s32 oclass, struct nouveau_vmm *vmm)
{ {
int ret = nvif_vmm_init(&cli->mmu, oclass, PAGE_SIZE, 0, NULL, 0, int ret = nvif_vmm_init(&cli->mmu, oclass, false, PAGE_SIZE, 0, NULL, 0,
&vmm->vmm); &vmm->vmm);
if (ret) if (ret)
return ret; return ret;
......
...@@ -25,6 +25,7 @@ void nouveau_vma_unmap(struct nouveau_vma *); ...@@ -25,6 +25,7 @@ void nouveau_vma_unmap(struct nouveau_vma *);
struct nouveau_vmm { struct nouveau_vmm {
struct nouveau_cli *cli; struct nouveau_cli *cli;
struct nvif_vmm vmm; struct nvif_vmm vmm;
struct nouveau_svmm *svmm;
}; };
int nouveau_vmm_init(struct nouveau_cli *, s32 oclass, struct nouveau_vmm *); int nouveau_vmm_init(struct nouveau_cli *, s32 oclass, struct nouveau_vmm *);
......
...@@ -109,7 +109,6 @@ nv84_fence_context_del(struct nouveau_channel *chan) ...@@ -109,7 +109,6 @@ nv84_fence_context_del(struct nouveau_channel *chan)
int int
nv84_fence_context_new(struct nouveau_channel *chan) nv84_fence_context_new(struct nouveau_channel *chan)
{ {
struct nouveau_cli *cli = (void *)chan->user.client;
struct nv84_fence_priv *priv = chan->drm->fence; struct nv84_fence_priv *priv = chan->drm->fence;
struct nv84_fence_chan *fctx; struct nv84_fence_chan *fctx;
int ret; int ret;
...@@ -127,7 +126,7 @@ nv84_fence_context_new(struct nouveau_channel *chan) ...@@ -127,7 +126,7 @@ nv84_fence_context_new(struct nouveau_channel *chan)
fctx->base.sequence = nv84_fence_read(chan); fctx->base.sequence = nv84_fence_read(chan);
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
ret = nouveau_vma_new(priv->bo, &cli->vmm, &fctx->vma); ret = nouveau_vma_new(priv->bo, chan->vmm, &fctx->vma);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
if (ret) if (ret)
......
...@@ -34,7 +34,7 @@ int ...@@ -34,7 +34,7 @@ int
nvif_disp_ctor(struct nvif_device *device, s32 oclass, struct nvif_disp *disp) nvif_disp_ctor(struct nvif_device *device, s32 oclass, struct nvif_disp *disp)
{ {
static const struct nvif_mclass disps[] = { static const struct nvif_mclass disps[] = {
{ TU104_DISP, -1 }, { TU102_DISP, -1 },
{ GV100_DISP, -1 }, { GV100_DISP, -1 },
{ GP102_DISP, -1 }, { GP102_DISP, -1 },
{ GP100_DISP, -1 }, { GP100_DISP, -1 },
......
...@@ -112,8 +112,8 @@ nvif_vmm_fini(struct nvif_vmm *vmm) ...@@ -112,8 +112,8 @@ nvif_vmm_fini(struct nvif_vmm *vmm)
} }
int int
nvif_vmm_init(struct nvif_mmu *mmu, s32 oclass, u64 addr, u64 size, nvif_vmm_init(struct nvif_mmu *mmu, s32 oclass, bool managed, u64 addr,
void *argv, u32 argc, struct nvif_vmm *vmm) u64 size, void *argv, u32 argc, struct nvif_vmm *vmm)
{ {
struct nvif_vmm_v0 *args; struct nvif_vmm_v0 *args;
u32 argn = sizeof(*args) + argc; u32 argn = sizeof(*args) + argc;
...@@ -125,6 +125,7 @@ nvif_vmm_init(struct nvif_mmu *mmu, s32 oclass, u64 addr, u64 size, ...@@ -125,6 +125,7 @@ nvif_vmm_init(struct nvif_mmu *mmu, s32 oclass, u64 addr, u64 size,
if (!(args = kmalloc(argn, GFP_KERNEL))) if (!(args = kmalloc(argn, GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
args->version = 0; args->version = 0;
args->managed = managed;
args->addr = addr; args->addr = addr;
args->size = size; args->size = size;
memcpy(args->data, argv, argc); memcpy(args->data, argv, argc);
......
...@@ -39,6 +39,7 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = { ...@@ -39,6 +39,7 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = {
[NVKM_SUBDEV_FB ] = "fb", [NVKM_SUBDEV_FB ] = "fb",
[NVKM_SUBDEV_FUSE ] = "fuse", [NVKM_SUBDEV_FUSE ] = "fuse",
[NVKM_SUBDEV_GPIO ] = "gpio", [NVKM_SUBDEV_GPIO ] = "gpio",
[NVKM_SUBDEV_GSP ] = "gsp",
[NVKM_SUBDEV_I2C ] = "i2c", [NVKM_SUBDEV_I2C ] = "i2c",
[NVKM_SUBDEV_IBUS ] = "priv", [NVKM_SUBDEV_IBUS ] = "priv",
[NVKM_SUBDEV_ICCSENSE] = "iccsense", [NVKM_SUBDEV_ICCSENSE] = "iccsense",
......
...@@ -6,4 +6,4 @@ nvkm-y += nvkm/engine/ce/gm200.o ...@@ -6,4 +6,4 @@ nvkm-y += nvkm/engine/ce/gm200.o
nvkm-y += nvkm/engine/ce/gp100.o nvkm-y += nvkm/engine/ce/gp100.o
nvkm-y += nvkm/engine/ce/gp102.o nvkm-y += nvkm/engine/ce/gp102.o
nvkm-y += nvkm/engine/ce/gv100.o nvkm-y += nvkm/engine/ce/gv100.o
nvkm-y += nvkm/engine/ce/tu104.o nvkm-y += nvkm/engine/ce/tu102.o
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <nvif/class.h> #include <nvif/class.h>
static const struct nvkm_engine_func static const struct nvkm_engine_func
tu104_ce = { tu102_ce = {
.intr = gp100_ce_intr, .intr = gp100_ce_intr,
.sclass = { .sclass = {
{ -1, -1, TURING_DMA_COPY_A }, { -1, -1, TURING_DMA_COPY_A },
...@@ -33,8 +33,8 @@ tu104_ce = { ...@@ -33,8 +33,8 @@ tu104_ce = {
}; };
int int
tu104_ce_new(struct nvkm_device *device, int index, tu102_ce_new(struct nvkm_device *device, int index,
struct nvkm_engine **pengine) struct nvkm_engine **pengine)
{ {
return nvkm_engine_new_(&tu104_ce, device, index, true, pengine); return nvkm_engine_new_(&tu102_ce, device, index, true, pengine);
} }
...@@ -1613,7 +1613,7 @@ nvd7_chipset = { ...@@ -1613,7 +1613,7 @@ nvd7_chipset = {
.pci = gf106_pci_new, .pci = gf106_pci_new,
.therm = gf119_therm_new, .therm = gf119_therm_new,
.timer = nv41_timer_new, .timer = nv41_timer_new,
.volt = gf100_volt_new, .volt = gf117_volt_new,
.ce[0] = gf100_ce_new, .ce[0] = gf100_ce_new,
.disp = gf119_disp_new, .disp = gf119_disp_new,
.dma = gf119_dma_new, .dma = gf119_dma_new,
...@@ -2405,6 +2405,7 @@ nv140_chipset = { ...@@ -2405,6 +2405,7 @@ nv140_chipset = {
.fb = gv100_fb_new, .fb = gv100_fb_new,
.fuse = gm107_fuse_new, .fuse = gm107_fuse_new,
.gpio = gk104_gpio_new, .gpio = gk104_gpio_new,
.gsp = gv100_gsp_new,
.i2c = gm200_i2c_new, .i2c = gm200_i2c_new,
.ibus = gm200_ibus_new, .ibus = gm200_ibus_new,
.imem = nv50_instmem_new, .imem = nv50_instmem_new,
...@@ -2437,97 +2438,106 @@ nv140_chipset = { ...@@ -2437,97 +2438,106 @@ nv140_chipset = {
static const struct nvkm_device_chip static const struct nvkm_device_chip
nv162_chipset = { nv162_chipset = {
.name = "TU102", .name = "TU102",
.bar = tu104_bar_new, .bar = tu102_bar_new,
.bios = nvkm_bios_new, .bios = nvkm_bios_new,
.bus = gf100_bus_new, .bus = gf100_bus_new,
.devinit = tu104_devinit_new, .devinit = tu102_devinit_new,
.fault = tu104_fault_new, .fault = tu102_fault_new,
.fb = gv100_fb_new, .fb = gv100_fb_new,
.fuse = gm107_fuse_new, .fuse = gm107_fuse_new,
.gpio = gk104_gpio_new, .gpio = gk104_gpio_new,
.gsp = gv100_gsp_new,
.i2c = gm200_i2c_new, .i2c = gm200_i2c_new,
.ibus = gm200_ibus_new, .ibus = gm200_ibus_new,
.imem = nv50_instmem_new, .imem = nv50_instmem_new,
.ltc = gp102_ltc_new, .ltc = gp102_ltc_new,
.mc = tu104_mc_new, .mc = tu102_mc_new,
.mmu = tu104_mmu_new, .mmu = tu102_mmu_new,
.pci = gp100_pci_new, .pci = gp100_pci_new,
.pmu = gp102_pmu_new, .pmu = gp102_pmu_new,
.therm = gp100_therm_new, .therm = gp100_therm_new,
.timer = gk20a_timer_new, .timer = gk20a_timer_new,
.top = gk104_top_new, .top = gk104_top_new,
.ce[0] = tu104_ce_new, .ce[0] = tu102_ce_new,
.ce[1] = tu104_ce_new, .ce[1] = tu102_ce_new,
.ce[2] = tu104_ce_new, .ce[2] = tu102_ce_new,
.ce[3] = tu104_ce_new, .ce[3] = tu102_ce_new,
.ce[4] = tu104_ce_new, .ce[4] = tu102_ce_new,
.disp = tu104_disp_new, .disp = tu102_disp_new,
.dma = gv100_dma_new, .dma = gv100_dma_new,
.fifo = tu104_fifo_new, .fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.sec2 = tu102_sec2_new,
}; };
static const struct nvkm_device_chip static const struct nvkm_device_chip
nv164_chipset = { nv164_chipset = {
.name = "TU104", .name = "TU104",
.bar = tu104_bar_new, .bar = tu102_bar_new,
.bios = nvkm_bios_new, .bios = nvkm_bios_new,
.bus = gf100_bus_new, .bus = gf100_bus_new,
.devinit = tu104_devinit_new, .devinit = tu102_devinit_new,
.fault = tu104_fault_new, .fault = tu102_fault_new,
.fb = gv100_fb_new, .fb = gv100_fb_new,
.fuse = gm107_fuse_new, .fuse = gm107_fuse_new,
.gpio = gk104_gpio_new, .gpio = gk104_gpio_new,
.gsp = gv100_gsp_new,
.i2c = gm200_i2c_new, .i2c = gm200_i2c_new,
.ibus = gm200_ibus_new, .ibus = gm200_ibus_new,
.imem = nv50_instmem_new, .imem = nv50_instmem_new,
.ltc = gp102_ltc_new, .ltc = gp102_ltc_new,
.mc = tu104_mc_new, .mc = tu102_mc_new,
.mmu = tu104_mmu_new, .mmu = tu102_mmu_new,
.pci = gp100_pci_new, .pci = gp100_pci_new,
.pmu = gp102_pmu_new, .pmu = gp102_pmu_new,
.therm = gp100_therm_new, .therm = gp100_therm_new,
.timer = gk20a_timer_new, .timer = gk20a_timer_new,
.top = gk104_top_new, .top = gk104_top_new,
.ce[0] = tu104_ce_new, .ce[0] = tu102_ce_new,
.ce[1] = tu104_ce_new, .ce[1] = tu102_ce_new,
.ce[2] = tu104_ce_new, .ce[2] = tu102_ce_new,
.ce[3] = tu104_ce_new, .ce[3] = tu102_ce_new,
.ce[4] = tu104_ce_new, .ce[4] = tu102_ce_new,
.disp = tu104_disp_new, .disp = tu102_disp_new,
.dma = gv100_dma_new, .dma = gv100_dma_new,
.fifo = tu104_fifo_new, .fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.sec2 = tu102_sec2_new,
}; };
static const struct nvkm_device_chip static const struct nvkm_device_chip
nv166_chipset = { nv166_chipset = {
.name = "TU106", .name = "TU106",
.bar = tu104_bar_new, .bar = tu102_bar_new,
.bios = nvkm_bios_new, .bios = nvkm_bios_new,
.bus = gf100_bus_new, .bus = gf100_bus_new,
.devinit = tu104_devinit_new, .devinit = tu102_devinit_new,
.fault = tu104_fault_new, .fault = tu102_fault_new,
.fb = gv100_fb_new, .fb = gv100_fb_new,
.fuse = gm107_fuse_new, .fuse = gm107_fuse_new,
.gpio = gk104_gpio_new, .gpio = gk104_gpio_new,
.gsp = gv100_gsp_new,
.i2c = gm200_i2c_new, .i2c = gm200_i2c_new,
.ibus = gm200_ibus_new, .ibus = gm200_ibus_new,
.imem = nv50_instmem_new, .imem = nv50_instmem_new,
.ltc = gp102_ltc_new, .ltc = gp102_ltc_new,
.mc = tu104_mc_new, .mc = tu102_mc_new,
.mmu = tu104_mmu_new, .mmu = tu102_mmu_new,
.pci = gp100_pci_new, .pci = gp100_pci_new,
.pmu = gp102_pmu_new, .pmu = gp102_pmu_new,
.therm = gp100_therm_new, .therm = gp100_therm_new,
.timer = gk20a_timer_new, .timer = gk20a_timer_new,
.top = gk104_top_new, .top = gk104_top_new,
.ce[0] = tu104_ce_new, .ce[0] = tu102_ce_new,
.ce[1] = tu104_ce_new, .ce[1] = tu102_ce_new,
.ce[2] = tu104_ce_new, .ce[2] = tu102_ce_new,
.ce[3] = tu104_ce_new, .ce[3] = tu102_ce_new,
.ce[4] = tu104_ce_new, .ce[4] = tu102_ce_new,
.disp = tu104_disp_new, .disp = tu102_disp_new,
.dma = gv100_dma_new, .dma = gv100_dma_new,
.fifo = tu104_fifo_new, .fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.sec2 = tu102_sec2_new,
}; };
static int static int
...@@ -2567,6 +2577,7 @@ nvkm_device_subdev(struct nvkm_device *device, int index) ...@@ -2567,6 +2577,7 @@ nvkm_device_subdev(struct nvkm_device *device, int index)
_(FB , device->fb , &device->fb->subdev); _(FB , device->fb , &device->fb->subdev);
_(FUSE , device->fuse , &device->fuse->subdev); _(FUSE , device->fuse , &device->fuse->subdev);
_(GPIO , device->gpio , &device->gpio->subdev); _(GPIO , device->gpio , &device->gpio->subdev);
_(GSP , device->gsp , &device->gsp->subdev);
_(I2C , device->i2c , &device->i2c->subdev); _(I2C , device->i2c , &device->i2c->subdev);
_(IBUS , device->ibus , device->ibus); _(IBUS , device->ibus , device->ibus);
_(ICCSENSE, device->iccsense, &device->iccsense->subdev); _(ICCSENSE, device->iccsense, &device->iccsense->subdev);
...@@ -3050,6 +3061,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func, ...@@ -3050,6 +3061,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
_(NVKM_SUBDEV_FB , fb); _(NVKM_SUBDEV_FB , fb);
_(NVKM_SUBDEV_FUSE , fuse); _(NVKM_SUBDEV_FUSE , fuse);
_(NVKM_SUBDEV_GPIO , gpio); _(NVKM_SUBDEV_GPIO , gpio);
_(NVKM_SUBDEV_GSP , gsp);
_(NVKM_SUBDEV_I2C , i2c); _(NVKM_SUBDEV_I2C , i2c);
_(NVKM_SUBDEV_IBUS , ibus); _(NVKM_SUBDEV_IBUS , ibus);
_(NVKM_SUBDEV_ICCSENSE, iccsense); _(NVKM_SUBDEV_ICCSENSE, iccsense);
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include <subdev/fb.h> #include <subdev/fb.h>
#include <subdev/fuse.h> #include <subdev/fuse.h>
#include <subdev/gpio.h> #include <subdev/gpio.h>
#include <subdev/gsp.h>
#include <subdev/i2c.h> #include <subdev/i2c.h>
#include <subdev/ibus.h> #include <subdev/ibus.h>
#include <subdev/iccsense.h> #include <subdev/iccsense.h>
......
...@@ -365,16 +365,15 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index, ...@@ -365,16 +365,15 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
} }
if (!sclass) { if (!sclass) {
switch (index) { if (index-- == 0)
case 0: sclass = &nvkm_control_oclass; break; sclass = &nvkm_control_oclass;
case 1: else if (device->mmu && index-- == 0)
if (!device->mmu)
return -EINVAL;
sclass = &device->mmu->user; sclass = &device->mmu->user;
break; else if (device->fault && index-- == 0)
default: sclass = &device->fault->user;
else
return -EINVAL; return -EINVAL;
}
oclass->base = sclass->base; oclass->base = sclass->base;
} }
......
...@@ -15,7 +15,7 @@ nvkm-y += nvkm/engine/disp/gm200.o ...@@ -15,7 +15,7 @@ nvkm-y += nvkm/engine/disp/gm200.o
nvkm-y += nvkm/engine/disp/gp100.o nvkm-y += nvkm/engine/disp/gp100.o
nvkm-y += nvkm/engine/disp/gp102.o nvkm-y += nvkm/engine/disp/gp102.o
nvkm-y += nvkm/engine/disp/gv100.o nvkm-y += nvkm/engine/disp/gv100.o
nvkm-y += nvkm/engine/disp/tu104.o nvkm-y += nvkm/engine/disp/tu102.o
nvkm-y += nvkm/engine/disp/vga.o nvkm-y += nvkm/engine/disp/vga.o
nvkm-y += nvkm/engine/disp/head.o nvkm-y += nvkm/engine/disp/head.o
...@@ -39,7 +39,7 @@ nvkm-y += nvkm/engine/disp/sorgk104.o ...@@ -39,7 +39,7 @@ nvkm-y += nvkm/engine/disp/sorgk104.o
nvkm-y += nvkm/engine/disp/sorgm107.o nvkm-y += nvkm/engine/disp/sorgm107.o
nvkm-y += nvkm/engine/disp/sorgm200.o nvkm-y += nvkm/engine/disp/sorgm200.o
nvkm-y += nvkm/engine/disp/sorgv100.o nvkm-y += nvkm/engine/disp/sorgv100.o
nvkm-y += nvkm/engine/disp/sortu104.o nvkm-y += nvkm/engine/disp/sortu102.o
nvkm-y += nvkm/engine/disp/outp.o nvkm-y += nvkm/engine/disp/outp.o
nvkm-y += nvkm/engine/disp/dp.o nvkm-y += nvkm/engine/disp/dp.o
...@@ -71,7 +71,7 @@ nvkm-y += nvkm/engine/disp/rootgm200.o ...@@ -71,7 +71,7 @@ nvkm-y += nvkm/engine/disp/rootgm200.o
nvkm-y += nvkm/engine/disp/rootgp100.o nvkm-y += nvkm/engine/disp/rootgp100.o
nvkm-y += nvkm/engine/disp/rootgp102.o nvkm-y += nvkm/engine/disp/rootgp102.o
nvkm-y += nvkm/engine/disp/rootgv100.o nvkm-y += nvkm/engine/disp/rootgv100.o
nvkm-y += nvkm/engine/disp/roottu104.o nvkm-y += nvkm/engine/disp/roottu102.o
nvkm-y += nvkm/engine/disp/channv50.o nvkm-y += nvkm/engine/disp/channv50.o
nvkm-y += nvkm/engine/disp/changf119.o nvkm-y += nvkm/engine/disp/changf119.o
......
...@@ -91,15 +91,21 @@ gf119_disp_intr_error(struct nv50_disp *disp, int chid) ...@@ -91,15 +91,21 @@ gf119_disp_intr_error(struct nv50_disp *disp, int chid)
{ {
struct nvkm_subdev *subdev = &disp->base.engine.subdev; struct nvkm_subdev *subdev = &disp->base.engine.subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
u32 mthd = nvkm_rd32(device, 0x6101f0 + (chid * 12)); u32 stat = nvkm_rd32(device, 0x6101f0 + (chid * 12));
u32 type = (stat & 0x00007000) >> 12;
u32 mthd = (stat & 0x00000ffc);
u32 data = nvkm_rd32(device, 0x6101f4 + (chid * 12)); u32 data = nvkm_rd32(device, 0x6101f4 + (chid * 12));
u32 unkn = nvkm_rd32(device, 0x6101f8 + (chid * 12)); u32 code = nvkm_rd32(device, 0x6101f8 + (chid * 12));
const struct nvkm_enum *reason =
nvkm_enum_find(nv50_disp_intr_error_type, type);
nvkm_error(subdev, "chid %d mthd %04x data %08x %08x %08x\n", nvkm_error(subdev, "chid %d stat %08x reason %d [%s] mthd %04x "
chid, (mthd & 0x0000ffc), data, mthd, unkn); "data %08x code %08x\n",
chid, stat, type, reason ? reason->name : "",
mthd, data, code);
if (chid < ARRAY_SIZE(disp->chan)) { if (chid < ARRAY_SIZE(disp->chan)) {
switch (mthd & 0xffc) { switch (mthd) {
case 0x0080: case 0x0080:
nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR); nv50_disp_chan_mthd(disp->chan[chid], NV_DBG_ERROR);
break; break;
......
...@@ -103,10 +103,13 @@ gv100_disp_exception(struct nv50_disp *disp, int chid) ...@@ -103,10 +103,13 @@ gv100_disp_exception(struct nv50_disp *disp, int chid)
u32 mthd = (stat & 0x00000fff) << 2; u32 mthd = (stat & 0x00000fff) << 2;
u32 data = nvkm_rd32(device, 0x611024 + (chid * 12)); u32 data = nvkm_rd32(device, 0x611024 + (chid * 12));
u32 code = nvkm_rd32(device, 0x611028 + (chid * 12)); u32 code = nvkm_rd32(device, 0x611028 + (chid * 12));
const struct nvkm_enum *reason =
nvkm_enum_find(nv50_disp_intr_error_type, type);
nvkm_error(subdev, "chid %d %08x [type %d mthd %04x] " nvkm_error(subdev, "chid %d stat %08x reason %d [%s] mthd %04x "
"data %08x code %08x\n", "data %08x code %08x\n",
chid, stat, type, mthd, data, code); chid, stat, type, reason ? reason->name : "",
mthd, data, code);
if (chid < ARRAY_SIZE(disp->chan) && disp->chan[chid]) { if (chid < ARRAY_SIZE(disp->chan) && disp->chan[chid]) {
switch (mthd) { switch (mthd) {
......
...@@ -201,5 +201,5 @@ int gm200_sor_new(struct nvkm_disp *, int); ...@@ -201,5 +201,5 @@ int gm200_sor_new(struct nvkm_disp *, int);
int gv100_sor_cnt(struct nvkm_disp *, unsigned long *); int gv100_sor_cnt(struct nvkm_disp *, unsigned long *);
int gv100_sor_new(struct nvkm_disp *, int); int gv100_sor_new(struct nvkm_disp *, int);
int tu104_sor_new(struct nvkm_disp *, int); int tu102_sor_new(struct nvkm_disp *, int);
#endif #endif
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
#include "rootnv50.h" #include "rootnv50.h"
#include <core/client.h> #include <core/client.h>
#include <core/enum.h>
#include <core/ramht.h> #include <core/ramht.h>
#include <subdev/bios.h> #include <subdev/bios.h>
#include <subdev/bios/disp.h> #include <subdev/bios/disp.h>
...@@ -593,12 +592,15 @@ nv50_disp_super(struct work_struct *work) ...@@ -593,12 +592,15 @@ nv50_disp_super(struct work_struct *work)
nvkm_wr32(device, 0x610030, 0x80000000); nvkm_wr32(device, 0x610030, 0x80000000);
} }
static const struct nvkm_enum const struct nvkm_enum
nv50_disp_intr_error_type[] = { nv50_disp_intr_error_type[] = {
{ 3, "ILLEGAL_MTHD" }, { 0, "NONE" },
{ 4, "INVALID_VALUE" }, { 1, "PUSHBUFFER_ERR" },
{ 2, "TRAP" },
{ 3, "RESERVED_METHOD" },
{ 4, "INVALID_ARG" },
{ 5, "INVALID_STATE" }, { 5, "INVALID_STATE" },
{ 7, "INVALID_HANDLE" }, { 7, "UNRESOLVABLE_HANDLE" },
{} {}
}; };
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include "priv.h" #include "priv.h"
struct nvkm_head; struct nvkm_head;
#include <core/enum.h>
struct nv50_disp { struct nv50_disp {
const struct nv50_disp_func *func; const struct nv50_disp_func *func;
struct nvkm_disp base; struct nvkm_disp base;
...@@ -71,6 +73,7 @@ int nv50_disp_init(struct nv50_disp *); ...@@ -71,6 +73,7 @@ int nv50_disp_init(struct nv50_disp *);
void nv50_disp_fini(struct nv50_disp *); void nv50_disp_fini(struct nv50_disp *);
void nv50_disp_intr(struct nv50_disp *); void nv50_disp_intr(struct nv50_disp *);
void nv50_disp_super(struct work_struct *); void nv50_disp_super(struct work_struct *);
extern const struct nvkm_enum nv50_disp_intr_error_type[];
int gf119_disp_init(struct nv50_disp *); int gf119_disp_init(struct nv50_disp *);
void gf119_disp_fini(struct nv50_disp *); void gf119_disp_fini(struct nv50_disp *);
......
...@@ -37,5 +37,5 @@ extern const struct nvkm_disp_oclass gm200_disp_root_oclass; ...@@ -37,5 +37,5 @@ extern const struct nvkm_disp_oclass gm200_disp_root_oclass;
extern const struct nvkm_disp_oclass gp100_disp_root_oclass; extern const struct nvkm_disp_oclass gp100_disp_root_oclass;
extern const struct nvkm_disp_oclass gp102_disp_root_oclass; extern const struct nvkm_disp_oclass gp102_disp_root_oclass;
extern const struct nvkm_disp_oclass gv100_disp_root_oclass; extern const struct nvkm_disp_oclass gv100_disp_root_oclass;
extern const struct nvkm_disp_oclass tu104_disp_root_oclass; extern const struct nvkm_disp_oclass tu102_disp_root_oclass;
#endif #endif
...@@ -25,28 +25,28 @@ ...@@ -25,28 +25,28 @@
#include <nvif/class.h> #include <nvif/class.h>
static const struct nv50_disp_root_func static const struct nv50_disp_root_func
tu104_disp_root = { tu102_disp_root = {
.user = { .user = {
{{0,0,TU104_DISP_CURSOR }, gv100_disp_curs_new }, {{0,0,TU102_DISP_CURSOR }, gv100_disp_curs_new },
{{0,0,TU104_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new }, {{0,0,TU102_DISP_WINDOW_IMM_CHANNEL_DMA}, gv100_disp_wimm_new },
{{0,0,TU104_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new }, {{0,0,TU102_DISP_CORE_CHANNEL_DMA }, gv100_disp_core_new },
{{0,0,TU104_DISP_WINDOW_CHANNEL_DMA }, gv100_disp_wndw_new }, {{0,0,TU102_DISP_WINDOW_CHANNEL_DMA }, gv100_disp_wndw_new },
{} {}
}, },
}; };
static int static int
tu104_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass, tu102_disp_root_new(struct nvkm_disp *disp, const struct nvkm_oclass *oclass,
void *data, u32 size, struct nvkm_object **pobject) void *data, u32 size, struct nvkm_object **pobject)
{ {
return nv50_disp_root_new_(&tu104_disp_root, disp, oclass, return nv50_disp_root_new_(&tu102_disp_root, disp, oclass,
data, size, pobject); data, size, pobject);
} }
const struct nvkm_disp_oclass const struct nvkm_disp_oclass
tu104_disp_root_oclass = { tu102_disp_root_oclass = {
.base.oclass = TU104_DISP, .base.oclass = TU102_DISP,
.base.minver = -1, .base.minver = -1,
.base.maxver = -1, .base.maxver = -1,
.ctor = tu104_disp_root_new, .ctor = tu102_disp_root_new,
}; };
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
#include <subdev/timer.h> #include <subdev/timer.h>
static void static void
tu104_sor_dp_vcpi(struct nvkm_ior *sor, int head, tu102_sor_dp_vcpi(struct nvkm_ior *sor, int head,
u8 slot, u8 slot_nr, u16 pbn, u16 aligned) u8 slot, u8 slot_nr, u16 pbn, u16 aligned)
{ {
struct nvkm_device *device = sor->disp->engine.subdev.device; struct nvkm_device *device = sor->disp->engine.subdev.device;
...@@ -35,7 +35,7 @@ tu104_sor_dp_vcpi(struct nvkm_ior *sor, int head, ...@@ -35,7 +35,7 @@ tu104_sor_dp_vcpi(struct nvkm_ior *sor, int head,
} }
static int static int
tu104_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux) tu102_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
{ {
struct nvkm_device *device = sor->disp->engine.subdev.device; struct nvkm_device *device = sor->disp->engine.subdev.device;
const u32 soff = nv50_ior_base(sor); const u32 soff = nv50_ior_base(sor);
...@@ -62,7 +62,7 @@ tu104_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux) ...@@ -62,7 +62,7 @@ tu104_sor_dp_links(struct nvkm_ior *sor, struct nvkm_i2c_aux *aux)
} }
static const struct nvkm_ior_func static const struct nvkm_ior_func
tu104_sor = { tu102_sor = {
.route = { .route = {
.get = gm200_sor_route_get, .get = gm200_sor_route_get,
.set = gm200_sor_route_set, .set = gm200_sor_route_set,
...@@ -75,11 +75,11 @@ tu104_sor = { ...@@ -75,11 +75,11 @@ tu104_sor = {
}, },
.dp = { .dp = {
.lanes = { 0, 1, 2, 3 }, .lanes = { 0, 1, 2, 3 },
.links = tu104_sor_dp_links, .links = tu102_sor_dp_links,
.power = g94_sor_dp_power, .power = g94_sor_dp_power,
.pattern = gm107_sor_dp_pattern, .pattern = gm107_sor_dp_pattern,
.drive = gm200_sor_dp_drive, .drive = gm200_sor_dp_drive,
.vcpi = tu104_sor_dp_vcpi, .vcpi = tu102_sor_dp_vcpi,
.audio = gv100_sor_dp_audio, .audio = gv100_sor_dp_audio,
.audio_sym = gv100_sor_dp_audio_sym, .audio_sym = gv100_sor_dp_audio_sym,
.watermark = gv100_sor_dp_watermark, .watermark = gv100_sor_dp_watermark,
...@@ -91,7 +91,7 @@ tu104_sor = { ...@@ -91,7 +91,7 @@ tu104_sor = {
}; };
int int
tu104_sor_new(struct nvkm_disp *disp, int id) tu102_sor_new(struct nvkm_disp *disp, int id)
{ {
return nvkm_ior_new_(&tu104_sor, disp, SOR, id); return nvkm_ior_new_(&tu102_sor, disp, SOR, id);
} }
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <subdev/timer.h> #include <subdev/timer.h>
static int static int
tu104_disp_init(struct nv50_disp *disp) tu102_disp_init(struct nv50_disp *disp)
{ {
struct nvkm_device *device = disp->base.engine.subdev.device; struct nvkm_device *device = disp->base.engine.subdev.device;
struct nvkm_head *head; struct nvkm_head *head;
...@@ -132,21 +132,21 @@ tu104_disp_init(struct nv50_disp *disp) ...@@ -132,21 +132,21 @@ tu104_disp_init(struct nv50_disp *disp)
} }
static const struct nv50_disp_func static const struct nv50_disp_func
tu104_disp = { tu102_disp = {
.init = tu104_disp_init, .init = tu102_disp_init,
.fini = gv100_disp_fini, .fini = gv100_disp_fini,
.intr = gv100_disp_intr, .intr = gv100_disp_intr,
.uevent = &gv100_disp_chan_uevent, .uevent = &gv100_disp_chan_uevent,
.super = gv100_disp_super, .super = gv100_disp_super,
.root = &tu104_disp_root_oclass, .root = &tu102_disp_root_oclass,
.wndw = { .cnt = gv100_disp_wndw_cnt }, .wndw = { .cnt = gv100_disp_wndw_cnt },
.head = { .cnt = gv100_head_cnt, .new = gv100_head_new }, .head = { .cnt = gv100_head_cnt, .new = gv100_head_new },
.sor = { .cnt = gv100_sor_cnt, .new = tu104_sor_new }, .sor = { .cnt = gv100_sor_cnt, .new = tu102_sor_new },
.ramht_size = 0x2000, .ramht_size = 0x2000,
}; };
int int
tu104_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp) tu102_disp_new(struct nvkm_device *device, int index, struct nvkm_disp **pdisp)
{ {
return nv50_disp_new_(&tu104_disp, device, index, pdisp); return nv50_disp_new_(&tu102_disp, device, index, pdisp);
} }
...@@ -16,7 +16,7 @@ nvkm-y += nvkm/engine/fifo/gm20b.o ...@@ -16,7 +16,7 @@ nvkm-y += nvkm/engine/fifo/gm20b.o
nvkm-y += nvkm/engine/fifo/gp100.o nvkm-y += nvkm/engine/fifo/gp100.o
nvkm-y += nvkm/engine/fifo/gp10b.o nvkm-y += nvkm/engine/fifo/gp10b.o
nvkm-y += nvkm/engine/fifo/gv100.o nvkm-y += nvkm/engine/fifo/gv100.o
nvkm-y += nvkm/engine/fifo/tu104.o nvkm-y += nvkm/engine/fifo/tu102.o
nvkm-y += nvkm/engine/fifo/chan.o nvkm-y += nvkm/engine/fifo/chan.o
nvkm-y += nvkm/engine/fifo/channv50.o nvkm-y += nvkm/engine/fifo/channv50.o
...@@ -34,7 +34,7 @@ nvkm-y += nvkm/engine/fifo/gpfifog84.o ...@@ -34,7 +34,7 @@ nvkm-y += nvkm/engine/fifo/gpfifog84.o
nvkm-y += nvkm/engine/fifo/gpfifogf100.o nvkm-y += nvkm/engine/fifo/gpfifogf100.o
nvkm-y += nvkm/engine/fifo/gpfifogk104.o nvkm-y += nvkm/engine/fifo/gpfifogk104.o
nvkm-y += nvkm/engine/fifo/gpfifogv100.o nvkm-y += nvkm/engine/fifo/gpfifogv100.o
nvkm-y += nvkm/engine/fifo/gpfifotu104.o nvkm-y += nvkm/engine/fifo/gpfifotu102.o
nvkm-y += nvkm/engine/fifo/usergv100.o nvkm-y += nvkm/engine/fifo/usergv100.o
nvkm-y += nvkm/engine/fifo/usertu104.o nvkm-y += nvkm/engine/fifo/usertu102.o
...@@ -47,6 +47,6 @@ int gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *, ...@@ -47,6 +47,6 @@ int gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan *,
int gv100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *, int gv100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan *,
struct nvkm_engine *, bool); struct nvkm_engine *, bool);
int tu104_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *, int tu102_fifo_gpfifo_new(struct gk104_fifo *, const struct nvkm_oclass *,
void *data, u32 size, struct nvkm_object **); void *data, u32 size, struct nvkm_object **);
#endif #endif
...@@ -29,14 +29,14 @@ ...@@ -29,14 +29,14 @@
#include <nvif/unpack.h> #include <nvif/unpack.h>
static u32 static u32
tu104_fifo_gpfifo_submit_token(struct nvkm_fifo_chan *base) tu102_fifo_gpfifo_submit_token(struct nvkm_fifo_chan *base)
{ {
struct gk104_fifo_chan *chan = gk104_fifo_chan(base); struct gk104_fifo_chan *chan = gk104_fifo_chan(base);
return (chan->runl << 16) | chan->base.chid; return (chan->runl << 16) | chan->base.chid;
} }
static const struct nvkm_fifo_chan_func static const struct nvkm_fifo_chan_func
tu104_fifo_gpfifo = { tu102_fifo_gpfifo = {
.dtor = gk104_fifo_gpfifo_dtor, .dtor = gk104_fifo_gpfifo_dtor,
.init = gk104_fifo_gpfifo_init, .init = gk104_fifo_gpfifo_init,
.fini = gk104_fifo_gpfifo_fini, .fini = gk104_fifo_gpfifo_fini,
...@@ -45,11 +45,11 @@ tu104_fifo_gpfifo = { ...@@ -45,11 +45,11 @@ tu104_fifo_gpfifo = {
.engine_dtor = gk104_fifo_gpfifo_engine_dtor, .engine_dtor = gk104_fifo_gpfifo_engine_dtor,
.engine_init = gv100_fifo_gpfifo_engine_init, .engine_init = gv100_fifo_gpfifo_engine_init,
.engine_fini = gv100_fifo_gpfifo_engine_fini, .engine_fini = gv100_fifo_gpfifo_engine_fini,
.submit_token = tu104_fifo_gpfifo_submit_token, .submit_token = tu102_fifo_gpfifo_submit_token,
}; };
int int
tu104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass, tu102_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
void *data, u32 size, struct nvkm_object **pobject) void *data, u32 size, struct nvkm_object **pobject)
{ {
struct nvkm_object *parent = oclass->parent; struct nvkm_object *parent = oclass->parent;
...@@ -67,7 +67,7 @@ tu104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass, ...@@ -67,7 +67,7 @@ tu104_fifo_gpfifo_new(struct gk104_fifo *fifo, const struct nvkm_oclass *oclass,
args->v0.ilength, args->v0.runlist, args->v0.priv); args->v0.ilength, args->v0.runlist, args->v0.priv);
if (args->v0.priv && !oclass->client->super) if (args->v0.priv && !oclass->client->super)
return -EINVAL; return -EINVAL;
return gv100_fifo_gpfifo_new_(&tu104_fifo_gpfifo, fifo, return gv100_fifo_gpfifo_new_(&tu102_fifo_gpfifo, fifo,
&args->v0.runlist, &args->v0.runlist,
&args->v0.chid, &args->v0.chid,
args->v0.vmm, args->v0.vmm,
......
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
#include <nvif/class.h> #include <nvif/class.h>
static void static void
tu104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl, tu102_fifo_runlist_commit(struct gk104_fifo *fifo, int runl,
struct nvkm_memory *mem, int nr) struct nvkm_memory *mem, int nr)
{ {
struct nvkm_device *device = fifo->base.engine.subdev.device; struct nvkm_device *device = fifo->base.engine.subdev.device;
...@@ -44,15 +44,15 @@ tu104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl, ...@@ -44,15 +44,15 @@ tu104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl,
} }
const struct gk104_fifo_runlist_func const struct gk104_fifo_runlist_func
tu104_fifo_runlist = { tu102_fifo_runlist = {
.size = 16, .size = 16,
.cgrp = gv100_fifo_runlist_cgrp, .cgrp = gv100_fifo_runlist_cgrp,
.chan = gv100_fifo_runlist_chan, .chan = gv100_fifo_runlist_chan,
.commit = tu104_fifo_runlist_commit, .commit = tu102_fifo_runlist_commit,
}; };
static const struct nvkm_enum static const struct nvkm_enum
tu104_fifo_fault_engine[] = { tu102_fifo_fault_engine[] = {
{ 0x01, "DISPLAY" }, { 0x01, "DISPLAY" },
{ 0x03, "PTP" }, { 0x03, "PTP" },
{ 0x06, "PWR_PMU" }, { 0x06, "PWR_PMU" },
...@@ -80,7 +80,7 @@ tu104_fifo_fault_engine[] = { ...@@ -80,7 +80,7 @@ tu104_fifo_fault_engine[] = {
}; };
static void static void
tu104_fifo_pbdma_init(struct gk104_fifo *fifo) tu102_fifo_pbdma_init(struct gk104_fifo *fifo)
{ {
struct nvkm_device *device = fifo->base.engine.subdev.device; struct nvkm_device *device = fifo->base.engine.subdev.device;
const u32 mask = (1 << fifo->pbdma_nr) - 1; const u32 mask = (1 << fifo->pbdma_nr) - 1;
...@@ -89,28 +89,28 @@ tu104_fifo_pbdma_init(struct gk104_fifo *fifo) ...@@ -89,28 +89,28 @@ tu104_fifo_pbdma_init(struct gk104_fifo *fifo)
} }
static const struct gk104_fifo_pbdma_func static const struct gk104_fifo_pbdma_func
tu104_fifo_pbdma = { tu102_fifo_pbdma = {
.nr = gm200_fifo_pbdma_nr, .nr = gm200_fifo_pbdma_nr,
.init = tu104_fifo_pbdma_init, .init = tu102_fifo_pbdma_init,
.init_timeout = gk208_fifo_pbdma_init_timeout, .init_timeout = gk208_fifo_pbdma_init_timeout,
}; };
static const struct gk104_fifo_func static const struct gk104_fifo_func
tu104_fifo = { tu102_fifo = {
.pbdma = &tu104_fifo_pbdma, .pbdma = &tu102_fifo_pbdma,
.fault.access = gv100_fifo_fault_access, .fault.access = gv100_fifo_fault_access,
.fault.engine = tu104_fifo_fault_engine, .fault.engine = tu102_fifo_fault_engine,
.fault.reason = gv100_fifo_fault_reason, .fault.reason = gv100_fifo_fault_reason,
.fault.hubclient = gv100_fifo_fault_hubclient, .fault.hubclient = gv100_fifo_fault_hubclient,
.fault.gpcclient = gv100_fifo_fault_gpcclient, .fault.gpcclient = gv100_fifo_fault_gpcclient,
.runlist = &tu104_fifo_runlist, .runlist = &tu102_fifo_runlist,
.user = {{-1,-1,VOLTA_USERMODE_A }, tu104_fifo_user_new }, .user = {{-1,-1,VOLTA_USERMODE_A }, tu102_fifo_user_new },
.chan = {{ 0, 0,TURING_CHANNEL_GPFIFO_A}, tu104_fifo_gpfifo_new }, .chan = {{ 0, 0,TURING_CHANNEL_GPFIFO_A}, tu102_fifo_gpfifo_new },
.cgrp_force = true, .cgrp_force = true,
}; };
int int
tu104_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo) tu102_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{ {
return gk104_fifo_new_(&tu104_fifo, device, index, 4096, pfifo); return gk104_fifo_new_(&tu102_fifo, device, index, 4096, pfifo);
} }
...@@ -3,6 +3,6 @@ ...@@ -3,6 +3,6 @@
#include "priv.h" #include "priv.h"
int gv100_fifo_user_new(const struct nvkm_oclass *, void *, u32, int gv100_fifo_user_new(const struct nvkm_oclass *, void *, u32,
struct nvkm_object **); struct nvkm_object **);
int tu104_fifo_user_new(const struct nvkm_oclass *, void *, u32, int tu102_fifo_user_new(const struct nvkm_oclass *, void *, u32,
struct nvkm_object **); struct nvkm_object **);
#endif #endif
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include "user.h" #include "user.h"
static int static int
tu104_fifo_user_map(struct nvkm_object *object, void *argv, u32 argc, tu102_fifo_user_map(struct nvkm_object *object, void *argv, u32 argc,
enum nvkm_object_map *type, u64 *addr, u64 *size) enum nvkm_object_map *type, u64 *addr, u64 *size)
{ {
struct nvkm_device *device = object->engine->subdev.device; struct nvkm_device *device = object->engine->subdev.device;
...@@ -33,13 +33,13 @@ tu104_fifo_user_map(struct nvkm_object *object, void *argv, u32 argc, ...@@ -33,13 +33,13 @@ tu104_fifo_user_map(struct nvkm_object *object, void *argv, u32 argc,
} }
static const struct nvkm_object_func static const struct nvkm_object_func
tu104_fifo_user = { tu102_fifo_user = {
.map = tu104_fifo_user_map, .map = tu102_fifo_user_map,
}; };
int int
tu104_fifo_user_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, tu102_fifo_user_new(const struct nvkm_oclass *oclass, void *argv, u32 argc,
struct nvkm_object **pobject) struct nvkm_object **pobject)
{ {
return nvkm_object_new_(&tu104_fifo_user, oclass, argv, argc, pobject); return nvkm_object_new_(&tu102_fifo_user, oclass, argv, argc, pobject);
} }
...@@ -25,6 +25,33 @@ ...@@ -25,6 +25,33 @@
#include <engine/fifo.h> #include <engine/fifo.h>
u32
nvkm_gr_ctxsw_inst(struct nvkm_device *device)
{
struct nvkm_gr *gr = device->gr;
if (gr && gr->func->ctxsw.inst)
return gr->func->ctxsw.inst(gr);
return 0;
}
int
nvkm_gr_ctxsw_resume(struct nvkm_device *device)
{
struct nvkm_gr *gr = device->gr;
if (gr && gr->func->ctxsw.resume)
return gr->func->ctxsw.resume(gr);
return 0;
}
int
nvkm_gr_ctxsw_pause(struct nvkm_device *device)
{
struct nvkm_gr *gr = device->gr;
if (gr && gr->func->ctxsw.pause)
return gr->func->ctxsw.pause(gr);
return 0;
}
static bool static bool
nvkm_gr_chsw_load(struct nvkm_engine *engine) nvkm_gr_chsw_load(struct nvkm_engine *engine)
{ {
......
...@@ -1523,13 +1523,9 @@ gf100_grctx_generate(struct gf100_gr *gr) ...@@ -1523,13 +1523,9 @@ gf100_grctx_generate(struct gf100_gr *gr)
/* Make channel current. */ /* Make channel current. */
addr = nvkm_memory_addr(inst) >> 12; addr = nvkm_memory_addr(inst) >> 12;
if (gr->firmware) { if (gr->firmware) {
nvkm_wr32(device, 0x409840, 0x00000030); ret = gf100_gr_fecs_bind_pointer(gr, 0x80000000 | addr);
nvkm_wr32(device, 0x409500, 0x80000000 | addr); if (ret)
nvkm_wr32(device, 0x409504, 0x00000003); goto done;
nvkm_msec(device, 2000,
if (nvkm_rd32(device, 0x409800) & 0x00000010)
break;
);
nvkm_kmap(data); nvkm_kmap(data);
nvkm_wo32(data, 0x1c, 1); nvkm_wo32(data, 0x1c, 1);
......
...@@ -82,8 +82,16 @@ struct gf100_gr { ...@@ -82,8 +82,16 @@ struct gf100_gr {
const struct gf100_gr_func *func; const struct gf100_gr_func *func;
struct nvkm_gr base; struct nvkm_gr base;
struct nvkm_falcon *fecs; struct {
struct nvkm_falcon *gpccs; struct nvkm_falcon *falcon;
struct mutex mutex;
u32 disable;
} fecs;
struct {
struct nvkm_falcon *falcon;
} gpccs;
struct gf100_gr_fuc fuc409c; struct gf100_gr_fuc fuc409c;
struct gf100_gr_fuc fuc409d; struct gf100_gr_fuc fuc409d;
struct gf100_gr_fuc fuc41ac; struct gf100_gr_fuc fuc41ac;
...@@ -128,6 +136,8 @@ struct gf100_gr { ...@@ -128,6 +136,8 @@ struct gf100_gr {
struct gf100_gr_mmio mmio_list[4096/8]; struct gf100_gr_mmio mmio_list[4096/8];
u32 size; u32 size;
u32 *data; u32 *data;
u32 size_zcull;
u32 size_pm;
}; };
int gf100_gr_ctor(const struct gf100_gr_func *, struct nvkm_device *, int gf100_gr_ctor(const struct gf100_gr_func *, struct nvkm_device *,
...@@ -136,6 +146,8 @@ int gf100_gr_new_(const struct gf100_gr_func *, struct nvkm_device *, ...@@ -136,6 +146,8 @@ int gf100_gr_new_(const struct gf100_gr_func *, struct nvkm_device *,
int, struct nvkm_gr **); int, struct nvkm_gr **);
void *gf100_gr_dtor(struct nvkm_gr *); void *gf100_gr_dtor(struct nvkm_gr *);
int gf100_gr_fecs_bind_pointer(struct gf100_gr *, u32 inst);
struct gf100_gr_func_zbc { struct gf100_gr_func_zbc {
void (*clear_color)(struct gf100_gr *, int zbc); void (*clear_color)(struct gf100_gr *, int zbc);
void (*clear_depth)(struct gf100_gr *, int zbc); void (*clear_depth)(struct gf100_gr *, int zbc);
......
...@@ -27,6 +27,11 @@ struct nvkm_gr_func { ...@@ -27,6 +27,11 @@ struct nvkm_gr_func {
*/ */
u64 (*units)(struct nvkm_gr *); u64 (*units)(struct nvkm_gr *);
bool (*chsw_load)(struct nvkm_gr *); bool (*chsw_load)(struct nvkm_gr *);
struct {
int (*pause)(struct nvkm_gr *);
int (*resume)(struct nvkm_gr *);
u32 (*inst)(struct nvkm_gr *);
} ctxsw;
struct nvkm_sclass sclass[]; struct nvkm_sclass sclass[];
}; };
......
...@@ -21,13 +21,21 @@ ...@@ -21,13 +21,21 @@
*/ */
#include "priv.h" #include "priv.h"
#include <subdev/top.h>
#include <engine/falcon.h> #include <engine/falcon.h>
static int static int
nvkm_nvdec_oneinit(struct nvkm_engine *engine) nvkm_nvdec_oneinit(struct nvkm_engine *engine)
{ {
struct nvkm_nvdec *nvdec = nvkm_nvdec(engine); struct nvkm_nvdec *nvdec = nvkm_nvdec(engine);
return nvkm_falcon_v1_new(&nvdec->engine.subdev, "NVDEC", 0x84000, struct nvkm_subdev *subdev = &nvdec->engine.subdev;
nvdec->addr = nvkm_top_addr(subdev->device, subdev->index);
if (!nvdec->addr)
return -EINVAL;
/*XXX: fix naming of this when adding support for multiple-NVDEC */
return nvkm_falcon_v1_new(subdev, "NVDEC", nvdec->addr,
&nvdec->falcon); &nvdec->falcon);
} }
......
nvkm-y += nvkm/engine/sec2/base.o nvkm-y += nvkm/engine/sec2/base.o
nvkm-y += nvkm/engine/sec2/gp102.o nvkm-y += nvkm/engine/sec2/gp102.o
nvkm-y += nvkm/engine/sec2/tu102.o
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include "priv.h" #include "priv.h"
#include <core/msgqueue.h> #include <core/msgqueue.h>
#include <subdev/top.h>
#include <engine/falcon.h> #include <engine/falcon.h>
static void * static void *
...@@ -39,18 +40,18 @@ nvkm_sec2_intr(struct nvkm_engine *engine) ...@@ -39,18 +40,18 @@ nvkm_sec2_intr(struct nvkm_engine *engine)
struct nvkm_sec2 *sec2 = nvkm_sec2(engine); struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
struct nvkm_subdev *subdev = &engine->subdev; struct nvkm_subdev *subdev = &engine->subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
u32 disp = nvkm_rd32(device, 0x8701c); u32 disp = nvkm_rd32(device, sec2->addr + 0x01c);
u32 intr = nvkm_rd32(device, 0x87008) & disp & ~(disp >> 16); u32 intr = nvkm_rd32(device, sec2->addr + 0x008) & disp & ~(disp >> 16);
if (intr & 0x00000040) { if (intr & 0x00000040) {
schedule_work(&sec2->work); schedule_work(&sec2->work);
nvkm_wr32(device, 0x87004, 0x00000040); nvkm_wr32(device, sec2->addr + 0x004, 0x00000040);
intr &= ~0x00000040; intr &= ~0x00000040;
} }
if (intr) { if (intr) {
nvkm_error(subdev, "unhandled intr %08x\n", intr); nvkm_error(subdev, "unhandled intr %08x\n", intr);
nvkm_wr32(device, 0x87004, intr); nvkm_wr32(device, sec2->addr + 0x004, intr);
} }
} }
...@@ -74,8 +75,15 @@ static int ...@@ -74,8 +75,15 @@ static int
nvkm_sec2_oneinit(struct nvkm_engine *engine) nvkm_sec2_oneinit(struct nvkm_engine *engine)
{ {
struct nvkm_sec2 *sec2 = nvkm_sec2(engine); struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
return nvkm_falcon_v1_new(&sec2->engine.subdev, "SEC2", 0x87000, struct nvkm_subdev *subdev = &sec2->engine.subdev;
&sec2->falcon);
if (!sec2->addr) {
sec2->addr = nvkm_top_addr(subdev->device, subdev->index);
if (WARN_ON(!sec2->addr))
return -EINVAL;
}
return nvkm_falcon_v1_new(subdev, "SEC2", sec2->addr, &sec2->falcon);
} }
static int static int
...@@ -95,13 +103,14 @@ nvkm_sec2 = { ...@@ -95,13 +103,14 @@ nvkm_sec2 = {
}; };
int int
nvkm_sec2_new_(struct nvkm_device *device, int index, nvkm_sec2_new_(struct nvkm_device *device, int index, u32 addr,
struct nvkm_sec2 **psec2) struct nvkm_sec2 **psec2)
{ {
struct nvkm_sec2 *sec2; struct nvkm_sec2 *sec2;
if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL))) if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL)))
return -ENOMEM; return -ENOMEM;
sec2->addr = addr;
INIT_WORK(&sec2->work, nvkm_sec2_recv); INIT_WORK(&sec2->work, nvkm_sec2_recv);
return nvkm_engine_ctor(&nvkm_sec2, device, index, true, &sec2->engine); return nvkm_engine_ctor(&nvkm_sec2, device, index, true, &sec2->engine);
......
...@@ -26,5 +26,5 @@ int ...@@ -26,5 +26,5 @@ int
gp102_sec2_new(struct nvkm_device *device, int index, gp102_sec2_new(struct nvkm_device *device, int index,
struct nvkm_sec2 **psec2) struct nvkm_sec2 **psec2)
{ {
return nvkm_sec2_new_(device, index, psec2); return nvkm_sec2_new_(device, index, 0, psec2);
} }
...@@ -5,6 +5,5 @@ ...@@ -5,6 +5,5 @@
#define nvkm_sec2(p) container_of((p), struct nvkm_sec2, engine) #define nvkm_sec2(p) container_of((p), struct nvkm_sec2, engine)
int nvkm_sec2_new_(struct nvkm_device *, int, struct nvkm_sec2 **); int nvkm_sec2_new_(struct nvkm_device *, int, u32 addr, struct nvkm_sec2 **);
#endif #endif
/*
* Copyright 2019 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "priv.h"
int
tu102_sec2_new(struct nvkm_device *device, int index,
struct nvkm_sec2 **psec2)
{
/* TOP info wasn't updated on Turing to reflect the PRI
* address change for some reason. We override it here.
*/
return nvkm_sec2_new_(device, index, 0x840000, psec2);
}
...@@ -204,6 +204,9 @@ nvkm_falcon_ctor(const struct nvkm_falcon_func *func, ...@@ -204,6 +204,9 @@ nvkm_falcon_ctor(const struct nvkm_falcon_func *func,
debug_reg = 0x408; debug_reg = 0x408;
falcon->has_emem = true; falcon->has_emem = true;
break; break;
case NVKM_SUBDEV_GSP:
debug_reg = 0x0; /*XXX*/
break;
default: default:
nvkm_warn(subdev, "unsupported falcon %s!\n", nvkm_warn(subdev, "unsupported falcon %s!\n",
nvkm_subdev_name[subdev->index]); nvkm_subdev_name[subdev->index]);
......
...@@ -7,6 +7,7 @@ include $(src)/nvkm/subdev/fault/Kbuild ...@@ -7,6 +7,7 @@ include $(src)/nvkm/subdev/fault/Kbuild
include $(src)/nvkm/subdev/fb/Kbuild include $(src)/nvkm/subdev/fb/Kbuild
include $(src)/nvkm/subdev/fuse/Kbuild include $(src)/nvkm/subdev/fuse/Kbuild
include $(src)/nvkm/subdev/gpio/Kbuild include $(src)/nvkm/subdev/gpio/Kbuild
include $(src)/nvkm/subdev/gsp/Kbuild
include $(src)/nvkm/subdev/i2c/Kbuild include $(src)/nvkm/subdev/i2c/Kbuild
include $(src)/nvkm/subdev/ibus/Kbuild include $(src)/nvkm/subdev/ibus/Kbuild
include $(src)/nvkm/subdev/iccsense/Kbuild include $(src)/nvkm/subdev/iccsense/Kbuild
......
...@@ -5,4 +5,4 @@ nvkm-y += nvkm/subdev/bar/gf100.o ...@@ -5,4 +5,4 @@ nvkm-y += nvkm/subdev/bar/gf100.o
nvkm-y += nvkm/subdev/bar/gk20a.o nvkm-y += nvkm/subdev/bar/gk20a.o
nvkm-y += nvkm/subdev/bar/gm107.o nvkm-y += nvkm/subdev/bar/gm107.o
nvkm-y += nvkm/subdev/bar/gm20b.o nvkm-y += nvkm/subdev/bar/gm20b.o
nvkm-y += nvkm/subdev/bar/tu104.o nvkm-y += nvkm/subdev/bar/tu102.o
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#include <subdev/timer.h> #include <subdev/timer.h>
static void static void
tu104_bar_bar2_wait(struct nvkm_bar *bar) tu102_bar_bar2_wait(struct nvkm_bar *bar)
{ {
struct nvkm_device *device = bar->subdev.device; struct nvkm_device *device = bar->subdev.device;
nvkm_msec(device, 2000, nvkm_msec(device, 2000,
...@@ -35,13 +35,13 @@ tu104_bar_bar2_wait(struct nvkm_bar *bar) ...@@ -35,13 +35,13 @@ tu104_bar_bar2_wait(struct nvkm_bar *bar)
} }
static void static void
tu104_bar_bar2_fini(struct nvkm_bar *bar) tu102_bar_bar2_fini(struct nvkm_bar *bar)
{ {
nvkm_mask(bar->subdev.device, 0xb80f48, 0x80000000, 0x00000000); nvkm_mask(bar->subdev.device, 0xb80f48, 0x80000000, 0x00000000);
} }
static void static void
tu104_bar_bar2_init(struct nvkm_bar *base) tu102_bar_bar2_init(struct nvkm_bar *base)
{ {
struct nvkm_device *device = base->subdev.device; struct nvkm_device *device = base->subdev.device;
struct gf100_bar *bar = gf100_bar(base); struct gf100_bar *bar = gf100_bar(base);
...@@ -52,7 +52,7 @@ tu104_bar_bar2_init(struct nvkm_bar *base) ...@@ -52,7 +52,7 @@ tu104_bar_bar2_init(struct nvkm_bar *base)
} }
static void static void
tu104_bar_bar1_wait(struct nvkm_bar *bar) tu102_bar_bar1_wait(struct nvkm_bar *bar)
{ {
struct nvkm_device *device = bar->subdev.device; struct nvkm_device *device = bar->subdev.device;
nvkm_msec(device, 2000, nvkm_msec(device, 2000,
...@@ -62,13 +62,13 @@ tu104_bar_bar1_wait(struct nvkm_bar *bar) ...@@ -62,13 +62,13 @@ tu104_bar_bar1_wait(struct nvkm_bar *bar)
} }
static void static void
tu104_bar_bar1_fini(struct nvkm_bar *bar) tu102_bar_bar1_fini(struct nvkm_bar *bar)
{ {
nvkm_mask(bar->subdev.device, 0xb80f40, 0x80000000, 0x00000000); nvkm_mask(bar->subdev.device, 0xb80f40, 0x80000000, 0x00000000);
} }
static void static void
tu104_bar_bar1_init(struct nvkm_bar *base) tu102_bar_bar1_init(struct nvkm_bar *base)
{ {
struct nvkm_device *device = base->subdev.device; struct nvkm_device *device = base->subdev.device;
struct gf100_bar *bar = gf100_bar(base); struct gf100_bar *bar = gf100_bar(base);
...@@ -77,22 +77,22 @@ tu104_bar_bar1_init(struct nvkm_bar *base) ...@@ -77,22 +77,22 @@ tu104_bar_bar1_init(struct nvkm_bar *base)
} }
static const struct nvkm_bar_func static const struct nvkm_bar_func
tu104_bar = { tu102_bar = {
.dtor = gf100_bar_dtor, .dtor = gf100_bar_dtor,
.oneinit = gf100_bar_oneinit, .oneinit = gf100_bar_oneinit,
.bar1.init = tu104_bar_bar1_init, .bar1.init = tu102_bar_bar1_init,
.bar1.fini = tu104_bar_bar1_fini, .bar1.fini = tu102_bar_bar1_fini,
.bar1.wait = tu104_bar_bar1_wait, .bar1.wait = tu102_bar_bar1_wait,
.bar1.vmm = gf100_bar_bar1_vmm, .bar1.vmm = gf100_bar_bar1_vmm,
.bar2.init = tu104_bar_bar2_init, .bar2.init = tu102_bar_bar2_init,
.bar2.fini = tu104_bar_bar2_fini, .bar2.fini = tu102_bar_bar2_fini,
.bar2.wait = tu104_bar_bar2_wait, .bar2.wait = tu102_bar_bar2_wait,
.bar2.vmm = gf100_bar_bar2_vmm, .bar2.vmm = gf100_bar_bar2_vmm,
.flush = g84_bar_flush, .flush = g84_bar_flush,
}; };
int int
tu104_bar_new(struct nvkm_device *device, int index, struct nvkm_bar **pbar) tu102_bar_new(struct nvkm_device *device, int index, struct nvkm_bar **pbar)
{ {
return gf100_bar_new_(&tu104_bar, device, index, pbar); return gf100_bar_new_(&tu102_bar, device, index, pbar);
} }
...@@ -212,7 +212,7 @@ nvbios_dpcfg_match(struct nvkm_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe, ...@@ -212,7 +212,7 @@ nvbios_dpcfg_match(struct nvkm_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe,
u16 data; u16 data;
if (*ver >= 0x30) { if (*ver >= 0x30) {
const u8 vsoff[] = { 0, 4, 7, 9 }; static const u8 vsoff[] = { 0, 4, 7, 9 };
idx = (pc * 10) + vsoff[vs] + pe; idx = (pc * 10) + vsoff[vs] + pe;
if (*ver >= 0x40 && *ver <= 0x41 && *hdr >= 0x12) if (*ver >= 0x40 && *ver <= 0x41 && *hdr >= 0x12)
idx += nvbios_rd08(bios, outp + 0x11) * 40; idx += nvbios_rd08(bios, outp + 0x11) * 40;
......
...@@ -806,12 +806,12 @@ init_generic_condition(struct nvbios_init *init) ...@@ -806,12 +806,12 @@ init_generic_condition(struct nvbios_init *init)
init->offset += 3; init->offset += 3;
switch (cond) { switch (cond) {
case 0: case 0: /* CONDITION_ID_INT_DP. */
if (init_conn(init) != DCB_CONNECTOR_eDP) if (init_conn(init) != DCB_CONNECTOR_eDP)
init_exec_set(init, false); init_exec_set(init, false);
break; break;
case 1: case 1: /* CONDITION_ID_USE_SPPLL0. */
case 2: case 2: /* CONDITION_ID_USE_SPPLL1. */
if ( init->outp && if ( init->outp &&
(data = nvbios_dpout_match(bios, DCB_OUTPUT_DP, (data = nvbios_dpout_match(bios, DCB_OUTPUT_DP,
(init->outp->or << 0) | (init->outp->or << 0) |
...@@ -826,10 +826,13 @@ init_generic_condition(struct nvbios_init *init) ...@@ -826,10 +826,13 @@ init_generic_condition(struct nvbios_init *init)
if (init_exec(init)) if (init_exec(init))
warn("script needs dp output table data\n"); warn("script needs dp output table data\n");
break; break;
case 5: case 5: /* CONDITION_ID_ASSR_SUPPORT. */
if (!(init_rdauxr(init, 0x0d) & 1)) if (!(init_rdauxr(init, 0x0d) & 1))
init_exec_set(init, false); init_exec_set(init, false);
break; break;
case 7: /* CONDITION_ID_NO_PANEL_SEQ_DELAYS. */
init_exec_set(init, false);
break;
default: default:
warn("INIT_GENERIC_CONDITON: unknown 0x%02x\n", cond); warn("INIT_GENERIC_CONDITON: unknown 0x%02x\n", cond);
init->offset += size; init->offset += size;
......
...@@ -13,4 +13,4 @@ nvkm-y += nvkm/subdev/devinit/gf100.o ...@@ -13,4 +13,4 @@ nvkm-y += nvkm/subdev/devinit/gf100.o
nvkm-y += nvkm/subdev/devinit/gm107.o nvkm-y += nvkm/subdev/devinit/gm107.o
nvkm-y += nvkm/subdev/devinit/gm200.o nvkm-y += nvkm/subdev/devinit/gm200.o
nvkm-y += nvkm/subdev/devinit/gv100.o nvkm-y += nvkm/subdev/devinit/gv100.o
nvkm-y += nvkm/subdev/devinit/tu104.o nvkm-y += nvkm/subdev/devinit/tu102.o
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#include <subdev/clk/pll.h> #include <subdev/clk/pll.h>
static int static int
tu104_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) tu102_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
{ {
struct nvkm_subdev *subdev = &init->subdev; struct nvkm_subdev *subdev = &init->subdev;
struct nvkm_device *device = subdev->device; struct nvkm_device *device = subdev->device;
...@@ -66,7 +66,7 @@ tu104_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq) ...@@ -66,7 +66,7 @@ tu104_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
} }
static int static int
tu104_devinit_post(struct nvkm_devinit *base, bool post) tu102_devinit_post(struct nvkm_devinit *base, bool post)
{ {
struct nv50_devinit *init = nv50_devinit(base); struct nv50_devinit *init = nv50_devinit(base);
gm200_devinit_preos(init, post); gm200_devinit_preos(init, post);
...@@ -74,16 +74,16 @@ tu104_devinit_post(struct nvkm_devinit *base, bool post) ...@@ -74,16 +74,16 @@ tu104_devinit_post(struct nvkm_devinit *base, bool post)
} }
static const struct nvkm_devinit_func static const struct nvkm_devinit_func
tu104_devinit = { tu102_devinit = {
.init = nv50_devinit_init, .init = nv50_devinit_init,
.post = tu104_devinit_post, .post = tu102_devinit_post,
.pll_set = tu104_devinit_pll_set, .pll_set = tu102_devinit_pll_set,
.disable = gm107_devinit_disable, .disable = gm107_devinit_disable,
}; };
int int
tu104_devinit_new(struct nvkm_device *device, int index, tu102_devinit_new(struct nvkm_device *device, int index,
struct nvkm_devinit **pinit) struct nvkm_devinit **pinit)
{ {
return nv50_devinit_new_(&tu104_devinit, device, index, pinit); return nv50_devinit_new_(&tu102_devinit, device, index, pinit);
} }
nvkm-y += nvkm/subdev/fault/base.o nvkm-y += nvkm/subdev/fault/base.o
nvkm-y += nvkm/subdev/fault/user.o
nvkm-y += nvkm/subdev/fault/gp100.o nvkm-y += nvkm/subdev/fault/gp100.o
nvkm-y += nvkm/subdev/fault/gv100.o nvkm-y += nvkm/subdev/fault/gv100.o
nvkm-y += nvkm/subdev/fault/tu104.o nvkm-y += nvkm/subdev/fault/tu102.o
...@@ -176,5 +176,7 @@ nvkm_fault_new_(const struct nvkm_fault_func *func, struct nvkm_device *device, ...@@ -176,5 +176,7 @@ nvkm_fault_new_(const struct nvkm_fault_func *func, struct nvkm_device *device,
return -ENOMEM; return -ENOMEM;
nvkm_subdev_ctor(&nvkm_fault, device, index, &fault->subdev); nvkm_subdev_ctor(&nvkm_fault, device, index, &fault->subdev);
fault->func = func; fault->func = func;
fault->user.ctor = nvkm_ufault_new;
fault->user.base = func->user.base;
return 0; return 0;
} }
...@@ -23,6 +23,8 @@ ...@@ -23,6 +23,8 @@
#include <subdev/mc.h> #include <subdev/mc.h>
#include <nvif/class.h>
static void static void
gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable) gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
{ {
...@@ -69,6 +71,7 @@ gp100_fault = { ...@@ -69,6 +71,7 @@ gp100_fault = {
.buffer.init = gp100_fault_buffer_init, .buffer.init = gp100_fault_buffer_init,
.buffer.fini = gp100_fault_buffer_fini, .buffer.fini = gp100_fault_buffer_fini,
.buffer.intr = gp100_fault_buffer_intr, .buffer.intr = gp100_fault_buffer_intr,
.user = { { 0, 0, MAXWELL_FAULT_BUFFER_A }, 0 },
}; };
int int
......
...@@ -25,6 +25,8 @@ ...@@ -25,6 +25,8 @@
#include <subdev/mmu.h> #include <subdev/mmu.h>
#include <engine/fifo.h> #include <engine/fifo.h>
#include <nvif/class.h>
static void static void
gv100_fault_buffer_process(struct nvkm_fault_buffer *buffer) gv100_fault_buffer_process(struct nvkm_fault_buffer *buffer)
{ {
...@@ -166,6 +168,13 @@ gv100_fault_intr(struct nvkm_fault *fault) ...@@ -166,6 +168,13 @@ gv100_fault_intr(struct nvkm_fault *fault)
} }
} }
if (stat & 0x08000000) {
if (fault->buffer[1]) {
nvkm_event_send(&fault->event, 1, 1, NULL, 0);
stat &= ~0x08000000;
}
}
if (stat) { if (stat) {
nvkm_debug(subdev, "intr %08x\n", stat); nvkm_debug(subdev, "intr %08x\n", stat);
} }
...@@ -208,6 +217,13 @@ gv100_fault = { ...@@ -208,6 +217,13 @@ gv100_fault = {
.buffer.init = gv100_fault_buffer_init, .buffer.init = gv100_fault_buffer_init,
.buffer.fini = gv100_fault_buffer_fini, .buffer.fini = gv100_fault_buffer_fini,
.buffer.intr = gv100_fault_buffer_intr, .buffer.intr = gv100_fault_buffer_intr,
/*TODO: Figure out how to expose non-replayable fault buffer, which,
* for some reason, is where recoverable CE faults appear...
*
* It's a bit tricky, as both NVKM and SVM will need access to
* the non-replayable fault buffer.
*/
.user = { { 0, 0, VOLTA_FAULT_BUFFER_A }, 1 },
}; };
int int
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment