提交 02e546ea 编写于 作者: D Dave Airlie

Merge branch 'linux-4.18' of git://github.com/skeggsb/linux into drm-fixes

- fix problem with pascal and large memory systems
- fix a bunch of MST problems
- fix a runtime PM interaction with MST
Signed-off-by: NDave Airlie <airlied@redhat.com>
Link: https://patchwork.freedesktop.org/patch/msgid/CACAvsv79O8deSts2fxJ_oS6=q8yA+OgwBSEpp5R=BQBmWa+oyg@mail.gmail.com
...@@ -55,6 +55,9 @@ nv04_display_create(struct drm_device *dev) ...@@ -55,6 +55,9 @@ nv04_display_create(struct drm_device *dev)
nouveau_display(dev)->init = nv04_display_init; nouveau_display(dev)->init = nv04_display_init;
nouveau_display(dev)->fini = nv04_display_fini; nouveau_display(dev)->fini = nv04_display_fini;
/* Pre-nv50 doesn't support atomic, so don't expose the ioctls */
dev->driver->driver_features &= ~DRIVER_ATOMIC;
nouveau_hw_save_vga_fonts(dev, 1); nouveau_hw_save_vga_fonts(dev, 1);
nv04_crtc_create(dev, 0); nv04_crtc_create(dev, 0);
......
...@@ -1585,8 +1585,9 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe) ...@@ -1585,8 +1585,9 @@ nv50_pior_create(struct drm_connector *connector, struct dcb_output *dcbe)
*****************************************************************************/ *****************************************************************************/
static void static void
nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 *interlock) nv50_disp_atomic_commit_core(struct drm_atomic_state *state, u32 *interlock)
{ {
struct nouveau_drm *drm = nouveau_drm(state->dev);
struct nv50_disp *disp = nv50_disp(drm->dev); struct nv50_disp *disp = nv50_disp(drm->dev);
struct nv50_core *core = disp->core; struct nv50_core *core = disp->core;
struct nv50_mstm *mstm; struct nv50_mstm *mstm;
...@@ -1617,6 +1618,22 @@ nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 *interlock) ...@@ -1617,6 +1618,22 @@ nv50_disp_atomic_commit_core(struct nouveau_drm *drm, u32 *interlock)
} }
} }
static void
nv50_disp_atomic_commit_wndw(struct drm_atomic_state *state, u32 *interlock)
{
struct drm_plane_state *new_plane_state;
struct drm_plane *plane;
int i;
for_each_new_plane_in_state(state, plane, new_plane_state, i) {
struct nv50_wndw *wndw = nv50_wndw(plane);
if (interlock[wndw->interlock.type] & wndw->interlock.data) {
if (wndw->func->update)
wndw->func->update(wndw, interlock);
}
}
}
static void static void
nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
{ {
...@@ -1684,7 +1701,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -1684,7 +1701,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
help->disable(encoder); help->disable(encoder);
interlock[NV50_DISP_INTERLOCK_CORE] |= 1; interlock[NV50_DISP_INTERLOCK_CORE] |= 1;
if (outp->flush_disable) { if (outp->flush_disable) {
nv50_disp_atomic_commit_core(drm, interlock); nv50_disp_atomic_commit_wndw(state, interlock);
nv50_disp_atomic_commit_core(state, interlock);
memset(interlock, 0x00, sizeof(interlock)); memset(interlock, 0x00, sizeof(interlock));
} }
} }
...@@ -1693,15 +1711,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -1693,15 +1711,8 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
/* Flush disable. */ /* Flush disable. */
if (interlock[NV50_DISP_INTERLOCK_CORE]) { if (interlock[NV50_DISP_INTERLOCK_CORE]) {
if (atom->flush_disable) { if (atom->flush_disable) {
for_each_new_plane_in_state(state, plane, new_plane_state, i) { nv50_disp_atomic_commit_wndw(state, interlock);
struct nv50_wndw *wndw = nv50_wndw(plane); nv50_disp_atomic_commit_core(state, interlock);
if (interlock[wndw->interlock.type] & wndw->interlock.data) {
if (wndw->func->update)
wndw->func->update(wndw, interlock);
}
}
nv50_disp_atomic_commit_core(drm, interlock);
memset(interlock, 0x00, sizeof(interlock)); memset(interlock, 0x00, sizeof(interlock));
} }
} }
...@@ -1762,18 +1773,14 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state) ...@@ -1762,18 +1773,14 @@ nv50_disp_atomic_commit_tail(struct drm_atomic_state *state)
} }
/* Flush update. */ /* Flush update. */
for_each_new_plane_in_state(state, plane, new_plane_state, i) { nv50_disp_atomic_commit_wndw(state, interlock);
struct nv50_wndw *wndw = nv50_wndw(plane);
if (interlock[wndw->interlock.type] & wndw->interlock.data) {
if (wndw->func->update)
wndw->func->update(wndw, interlock);
}
}
if (interlock[NV50_DISP_INTERLOCK_CORE]) { if (interlock[NV50_DISP_INTERLOCK_CORE]) {
if (interlock[NV50_DISP_INTERLOCK_BASE] || if (interlock[NV50_DISP_INTERLOCK_BASE] ||
interlock[NV50_DISP_INTERLOCK_OVLY] ||
interlock[NV50_DISP_INTERLOCK_WNDW] ||
!atom->state.legacy_cursor_update) !atom->state.legacy_cursor_update)
nv50_disp_atomic_commit_core(drm, interlock); nv50_disp_atomic_commit_core(state, interlock);
else else
disp->core->func->update(disp->core, interlock, false); disp->core->func->update(disp->core, interlock, false);
} }
...@@ -1871,7 +1878,7 @@ nv50_disp_atomic_commit(struct drm_device *dev, ...@@ -1871,7 +1878,7 @@ nv50_disp_atomic_commit(struct drm_device *dev,
nv50_disp_atomic_commit_tail(state); nv50_disp_atomic_commit_tail(state);
drm_for_each_crtc(crtc, dev) { drm_for_each_crtc(crtc, dev) {
if (crtc->state->enable) { if (crtc->state->active) {
if (!drm->have_disp_power_ref) { if (!drm->have_disp_power_ref) {
drm->have_disp_power_ref = true; drm->have_disp_power_ref = true;
return 0; return 0;
...@@ -2119,10 +2126,6 @@ nv50_display_destroy(struct drm_device *dev) ...@@ -2119,10 +2126,6 @@ nv50_display_destroy(struct drm_device *dev)
kfree(disp); kfree(disp);
} }
MODULE_PARM_DESC(atomic, "Expose atomic ioctl (default: disabled)");
static int nouveau_atomic = 0;
module_param_named(atomic, nouveau_atomic, int, 0400);
int int
nv50_display_create(struct drm_device *dev) nv50_display_create(struct drm_device *dev)
{ {
...@@ -2147,8 +2150,6 @@ nv50_display_create(struct drm_device *dev) ...@@ -2147,8 +2150,6 @@ nv50_display_create(struct drm_device *dev)
disp->disp = &nouveau_display(dev)->disp; disp->disp = &nouveau_display(dev)->disp;
dev->mode_config.funcs = &nv50_disp_func; dev->mode_config.funcs = &nv50_disp_func;
dev->driver->driver_features |= DRIVER_PREFER_XBGR_30BPP; dev->driver->driver_features |= DRIVER_PREFER_XBGR_30BPP;
if (nouveau_atomic)
dev->driver->driver_features |= DRIVER_ATOMIC;
/* small shared memory area we use for notifiers and semaphores */ /* small shared memory area we use for notifiers and semaphores */
ret = nouveau_bo_new(&drm->client, 4096, 0x1000, TTM_PL_FLAG_VRAM, ret = nouveau_bo_new(&drm->client, 4096, 0x1000, TTM_PL_FLAG_VRAM,
......
...@@ -267,6 +267,7 @@ nouveau_backlight_init(struct drm_device *dev) ...@@ -267,6 +267,7 @@ nouveau_backlight_init(struct drm_device *dev)
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nvif_device *device = &drm->client.device; struct nvif_device *device = &drm->client.device;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
INIT_LIST_HEAD(&drm->bl_connectors); INIT_LIST_HEAD(&drm->bl_connectors);
...@@ -275,7 +276,8 @@ nouveau_backlight_init(struct drm_device *dev) ...@@ -275,7 +276,8 @@ nouveau_backlight_init(struct drm_device *dev)
return 0; return 0;
} }
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_connector_list_iter_begin(dev, &conn_iter);
drm_for_each_connector_iter(connector, &conn_iter) {
if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS &&
connector->connector_type != DRM_MODE_CONNECTOR_eDP) connector->connector_type != DRM_MODE_CONNECTOR_eDP)
continue; continue;
...@@ -292,7 +294,7 @@ nouveau_backlight_init(struct drm_device *dev) ...@@ -292,7 +294,7 @@ nouveau_backlight_init(struct drm_device *dev)
break; break;
} }
} }
drm_connector_list_iter_end(&conn_iter);
return 0; return 0;
} }
......
...@@ -1208,14 +1208,19 @@ nouveau_connector_create(struct drm_device *dev, int index) ...@@ -1208,14 +1208,19 @@ nouveau_connector_create(struct drm_device *dev, int index)
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_connector *nv_connector = NULL; struct nouveau_connector *nv_connector = NULL;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
int type, ret = 0; int type, ret = 0;
bool dummy; bool dummy;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
nv_connector = nouveau_connector(connector); nv_connector = nouveau_connector(connector);
if (nv_connector->index == index) if (nv_connector->index == index) {
drm_connector_list_iter_end(&conn_iter);
return connector; return connector;
}
} }
drm_connector_list_iter_end(&conn_iter);
nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL);
if (!nv_connector) if (!nv_connector)
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include <drm/drm_encoder.h> #include <drm/drm_encoder.h>
#include <drm/drm_dp_helper.h> #include <drm/drm_dp_helper.h>
#include "nouveau_crtc.h" #include "nouveau_crtc.h"
#include "nouveau_encoder.h"
struct nvkm_i2c_port; struct nvkm_i2c_port;
...@@ -60,19 +61,46 @@ static inline struct nouveau_connector *nouveau_connector( ...@@ -60,19 +61,46 @@ static inline struct nouveau_connector *nouveau_connector(
return container_of(con, struct nouveau_connector, base); return container_of(con, struct nouveau_connector, base);
} }
static inline bool
nouveau_connector_is_mst(struct drm_connector *connector)
{
const struct nouveau_encoder *nv_encoder;
const struct drm_encoder *encoder;
if (connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort)
return false;
nv_encoder = find_encoder(connector, DCB_OUTPUT_ANY);
if (!nv_encoder)
return false;
encoder = &nv_encoder->base.base;
return encoder->encoder_type == DRM_MODE_ENCODER_DPMST;
}
#define nouveau_for_each_non_mst_connector_iter(connector, iter) \
drm_for_each_connector_iter(connector, iter) \
for_each_if(!nouveau_connector_is_mst(connector))
static inline struct nouveau_connector * static inline struct nouveau_connector *
nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc)
{ {
struct drm_device *dev = nv_crtc->base.dev; struct drm_device *dev = nv_crtc->base.dev;
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
struct nouveau_connector *nv_connector = NULL;
struct drm_crtc *crtc = to_drm_crtc(nv_crtc); struct drm_crtc *crtc = to_drm_crtc(nv_crtc);
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_connector_list_iter_begin(dev, &conn_iter);
if (connector->encoder && connector->encoder->crtc == crtc) nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
return nouveau_connector(connector); if (connector->encoder && connector->encoder->crtc == crtc) {
nv_connector = nouveau_connector(connector);
break;
}
} }
drm_connector_list_iter_end(&conn_iter);
return NULL; return nv_connector;
} }
struct drm_connector * struct drm_connector *
......
...@@ -404,6 +404,7 @@ nouveau_display_init(struct drm_device *dev) ...@@ -404,6 +404,7 @@ nouveau_display_init(struct drm_device *dev)
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
int ret; int ret;
ret = disp->init(dev); ret = disp->init(dev);
...@@ -411,10 +412,12 @@ nouveau_display_init(struct drm_device *dev) ...@@ -411,10 +412,12 @@ nouveau_display_init(struct drm_device *dev)
return ret; return ret;
/* enable hotplug interrupts */ /* enable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
struct nouveau_connector *conn = nouveau_connector(connector); struct nouveau_connector *conn = nouveau_connector(connector);
nvif_notify_get(&conn->hpd); nvif_notify_get(&conn->hpd);
} }
drm_connector_list_iter_end(&conn_iter);
/* enable flip completion events */ /* enable flip completion events */
nvif_notify_get(&drm->flip); nvif_notify_get(&drm->flip);
...@@ -427,6 +430,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend) ...@@ -427,6 +430,7 @@ nouveau_display_fini(struct drm_device *dev, bool suspend)
struct nouveau_display *disp = nouveau_display(dev); struct nouveau_display *disp = nouveau_display(dev);
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct drm_connector *connector; struct drm_connector *connector;
struct drm_connector_list_iter conn_iter;
if (!suspend) { if (!suspend) {
if (drm_drv_uses_atomic_modeset(dev)) if (drm_drv_uses_atomic_modeset(dev))
...@@ -439,10 +443,12 @@ nouveau_display_fini(struct drm_device *dev, bool suspend) ...@@ -439,10 +443,12 @@ nouveau_display_fini(struct drm_device *dev, bool suspend)
nvif_notify_put(&drm->flip); nvif_notify_put(&drm->flip);
/* disable hotplug interrupts */ /* disable hotplug interrupts */
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { drm_connector_list_iter_begin(dev, &conn_iter);
nouveau_for_each_non_mst_connector_iter(connector, &conn_iter) {
struct nouveau_connector *conn = nouveau_connector(connector); struct nouveau_connector *conn = nouveau_connector(connector);
nvif_notify_put(&conn->hpd); nvif_notify_put(&conn->hpd);
} }
drm_connector_list_iter_end(&conn_iter);
drm_kms_helper_poll_disable(dev); drm_kms_helper_poll_disable(dev);
disp->fini(dev); disp->fini(dev);
......
...@@ -81,6 +81,10 @@ MODULE_PARM_DESC(modeset, "enable driver (default: auto, " ...@@ -81,6 +81,10 @@ MODULE_PARM_DESC(modeset, "enable driver (default: auto, "
int nouveau_modeset = -1; int nouveau_modeset = -1;
module_param_named(modeset, nouveau_modeset, int, 0400); module_param_named(modeset, nouveau_modeset, int, 0400);
MODULE_PARM_DESC(atomic, "Expose atomic ioctl (default: disabled)");
static int nouveau_atomic = 0;
module_param_named(atomic, nouveau_atomic, int, 0400);
MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1)"); MODULE_PARM_DESC(runpm, "disable (0), force enable (1), optimus only default (-1)");
static int nouveau_runtime_pm = -1; static int nouveau_runtime_pm = -1;
module_param_named(runpm, nouveau_runtime_pm, int, 0400); module_param_named(runpm, nouveau_runtime_pm, int, 0400);
...@@ -509,6 +513,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev, ...@@ -509,6 +513,9 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
pci_set_master(pdev); pci_set_master(pdev);
if (nouveau_atomic)
driver_pci.driver_features |= DRIVER_ATOMIC;
ret = drm_get_pci_dev(pdev, pent, &driver_pci); ret = drm_get_pci_dev(pdev, pent, &driver_pci);
if (ret) { if (ret) {
nvkm_device_del(&device); nvkm_device_del(&device);
...@@ -874,22 +881,11 @@ nouveau_pmops_runtime_resume(struct device *dev) ...@@ -874,22 +881,11 @@ nouveau_pmops_runtime_resume(struct device *dev)
static int static int
nouveau_pmops_runtime_idle(struct device *dev) nouveau_pmops_runtime_idle(struct device *dev)
{ {
struct pci_dev *pdev = to_pci_dev(dev);
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct nouveau_drm *drm = nouveau_drm(drm_dev);
struct drm_crtc *crtc;
if (!nouveau_pmops_runtime()) { if (!nouveau_pmops_runtime()) {
pm_runtime_forbid(dev); pm_runtime_forbid(dev);
return -EBUSY; return -EBUSY;
} }
list_for_each_entry(crtc, &drm->dev->mode_config.crtc_list, head) {
if (crtc->enabled) {
DRM_DEBUG_DRIVER("failing to power off - crtc active\n");
return -EBUSY;
}
}
pm_runtime_mark_last_busy(dev); pm_runtime_mark_last_busy(dev);
pm_runtime_autosuspend(dev); pm_runtime_autosuspend(dev);
/* we don't want the main rpm_idle to call suspend - we want to autosuspend */ /* we don't want the main rpm_idle to call suspend - we want to autosuspend */
......
...@@ -616,7 +616,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, ...@@ -616,7 +616,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
struct nouveau_bo *nvbo; struct nouveau_bo *nvbo;
uint32_t data; uint32_t data;
if (unlikely(r->bo_index > req->nr_buffers)) { if (unlikely(r->bo_index >= req->nr_buffers)) {
NV_PRINTK(err, cli, "reloc bo index invalid\n"); NV_PRINTK(err, cli, "reloc bo index invalid\n");
ret = -EINVAL; ret = -EINVAL;
break; break;
...@@ -626,7 +626,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, ...@@ -626,7 +626,7 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
if (b->presumed.valid) if (b->presumed.valid)
continue; continue;
if (unlikely(r->reloc_bo_index > req->nr_buffers)) { if (unlikely(r->reloc_bo_index >= req->nr_buffers)) {
NV_PRINTK(err, cli, "reloc container bo index invalid\n"); NV_PRINTK(err, cli, "reloc container bo index invalid\n");
ret = -EINVAL; ret = -EINVAL;
break; break;
......
...@@ -140,6 +140,9 @@ nvkm_fb_init(struct nvkm_subdev *subdev) ...@@ -140,6 +140,9 @@ nvkm_fb_init(struct nvkm_subdev *subdev)
if (fb->func->init) if (fb->func->init)
fb->func->init(fb); fb->func->init(fb);
if (fb->func->init_remapper)
fb->func->init_remapper(fb);
if (fb->func->init_page) { if (fb->func->init_page) {
ret = fb->func->init_page(fb); ret = fb->func->init_page(fb);
if (WARN_ON(ret)) if (WARN_ON(ret))
......
...@@ -36,6 +36,14 @@ gp100_fb_init_unkn(struct nvkm_fb *base) ...@@ -36,6 +36,14 @@ gp100_fb_init_unkn(struct nvkm_fb *base)
nvkm_wr32(device, 0x1faccc, nvkm_rd32(device, 0x100ccc)); nvkm_wr32(device, 0x1faccc, nvkm_rd32(device, 0x100ccc));
} }
void
gp100_fb_init_remapper(struct nvkm_fb *fb)
{
struct nvkm_device *device = fb->subdev.device;
/* Disable address remapper. */
nvkm_mask(device, 0x100c14, 0x00040000, 0x00000000);
}
void void
gp100_fb_init(struct nvkm_fb *base) gp100_fb_init(struct nvkm_fb *base)
{ {
...@@ -56,6 +64,7 @@ gp100_fb = { ...@@ -56,6 +64,7 @@ gp100_fb = {
.dtor = gf100_fb_dtor, .dtor = gf100_fb_dtor,
.oneinit = gf100_fb_oneinit, .oneinit = gf100_fb_oneinit,
.init = gp100_fb_init, .init = gp100_fb_init,
.init_remapper = gp100_fb_init_remapper,
.init_page = gm200_fb_init_page, .init_page = gm200_fb_init_page,
.init_unkn = gp100_fb_init_unkn, .init_unkn = gp100_fb_init_unkn,
.ram_new = gp100_ram_new, .ram_new = gp100_ram_new,
......
...@@ -31,6 +31,7 @@ gp102_fb = { ...@@ -31,6 +31,7 @@ gp102_fb = {
.dtor = gf100_fb_dtor, .dtor = gf100_fb_dtor,
.oneinit = gf100_fb_oneinit, .oneinit = gf100_fb_oneinit,
.init = gp100_fb_init, .init = gp100_fb_init,
.init_remapper = gp100_fb_init_remapper,
.init_page = gm200_fb_init_page, .init_page = gm200_fb_init_page,
.ram_new = gp100_ram_new, .ram_new = gp100_ram_new,
}; };
......
...@@ -11,6 +11,7 @@ struct nvkm_fb_func { ...@@ -11,6 +11,7 @@ struct nvkm_fb_func {
u32 (*tags)(struct nvkm_fb *); u32 (*tags)(struct nvkm_fb *);
int (*oneinit)(struct nvkm_fb *); int (*oneinit)(struct nvkm_fb *);
void (*init)(struct nvkm_fb *); void (*init)(struct nvkm_fb *);
void (*init_remapper)(struct nvkm_fb *);
int (*init_page)(struct nvkm_fb *); int (*init_page)(struct nvkm_fb *);
void (*init_unkn)(struct nvkm_fb *); void (*init_unkn)(struct nvkm_fb *);
void (*intr)(struct nvkm_fb *); void (*intr)(struct nvkm_fb *);
...@@ -69,5 +70,6 @@ int gf100_fb_init_page(struct nvkm_fb *); ...@@ -69,5 +70,6 @@ int gf100_fb_init_page(struct nvkm_fb *);
int gm200_fb_init_page(struct nvkm_fb *); int gm200_fb_init_page(struct nvkm_fb *);
void gp100_fb_init_remapper(struct nvkm_fb *);
void gp100_fb_init_unkn(struct nvkm_fb *); void gp100_fb_init_unkn(struct nvkm_fb *);
#endif #endif
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册