Commit dd22dfa6 authored by Dave Airlie's avatar Dave Airlie

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

- Rewrite of the ACR (formerly "secure boot") code, both to support
Turing, support multiple FW revisions, and to make life easier when
having to debug HW/FW bring-up in the future
- Support for TU10x graphics engine, TU11x not available yet as FW isn't ready
- Proper page 'kind' mappings for Turing
- 10-bit LUT support
- GP10B (Tegra) fixes
- Misc other fixes
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
From: Ben Skeggs <skeggsb@gmail.com>
Link: https://patchwork.freedesktop.org/patch/msgid/ <CACAvsv5GKasg9-hEUwp9+aHVJg+nbQ0LukXyudgj6=YKu96jWQ@mail.gmail.com
parents 6fc376f0 afa3b96b
......@@ -54,7 +54,7 @@ static void
nv04_calc_arb(struct nv_fifo_info *fifo, struct nv_sim_state *arb)
{
int pagemiss, cas, width, bpp;
int nvclks, mclks, pclks, crtpagemiss;
int nvclks, mclks, crtpagemiss;
int found, mclk_extra, mclk_loop, cbs, m1, p1;
int mclk_freq, pclk_freq, nvclk_freq;
int us_m, us_n, us_p, crtc_drain_rate;
......@@ -69,7 +69,6 @@ nv04_calc_arb(struct nv_fifo_info *fifo, struct nv_sim_state *arb)
bpp = arb->bpp;
cbs = 128;
pclks = 2;
nvclks = 10;
mclks = 13 + cas;
mclk_extra = 3;
......
......@@ -644,16 +644,13 @@ static int nv17_tv_create_resources(struct drm_encoder *encoder,
int i;
if (nouveau_tv_norm) {
for (i = 0; i < num_tv_norms; i++) {
if (!strcmp(nv17_tv_norm_names[i], nouveau_tv_norm)) {
tv_enc->tv_norm = i;
break;
}
}
if (i == num_tv_norms)
i = match_string(nv17_tv_norm_names, num_tv_norms,
nouveau_tv_norm);
if (i < 0)
NV_WARN(drm, "Invalid TV norm setting \"%s\"\n",
nouveau_tv_norm);
else
tv_enc->tv_norm = i;
}
drm_mode_create_tv_properties(dev, num_tv_norms, nv17_tv_norm_names);
......
......@@ -75,12 +75,16 @@ base907c_xlut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
}
}
static void
base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
static bool
base907c_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
{
asyw->xlut.i.mode = 7;
if (size != 256 && size != 1024)
return false;
asyw->xlut.i.mode = size == 1024 ? 4 : 7;
asyw->xlut.i.enable = 2;
asyw->xlut.i.load = head907d_olut_load;
return true;
}
static inline u32
......@@ -160,6 +164,7 @@ base907c = {
.csc_set = base907c_csc_set,
.csc_clr = base907c_csc_clr,
.olut_core = true,
.ilut_size = 1024,
.xlut_set = base907c_xlut_set,
.xlut_clr = base907c_xlut_clr,
.image_set = base907c_image_set,
......
......@@ -660,7 +660,6 @@ struct nv50_mstm {
struct nouveau_encoder *outp;
struct drm_dp_mst_topology_mgr mgr;
struct nv50_msto *msto[4];
bool modified;
bool disabled;
......@@ -726,7 +725,6 @@ nv50_msto_cleanup(struct nv50_msto *msto)
drm_dp_mst_deallocate_vcpi(&mstm->mgr, mstc->port);
msto->mstc = NULL;
msto->head = NULL;
msto->disabled = false;
}
......@@ -872,7 +870,6 @@ nv50_msto_enable(struct drm_encoder *encoder)
mstm->outp->update(mstm->outp, head->base.index, armh, proto,
nv50_dp_bpc_to_depth(armh->or.bpc));
msto->head = head;
msto->mstc = mstc;
mstm->modified = true;
}
......@@ -913,45 +910,40 @@ nv50_msto = {
.destroy = nv50_msto_destroy,
};
static int
nv50_msto_new(struct drm_device *dev, u32 heads, const char *name, int id,
struct nv50_msto **pmsto)
static struct nv50_msto *
nv50_msto_new(struct drm_device *dev, struct nv50_head *head, int id)
{
struct nv50_msto *msto;
int ret;
if (!(msto = *pmsto = kzalloc(sizeof(*msto), GFP_KERNEL)))
return -ENOMEM;
msto = kzalloc(sizeof(*msto), GFP_KERNEL);
if (!msto)
return ERR_PTR(-ENOMEM);
ret = drm_encoder_init(dev, &msto->encoder, &nv50_msto,
DRM_MODE_ENCODER_DPMST, "%s-mst-%d", name, id);
DRM_MODE_ENCODER_DPMST, "mst-%d", id);
if (ret) {
kfree(*pmsto);
*pmsto = NULL;
return ret;
kfree(msto);
return ERR_PTR(ret);
}
drm_encoder_helper_add(&msto->encoder, &nv50_msto_help);
msto->encoder.possible_crtcs = heads;
return 0;
msto->encoder.possible_crtcs = drm_crtc_mask(&head->base.base);
msto->head = head;
return msto;
}
static struct drm_encoder *
nv50_mstc_atomic_best_encoder(struct drm_connector *connector,
struct drm_connector_state *connector_state)
{
struct nv50_head *head = nv50_head(connector_state->crtc);
struct nv50_mstc *mstc = nv50_mstc(connector);
struct drm_crtc *crtc = connector_state->crtc;
return &mstc->mstm->msto[head->base.index]->encoder;
}
static struct drm_encoder *
nv50_mstc_best_encoder(struct drm_connector *connector)
{
struct nv50_mstc *mstc = nv50_mstc(connector);
if (!(mstc->mstm->outp->dcb->heads & drm_crtc_mask(crtc)))
return NULL;
return &mstc->mstm->msto[0]->encoder;
return &nv50_head(crtc)->msto->encoder;
}
static enum drm_mode_status
......@@ -1038,7 +1030,6 @@ static const struct drm_connector_helper_funcs
nv50_mstc_help = {
.get_modes = nv50_mstc_get_modes,
.mode_valid = nv50_mstc_mode_valid,
.best_encoder = nv50_mstc_best_encoder,
.atomic_best_encoder = nv50_mstc_atomic_best_encoder,
.atomic_check = nv50_mstc_atomic_check,
.detect_ctx = nv50_mstc_detect,
......@@ -1071,8 +1062,9 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
const char *path, struct nv50_mstc **pmstc)
{
struct drm_device *dev = mstm->outp->base.base.dev;
struct drm_crtc *crtc;
struct nv50_mstc *mstc;
int ret, i;
int ret;
if (!(mstc = *pmstc = kzalloc(sizeof(*mstc), GFP_KERNEL)))
return -ENOMEM;
......@@ -1092,8 +1084,13 @@ nv50_mstc_new(struct nv50_mstm *mstm, struct drm_dp_mst_port *port,
mstc->connector.funcs->reset(&mstc->connector);
nouveau_conn_attach_properties(&mstc->connector);
for (i = 0; i < ARRAY_SIZE(mstm->msto) && mstm->msto[i]; i++)
drm_connector_attach_encoder(&mstc->connector, &mstm->msto[i]->encoder);
drm_for_each_crtc(crtc, dev) {
if (!(mstm->outp->dcb->heads & drm_crtc_mask(crtc)))
continue;
drm_connector_attach_encoder(&mstc->connector,
&nv50_head(crtc)->msto->encoder);
}
drm_object_attach_property(&mstc->connector.base, dev->mode_config.path_property, 0);
drm_object_attach_property(&mstc->connector.base, dev->mode_config.tile_property, 0);
......@@ -1367,7 +1364,7 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
const int max_payloads = hweight8(outp->dcb->heads);
struct drm_device *dev = outp->base.base.dev;
struct nv50_mstm *mstm;
int ret, i;
int ret;
u8 dpcd;
/* This is a workaround for some monitors not functioning
......@@ -1390,13 +1387,6 @@ nv50_mstm_new(struct nouveau_encoder *outp, struct drm_dp_aux *aux, int aux_max,
if (ret)
return ret;
for (i = 0; i < max_payloads; i++) {
ret = nv50_msto_new(dev, outp->dcb->heads, outp->base.base.name,
i, &mstm->msto[i]);
if (ret)
return ret;
}
return 0;
}
......@@ -1569,17 +1559,24 @@ nv50_sor_func = {
.destroy = nv50_sor_destroy,
};
static bool nv50_has_mst(struct nouveau_drm *drm)
{
struct nvkm_bios *bios = nvxx_bios(&drm->client.device);
u32 data;
u8 ver, hdr, cnt, len;
data = nvbios_dp_table(bios, &ver, &hdr, &cnt, &len);
return data && ver >= 0x40 && (nvbios_rd08(bios, data + 0x08) & 0x04);
}
static int
nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
{
struct nouveau_connector *nv_connector = nouveau_connector(connector);
struct nouveau_drm *drm = nouveau_drm(connector->dev);
struct nvkm_bios *bios = nvxx_bios(&drm->client.device);
struct nvkm_i2c *i2c = nvxx_i2c(&drm->client.device);
struct nouveau_encoder *nv_encoder;
struct drm_encoder *encoder;
u8 ver, hdr, cnt, len;
u32 data;
int type, ret;
switch (dcbe->type) {
......@@ -1624,10 +1621,9 @@ nv50_sor_create(struct drm_connector *connector, struct dcb_output *dcbe)
}
if (nv_connector->type != DCB_CONNECTOR_eDP &&
(data = nvbios_dp_table(bios, &ver, &hdr, &cnt, &len)) &&
ver >= 0x40 && (nvbios_rd08(bios, data + 0x08) & 0x04)) {
ret = nv50_mstm_new(nv_encoder, &nv_connector->aux, 16,
nv_connector->base.base.id,
nv50_has_mst(drm)) {
ret = nv50_mstm_new(nv_encoder, &nv_connector->aux,
16, nv_connector->base.base.id,
&nv_encoder->dp.mstm);
if (ret)
return ret;
......@@ -2323,6 +2319,7 @@ nv50_display_create(struct drm_device *dev)
struct nv50_disp *disp;
struct dcb_output *dcbe;
int crtcs, ret, i;
bool has_mst = nv50_has_mst(drm);
disp = kzalloc(sizeof(*disp), GFP_KERNEL);
if (!disp)
......@@ -2371,11 +2368,37 @@ nv50_display_create(struct drm_device *dev)
crtcs = 0x3;
for (i = 0; i < fls(crtcs); i++) {
struct nv50_head *head;
if (!(crtcs & (1 << i)))
continue;
ret = nv50_head_create(dev, i);
if (ret)
head = nv50_head_create(dev, i);
if (IS_ERR(head)) {
ret = PTR_ERR(head);
goto out;
}
if (has_mst) {
head->msto = nv50_msto_new(dev, head, i);
if (IS_ERR(head->msto)) {
ret = PTR_ERR(head->msto);
head->msto = NULL;
goto out;
}
/*
* FIXME: This is a hack to workaround the following
* issues:
*
* https://gitlab.gnome.org/GNOME/mutter/issues/759
* https://gitlab.freedesktop.org/xorg/xserver/merge_requests/277
*
* Once these issues are closed, this should be
* removed
*/
head->msto->encoder.possible_crtcs = crtcs;
}
}
/* create encoder/connector objects based on VBIOS DCB table */
......
......@@ -4,6 +4,8 @@
#include "nouveau_display.h"
struct nv50_msto;
struct nv50_disp {
struct nvif_disp *disp;
struct nv50_core *core;
......
......@@ -213,6 +213,7 @@ nv50_head_atomic_check_lut(struct nv50_head *head,
{
struct nv50_disp *disp = nv50_disp(head->base.base.dev);
struct drm_property_blob *olut = asyh->state.gamma_lut;
int size;
/* Determine whether core output LUT should be enabled. */
if (olut) {
......@@ -229,14 +230,23 @@ nv50_head_atomic_check_lut(struct nv50_head *head,
}
}
if (!olut && !head->func->olut_identity) {
asyh->olut.handle = 0;
return 0;
if (!olut) {
if (!head->func->olut_identity) {
asyh->olut.handle = 0;
return 0;
}
size = 0;
} else {
size = drm_color_lut_size(olut);
}
if (!head->func->olut(head, asyh, size)) {
DRM_DEBUG_KMS("Invalid olut\n");
return -EINVAL;
}
asyh->olut.handle = disp->core->chan.vram.handle;
asyh->olut.buffer = !asyh->olut.buffer;
head->func->olut(head, asyh);
return 0;
}
......@@ -473,7 +483,7 @@ nv50_head_func = {
.atomic_destroy_state = nv50_head_atomic_destroy_state,
};
int
struct nv50_head *
nv50_head_create(struct drm_device *dev, int index)
{
struct nouveau_drm *drm = nouveau_drm(dev);
......@@ -485,7 +495,7 @@ nv50_head_create(struct drm_device *dev, int index)
head = kzalloc(sizeof(*head), GFP_KERNEL);
if (!head)
return -ENOMEM;
return ERR_PTR(-ENOMEM);
head->func = disp->core->func->head;
head->base.index = index;
......@@ -503,27 +513,26 @@ nv50_head_create(struct drm_device *dev, int index)
ret = nv50_curs_new(drm, head->base.index, &curs);
if (ret) {
kfree(head);
return ret;
return ERR_PTR(ret);
}
crtc = &head->base.base;
drm_crtc_init_with_planes(dev, crtc, &base->plane, &curs->plane,
&nv50_head_func, "head-%d", head->base.index);
drm_crtc_helper_add(crtc, &nv50_head_help);
/* Keep the legacy gamma size at 256 to avoid compatibility issues */
drm_mode_crtc_set_gamma_size(crtc, 256);
if (disp->disp->object.oclass >= GF110_DISP)
drm_crtc_enable_color_mgmt(crtc, 256, true, 256);
else
drm_crtc_enable_color_mgmt(crtc, 0, false, 256);
drm_crtc_enable_color_mgmt(crtc, base->func->ilut_size,
disp->disp->object.oclass >= GF110_DISP,
head->func->olut_size);
if (head->func->olut_set) {
ret = nv50_lut_init(disp, &drm->client.mmu, &head->olut);
if (ret)
goto out;
if (ret) {
nv50_head_destroy(crtc);
return ERR_PTR(ret);
}
}
out:
if (ret)
nv50_head_destroy(crtc);
return ret;
return head;
}
......@@ -11,17 +11,19 @@ struct nv50_head {
const struct nv50_head_func *func;
struct nouveau_crtc base;
struct nv50_lut olut;
struct nv50_msto *msto;
};
int nv50_head_create(struct drm_device *, int index);
struct nv50_head *nv50_head_create(struct drm_device *, int index);
void nv50_head_flush_set(struct nv50_head *, struct nv50_head_atom *);
void nv50_head_flush_clr(struct nv50_head *, struct nv50_head_atom *, bool y);
struct nv50_head_func {
void (*view)(struct nv50_head *, struct nv50_head_atom *);
void (*mode)(struct nv50_head *, struct nv50_head_atom *);
void (*olut)(struct nv50_head *, struct nv50_head_atom *);
bool (*olut)(struct nv50_head *, struct nv50_head_atom *, int);
bool olut_identity;
int olut_size;
void (*olut_set)(struct nv50_head *, struct nv50_head_atom *);
void (*olut_clr)(struct nv50_head *);
void (*core_calc)(struct nv50_head *, struct nv50_head_atom *);
......@@ -43,7 +45,7 @@ struct nv50_head_func {
extern const struct nv50_head_func head507d;
void head507d_view(struct nv50_head *, struct nv50_head_atom *);
void head507d_mode(struct nv50_head *, struct nv50_head_atom *);
void head507d_olut(struct nv50_head *, struct nv50_head_atom *);
bool head507d_olut(struct nv50_head *, struct nv50_head_atom *, int);
void head507d_core_calc(struct nv50_head *, struct nv50_head_atom *);
void head507d_core_clr(struct nv50_head *);
int head507d_curs_layout(struct nv50_head *, struct nv50_wndw_atom *,
......@@ -60,7 +62,7 @@ extern const struct nv50_head_func head827d;
extern const struct nv50_head_func head907d;
void head907d_view(struct nv50_head *, struct nv50_head_atom *);
void head907d_mode(struct nv50_head *, struct nv50_head_atom *);
void head907d_olut(struct nv50_head *, struct nv50_head_atom *);
bool head907d_olut(struct nv50_head *, struct nv50_head_atom *, int);
void head907d_olut_set(struct nv50_head *, struct nv50_head_atom *);
void head907d_olut_clr(struct nv50_head *);
void head907d_core_set(struct nv50_head *, struct nv50_head_atom *);
......
......@@ -271,15 +271,19 @@ head507d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
writew(readw(mem - 4), mem + 4);
}
void
head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
bool
head507d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
{
if (size != 256)
return false;
if (asyh->base.cpp == 1)
asyh->olut.mode = 0;
else
asyh->olut.mode = 1;
asyh->olut.load = head507d_olut_load;
return true;
}
void
......@@ -328,6 +332,7 @@ head507d = {
.view = head507d_view,
.mode = head507d_mode,
.olut = head507d_olut,
.olut_size = 256,
.olut_set = head507d_olut_set,
.olut_clr = head507d_olut_clr,
.core_calc = head507d_core_calc,
......
......@@ -108,6 +108,7 @@ head827d = {
.view = head507d_view,
.mode = head507d_mode,
.olut = head507d_olut,
.olut_size = 256,
.olut_set = head827d_olut_set,
.olut_clr = head827d_olut_clr,
.core_calc = head507d_core_calc,
......
......@@ -230,11 +230,15 @@ head907d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
writew(readw(mem - 4), mem + 4);
}
void
head907d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
bool
head907d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
{
asyh->olut.mode = 7;
if (size != 256 && size != 1024)
return false;
asyh->olut.mode = size == 1024 ? 4 : 7;
asyh->olut.load = head907d_olut_load;
return true;
}
void
......@@ -285,6 +289,7 @@ head907d = {
.view = head907d_view,
.mode = head907d_mode,
.olut = head907d_olut,
.olut_size = 1024,
.olut_set = head907d_olut_set,
.olut_clr = head907d_olut_clr,
.core_calc = head507d_core_calc,
......
......@@ -83,6 +83,7 @@ head917d = {
.view = head907d_view,
.mode = head907d_mode,
.olut = head907d_olut,
.olut_size = 1024,
.olut_set = head907d_olut_set,
.olut_clr = head907d_olut_clr,
.core_calc = head507d_core_calc,
......
......@@ -148,14 +148,18 @@ headc37d_olut_set(struct nv50_head *head, struct nv50_head_atom *asyh)
}
}
static void
headc37d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
static bool
headc37d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
{
if (size != 256 && size != 1024)
return false;
asyh->olut.mode = 2;
asyh->olut.size = 0;
asyh->olut.size = size == 1024 ? 2 : 0;
asyh->olut.range = 0;
asyh->olut.output_mode = 1;
asyh->olut.load = head907d_olut_load;
return true;
}
static void
......@@ -201,6 +205,7 @@ headc37d = {
.view = headc37d_view,
.mode = headc37d_mode,
.olut = headc37d_olut,
.olut_size = 1024,
.olut_set = headc37d_olut_set,
.olut_clr = headc37d_olut_clr,
.curs_layout = head917d_curs_layout,
......
......@@ -151,17 +151,20 @@ headc57d_olut_load(struct drm_color_lut *in, int size, void __iomem *mem)
writew(readw(mem - 4), mem + 4);
}
void
headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh)
bool
headc57d_olut(struct nv50_head *head, struct nv50_head_atom *asyh, int size)
{
if (size != 0 && size != 256 && size != 1024)
return false;
asyh->olut.mode = 2; /* DIRECT10 */
asyh->olut.size = 4 /* VSS header. */ + 1024 + 1 /* Entries. */;
asyh->olut.output_mode = 1; /* INTERPOLATE_ENABLE. */
if (asyh->state.gamma_lut &&
asyh->state.gamma_lut->length / sizeof(struct drm_color_lut) == 256)
if (size == 256)
asyh->olut.load = headc57d_olut_load_8;
else
asyh->olut.load = headc57d_olut_load;
return true;
}
static void
......@@ -194,6 +197,7 @@ headc57d = {
.mode = headc57d_mode,
.olut = headc57d_olut,
.olut_identity = true,
.olut_size = 1024,
.olut_set = headc57d_olut_set,
.olut_clr = headc57d_olut_clr,
.curs_layout = head917d_curs_layout,
......
......@@ -49,7 +49,7 @@ nv50_lut_load(struct nv50_lut *lut, int buffer, struct drm_property_blob *blob,
kvfree(in);
}
} else {
load(in, blob->length / sizeof(*in), mem);
load(in, drm_color_lut_size(blob), mem);
}
return addr;
......
......@@ -318,7 +318,7 @@ nv50_wndw_atomic_check_acquire(struct nv50_wndw *wndw, bool modeset,
return wndw->func->acquire(wndw, asyw, asyh);
}
static void
static int
nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
struct nv50_wndw_atom *armw,
struct nv50_wndw_atom *asyw,
......@@ -340,7 +340,7 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
*/
if (!(ilut = asyh->state.gamma_lut)) {
asyw->visible = false;
return;
return 0;
}
if (wndw->func->ilut)
......@@ -359,7 +359,10 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
/* Recalculate LUT state. */
memset(&asyw->xlut, 0x00, sizeof(asyw->xlut));
if ((asyw->ilut = wndw->func->ilut ? ilut : NULL)) {
wndw->func->ilut(wndw, asyw);
if (!wndw->func->ilut(wndw, asyw, drm_color_lut_size(ilut))) {
DRM_DEBUG_KMS("Invalid ilut\n");
return -EINVAL;
}
asyw->xlut.handle = wndw->wndw.vram.handle;
asyw->xlut.i.buffer = !asyw->xlut.i.buffer;
asyw->set.xlut = true;
......@@ -384,6 +387,7 @@ nv50_wndw_atomic_check_lut(struct nv50_wndw *wndw,
/* Can't do an immediate flip while changing the LUT. */
asyh->state.async_flip = false;
return 0;
}
static int
......@@ -424,8 +428,11 @@ nv50_wndw_atomic_check(struct drm_plane *plane, struct drm_plane_state *state)
(!armw->visible ||
asyh->state.color_mgmt_changed ||
asyw->state.fb->format->format !=
armw->state.fb->format->format))
nv50_wndw_atomic_check_lut(wndw, armw, asyw, asyh);
armw->state.fb->format->format)) {
ret = nv50_wndw_atomic_check_lut(wndw, armw, asyw, asyh);
if (ret)
return ret;
}
/* Calculate new window state. */
if (asyw->visible) {
......
......@@ -64,12 +64,13 @@ struct nv50_wndw_func {
void (*ntfy_clr)(struct nv50_wndw *);
int (*ntfy_wait_begun)(struct nouveau_bo *, u32 offset,
struct nvif_device *);
void (*ilut)(struct nv50_wndw *, struct nv50_wndw_atom *);
bool (*ilut)(struct nv50_wndw *, struct nv50_wndw_atom *, int);
void (*csc)(struct nv50_wndw *, struct nv50_wndw_atom *,
const struct drm_color_ctm *);
void (*csc_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
void (*csc_clr)(struct nv50_wndw *);
bool ilut_identity;
int ilut_size;
bool olut_core;
void (*xlut_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
void (*xlut_clr)(struct nv50_wndw *);
......
......@@ -71,14 +71,18 @@ wndwc37e_ilut_set(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
}
}
static void
wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
static bool
wndwc37e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
{
if (size != 256 && size != 1024)
return false;
asyw->xlut.i.mode = 2;
asyw->xlut.i.size = 0;
asyw->xlut.i.size = size == 1024 ? 2 : 0;
asyw->xlut.i.range = 0;
asyw->xlut.i.output_mode = 1;
asyw->xlut.i.load = head907d_olut_load;
return true;
}
void
......@@ -261,6 +265,7 @@ wndwc37e = {
.ntfy_reset = corec37d_ntfy_init,
.ntfy_wait_begun = base507c_ntfy_wait_begun,
.ilut = wndwc37e_ilut,
.ilut_size = 1024,
.xlut_set = wndwc37e_ilut_set,
.xlut_clr = wndwc37e_ilut_clr,
.csc = base907c_csc,
......
......@@ -156,19 +156,21 @@ wndwc57e_ilut_load(struct drm_color_lut *in, int size, void __iomem *mem)
writew(readw(mem - 4), mem + 4);
}
static void
wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
static bool
wndwc57e_ilut(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw, int size)
{
u16 size = asyw->ilut->length / sizeof(struct drm_color_lut);
if (size = size ? size : 1024, size != 256 && size != 1024)
return false;
if (size == 256) {
asyw->xlut.i.mode = 1; /* DIRECT8. */
} else {
asyw->xlut.i.mode = 2; /* DIRECT10. */
size = 1024;
}
asyw->xlut.i.size = 4 /* VSS header. */ + size + 1 /* Entries. */;
asyw->xlut.i.output_mode = 0; /* INTERPOLATE_DISABLE. */
asyw->xlut.i.load = wndwc57e_ilut_load;
return true;
}
static const struct nv50_wndw_func
......@@ -183,6 +185,7 @@ wndwc57e = {
.ntfy_wait_begun = base507c_ntfy_wait_begun,
.ilut = wndwc57e_ilut,
.ilut_identity = true,
.ilut_size = 1024,
.xlut_set = wndwc57e_ilut_set,
.xlut_clr = wndwc57e_ilut_clr,
.csc = base907c_csc,
......
#ifndef __NVFW_ACR_H__
#define __NVFW_ACR_H__
struct wpr_header {
#define WPR_HEADER_V0_FALCON_ID_INVALID 0xffffffff
u32 falcon_id;
u32 lsb_offset;
u32 bootstrap_owner;
u32 lazy_bootstrap;
#define WPR_HEADER_V0_STATUS_NONE 0
#define WPR_HEADER_V0_STATUS_COPY 1
#define WPR_HEADER_V0_STATUS_VALIDATION_CODE_FAILED 2
#define WPR_HEADER_V0_STATUS_VALIDATION_DATA_FAILED 3
#define WPR_HEADER_V0_STATUS_VALIDATION_DONE 4
#define WPR_HEADER_V0_STATUS_VALIDATION_SKIPPED 5
#define WPR_HEADER_V0_STATUS_BOOTSTRAP_READY 6
u32 status;
};
void wpr_header_dump(struct nvkm_subdev *, const struct wpr_header *);
struct wpr_header_v1 {
#define WPR_HEADER_V1_FALCON_ID_INVALID 0xffffffff
u32 falcon_id;
u32 lsb_offset;
u32 bootstrap_owner;
u32 lazy_bootstrap;
u32 bin_version;
#define WPR_HEADER_V1_STATUS_NONE 0
#define WPR_HEADER_V1_STATUS_COPY 1
#define WPR_HEADER_V1_STATUS_VALIDATION_CODE_FAILED 2
#define WPR_HEADER_V1_STATUS_VALIDATION_DATA_FAILED 3
#define WPR_HEADER_V1_STATUS_VALIDATION_DONE 4
#define WPR_HEADER_V1_STATUS_VALIDATION_SKIPPED 5
#define WPR_HEADER_V1_STATUS_BOOTSTRAP_READY 6
#define WPR_HEADER_V1_STATUS_REVOCATION_CHECK_FAILED 7
u32 status;
};
void wpr_header_v1_dump(struct nvkm_subdev *, const struct wpr_header_v1 *);
struct lsf_signature {
u8 prd_keys[2][16];
u8 dbg_keys[2][16];
u32 b_prd_present;
u32 b_dbg_present;
u32 falcon_id;
};
struct lsf_signature_v1 {
u8 prd_keys[2][16];
u8 dbg_keys[2][16];
u32 b_prd_present;
u32 b_dbg_present;
u32 falcon_id;
u32 supports_versioning;
u32 version;
u32 depmap_count;
u8 depmap[11/*LSF_LSB_DEPMAP_SIZE*/ * 2 * 4];
u8 kdf[16];
};
struct lsb_header_tail {
u32 ucode_off;
u32 ucode_size;
u32 data_size;
u32 bl_code_size;
u32 bl_imem_off;
u32 bl_data_off;
u32 bl_data_size;
u32 app_code_off;
u32 app_code_size;
u32 app_data_off;
u32 app_data_size;
u32 flags;
};
struct lsb_header {
struct lsf_signature signature;
struct lsb_header_tail tail;
};
void lsb_header_dump(struct nvkm_subdev *, struct lsb_header *);
struct lsb_header_v1 {
struct lsf_signature_v1 signature;
struct lsb_header_tail tail;
};
void lsb_header_v1_dump(struct nvkm_subdev *, struct lsb_header_v1 *);
struct flcn_acr_desc {
union {
u8 reserved_dmem[0x200];
u32 signatures[4];
} ucode_reserved_space;
u32 wpr_region_id;
u32 wpr_offset;
u32 mmu_mem_range;
struct {
u32 no_regions;
struct {
u32 start_addr;
u32 end_addr;
u32 region_id;
u32 read_mask;
u32 write_mask;
u32 client_mask;
} region_props[2];
} regions;
u32 ucode_blob_size;
u64 ucode_blob_base __aligned(8);
struct {
u32 vpr_enabled;
u32 vpr_start;
u32 vpr_end;
u32 hdcp_policies;
} vpr_desc;
};
void flcn_acr_desc_dump(struct nvkm_subdev *, struct flcn_acr_desc *);
struct flcn_acr_desc_v1 {
u8 reserved_dmem[0x200];
u32 signatures[4];
u32 wpr_region_id;
u32 wpr_offset;
u32 mmu_memory_range;
struct {
u32 no_regions;
struct {
u32 start_addr;
u32 end_addr;
u32 region_id;
u32 read_mask;
u32 write_mask;
u32 client_mask;
u32 shadow_mem_start_addr;
} region_props[2];
} regions;
u32 ucode_blob_size;
u64 ucode_blob_base __aligned(8);
struct {
u32 vpr_enabled;
u32 vpr_start;
u32 vpr_end;
u32 hdcp_policies;
} vpr_desc;
};
void flcn_acr_desc_v1_dump(struct nvkm_subdev *, struct flcn_acr_desc_v1 *);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVFW_FLCN_H__
#define __NVFW_FLCN_H__
#include <core/os.h>
struct nvkm_subdev;
struct loader_config {
u32 dma_idx;
u32 code_dma_base;
u32 code_size_total;
u32 code_size_to_load;
u32 code_entry_point;
u32 data_dma_base;
u32 data_size;
u32 overlay_dma_base;
u32 argc;
u32 argv;
u32 code_dma_base1;
u32 data_dma_base1;
u32 overlay_dma_base1;
};
void
loader_config_dump(struct nvkm_subdev *, const struct loader_config *);
struct loader_config_v1 {
u32 reserved;
u32 dma_idx;
u64 code_dma_base;
u32 code_size_total;
u32 code_size_to_load;
u32 code_entry_point;
u64 data_dma_base;
u32 data_size;
u64 overlay_dma_base;
u32 argc;
u32 argv;
} __packed;
void
loader_config_v1_dump(struct nvkm_subdev *, const struct loader_config_v1 *);
struct flcn_bl_dmem_desc {
u32 reserved[4];
u32 signature[4];
u32 ctx_dma;
u32 code_dma_base;
u32 non_sec_code_off;
u32 non_sec_code_size;
u32 sec_code_off;
u32 sec_code_size;
u32 code_entry_point;
u32 data_dma_base;
u32 data_size;
u32 code_dma_base1;
u32 data_dma_base1;
};
void
flcn_bl_dmem_desc_dump(struct nvkm_subdev *, const struct flcn_bl_dmem_desc *);
struct flcn_bl_dmem_desc_v1 {
u32 reserved[4];
u32 signature[4];
u32 ctx_dma;
u64 code_dma_base;
u32 non_sec_code_off;
u32 non_sec_code_size;
u32 sec_code_off;
u32 sec_code_size;
u32 code_entry_point;
u64 data_dma_base;
u32 data_size;
} __packed;
void flcn_bl_dmem_desc_v1_dump(struct nvkm_subdev *,
const struct flcn_bl_dmem_desc_v1 *);
struct flcn_bl_dmem_desc_v2 {
u32 reserved[4];
u32 signature[4];
u32 ctx_dma;
u64 code_dma_base;
u32 non_sec_code_off;
u32 non_sec_code_size;
u32 sec_code_off;
u32 sec_code_size;
u32 code_entry_point;
u64 data_dma_base;
u32 data_size;
u32 argc;
u32 argv;
} __packed;
void flcn_bl_dmem_desc_v2_dump(struct nvkm_subdev *,
const struct flcn_bl_dmem_desc_v2 *);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVFW_FW_H__
#define __NVFW_FW_H__
#include <core/os.h>
struct nvkm_subdev;
struct nvfw_bin_hdr {
u32 bin_magic;
u32 bin_ver;
u32 bin_size;
u32 header_offset;
u32 data_offset;
u32 data_size;
};
const struct nvfw_bin_hdr *nvfw_bin_hdr(struct nvkm_subdev *, const void *);
struct nvfw_bl_desc {
u32 start_tag;
u32 dmem_load_off;
u32 code_off;
u32 code_size;
u32 data_off;
u32 data_size;
};
const struct nvfw_bl_desc *nvfw_bl_desc(struct nvkm_subdev *, const void *);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVFW_HS_H__
#define __NVFW_HS_H__
#include <core/os.h>
struct nvkm_subdev;
struct nvfw_hs_header {
u32 sig_dbg_offset;
u32 sig_dbg_size;
u32 sig_prod_offset;
u32 sig_prod_size;
u32 patch_loc;
u32 patch_sig;
u32 hdr_offset;
u32 hdr_size;
};
const struct nvfw_hs_header *nvfw_hs_header(struct nvkm_subdev *, const void *);
struct nvfw_hs_load_header {
u32 non_sec_code_off;
u32 non_sec_code_size;
u32 data_dma_base;
u32 data_size;
u32 num_apps;
u32 apps[0];
};
const struct nvfw_hs_load_header *
nvfw_hs_load_header(struct nvkm_subdev *, const void *);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVFW_LS_H__
#define __NVFW_LS_H__
#include <core/os.h>
struct nvkm_subdev;
struct nvfw_ls_desc_head {
u32 descriptor_size;
u32 image_size;
u32 tools_version;
u32 app_version;
char date[64];
u32 bootloader_start_offset;
u32 bootloader_size;
u32 bootloader_imem_offset;
u32 bootloader_entry_point;
u32 app_start_offset;
u32 app_size;
u32 app_imem_offset;
u32 app_imem_entry;
u32 app_dmem_offset;
u32 app_resident_code_offset;
u32 app_resident_code_size;
u32 app_resident_data_offset;
u32 app_resident_data_size;
};
struct nvfw_ls_desc {
struct nvfw_ls_desc_head head;
u32 nb_overlays;
struct {
u32 start;
u32 size;
} load_ovl[64];
u32 compressed;
};
const struct nvfw_ls_desc *nvfw_ls_desc(struct nvkm_subdev *, const void *);
struct nvfw_ls_desc_v1 {
struct nvfw_ls_desc_head head;
u32 nb_imem_overlays;
u32 nb_dmem_overlays;
struct {
u32 start;
u32 size;
} load_ovl[64];
u32 compressed;
};
const struct nvfw_ls_desc_v1 *
nvfw_ls_desc_v1(struct nvkm_subdev *, const void *);
#endif
#ifndef __NVFW_PMU_H__
#define __NVFW_PMU_H__
struct nv_pmu_args {
u32 reserved;
u32 freq_hz;
u32 trace_size;
u32 trace_dma_base;
u16 trace_dma_base1;
u8 trace_dma_offset;
u32 trace_dma_idx;
bool secure_mode;
bool raise_priv_sec;
struct {
u32 dma_base;
u16 dma_base1;
u8 dma_offset;
u16 fb_size;
u8 dma_idx;
} gc6_ctx;
u8 pad;
};
#define NV_PMU_UNIT_INIT 0x07
#define NV_PMU_UNIT_ACR 0x0a
struct nv_pmu_init_msg {
struct nv_falcon_msg hdr;
#define NV_PMU_INIT_MSG_INIT 0x00
u8 msg_type;
u8 pad;
u16 os_debug_entry_point;
struct {
u16 size;
u16 offset;
u8 index;
u8 pad;
} queue_info[5];
u16 sw_managed_area_offset;
u16 sw_managed_area_size;
};
struct nv_pmu_acr_cmd {
struct nv_falcon_cmd hdr;
#define NV_PMU_ACR_CMD_INIT_WPR_REGION 0x00
#define NV_PMU_ACR_CMD_BOOTSTRAP_FALCON 0x01
#define NV_PMU_ACR_CMD_BOOTSTRAP_MULTIPLE_FALCONS 0x03
u8 cmd_type;
};
struct nv_pmu_acr_msg {
struct nv_falcon_cmd hdr;
u8 msg_type;
};
struct nv_pmu_acr_init_wpr_region_cmd {
struct nv_pmu_acr_cmd cmd;
u32 region_id;
u32 wpr_offset;
};
struct nv_pmu_acr_init_wpr_region_msg {
struct nv_pmu_acr_msg msg;
u32 error_code;
};
struct nv_pmu_acr_bootstrap_falcon_cmd {
struct nv_pmu_acr_cmd cmd;
#define NV_PMU_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_YES 0x00000000
#define NV_PMU_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_NO 0x00000001
u32 flags;
u32 falcon_id;
};
struct nv_pmu_acr_bootstrap_falcon_msg {
struct nv_pmu_acr_msg msg;
u32 falcon_id;
};
struct nv_pmu_acr_bootstrap_multiple_falcons_cmd {
struct nv_pmu_acr_cmd cmd;
#define NV_PMU_ACR_BOOTSTRAP_MULTIPLE_FALCONS_FLAGS_RESET_YES 0x00000000
#define NV_PMU_ACR_BOOTSTRAP_MULTIPLE_FALCONS_FLAGS_RESET_NO 0x00000001
u32 flags;
u32 falcon_mask;
u32 use_va_mask;
u32 wpr_lo;
u32 wpr_hi;
};
struct nv_pmu_acr_bootstrap_multiple_falcons_msg {
struct nv_pmu_acr_msg msg;
u32 falcon_mask;
};
#endif
#ifndef __NVFW_SEC2_H__
#define __NVFW_SEC2_H__
struct nv_sec2_args {
u32 freq_hz;
u32 falc_trace_size;
u32 falc_trace_dma_base;
u32 falc_trace_dma_idx;
bool secure_mode;
};
#define NV_SEC2_UNIT_INIT 0x01
#define NV_SEC2_UNIT_ACR 0x08
struct nv_sec2_init_msg {
struct nv_falcon_msg hdr;
#define NV_SEC2_INIT_MSG_INIT 0x00
u8 msg_type;
u8 num_queues;
u16 os_debug_entry_point;
struct {
u32 offset;
u16 size;
u8 index;
#define NV_SEC2_INIT_MSG_QUEUE_ID_CMDQ 0x00
#define NV_SEC2_INIT_MSG_QUEUE_ID_MSGQ 0x01
u8 id;
} queue_info[2];
u32 sw_managed_area_offset;
u16 sw_managed_area_size;
};
struct nv_sec2_acr_cmd {
struct nv_falcon_cmd hdr;
#define NV_SEC2_ACR_CMD_BOOTSTRAP_FALCON 0x00
u8 cmd_type;
};
struct nv_sec2_acr_msg {
struct nv_falcon_cmd hdr;
u8 msg_type;
};
struct nv_sec2_acr_bootstrap_falcon_cmd {
struct nv_sec2_acr_cmd cmd;
#define NV_SEC2_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_YES 0x00000000
#define NV_SEC2_ACR_BOOTSTRAP_FALCON_FLAGS_RESET_NO 0x00000001
u32 flags;
u32 falcon_id;
};
struct nv_sec2_acr_bootstrap_falcon_msg {
struct nv_sec2_acr_msg msg;
u32 error_code;
u32 falcon_id;
};
#endif
......@@ -166,6 +166,8 @@
#define VOLTA_A /* cl9097.h */ 0x0000c397
#define TURING_A /* cl9097.h */ 0x0000c597
#define NV74_BSP 0x000074b0
#define GT212_MSVLD 0x000085b1
......@@ -207,6 +209,7 @@
#define PASCAL_COMPUTE_A 0x0000c0c0
#define PASCAL_COMPUTE_B 0x0000c1c0
#define VOLTA_COMPUTE_A 0x0000c3c0
#define TURING_COMPUTE_A 0x0000c5c0
#define NV74_CIPHER 0x000074c1
#endif
......@@ -35,7 +35,7 @@ struct nvif_mmu_type_v0 {
struct nvif_mmu_kind_v0 {
__u8 version;
__u8 pad01[1];
__u8 kind_inv;
__u16 count;
__u8 data[];
};
......
......@@ -7,6 +7,7 @@ struct nvif_mmu {
u8 dmabits;
u8 heap_nr;
u8 type_nr;
u8 kind_inv;
u16 kind_nr;
s32 mem;
......@@ -36,9 +37,8 @@ void nvif_mmu_fini(struct nvif_mmu *);
static inline bool
nvif_mmu_kind_valid(struct nvif_mmu *mmu, u8 kind)
{
const u8 invalid = mmu->kind_nr - 1;
if (kind) {
if (kind >= mmu->kind_nr || mmu->kind[kind] == invalid)
if (kind >= mmu->kind_nr || mmu->kind[kind] == mmu->kind_inv)
return false;
}
return true;
......
......@@ -23,13 +23,13 @@ enum nvkm_devidx {
NVKM_SUBDEV_MMU,
NVKM_SUBDEV_BAR,
NVKM_SUBDEV_FAULT,
NVKM_SUBDEV_ACR,
NVKM_SUBDEV_PMU,
NVKM_SUBDEV_VOLT,
NVKM_SUBDEV_ICCSENSE,
NVKM_SUBDEV_THERM,
NVKM_SUBDEV_CLK,
NVKM_SUBDEV_GSP,
NVKM_SUBDEV_SECBOOT,
NVKM_ENGINE_BSP,
......@@ -129,6 +129,7 @@ struct nvkm_device {
struct notifier_block nb;
} acpi;
struct nvkm_acr *acr;
struct nvkm_bar *bar;
struct nvkm_bios *bios;
struct nvkm_bus *bus;
......@@ -149,7 +150,6 @@ struct nvkm_device {
struct nvkm_subdev *mxm;
struct nvkm_pci *pci;
struct nvkm_pmu *pmu;
struct nvkm_secboot *secboot;
struct nvkm_therm *therm;
struct nvkm_timer *timer;
struct nvkm_top *top;
......@@ -169,7 +169,7 @@ struct nvkm_device {
struct nvkm_engine *mspdec;
struct nvkm_engine *msppp;
struct nvkm_engine *msvld;
struct nvkm_engine *nvenc[3];
struct nvkm_nvenc *nvenc[3];
struct nvkm_nvdec *nvdec[3];
struct nvkm_pm *pm;
struct nvkm_engine *sec;
......@@ -202,6 +202,7 @@ struct nvkm_device_quirk {
struct nvkm_device_chip {
const char *name;
int (*acr )(struct nvkm_device *, int idx, struct nvkm_acr **);
int (*bar )(struct nvkm_device *, int idx, struct nvkm_bar **);
int (*bios )(struct nvkm_device *, int idx, struct nvkm_bios **);
int (*bus )(struct nvkm_device *, int idx, struct nvkm_bus **);
......@@ -222,7 +223,6 @@ struct nvkm_device_chip {
int (*mxm )(struct nvkm_device *, int idx, struct nvkm_subdev **);
int (*pci )(struct nvkm_device *, int idx, struct nvkm_pci **);
int (*pmu )(struct nvkm_device *, int idx, struct nvkm_pmu **);
int (*secboot )(struct nvkm_device *, int idx, struct nvkm_secboot **);
int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **);
int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **);
int (*top )(struct nvkm_device *, int idx, struct nvkm_top **);
......@@ -242,7 +242,7 @@ struct nvkm_device_chip {
int (*mspdec )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*msppp )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*msvld )(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*nvenc[3])(struct nvkm_device *, int idx, struct nvkm_engine **);
int (*nvenc[3])(struct nvkm_device *, int idx, struct nvkm_nvenc **);
int (*nvdec[3])(struct nvkm_device *, int idx, struct nvkm_nvdec **);
int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **);
int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **);
......
#ifndef __NVKM_FALCON_H__
#define __NVKM_FALCON_H__
#include <engine/falcon.h>
int nvkm_falcon_ctor(const struct nvkm_falcon_func *, struct nvkm_subdev *owner,
const char *name, u32 addr, struct nvkm_falcon *);
void nvkm_falcon_dtor(struct nvkm_falcon *);
void nvkm_falcon_v1_load_imem(struct nvkm_falcon *,
void *, u32, u32, u16, u8, bool);
void nvkm_falcon_v1_load_dmem(struct nvkm_falcon *, void *, u32, u32, u8);
void nvkm_falcon_v1_read_dmem(struct nvkm_falcon *, u32, u32, u8, void *);
void nvkm_falcon_v1_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
int nvkm_falcon_v1_wait_for_halt(struct nvkm_falcon *, u32);
int nvkm_falcon_v1_clear_interrupt(struct nvkm_falcon *, u32);
void nvkm_falcon_v1_set_start_addr(struct nvkm_falcon *, u32 start_addr);
void nvkm_falcon_v1_start(struct nvkm_falcon *);
int nvkm_falcon_v1_enable(struct nvkm_falcon *);
void nvkm_falcon_v1_disable(struct nvkm_falcon *);
void gp102_sec2_flcn_bind_context(struct nvkm_falcon *, struct nvkm_memory *);
int gp102_sec2_flcn_enable(struct nvkm_falcon *);
#define FLCN_PRINTK(t,f,fmt,a...) do { \
if (nvkm_subdev_name[(f)->owner->index] != (f)->name) \
nvkm_##t((f)->owner, "%s: "fmt"\n", (f)->name, ##a); \
else \
nvkm_##t((f)->owner, fmt"\n", ##a); \
} while(0)
#define FLCN_DBG(f,fmt,a...) FLCN_PRINTK(debug, (f), fmt, ##a)
#define FLCN_ERR(f,fmt,a...) FLCN_PRINTK(error, (f), fmt, ##a)
/**
* struct nv_falcon_msg - header for all messages
*
* @unit_id: id of firmware process that sent the message
* @size: total size of message
* @ctrl_flags: control flags
* @seq_id: used to match a message from its corresponding command
*/
struct nv_falcon_msg {
u8 unit_id;
u8 size;
u8 ctrl_flags;
u8 seq_id;
};
#define nv_falcon_cmd nv_falcon_msg
#define NV_FALCON_CMD_UNIT_ID_REWIND 0x00
struct nvkm_falcon_qmgr;
int nvkm_falcon_qmgr_new(struct nvkm_falcon *, struct nvkm_falcon_qmgr **);
void nvkm_falcon_qmgr_del(struct nvkm_falcon_qmgr **);
typedef int
(*nvkm_falcon_qmgr_callback)(void *priv, struct nv_falcon_msg *);
struct nvkm_falcon_cmdq;
int nvkm_falcon_cmdq_new(struct nvkm_falcon_qmgr *, const char *name,
struct nvkm_falcon_cmdq **);
void nvkm_falcon_cmdq_del(struct nvkm_falcon_cmdq **);
void nvkm_falcon_cmdq_init(struct nvkm_falcon_cmdq *,
u32 index, u32 offset, u32 size);
void nvkm_falcon_cmdq_fini(struct nvkm_falcon_cmdq *);
int nvkm_falcon_cmdq_send(struct nvkm_falcon_cmdq *, struct nv_falcon_cmd *,
nvkm_falcon_qmgr_callback, void *priv,
unsigned long timeout_jiffies);
struct nvkm_falcon_msgq;
int nvkm_falcon_msgq_new(struct nvkm_falcon_qmgr *, const char *name,
struct nvkm_falcon_msgq **);
void nvkm_falcon_msgq_del(struct nvkm_falcon_msgq **);
void nvkm_falcon_msgq_init(struct nvkm_falcon_msgq *,
u32 index, u32 offset, u32 size);
int nvkm_falcon_msgq_recv_initmsg(struct nvkm_falcon_msgq *, void *, u32 size);
void nvkm_falcon_msgq_recv(struct nvkm_falcon_msgq *);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FIRMWARE_H__
#define __NVKM_FIRMWARE_H__
#include <core/option.h>
#include <core/subdev.h>
int nvkm_firmware_get_version(const struct nvkm_subdev *, const char *fwname,
int min_version, int max_version,
const struct firmware **);
int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname,
int nvkm_firmware_get(const struct nvkm_subdev *, const char *fwname, int ver,
const struct firmware **);
void nvkm_firmware_put(const struct firmware *);
int nvkm_firmware_load_blob(const struct nvkm_subdev *subdev, const char *path,
const char *name, int ver, struct nvkm_blob *);
int nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *path,
const char *name, int ver,
const struct firmware **);
#define nvkm_firmware_load(s,l,o,p...) ({ \
struct nvkm_subdev *_s = (s); \
const char *_opts = (o); \
char _option[32]; \
typeof(l[0]) *_list = (l), *_next, *_fwif = NULL; \
int _ver, _fwv, _ret = 0; \
\
snprintf(_option, sizeof(_option), "Nv%sFw", _opts); \
_ver = nvkm_longopt(_s->device->cfgopt, _option, -2); \
if (_ver >= -1) { \
for (_next = _list; !_fwif && _next->load; _next++) { \
if (_next->version == _ver) \
_fwif = _next; \
} \
_ret = _fwif ? 0 : -EINVAL; \
} \
\
if (_ret == 0) { \
snprintf(_option, sizeof(_option), "Nv%sFwVer", _opts); \
_fwv = _fwif ? _fwif->version : -1; \
_ver = nvkm_longopt(_s->device->cfgopt, _option, _fwv); \
for (_next = _fwif ? _fwif : _list; _next->load; _next++) { \
_fwv = (_ver >= 0) ? _ver : _next->version; \
_ret = _next->load(p, _fwv, _next); \
if (_ret == 0 || _ver >= 0) { \
_fwif = _next; \
break; \
} \
} \
} \
\
if (_ret) { \
nvkm_error(_s, "failed to load firmware\n"); \
_fwif = ERR_PTR(_ret); \
} \
\
_fwif; \
})
#endif
......@@ -84,6 +84,22 @@ void nvkm_memory_tags_put(struct nvkm_memory *, struct nvkm_device *,
nvkm_wo32((o), __a + 4, upper_32_bits(__d)); \
} while(0)
#define nvkm_robj(o,a,p,s) do { \
u32 _addr = (a), _size = (s) >> 2, *_data = (void *)(p); \
while (_size--) { \
*(_data++) = nvkm_ro32((o), _addr); \
_addr += 4; \
} \
} while(0)
#define nvkm_wobj(o,a,p,s) do { \
u32 _addr = (a), _size = (s) >> 2, *_data = (void *)(p); \
while (_size--) { \
nvkm_wo32((o), _addr, *(_data++)); \
_addr += 4; \
} \
} while(0)
#define nvkm_fill(t,s,o,a,d,c) do { \
u64 _a = (a), _c = (c), _d = (d), _o = _a >> s, _s = _c << s; \
u##t __iomem *_m = nvkm_kmap(o); \
......
/*
* Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
*
* 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 AUTHORS OR COPYRIGHT HOLDERS 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 __NVKM_CORE_MSGQUEUE_H
#define __NVKM_CORE_MSGQUEUE_H
#include <subdev/secboot.h>
struct nvkm_msgqueue;
/* Hopefully we will never have firmware arguments larger than that... */
#define NVKM_MSGQUEUE_CMDLINE_SIZE 0x100
int nvkm_msgqueue_new(u32, struct nvkm_falcon *, const struct nvkm_secboot *,
struct nvkm_msgqueue **);
void nvkm_msgqueue_del(struct nvkm_msgqueue **);
void nvkm_msgqueue_recv(struct nvkm_msgqueue *);
int nvkm_msgqueue_reinit(struct nvkm_msgqueue *);
/* useful if we run a NVIDIA-signed firmware */
void nvkm_msgqueue_write_cmdline(struct nvkm_msgqueue *, void *);
/* interface to ACR unit running on falcon (NVIDIA signed firmware) */
int nvkm_msgqueue_acr_boot_falcons(struct nvkm_msgqueue *, unsigned long);
#endif
......@@ -21,4 +21,17 @@
iowrite32_native(lower_32_bits(_v), &_p[0]); \
iowrite32_native(upper_32_bits(_v), &_p[1]); \
} while(0)
struct nvkm_blob {
void *data;
u32 size;
};
static inline void
nvkm_blob_dtor(struct nvkm_blob *blob)
{
kfree(blob->data);
blob->data = NULL;
blob->size = 0;
}
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_FALCON_H__
#define __NVKM_FALCON_H__
#ifndef __NVKM_FLCNEN_H__
#define __NVKM_FLCNEN_H__
#define nvkm_falcon(p) container_of((p), struct nvkm_falcon, engine)
#include <core/engine.h>
struct nvkm_fifo_chan;
......@@ -23,12 +23,13 @@ struct nvkm_falcon {
struct mutex mutex;
struct mutex dmem_mutex;
bool oneinit;
const struct nvkm_subdev *user;
u8 version;
u8 secret;
bool debug;
bool has_emem;
struct nvkm_memory *core;
bool external;
......@@ -76,9 +77,14 @@ struct nvkm_falcon_func {
} data;
void (*init)(struct nvkm_falcon *);
void (*intr)(struct nvkm_falcon *, struct nvkm_fifo_chan *);
u32 debug;
u32 fbif;
void (*load_imem)(struct nvkm_falcon *, void *, u32, u32, u16, u8, bool);
void (*load_dmem)(struct nvkm_falcon *, void *, u32, u32, u8);
void (*read_dmem)(struct nvkm_falcon *, u32, u32, u8, void *);
u32 emem_addr;
void (*bind_context)(struct nvkm_falcon *, struct nvkm_memory *);
int (*wait_for_halt)(struct nvkm_falcon *, u32);
int (*clear_interrupt)(struct nvkm_falcon *, u32);
......@@ -86,6 +92,13 @@ struct nvkm_falcon_func {
void (*start)(struct nvkm_falcon *);
int (*enable)(struct nvkm_falcon *falcon);
void (*disable)(struct nvkm_falcon *falcon);
int (*reset)(struct nvkm_falcon *);
struct {
u32 head;
u32 tail;
u32 stride;
} cmdq, msgq;
struct nvkm_sclass sclass[];
};
......@@ -122,5 +135,4 @@ int nvkm_falcon_clear_interrupt(struct nvkm_falcon *, u32);
int nvkm_falcon_enable(struct nvkm_falcon *);
void nvkm_falcon_disable(struct nvkm_falcon *);
int nvkm_falcon_reset(struct nvkm_falcon *);
#endif
......@@ -50,6 +50,8 @@ int gp100_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gp102_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gp104_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gp107_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gp108_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gp10b_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int gv100_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
int tu102_gr_new(struct nvkm_device *, int, struct nvkm_gr **);
#endif
......@@ -3,13 +3,13 @@
#define __NVKM_NVDEC_H__
#define nvkm_nvdec(p) container_of((p), struct nvkm_nvdec, engine)
#include <core/engine.h>
#include <core/falcon.h>
struct nvkm_nvdec {
const struct nvkm_nvdec_func *func;
struct nvkm_engine engine;
u32 addr;
struct nvkm_falcon *falcon;
struct nvkm_falcon falcon;
};
int gp102_nvdec_new(struct nvkm_device *, int, struct nvkm_nvdec **);
int gm107_nvdec_new(struct nvkm_device *, int, struct nvkm_nvdec **);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_NVENC_H__
#define __NVKM_NVENC_H__
#define nvkm_nvenc(p) container_of((p), struct nvkm_nvenc, engine)
#include <core/engine.h>
#include <core/falcon.h>
struct nvkm_nvenc {
const struct nvkm_nvenc_func *func;
struct nvkm_engine engine;
struct nvkm_falcon falcon;
};
int gm107_nvenc_new(struct nvkm_device *, int, struct nvkm_nvenc **);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_SEC2_H__
#define __NVKM_SEC2_H__
#define nvkm_sec2(p) container_of((p), struct nvkm_sec2, engine)
#include <core/engine.h>
#include <core/falcon.h>
struct nvkm_sec2 {
const struct nvkm_sec2_func *func;
struct nvkm_engine engine;
u32 addr;
struct nvkm_falcon falcon;
struct nvkm_falcon_qmgr *qmgr;
struct nvkm_falcon_cmdq *cmdq;
struct nvkm_falcon_msgq *msgq;
struct nvkm_falcon *falcon;
struct nvkm_msgqueue *queue;
struct work_struct work;
bool initmsg_received;
};
int gp102_sec2_new(struct nvkm_device *, int, struct nvkm_sec2 **);
int gp108_sec2_new(struct nvkm_device *, int, struct nvkm_sec2 **);
int tu102_sec2_new(struct nvkm_device *, int, struct nvkm_sec2 **);
#endif
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_ACR_H__
#define __NVKM_ACR_H__
#define nvkm_acr(p) container_of((p), struct nvkm_acr, subdev)
#include <core/subdev.h>
#include <core/falcon.h>
enum nvkm_acr_lsf_id {
NVKM_ACR_LSF_PMU = 0,
NVKM_ACR_LSF_GSPLITE = 1,
NVKM_ACR_LSF_FECS = 2,
NVKM_ACR_LSF_GPCCS = 3,
NVKM_ACR_LSF_NVDEC = 4,
NVKM_ACR_LSF_SEC2 = 7,
NVKM_ACR_LSF_MINION = 10,
NVKM_ACR_LSF_NUM
};
static inline const char *
nvkm_acr_lsf_id(enum nvkm_acr_lsf_id id)
{
switch (id) {
case NVKM_ACR_LSF_PMU : return "pmu";
case NVKM_ACR_LSF_GSPLITE: return "gsplite";
case NVKM_ACR_LSF_FECS : return "fecs";
case NVKM_ACR_LSF_GPCCS : return "gpccs";
case NVKM_ACR_LSF_NVDEC : return "nvdec";
case NVKM_ACR_LSF_SEC2 : return "sec2";
case NVKM_ACR_LSF_MINION : return "minion";
default:
return "unknown";
}
}
struct nvkm_acr {
const struct nvkm_acr_func *func;
struct nvkm_subdev subdev;
struct list_head hsfw, hsf;
struct list_head lsfw, lsf;
struct nvkm_memory *wpr;
u64 wpr_start;
u64 wpr_end;
u64 shadow_start;
struct nvkm_memory *inst;
struct nvkm_vmm *vmm;
bool done;
const struct firmware *wpr_fw;
bool wpr_comp;
u64 wpr_prev;
};
bool nvkm_acr_managed_falcon(struct nvkm_device *, enum nvkm_acr_lsf_id);
int nvkm_acr_bootstrap_falcons(struct nvkm_device *, unsigned long mask);
int gm200_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
int gm20b_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
int gp102_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
int gp108_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
int gp10b_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
int tu102_acr_new(struct nvkm_device *, int, struct nvkm_acr **);
struct nvkm_acr_lsfw {
const struct nvkm_acr_lsf_func *func;
struct nvkm_falcon *falcon;
enum nvkm_acr_lsf_id id;
struct list_head head;
struct nvkm_blob img;
const struct firmware *sig;
u32 bootloader_size;
u32 bootloader_imem_offset;
u32 app_size;
u32 app_start_offset;
u32 app_imem_entry;
u32 app_resident_code_offset;
u32 app_resident_code_size;
u32 app_resident_data_offset;
u32 app_resident_data_size;
u32 ucode_size;
u32 data_size;
struct {
u32 lsb;
u32 img;
u32 bld;
} offset;
u32 bl_data_size;
};
struct nvkm_acr_lsf_func {
/* The (currently) map directly to LSB header flags. */
#define NVKM_ACR_LSF_LOAD_CODE_AT_0 0x00000001
#define NVKM_ACR_LSF_DMACTL_REQ_CTX 0x00000004
#define NVKM_ACR_LSF_FORCE_PRIV_LOAD 0x00000008
u32 flags;
u32 bld_size;
void (*bld_write)(struct nvkm_acr *, u32 bld, struct nvkm_acr_lsfw *);
void (*bld_patch)(struct nvkm_acr *, u32 bld, s64 adjust);
int (*boot)(struct nvkm_falcon *);
int (*bootstrap_falcon)(struct nvkm_falcon *, enum nvkm_acr_lsf_id);
int (*bootstrap_multiple_falcons)(struct nvkm_falcon *, u32 mask);
};
int
nvkm_acr_lsfw_load_sig_image_desc(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_sig_image_desc_v1(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
int
nvkm_acr_lsfw_load_bl_inst_data_sig(struct nvkm_subdev *, struct nvkm_falcon *,
enum nvkm_acr_lsf_id, const char *path,
int ver, const struct nvkm_acr_lsf_func *);
#endif
......@@ -31,6 +31,7 @@ struct nvkm_fault_data {
};
int gp100_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
int gp10b_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
int gv100_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
int tu102_fault_new(struct nvkm_device *, int, struct nvkm_fault **);
#endif
......@@ -33,6 +33,8 @@ struct nvkm_fb {
const struct nvkm_fb_func *func;
struct nvkm_subdev subdev;
struct nvkm_blob vpr_scrubber;
struct nvkm_ram *ram;
struct nvkm_mm tags;
......
......@@ -2,12 +2,11 @@
#define __NVKM_GSP_H__
#define nvkm_gsp(p) container_of((p), struct nvkm_gsp, subdev)
#include <core/subdev.h>
#include <core/falcon.h>
struct nvkm_gsp {
struct nvkm_subdev subdev;
u32 addr;
struct nvkm_falcon *falcon;
struct nvkm_falcon falcon;
};
int gv100_gsp_new(struct nvkm_device *, int, struct nvkm_gsp **);
......
......@@ -40,4 +40,5 @@ int gm107_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gm200_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gp100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gp102_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
int gp10b_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **);
#endif
......@@ -2,13 +2,20 @@
#ifndef __NVKM_PMU_H__
#define __NVKM_PMU_H__
#include <core/subdev.h>
#include <engine/falcon.h>
#include <core/falcon.h>
struct nvkm_pmu {
const struct nvkm_pmu_func *func;
struct nvkm_subdev subdev;
struct nvkm_falcon *falcon;
struct nvkm_msgqueue *queue;
struct nvkm_falcon falcon;
struct nvkm_falcon_qmgr *qmgr;
struct nvkm_falcon_cmdq *hpq;
struct nvkm_falcon_cmdq *lpq;
struct nvkm_falcon_msgq *msgq;
bool initmsg_received;
struct completion wpr_ready;
struct {
u32 base;
......@@ -43,6 +50,7 @@ int gm107_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **);
int gm20b_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **);
int gp100_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **);
int gp102_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **);
int gp10b_pmu_new(struct nvkm_device *, int, struct nvkm_pmu **);
/* interface to MEMX process running on PMU */
struct nvkm_memx;
......
......@@ -1162,7 +1162,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
void
nouveau_bo_move_init(struct nouveau_drm *drm)
{
static const struct {
static const struct _method_table {
const char *name;
int engine;
s32 oclass;
......@@ -1192,7 +1192,8 @@ nouveau_bo_move_init(struct nouveau_drm *drm)
{ "M2MF", 0, 0x0039, nv04_bo_move_m2mf, nv04_bo_move_init },
{},
{ "CRYPT", 0, 0x88b4, nv98_bo_move_exec, nv50_bo_move_init },
}, *mthd = _methods;
};
const struct _method_table *mthd = _methods;
const char *name = "CPU";
int ret;
......
......@@ -635,10 +635,10 @@ nouveau_dmem_migrate_vma(struct nouveau_drm *drm,
unsigned long c, i;
int ret = -ENOMEM;
args.src = kcalloc(max, sizeof(args.src), GFP_KERNEL);
args.src = kcalloc(max, sizeof(*args.src), GFP_KERNEL);
if (!args.src)
goto out;
args.dst = kcalloc(max, sizeof(args.dst), GFP_KERNEL);
args.dst = kcalloc(max, sizeof(*args.dst), GFP_KERNEL);
if (!args.dst)
goto out_free_src;
......
......@@ -715,7 +715,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev,
void
nouveau_drm_device_remove(struct drm_device *dev)
{
struct pci_dev *pdev = dev->pdev;
struct nouveau_drm *drm = nouveau_drm(dev);
struct nvkm_client *client;
struct nvkm_device *device;
......@@ -727,7 +726,6 @@ nouveau_drm_device_remove(struct drm_device *dev)
device = nvkm_device_find(client->device);
nouveau_drm_device_fini(dev);
pci_disable_device(pdev);
drm_dev_put(dev);
nvkm_device_del(&device);
}
......@@ -738,6 +736,7 @@ nouveau_drm_remove(struct pci_dev *pdev)
struct drm_device *dev = pci_get_drvdata(pdev);
nouveau_drm_device_remove(dev);
pci_disable_device(pdev);
}
static int
......
......@@ -156,7 +156,7 @@ nouveau_fence_wait_uevent_handler(struct nvif_notify *notify)
fence = list_entry(fctx->pending.next, typeof(*fence), head);
chan = rcu_dereference_protected(fence->channel, lockdep_is_held(&fctx->lock));
if (nouveau_fence_update(fence->channel, fctx))
if (nouveau_fence_update(chan, fctx))
ret = NVIF_NOTIFY_DROP;
}
spin_unlock_irqrestore(&fctx->lock, flags);
......
......@@ -741,7 +741,7 @@ nouveau_hwmon_init(struct drm_device *dev)
special_groups[i++] = &pwm_fan_sensor_group;
}
special_groups[i] = 0;
special_groups[i] = NULL;
hwmon_dev = hwmon_device_register_with_info(dev->dev, "nouveau", dev,
&nouveau_chip_info,
special_groups);
......
......@@ -63,14 +63,12 @@ nouveau_vram_manager_new(struct ttm_mem_type_manager *man,
{
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
struct nouveau_mem *mem;
int ret;
if (drm->client.device.info.ram_size == 0)
return -ENOMEM;
ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg);
mem = nouveau_mem(reg);
if (ret)
return ret;
......@@ -103,11 +101,9 @@ nouveau_gart_manager_new(struct ttm_mem_type_manager *man,
{
struct nouveau_bo *nvbo = nouveau_bo(bo);
struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
struct nouveau_mem *mem;
int ret;
ret = nouveau_mem_new(&drm->master, nvbo->kind, nvbo->comp, reg);
mem = nouveau_mem(reg);
if (ret)
return ret;
......
......@@ -121,6 +121,7 @@ nvif_mmu_init(struct nvif_object *parent, s32 oclass, struct nvif_mmu *mmu)
kind, argc);
if (ret == 0)
memcpy(mmu->kind, kind->data, kind->count);
mmu->kind_inv = kind->kind_inv;
kfree(kind);
}
......
# SPDX-License-Identifier: MIT
include $(src)/nvkm/core/Kbuild
include $(src)/nvkm/nvfw/Kbuild
include $(src)/nvkm/falcon/Kbuild
include $(src)/nvkm/subdev/Kbuild
include $(src)/nvkm/engine/Kbuild
......@@ -22,6 +22,40 @@
#include <core/device.h>
#include <core/firmware.h>
int
nvkm_firmware_load_name(const struct nvkm_subdev *subdev, const char *base,
const char *name, int ver, const struct firmware **pfw)
{
char path[64];
int ret;
snprintf(path, sizeof(path), "%s%s", base, name);
ret = nvkm_firmware_get(subdev, path, ver, pfw);
if (ret < 0)
return ret;
return 0;
}
int
nvkm_firmware_load_blob(const struct nvkm_subdev *subdev, const char *base,
const char *name, int ver, struct nvkm_blob *blob)
{
const struct firmware *fw;
int ret;
ret = nvkm_firmware_load_name(subdev, base, name, ver, &fw);
if (ret == 0) {
blob->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
blob->size = fw->size;
nvkm_firmware_put(fw);
if (!blob->data)
return -ENOMEM;
}
return ret;
}
/**
* nvkm_firmware_get - load firmware from the official nvidia/chip/ directory
* @subdev subdevice that will use that firmware
......@@ -32,9 +66,8 @@
* Firmware files released by NVIDIA will always follow this format.
*/
int
nvkm_firmware_get_version(const struct nvkm_subdev *subdev, const char *fwname,
int min_version, int max_version,
const struct firmware **fw)
nvkm_firmware_get(const struct nvkm_subdev *subdev, const char *fwname, int ver,
const struct firmware **fw)
{
struct nvkm_device *device = subdev->device;
char f[64];
......@@ -50,31 +83,21 @@ nvkm_firmware_get_version(const struct nvkm_subdev *subdev, const char *fwname,
cname[i] = tolower(cname[i]);
}
for (i = max_version; i >= min_version; i--) {
if (i != 0)
snprintf(f, sizeof(f), "nvidia/%s/%s-%d.bin", cname, fwname, i);
else
snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
if (!firmware_request_nowarn(fw, f, device->dev)) {
nvkm_debug(subdev, "firmware \"%s\" loaded\n", f);
return i;
}
if (ver != 0)
snprintf(f, sizeof(f), "nvidia/%s/%s-%d.bin", cname, fwname, ver);
else
snprintf(f, sizeof(f), "nvidia/%s/%s.bin", cname, fwname);
nvkm_debug(subdev, "firmware \"%s\" unavailable\n", f);
if (!firmware_request_nowarn(fw, f, device->dev)) {
nvkm_debug(subdev, "firmware \"%s\" loaded - %zu byte(s)\n",
f, (*fw)->size);
return 0;
}
nvkm_error(subdev, "failed to load firmware \"%s\"", fwname);
nvkm_debug(subdev, "firmware \"%s\" unavailable\n", f);
return -ENOENT;
}
int
nvkm_firmware_get(const struct nvkm_subdev *subdev, const char *fwname,
const struct firmware **fw)
{
return nvkm_firmware_get_version(subdev, fwname, 0, 0, fw);
}
/**
* nvkm_firmware_put - release firmware loaded with nvkm_firmware_get
*/
......
......@@ -30,6 +30,7 @@ static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR];
const char *
nvkm_subdev_name[NVKM_SUBDEV_NR] = {
[NVKM_SUBDEV_ACR ] = "acr",
[NVKM_SUBDEV_BAR ] = "bar",
[NVKM_SUBDEV_VBIOS ] = "bios",
[NVKM_SUBDEV_BUS ] = "bus",
......@@ -50,7 +51,6 @@ nvkm_subdev_name[NVKM_SUBDEV_NR] = {
[NVKM_SUBDEV_MXM ] = "mxm",
[NVKM_SUBDEV_PCI ] = "pci",
[NVKM_SUBDEV_PMU ] = "pmu",
[NVKM_SUBDEV_SECBOOT ] = "secboot",
[NVKM_SUBDEV_THERM ] = "therm",
[NVKM_SUBDEV_TIMER ] = "tmr",
[NVKM_SUBDEV_TOP ] = "top",
......
......@@ -3,6 +3,7 @@
#define __NVKM_DEVICE_PRIV_H__
#include <core/device.h>
#include <subdev/acr.h>
#include <subdev/bar.h>
#include <subdev/bios.h>
#include <subdev/bus.h>
......@@ -27,7 +28,6 @@
#include <subdev/timer.h>
#include <subdev/top.h>
#include <subdev/volt.h>
#include <subdev/secboot.h>
#include <engine/bsp.h>
#include <engine/ce.h>
......
......@@ -52,18 +52,18 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev)
clk_set_rate(tdev->clk_pwr, 204000000);
udelay(10);
reset_control_assert(tdev->rst);
udelay(10);
if (!tdev->pdev->dev.pm_domain) {
reset_control_assert(tdev->rst);
udelay(10);
ret = tegra_powergate_remove_clamping(TEGRA_POWERGATE_3D);
if (ret)
goto err_clamp;
udelay(10);
}
reset_control_deassert(tdev->rst);
udelay(10);
reset_control_deassert(tdev->rst);
udelay(10);
}
return 0;
......@@ -279,6 +279,7 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
struct nvkm_device **pdevice)
{
struct nvkm_device_tegra *tdev;
unsigned long rate;
int ret;
if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL)))
......@@ -307,6 +308,17 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func,
goto free;
}
rate = clk_get_rate(tdev->clk);
if (rate == 0) {
ret = clk_set_rate(tdev->clk, ULONG_MAX);
if (ret < 0)
goto free;
rate = clk_get_rate(tdev->clk);
dev_dbg(&pdev->dev, "GPU clock set to %lu\n", rate);
}
if (func->require_ref_clk)
tdev->clk_ref = devm_clk_get(&pdev->dev, "ref");
if (IS_ERR(tdev->clk_ref)) {
......
......@@ -365,7 +365,7 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
* and it's better to have a failed modeset than that.
*/
for (cfg = nvkm_dp_rates; cfg->rate; cfg++) {
if (cfg->nr <= outp_nr && cfg->nr <= outp_bw) {
if (cfg->nr <= outp_nr && cfg->bw <= outp_bw) {
/* Try to respect sink limits too when selecting
* lowest link configuration.
*/
......
......@@ -36,8 +36,10 @@ nvkm-y += nvkm/engine/gr/gp100.o
nvkm-y += nvkm/engine/gr/gp102.o
nvkm-y += nvkm/engine/gr/gp104.o
nvkm-y += nvkm/engine/gr/gp107.o
nvkm-y += nvkm/engine/gr/gp108.o
nvkm-y += nvkm/engine/gr/gp10b.o
nvkm-y += nvkm/engine/gr/gv100.o
nvkm-y += nvkm/engine/gr/tu102.o
nvkm-y += nvkm/engine/gr/ctxnv40.o
nvkm-y += nvkm/engine/gr/ctxnv50.o
......@@ -60,3 +62,4 @@ nvkm-y += nvkm/engine/gr/ctxgp102.o
nvkm-y += nvkm/engine/gr/ctxgp104.o
nvkm-y += nvkm/engine/gr/ctxgp107.o
nvkm-y += nvkm/engine/gr/ctxgv100.o
nvkm-y += nvkm/engine/gr/ctxtu102.o
......@@ -1324,10 +1324,8 @@ gf100_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm)
void
gf100_grctx_generate_floorsweep(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const struct gf100_grctx_func *func = gr->func->grctx;
int gpc, sm, i, j;
u32 data;
int sm;
for (sm = 0; sm < gr->sm_nr; sm++) {
func->sm_id(gr, gr->sm[sm].gpc, gr->sm[sm].tpc, sm);
......@@ -1335,12 +1333,9 @@ gf100_grctx_generate_floorsweep(struct gf100_gr *gr)
func->tpc_nr(gr, gr->sm[sm].gpc);
}
for (gpc = 0, i = 0; i < 4; i++) {
for (data = 0, j = 0; j < 8 && gpc < gr->gpc_nr; j++, gpc++)
data |= gr->tpc_nr[gpc] << (j * 4);
nvkm_wr32(device, 0x406028 + (i * 4), data);
nvkm_wr32(device, 0x405870 + (i * 4), data);
}
gf100_gr_init_num_tpc_per_gpc(gr, false, true);
if (!func->skip_pd_num_tpc_per_gpc)
gf100_gr_init_num_tpc_per_gpc(gr, true, false);
if (func->r4060a8)
func->r4060a8(gr);
......@@ -1374,7 +1369,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_mc_unk260(device, 0);
if (!gr->fuc_sw_ctx) {
if (!gr->sw_ctx) {
gf100_gr_mmio(gr, grctx->hub);
gf100_gr_mmio(gr, grctx->gpc_0);
gf100_gr_mmio(gr, grctx->zcull);
......@@ -1382,7 +1377,7 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_gr_mmio(gr, grctx->tpc);
gf100_gr_mmio(gr, grctx->ppc);
} else {
gf100_gr_mmio(gr, gr->fuc_sw_ctx);
gf100_gr_mmio(gr, gr->sw_ctx);
}
gf100_gr_wait_idle(gr);
......@@ -1401,8 +1396,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
gf100_gr_wait_idle(gr);
if (grctx->r400088) grctx->r400088(gr, false);
if (gr->fuc_bundle)
gf100_gr_icmd(gr, gr->fuc_bundle);
if (gr->bundle)
gf100_gr_icmd(gr, gr->bundle);
else
gf100_gr_icmd(gr, grctx->icmd);
if (grctx->sw_veid_bundle_init)
......@@ -1411,8 +1406,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x404154, idle_timeout);
if (gr->fuc_method)
gf100_gr_mthd(gr, gr->fuc_method);
if (gr->method)
gf100_gr_mthd(gr, gr->method);
else
gf100_gr_mthd(gr, grctx->mthd);
nvkm_mc_unk260(device, 1);
......@@ -1431,6 +1426,8 @@ gf100_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
grctx->r419a3c(gr);
if (grctx->r408840)
grctx->r408840(gr);
if (grctx->r419c0c)
grctx->r419c0c(gr);
}
#define CB_RESERVED 0x80000
......
......@@ -57,6 +57,7 @@ struct gf100_grctx_func {
/* floorsweeping */
void (*sm_id)(struct gf100_gr *, int gpc, int tpc, int sm);
void (*tpc_nr)(struct gf100_gr *, int gpc);
bool skip_pd_num_tpc_per_gpc;
void (*r4060a8)(struct gf100_gr *);
void (*rop_mapping)(struct gf100_gr *);
void (*alpha_beta_tables)(struct gf100_gr *);
......@@ -76,6 +77,7 @@ struct gf100_grctx_func {
void (*r418e94)(struct gf100_gr *);
void (*r419a3c)(struct gf100_gr *);
void (*r408840)(struct gf100_gr *);
void (*r419c0c)(struct gf100_gr *);
};
extern const struct gf100_grctx_func gf100_grctx;
......@@ -153,6 +155,14 @@ extern const struct gf100_grctx_func gp107_grctx;
extern const struct gf100_grctx_func gv100_grctx;
extern const struct gf100_grctx_func tu102_grctx;
void gv100_grctx_unkn88c(struct gf100_gr *, bool);
void gv100_grctx_generate_unkn(struct gf100_gr *);
extern const struct gf100_gr_init gv100_grctx_init_sw_veid_bundle_init_0[];
void gv100_grctx_generate_attrib(struct gf100_grctx *);
void gv100_grctx_generate_rop_mapping(struct gf100_gr *);
void gv100_grctx_generate_r400088(struct gf100_gr *, bool);
/* context init value lists */
extern const struct gf100_gr_pack gf100_grctx_pack_icmd[];
......
......@@ -32,7 +32,7 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
u32 idle_timeout;
int i;
gf100_gr_mmio(gr, gr->fuc_sw_ctx);
gf100_gr_mmio(gr, gr->sw_ctx);
gf100_gr_wait_idle(gr);
......@@ -56,10 +56,10 @@ gk20a_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_wait_idle(gr);
gf100_gr_mthd(gr, gr->fuc_method);
gf100_gr_mthd(gr, gr->method);
gf100_gr_wait_idle(gr);
gf100_gr_icmd(gr, gr->fuc_bundle);
gf100_gr_icmd(gr, gr->bundle);
grctx->pagepool(info);
grctx->bundle(info);
}
......
......@@ -29,7 +29,7 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
u32 idle_timeout;
int i, tmp;
gf100_gr_mmio(gr, gr->fuc_sw_ctx);
gf100_gr_mmio(gr, gr->sw_ctx);
gf100_gr_wait_idle(gr);
......@@ -59,10 +59,10 @@ gm20b_grctx_generate_main(struct gf100_gr *gr, struct gf100_grctx *info)
nvkm_wr32(device, 0x404154, idle_timeout);
gf100_gr_wait_idle(gr);
gf100_gr_mthd(gr, gr->fuc_method);
gf100_gr_mthd(gr, gr->method);
gf100_gr_wait_idle(gr);
gf100_gr_icmd(gr, gr->fuc_bundle);
gf100_gr_icmd(gr, gr->bundle);
grctx->pagepool(info);
grctx->bundle(info);
}
......
......@@ -25,7 +25,7 @@
* PGRAPH context implementation
******************************************************************************/
static const struct gf100_gr_init
const struct gf100_gr_init
gv100_grctx_init_sw_veid_bundle_init_0[] = {
{ 0x00001000, 64, 0x00100000, 0x00000008 },
{ 0x00000941, 64, 0x00100000, 0x00000000 },
......@@ -58,7 +58,7 @@ gv100_grctx_pack_sw_veid_bundle_init[] = {
{}
};
static void
void
gv100_grctx_generate_attrib(struct gf100_grctx *info)
{
struct gf100_gr *gr = info->gr;
......@@ -67,14 +67,14 @@ gv100_grctx_generate_attrib(struct gf100_grctx *info)
const u32 attrib = grctx->attrib_nr;
const u32 gfxp = grctx->gfxp_nr;
const int s = 12;
const int max_batches = 0xffff;
u32 size = grctx->alpha_nr_max * gr->tpc_total;
u32 ao = 0;
u32 bo = ao + size;
int gpc, ppc, b, n = 0;
size += grctx->gfxp_nr * gr->tpc_total;
size = ((size * 0x20) + 128) & ~127;
for (gpc = 0; gpc < gr->gpc_nr; gpc++)
size += grctx->gfxp_nr * gr->ppc_nr[gpc] * gr->ppc_tpc_max;
size = ((size * 0x20) + 127) & ~127;
b = mmio_vram(info, size, (1 << s), false);
mmio_refn(info, 0x418810, 0x80000000, s, b);
......@@ -84,13 +84,12 @@ gv100_grctx_generate_attrib(struct gf100_grctx *info)
mmio_wr32(info, 0x419e04, 0x80000000 | size >> 7);
mmio_wr32(info, 0x405830, attrib);
mmio_wr32(info, 0x40585c, alpha);
mmio_wr32(info, 0x4064c4, ((alpha / 4) << 16) | max_batches);
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
for (ppc = 0; ppc < gr->ppc_nr[gpc]; ppc++, n++) {
const u32 as = alpha * gr->ppc_tpc_nr[gpc][ppc];
const u32 bs = attrib * gr->ppc_tpc_nr[gpc][ppc];
const u32 gs = gfxp * gr->ppc_tpc_nr[gpc][ppc];
const u32 bs = attrib * gr->ppc_tpc_max;
const u32 gs = gfxp * gr->ppc_tpc_max;
const u32 u = 0x418ea0 + (n * 0x04);
const u32 o = PPC_UNIT(gpc, ppc, 0);
if (!(gr->ppc_mask[gpc] & (1 << ppc)))
......@@ -110,7 +109,7 @@ gv100_grctx_generate_attrib(struct gf100_grctx *info)
mmio_wr32(info, 0x41befc, 0x00000100);
}
static void
void
gv100_grctx_generate_rop_mapping(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
......@@ -147,7 +146,7 @@ gv100_grctx_generate_rop_mapping(struct gf100_gr *gr)
gr->screen_tile_row_offset);
}
static void
void
gv100_grctx_generate_r400088(struct gf100_gr *gr, bool on)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
......@@ -163,7 +162,7 @@ gv100_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm)
nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), sm);
}
static void
void
gv100_grctx_generate_unkn(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
......@@ -174,7 +173,7 @@ gv100_grctx_generate_unkn(struct gf100_gr *gr)
nvkm_mask(device, 0x419c00, 0x00000008, 0x00000008);
}
static void
void
gv100_grctx_unkn88c(struct gf100_gr *gr, bool on)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
......
/*
* 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 "ctxgf100.h"
static void
tu102_grctx_generate_r419c0c(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
nvkm_mask(device, 0x419c0c, 0x80000000, 0x80000000);
nvkm_mask(device, 0x40584c, 0x00000008, 0x00000000);
nvkm_mask(device, 0x400080, 0x00000000, 0x00000000);
}
static void
tu102_grctx_generate_sm_id(struct gf100_gr *gr, int gpc, int tpc, int sm)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x608), sm);
nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x088), sm);
}
static const struct gf100_gr_init
tu102_grctx_init_unknown_bundle_init_0[] = {
{ 0x00001000, 1, 0x00000001, 0x00000004 },
{ 0x00002020, 64, 0x00000001, 0x00000000 },
{ 0x0001e100, 1, 0x00000001, 0x00000001 },
{}
};
static const struct gf100_gr_pack
tu102_grctx_pack_sw_veid_bundle_init[] = {
{ gv100_grctx_init_sw_veid_bundle_init_0 },
{ tu102_grctx_init_unknown_bundle_init_0 },
{}
};
static void
tu102_grctx_generate_attrib(struct gf100_grctx *info)
{
const u64 size = 0x80000; /*XXX: educated guess */
const int s = 8;
const int b = mmio_vram(info, size, (1 << s), true);
gv100_grctx_generate_attrib(info);
mmio_refn(info, 0x408070, 0x00000000, s, b);
mmio_wr32(info, 0x408074, size >> s); /*XXX: guess */
mmio_refn(info, 0x419034, 0x00000000, s, b);
mmio_wr32(info, 0x408078, 0x00000000);
}
const struct gf100_grctx_func
tu102_grctx = {
.unkn88c = gv100_grctx_unkn88c,
.main = gf100_grctx_generate_main,
.unkn = gv100_grctx_generate_unkn,
.sw_veid_bundle_init = tu102_grctx_pack_sw_veid_bundle_init,
.bundle = gm107_grctx_generate_bundle,
.bundle_size = 0x3000,
.bundle_min_gpm_fifo_depth = 0x180,
.bundle_token_limit = 0xa80,
.pagepool = gp100_grctx_generate_pagepool,
.pagepool_size = 0x20000,
.attrib = tu102_grctx_generate_attrib,
.attrib_nr_max = 0x800,
.attrib_nr = 0x700,
.alpha_nr_max = 0xc00,
.alpha_nr = 0x800,
.gfxp_nr = 0xfa8,
.sm_id = tu102_grctx_generate_sm_id,
.skip_pd_num_tpc_per_gpc = true,
.rop_mapping = gv100_grctx_generate_rop_mapping,
.r406500 = gm200_grctx_generate_r406500,
.r400088 = gv100_grctx_generate_r400088,
.r419c0c = tu102_grctx_generate_r419c0c,
};
......@@ -144,8 +144,15 @@ gf104_gr = {
}
};
static const struct gf100_gr_fwif
gf104_gr_fwif[] = {
{ -1, gf100_gr_load, &gf104_gr },
{ -1, gf100_gr_nofw, &gf104_gr },
{}
};
int
gf104_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf104_gr, device, index, pgr);
return gf100_gr_new_(gf104_gr_fwif, device, index, pgr);
}
......@@ -143,8 +143,15 @@ gf108_gr = {
}
};
const struct gf100_gr_fwif
gf108_gr_fwif[] = {
{ -1, gf100_gr_load, &gf108_gr },
{ -1, gf100_gr_nofw, &gf108_gr },
{}
};
int
gf108_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf108_gr, device, index, pgr);
return gf100_gr_new_(gf108_gr_fwif, device, index, pgr);
}
......@@ -119,8 +119,15 @@ gf110_gr = {
}
};
static const struct gf100_gr_fwif
gf110_gr_fwif[] = {
{ -1, gf100_gr_load, &gf110_gr },
{ -1, gf100_gr_nofw, &gf110_gr },
{}
};
int
gf110_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf110_gr, device, index, pgr);
return gf100_gr_new_(gf110_gr_fwif, device, index, pgr);
}
......@@ -184,8 +184,15 @@ gf117_gr = {
}
};
static const struct gf100_gr_fwif
gf117_gr_fwif[] = {
{ -1, gf100_gr_load, &gf117_gr },
{ -1, gf100_gr_nofw, &gf117_gr },
{}
};
int
gf117_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf117_gr, device, index, pgr);
return gf100_gr_new_(gf117_gr_fwif, device, index, pgr);
}
......@@ -210,8 +210,15 @@ gf119_gr = {
}
};
static const struct gf100_gr_fwif
gf119_gr_fwif[] = {
{ -1, gf100_gr_load, &gf119_gr },
{ -1, gf100_gr_nofw, &gf119_gr },
{}
};
int
gf119_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf119_gr, device, index, pgr);
return gf100_gr_new_(gf119_gr_fwif, device, index, pgr);
}
This diff is collapsed.
# SPDX-License-Identifier: MIT
nvkm-y += nvkm/engine/nvdec/base.o
nvkm-y += nvkm/engine/nvdec/gp102.o
nvkm-y += nvkm/engine/nvdec/gm107.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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