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: Dave 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
This commit is contained in:
Dave Airlie 2020-01-15 16:45:58 +10:00
commit dd22dfa62c
208 changed files with 8155 additions and 7806 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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,

View file

@ -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;
}
if (!(mstc->mstm->outp->dcb->heads & drm_crtc_mask(crtc)))
return NULL;
static struct drm_encoder *
nv50_mstc_best_encoder(struct drm_connector *connector)
{
struct nv50_mstc *mstc = nv50_mstc(connector);
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 */

View file

@ -4,6 +4,8 @@
#include "nouveau_display.h"
struct nv50_msto;
struct nv50_disp {
struct nvif_disp *disp;
struct nv50_core *core;

View file

@ -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;
}

View file

@ -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 *);

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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;

View file

@ -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) {

View file

@ -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 *);

View file

@ -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,

View file

@ -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,

View file

@ -0,0 +1,152 @@
#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

View file

@ -0,0 +1,97 @@
/* 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

View file

@ -0,0 +1,28 @@
/* 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

View file

@ -0,0 +1,31 @@
/* 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

View file

@ -0,0 +1,53 @@
/* 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

View file

@ -0,0 +1,98 @@
#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

View file

@ -0,0 +1,60 @@
#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

View file

@ -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

View file

@ -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[];
};

View file

@ -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;

View file

@ -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 **);

View file

@ -0,0 +1,77 @@
#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

View file

@ -1,12 +1,55 @@
/* 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

View file

@ -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); \

View file

@ -1,43 +0,0 @@
/*
* 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

View file

@ -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

View file

@ -1,6 +1,6 @@
/* 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

View file

@ -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

View file

@ -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

View file

@ -1,5 +1,15 @@
/* 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

View file

@ -1,17 +1,24 @@
/* 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

View file

@ -0,0 +1,126 @@
/* 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

View file

@ -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

View file

@ -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;

View file

@ -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 **);

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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);
}

View file

@ -1,5 +1,6 @@
# 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

View file

@ -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 (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);
if (!firmware_request_nowarn(fw, f, device->dev)) {
nvkm_debug(subdev, "firmware \"%s\" loaded\n", f);
return i;
}
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
*/

View file

@ -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",

View file

@ -1987,6 +1987,8 @@ nv117_chipset = {
.dma = gf119_dma_new,
.fifo = gm107_fifo_new,
.gr = gm107_gr_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.sw = gf100_sw_new,
};
@ -2027,6 +2029,7 @@ nv118_chipset = {
static const struct nvkm_device_chip
nv120_chipset = {
.name = "GM200",
.acr = gm200_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2045,7 +2048,6 @@ nv120_chipset = {
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
.volt = gk104_volt_new,
@ -2056,12 +2058,16 @@ nv120_chipset = {
.dma = gf119_dma_new,
.fifo = gm200_fifo_new,
.gr = gm200_gr_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.nvenc[1] = gm107_nvenc_new,
.sw = gf100_sw_new,
};
static const struct nvkm_device_chip
nv124_chipset = {
.name = "GM204",
.acr = gm200_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2080,7 +2086,6 @@ nv124_chipset = {
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
.volt = gk104_volt_new,
@ -2091,12 +2096,16 @@ nv124_chipset = {
.dma = gf119_dma_new,
.fifo = gm200_fifo_new,
.gr = gm200_gr_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.nvenc[1] = gm107_nvenc_new,
.sw = gf100_sw_new,
};
static const struct nvkm_device_chip
nv126_chipset = {
.name = "GM206",
.acr = gm200_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2115,7 +2124,6 @@ nv126_chipset = {
.pci = gk104_pci_new,
.pmu = gm107_pmu_new,
.therm = gm200_therm_new,
.secboot = gm200_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
.volt = gk104_volt_new,
@ -2126,12 +2134,15 @@ nv126_chipset = {
.dma = gf119_dma_new,
.fifo = gm200_fifo_new,
.gr = gm200_gr_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.sw = gf100_sw_new,
};
static const struct nvkm_device_chip
nv12b_chipset = {
.name = "GM20B",
.acr = gm20b_acr_new,
.bar = gm20b_bar_new,
.bus = gf100_bus_new,
.clk = gm20b_clk_new,
@ -2143,7 +2154,6 @@ nv12b_chipset = {
.mc = gk20a_mc_new,
.mmu = gm20b_mmu_new,
.pmu = gm20b_pmu_new,
.secboot = gm20b_secboot_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
.ce[2] = gm200_ce_new,
@ -2157,6 +2167,7 @@ nv12b_chipset = {
static const struct nvkm_device_chip
nv130_chipset = {
.name = "GP100",
.acr = gm200_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2172,7 +2183,6 @@ nv130_chipset = {
.mc = gp100_mc_new,
.mmu = gp100_mmu_new,
.therm = gp100_therm_new,
.secboot = gm200_secboot_new,
.pci = gp100_pci_new,
.pmu = gp100_pmu_new,
.timer = gk20a_timer_new,
@ -2187,12 +2197,17 @@ nv130_chipset = {
.disp = gp100_disp_new,
.fifo = gp100_fifo_new,
.gr = gp100_gr_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.nvenc[1] = gm107_nvenc_new,
.nvenc[2] = gm107_nvenc_new,
.sw = gf100_sw_new,
};
static const struct nvkm_device_chip
nv132_chipset = {
.name = "GP102",
.acr = gp102_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2208,7 +2223,6 @@ nv132_chipset = {
.mc = gp100_mc_new,
.mmu = gp100_mmu_new,
.therm = gp100_therm_new,
.secboot = gp102_secboot_new,
.pci = gp100_pci_new,
.pmu = gp102_pmu_new,
.timer = gk20a_timer_new,
@ -2221,7 +2235,9 @@ nv132_chipset = {
.dma = gf119_dma_new,
.fifo = gp100_fifo_new,
.gr = gp102_gr_new,
.nvdec[0] = gp102_nvdec_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.nvenc[1] = gm107_nvenc_new,
.sec2 = gp102_sec2_new,
.sw = gf100_sw_new,
};
@ -2229,6 +2245,7 @@ nv132_chipset = {
static const struct nvkm_device_chip
nv134_chipset = {
.name = "GP104",
.acr = gp102_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2244,7 +2261,6 @@ nv134_chipset = {
.mc = gp100_mc_new,
.mmu = gp100_mmu_new,
.therm = gp100_therm_new,
.secboot = gp102_secboot_new,
.pci = gp100_pci_new,
.pmu = gp102_pmu_new,
.timer = gk20a_timer_new,
@ -2257,7 +2273,9 @@ nv134_chipset = {
.dma = gf119_dma_new,
.fifo = gp100_fifo_new,
.gr = gp104_gr_new,
.nvdec[0] = gp102_nvdec_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.nvenc[1] = gm107_nvenc_new,
.sec2 = gp102_sec2_new,
.sw = gf100_sw_new,
};
@ -2265,6 +2283,7 @@ nv134_chipset = {
static const struct nvkm_device_chip
nv136_chipset = {
.name = "GP106",
.acr = gp102_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2280,7 +2299,6 @@ nv136_chipset = {
.mc = gp100_mc_new,
.mmu = gp100_mmu_new,
.therm = gp100_therm_new,
.secboot = gp102_secboot_new,
.pci = gp100_pci_new,
.pmu = gp102_pmu_new,
.timer = gk20a_timer_new,
@ -2293,7 +2311,8 @@ nv136_chipset = {
.dma = gf119_dma_new,
.fifo = gp100_fifo_new,
.gr = gp104_gr_new,
.nvdec[0] = gp102_nvdec_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.sec2 = gp102_sec2_new,
.sw = gf100_sw_new,
};
@ -2301,6 +2320,7 @@ nv136_chipset = {
static const struct nvkm_device_chip
nv137_chipset = {
.name = "GP107",
.acr = gp102_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2316,7 +2336,6 @@ nv137_chipset = {
.mc = gp100_mc_new,
.mmu = gp100_mmu_new,
.therm = gp100_therm_new,
.secboot = gp102_secboot_new,
.pci = gp100_pci_new,
.pmu = gp102_pmu_new,
.timer = gk20a_timer_new,
@ -2329,7 +2348,9 @@ nv137_chipset = {
.dma = gf119_dma_new,
.fifo = gp100_fifo_new,
.gr = gp107_gr_new,
.nvdec[0] = gp102_nvdec_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.nvenc[1] = gm107_nvenc_new,
.sec2 = gp102_sec2_new,
.sw = gf100_sw_new,
};
@ -2337,6 +2358,7 @@ nv137_chipset = {
static const struct nvkm_device_chip
nv138_chipset = {
.name = "GP108",
.acr = gp108_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2352,7 +2374,6 @@ nv138_chipset = {
.mc = gp100_mc_new,
.mmu = gp100_mmu_new,
.therm = gp100_therm_new,
.secboot = gp108_secboot_new,
.pci = gp100_pci_new,
.pmu = gp102_pmu_new,
.timer = gk20a_timer_new,
@ -2364,30 +2385,30 @@ nv138_chipset = {
.disp = gp102_disp_new,
.dma = gf119_dma_new,
.fifo = gp100_fifo_new,
.gr = gp107_gr_new,
.nvdec[0] = gp102_nvdec_new,
.sec2 = gp102_sec2_new,
.gr = gp108_gr_new,
.nvdec[0] = gm107_nvdec_new,
.sec2 = gp108_sec2_new,
.sw = gf100_sw_new,
};
static const struct nvkm_device_chip
nv13b_chipset = {
.name = "GP10B",
.acr = gp10b_acr_new,
.bar = gm20b_bar_new,
.bus = gf100_bus_new,
.fault = gp100_fault_new,
.fault = gp10b_fault_new,
.fb = gp10b_fb_new,
.fuse = gm107_fuse_new,
.ibus = gp10b_ibus_new,
.imem = gk20a_instmem_new,
.ltc = gp102_ltc_new,
.ltc = gp10b_ltc_new,
.mc = gp10b_mc_new,
.mmu = gp10b_mmu_new,
.secboot = gp10b_secboot_new,
.pmu = gm20b_pmu_new,
.pmu = gp10b_pmu_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
.ce[2] = gp102_ce_new,
.ce[0] = gp100_ce_new,
.dma = gf119_dma_new,
.fifo = gp10b_fifo_new,
.gr = gp10b_gr_new,
@ -2397,6 +2418,7 @@ nv13b_chipset = {
static const struct nvkm_device_chip
nv140_chipset = {
.name = "GV100",
.acr = gp108_acr_new,
.bar = gm107_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2414,7 +2436,6 @@ nv140_chipset = {
.mmu = gv100_mmu_new,
.pci = gp100_pci_new,
.pmu = gp102_pmu_new,
.secboot = gp108_secboot_new,
.therm = gp100_therm_new,
.timer = gk20a_timer_new,
.top = gk104_top_new,
@ -2431,13 +2452,17 @@ nv140_chipset = {
.dma = gv100_dma_new,
.fifo = gv100_fifo_new,
.gr = gv100_gr_new,
.nvdec[0] = gp102_nvdec_new,
.sec2 = gp102_sec2_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.nvenc[1] = gm107_nvenc_new,
.nvenc[2] = gm107_nvenc_new,
.sec2 = gp108_sec2_new,
};
static const struct nvkm_device_chip
nv162_chipset = {
.name = "TU102",
.acr = tu102_acr_new,
.bar = tu102_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2466,13 +2491,16 @@ nv162_chipset = {
.disp = tu102_disp_new,
.dma = gv100_dma_new,
.fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.gr = tu102_gr_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.sec2 = tu102_sec2_new,
};
static const struct nvkm_device_chip
nv164_chipset = {
.name = "TU104",
.acr = tu102_acr_new,
.bar = tu102_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2501,13 +2529,17 @@ nv164_chipset = {
.disp = tu102_disp_new,
.dma = gv100_dma_new,
.fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.gr = tu102_gr_new,
.nvdec[0] = gm107_nvdec_new,
.nvdec[1] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.sec2 = tu102_sec2_new,
};
static const struct nvkm_device_chip
nv166_chipset = {
.name = "TU106",
.acr = tu102_acr_new,
.bar = tu102_bar_new,
.bios = nvkm_bios_new,
.bus = gf100_bus_new,
@ -2536,7 +2568,11 @@ nv166_chipset = {
.disp = tu102_disp_new,
.dma = gv100_dma_new,
.fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.gr = tu102_gr_new,
.nvdec[0] = gm107_nvdec_new,
.nvdec[1] = gm107_nvdec_new,
.nvdec[2] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.sec2 = tu102_sec2_new,
};
@ -2571,7 +2607,8 @@ nv167_chipset = {
.disp = tu102_disp_new,
.dma = gv100_dma_new,
.fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.sec2 = tu102_sec2_new,
};
@ -2606,7 +2643,8 @@ nv168_chipset = {
.disp = tu102_disp_new,
.dma = gv100_dma_new,
.fifo = tu102_fifo_new,
.nvdec[0] = gp102_nvdec_new,
.nvdec[0] = gm107_nvdec_new,
.nvenc[0] = gm107_nvenc_new,
.sec2 = tu102_sec2_new,
};
@ -2638,6 +2676,7 @@ nvkm_device_subdev(struct nvkm_device *device, int index)
switch (index) {
#define _(n,p,m) case NVKM_SUBDEV_##n: if (p) return (m); break
_(ACR , device->acr , &device->acr->subdev);
_(BAR , device->bar , &device->bar->subdev);
_(VBIOS , device->bios , &device->bios->subdev);
_(BUS , device->bus , &device->bus->subdev);
@ -2658,7 +2697,6 @@ nvkm_device_subdev(struct nvkm_device *device, int index)
_(MXM , device->mxm , device->mxm);
_(PCI , device->pci , &device->pci->subdev);
_(PMU , device->pmu , &device->pmu->subdev);
_(SECBOOT , device->secboot , &device->secboot->subdev);
_(THERM , device->therm , &device->therm->subdev);
_(TIMER , device->timer , &device->timer->subdev);
_(TOP , device->top , &device->top->subdev);
@ -2703,9 +2741,9 @@ nvkm_device_engine(struct nvkm_device *device, int index)
_(MSPDEC , device->mspdec , device->mspdec);
_(MSPPP , device->msppp , device->msppp);
_(MSVLD , device->msvld , device->msvld);
_(NVENC0 , device->nvenc[0], device->nvenc[0]);
_(NVENC1 , device->nvenc[1], device->nvenc[1]);
_(NVENC2 , device->nvenc[2], device->nvenc[2]);
_(NVENC0 , device->nvenc[0], &device->nvenc[0]->engine);
_(NVENC1 , device->nvenc[1], &device->nvenc[1]->engine);
_(NVENC2 , device->nvenc[2], &device->nvenc[2]->engine);
_(NVDEC0 , device->nvdec[0], &device->nvdec[0]->engine);
_(NVDEC1 , device->nvdec[1], &device->nvdec[1]->engine);
_(NVDEC2 , device->nvdec[2], &device->nvdec[2]->engine);
@ -3144,6 +3182,7 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
} \
break
switch (i) {
_(NVKM_SUBDEV_ACR , acr);
_(NVKM_SUBDEV_BAR , bar);
_(NVKM_SUBDEV_VBIOS , bios);
_(NVKM_SUBDEV_BUS , bus);
@ -3164,7 +3203,6 @@ nvkm_device_ctor(const struct nvkm_device_func *func,
_(NVKM_SUBDEV_MXM , mxm);
_(NVKM_SUBDEV_PCI , pci);
_(NVKM_SUBDEV_PMU , pmu);
_(NVKM_SUBDEV_SECBOOT , secboot);
_(NVKM_SUBDEV_THERM , therm);
_(NVKM_SUBDEV_TIMER , timer);
_(NVKM_SUBDEV_TOP , top);

View file

@ -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>

View file

@ -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)) {

View file

@ -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.
*/

View file

@ -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

View file

@ -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

View file

@ -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[];

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;

View file

@ -0,0 +1,95 @@
/*
* 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,
};

View file

@ -441,7 +441,7 @@ static uint32_t gk208_grhub_code[] = {
0x020014fe,
0x12004002,
0xbd0002f6,
0x05c94104,
0x05ca4104,
0xbd0010fe,
0x07004024,
0xbd0002f6,
@ -460,423 +460,423 @@ static uint32_t gk208_grhub_code[] = {
0x01039204,
0x03090080,
0xbd0003f6,
0x87044204,
0xf6040040,
0x04bd0002,
0x00400402,
0x0002f603,
0x31f404bd,
0x96048e10,
0x00657e40,
0xc7feb200,
0x01b590f1,
0x1ff4f003,
0x01020fb5,
0x041fbb01,
0x800112b6,
0xf6010300,
0x04bd0001,
0x01040080,
0xbd0001f6,
0x01004104,
0xac7e020f,
0xbb7e0006,
0x100f0006,
0x0006fd7e,
0x98000e98,
0x207e010f,
0x14950001,
0xc0008008,
0x0004f601,
0x008004bd,
0x04f601c1,
0xb704bd00,
0xbb130030,
0xf5b6001f,
0xd3008002,
0x000ff601,
0x15b604bd,
0x0110b608,
0xb20814b6,
0x02687e1f,
0x001fbb00,
0x84020398,
/* 0x041f: init_gpc */
0xb8502000,
0x0008044e,
0x8f7e1fb2,
0x4eb80000,
0xbd00010c,
0x008f7ef4,
0x044eb800,
0x8f7e0001,
0x4eb80000,
0x0f000100,
0x008f7e02,
0x004eb800,
/* 0x044e: init_gpc_wait */
0x657e0008,
0xffc80000,
0xf90bf41f,
0x08044eb8,
0x00657e00,
0x001fbb00,
0x800040b7,
0xf40132b6,
0x000fb41b,
0x0006fd7e,
0xac7e000f,
0x00800006,
0x01f60201,
0xbd04bd00,
0x1f19f014,
0x02300080,
0xbd0001f6,
/* 0x0491: wait */
0x0028f404,
/* 0x0497: main */
0x0d0031f4,
0x00377e10,
0xf401f400,
0x4001e4b1,
0x00c71bf5,
0x99f094bd,
0x37008004,
0x0009f602,
0x008104bd,
0x11cf02c0,
0xc1008200,
0x0022cf02,
0xf41f13c8,
0x23c8770b,
0x550bf41f,
0x12b220f9,
0x99f094bd,
0x37008007,
0x0009f602,
0x32f404bd,
0x0231f401,
0x0008807e,
0x99f094bd,
0x17008007,
0x0009f602,
0x20fc04bd,
0x99f094bd,
0x37008006,
0x0009f602,
0x31f404bd,
0x08807e01,
0xf094bd00,
0x00800699,
0x09f60217,
0xf404bd00,
/* 0x0522: chsw_prev_no_next */
0x20f92f0e,
0x32f412b2,
0x0232f401,
0x0008807e,
0x008020fc,
0x02f602c0,
0xf404bd00,
/* 0x053e: chsw_no_prev */
0x23c8130e,
0x0d0bf41f,
0xf40131f4,
0x807e0232,
/* 0x054e: chsw_done */
0x01020008,
0x02c30080,
0x87048204,
0x04004000,
0xbd0002f6,
0xf094bd04,
0x00800499,
0x09f60217,
0xf504bd00,
/* 0x056b: main_not_ctx_switch */
0xb0ff300e,
0x1bf401e4,
0x7ef2b20c,
0xf4000820,
/* 0x057a: main_not_ctx_chan */
0xe4b0400e,
0x2c1bf402,
0x99f094bd,
0x37008007,
0x0009f602,
0x32f404bd,
0x0232f401,
0x0008807e,
0x99f094bd,
0x17008007,
0x0009f602,
0x0ef404bd,
/* 0x05a9: main_not_ctx_save */
0x10ef9411,
0x7e01f5f0,
0xf50002f8,
/* 0x05b7: main_done */
0xbdfee40e,
0x1f29f024,
0x02300080,
0xbd0002f6,
0xd20ef504,
/* 0x05c9: ih */
0xf900f9fe,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
0xe0f9d0f9,
0x04bdf0f9,
0xcf02004a,
0xabc400aa,
0x230bf404,
0x004e100d,
0x00eecf1a,
0xcf19004f,
0x047e00ff,
0xb0b70000,
0x010e0400,
0xf61d0040,
0x04bd000e,
/* 0x060c: ih_no_fifo */
0x0100abe4,
0x0d0c0bf4,
0x40014e10,
0x0000047e,
/* 0x061c: ih_no_ctxsw */
0x0400abe4,
0x8e560bf4,
0x7e400708,
0xb2000065,
0x040080ff,
0x000ff602,
0x048e04bd,
0x657e4007,
0xffb20000,
0x02030080,
0xbd000ff6,
0x50fec704,
0x8f02ee94,
0xbb400700,
0x657e00ef,
0x00800000,
0x0ff60202,
0x0f04bd00,
0x02f87e03,
0x01004b00,
0x448ebfb2,
0x8f7e4001,
/* 0x0676: ih_no_fwmthd */
0x044b0000,
0xffb0bd05,
0x0bf4b4ab,
0x0700800c,
0x000bf603,
/* 0x068a: ih_no_other */
0x004004bd,
0x000af601,
0xf0fc04bd,
0xd0fce0fc,
0xa0fcb0fc,
0x80fc90fc,
0xfc0088fe,
0xf400fc80,
0x01f80032,
/* 0x06ac: ctx_4170s */
0xb210f5f0,
0x41708eff,
0x008f7e40,
/* 0x06bb: ctx_4170w */
0x8e00f800,
0x7e404170,
0xb2000065,
0x10f4f0ff,
0xf8f31bf4,
/* 0x06cd: ctx_redswitch */
0x02004e00,
0xf040e5f0,
0xe5f020e5,
0x85008010,
0x000ef601,
0x080f04bd,
/* 0x06e4: ctx_redswitch_delay */
0xf401f2b6,
0xe5f1fd1b,
0xe5f10400,
0x00800100,
0x0ef60185,
0xf804bd00,
/* 0x06fd: ctx_86c */
0x23008000,
0x000ff602,
0xffb204bd,
0x408a148e,
0x00008f7e,
0x8c8effb2,
0x8f7e41a8,
0x00f80000,
/* 0x071c: ctx_mem */
0x02840080,
0xbd000ff6,
/* 0x0725: ctx_mem_wait */
0x84008f04,
0x00ffcf02,
0xf405fffd,
0x00f8f61b,
/* 0x0734: ctx_load */
0x99f094bd,
0x37008005,
0x0009f602,
0x0c0a04bd,
0x0000b87e,
0x0080f4bd,
0x0ff60289,
0x40040204,
0x02f60300,
0xf404bd00,
0x048e1031,
0x657e4096,
0xfeb20000,
0xb590f1c7,
0xf4f00301,
0x020fb51f,
0x1fbb0101,
0x0112b604,
0x01030080,
0xbd0001f6,
0x04008004,
0x0001f601,
0x004104bd,
0x7e020f01,
0x7e0006ad,
0x0f0006bc,
0x06fe7e10,
0x000e9800,
0x7e010f98,
0x95000120,
0x00800814,
0x04f601c0,
0x8004bd00,
0xf602c100,
0x04bd0002,
0x02830080,
0xbd0002f6,
0x7e070f04,
0x8000071c,
0xf601c100,
0x04bd0004,
0x130030b7,
0xb6001fbb,
0x008002f5,
0x0ff601d3,
0xb604bd00,
0x10b60815,
0x0814b601,
0x687e1fb2,
0x1fbb0002,
0x02039800,
0x50200084,
/* 0x0420: init_gpc */
0x08044eb8,
0x7e1fb200,
0xb800008f,
0x00010c4e,
0x8f7ef4bd,
0x4eb80000,
0x7e000104,
0xb800008f,
0x0001004e,
0x8f7e020f,
0x4eb80000,
/* 0x044f: init_gpc_wait */
0x7e000800,
0xc8000065,
0x0bf41fff,
0x044eb8f9,
0x657e0008,
0x1fbb0000,
0x0040b700,
0x0132b680,
0x0fb41bf4,
0x06fe7e00,
0x7e000f00,
0x800006ad,
0xf6020100,
0x04bd0001,
0x19f014bd,
0x3000801f,
0x0001f602,
/* 0x0492: wait */
0x28f404bd,
0x0031f400,
/* 0x0498: main */
0x377e100d,
0x01f40000,
0x01e4b1f4,
0xc71bf540,
0xf094bd00,
0x00800499,
0x09f60237,
0x8104bd00,
0xcf02c000,
0x00820011,
0x22cf02c1,
0x1f13c800,
0xc8770bf4,
0x0bf41f23,
0xb220f955,
0xf094bd12,
0x00800799,
0x09f60237,
0xf404bd00,
0x31f40132,
0x08817e02,
0xf094bd00,
0x00800799,
0x09f60217,
0xfc04bd00,
0xf094bd20,
0x00800699,
0x09f60237,
0xf404bd00,
0x817e0131,
0x94bd0008,
0x800699f0,
0xf6021700,
0x04bd0009,
/* 0x0523: chsw_prev_no_next */
0xf92f0ef4,
0xf412b220,
0x32f40132,
0x08817e02,
0x8020fc00,
0xf602c000,
0x04bd0002,
0xf0000bfe,
0x24b61f2a,
0x0220b604,
0x99f094bd,
0x37008008,
0x0009f602,
0x008004bd,
0x02f60281,
0xd204bd00,
0x80000000,
0x800225f0,
0xf6028800,
0x04bd0002,
0x00421001,
0x0223f002,
0xf80512fa,
0xf094bd03,
0x00800899,
/* 0x053f: chsw_no_prev */
0xc8130ef4,
0x0bf41f23,
0x0131f40d,
0x7e0232f4,
/* 0x054f: chsw_done */
0x02000881,
0xc3008001,
0x0002f602,
0x94bd04bd,
0x800499f0,
0xf6021700,
0x04bd0009,
0xff300ef5,
/* 0x056c: main_not_ctx_switch */
0xf401e4b0,
0xf2b20c1b,
0x0008217e,
/* 0x057b: main_not_ctx_chan */
0xb0400ef4,
0x1bf402e4,
0xf094bd2c,
0x00800799,
0x09f60237,
0xf404bd00,
0x32f40132,
0x08817e02,
0xf094bd00,
0x00800799,
0x09f60217,
0x9804bd00,
0x14b68101,
0x80029818,
0xfd0825b6,
0x01b50512,
0xf094bd16,
0x00800999,
0xf404bd00,
/* 0x05aa: main_not_ctx_save */
0xef94110e,
0x01f5f010,
0x0002f87e,
0xfee40ef5,
/* 0x05b8: main_done */
0x29f024bd,
0x3000801f,
0x0002f602,
0x0ef504bd,
/* 0x05ca: ih */
0x00f9fed2,
0x88fe80f9,
0xf980f901,
0xf9a0f990,
0xf9d0f9b0,
0xbdf0f9e0,
0x02004a04,
0xc400aacf,
0x0bf404ab,
0x4e100d23,
0xeecf1a00,
0x19004f00,
0x7e00ffcf,
0xb7000004,
0x0e0400b0,
0x1d004001,
0xbd000ef6,
/* 0x060d: ih_no_fifo */
0x00abe404,
0x0c0bf401,
0x014e100d,
0x00047e40,
/* 0x061d: ih_no_ctxsw */
0x00abe400,
0x560bf404,
0x4007088e,
0x0000657e,
0x0080ffb2,
0x0ff60204,
0x8e04bd00,
0x7e400704,
0xb2000065,
0x030080ff,
0x000ff602,
0xfec704bd,
0x02ee9450,
0x4007008f,
0x7e00efbb,
0x80000065,
0xf6020200,
0x04bd000f,
0xf87e030f,
0x004b0002,
0x8ebfb201,
0x7e400144,
/* 0x0677: ih_no_fwmthd */
0x4b00008f,
0xb0bd0504,
0xf4b4abff,
0x00800c0b,
0x0bf60307,
/* 0x068b: ih_no_other */
0x4004bd00,
0x0af60100,
0xfc04bd00,
0xfce0fcf0,
0xfcb0fcd0,
0xfc90fca0,
0x0088fe80,
0x00fc80fc,
0xf80032f4,
/* 0x06ad: ctx_4170s */
0x10f5f001,
0x708effb2,
0x8f7e4041,
0x00f80000,
/* 0x06bc: ctx_4170w */
0x4041708e,
0x0000657e,
0xf4f0ffb2,
0xf31bf410,
/* 0x06ce: ctx_redswitch */
0x004e00f8,
0x40e5f002,
0xf020e5f0,
0x008010e5,
0x0ef60185,
0x0f04bd00,
/* 0x06e5: ctx_redswitch_delay */
0x01f2b608,
0xf1fd1bf4,
0xf10400e5,
0x800100e5,
0xf6018500,
0x04bd000e,
/* 0x06fe: ctx_86c */
0x008000f8,
0x0ff60223,
0xb204bd00,
0x8a148eff,
0x008f7e40,
0x8effb200,
0x7e41a88c,
0xf800008f,
/* 0x071d: ctx_mem */
0x84008000,
0x000ff602,
/* 0x0726: ctx_mem_wait */
0x008f04bd,
0xffcf0284,
0x05fffd00,
0xf8f61bf4,
/* 0x0735: ctx_load */
0xf094bd00,
0x00800599,
0x09f60237,
0x0a04bd00,
0x00b87e0c,
0x80f4bd00,
0xf6028900,
0x04bd000f,
0x02c10080,
0xbd0002f6,
0x83008004,
0x0002f602,
0x070f04bd,
0x00071d7e,
0x02c00080,
0xbd0002f6,
0x000bfe04,
0xb61f2af0,
0x20b60424,
0xf094bd02,
0x00800899,
0x09f60237,
0x8004bd00,
0xf6028100,
0x04bd0001,
0x00800102,
0x02f60288,
0x4104bd00,
0x13f00100,
0x0501fa06,
0x04bd0002,
0x000000d2,
0x0225f080,
0x02880080,
0xbd0002f6,
0x42100104,
0x23f00200,
0x0512fa02,
0x94bd03f8,
0x800999f0,
0x800899f0,
0xf6021700,
0x04bd0009,
0x99f094bd,
0x17008005,
0x0009f602,
0x00f804bd,
/* 0x0820: ctx_chan */
0x0007347e,
0xb87e0c0a,
0x050f0000,
0x00071c7e,
/* 0x0832: ctx_mmio_exec */
0x039800f8,
0x81008041,
0x0003f602,
0x34bd04bd,
/* 0x0840: ctx_mmio_loop */
0xf4ff34c4,
0x00450e1b,
0x0653f002,
0xf80535fa,
/* 0x0851: ctx_mmio_pull */
0x804e9803,
0x7e814f98,
0xb600008f,
0x12b60830,
0xdf1bf401,
/* 0x0864: ctx_mmio_done */
0x80160398,
0xf6028100,
0x04bd0003,
0x414000b5,
0x13f00100,
0x0601fa06,
0x00f803f8,
/* 0x0880: ctx_xfer */
0x0080040e,
0x0ef60302,
/* 0x088b: ctx_xfer_idle */
0x8e04bd00,
0xcf030000,
0xe4f100ee,
0x1bf42000,
0x0611f4f5,
/* 0x089f: ctx_xfer_pre */
0x0f0c02f4,
0x06fd7e10,
0x1b11f400,
/* 0x08a8: ctx_xfer_pre_load */
0xac7e020f,
0xbb7e0006,
0xcd7e0006,
0xf4bd0006,
0x0006ac7e,
0x0007347e,
/* 0x08c0: ctx_xfer_exec */
0xbd160198,
0x05008024,
0x0002f601,
0x1fb204bd,
0x41a5008e,
0x00008f7e,
0xf001fcf0,
0x24b6022c,
0x05f2fd01,
0x048effb2,
0x8f7e41a5,
0x167e0000,
0x24bd0002,
0x0247fc80,
0xbd0002f6,
0x012cf004,
0x800320b6,
0xf6024afc,
0xb6810198,
0x02981814,
0x0825b680,
0xb50512fd,
0x94bd1601,
0x800999f0,
0xf6023700,
0x04bd0009,
0x02810080,
0xbd0001f6,
0x80010204,
0xf6028800,
0x04bd0002,
0xf001acf0,
0x000b06a5,
0x98000c98,
0x000e010d,
0x00013d7e,
0xec7e080a,
0x0a7e0000,
0x01f40002,
0x7e0c0a12,
0xf0010041,
0x01fa0613,
0xbd03f805,
0x0999f094,
0x02170080,
0xbd0009f6,
0xf094bd04,
0x00800599,
0x09f60217,
0xf804bd00,
/* 0x0821: ctx_chan */
0x07357e00,
0x7e0c0a00,
0x0f0000b8,
0x071c7e05,
0x2d02f400,
/* 0x093c: ctx_xfer_post */
0xac7e020f,
0xf4bd0006,
0x0006fd7e,
0x0002277e,
0x0006bb7e,
0xac7ef4bd,
0x071d7e05,
/* 0x0833: ctx_mmio_exec */
0x9800f800,
0x00804103,
0x03f60281,
0xbd04bd00,
/* 0x0841: ctx_mmio_loop */
0xff34c434,
0x450e1bf4,
0x53f00200,
0x0535fa06,
/* 0x0852: ctx_mmio_pull */
0x4e9803f8,
0x814f9880,
0x00008f7e,
0xb60830b6,
0x1bf40112,
/* 0x0865: ctx_mmio_done */
0x160398df,
0x02810080,
0xbd0003f6,
0x4000b504,
0xf0010041,
0x01fa0613,
0xf803f806,
/* 0x0881: ctx_xfer */
0x80040e00,
0xf6030200,
0x04bd000e,
/* 0x088c: ctx_xfer_idle */
0x0300008e,
0xf100eecf,
0xf42000e4,
0x11f4f51b,
0x0c02f406,
/* 0x08a0: ctx_xfer_pre */
0xfe7e100f,
0x11f40006,
0x40019810,
0xf40511fd,
0x327e070b,
/* 0x0966: ctx_xfer_no_post_mmio */
/* 0x0966: ctx_xfer_done */
0x00f80008,
/* 0x08a9: ctx_xfer_pre_load */
0x7e020f1b,
0x7e0006ad,
0x7e0006bc,
0xbd0006ce,
0x06ad7ef4,
0x07357e00,
/* 0x08c1: ctx_xfer_exec */
0x16019800,
0x008024bd,
0x02f60105,
0xb204bd00,
0xa5008e1f,
0x008f7e41,
0x01fcf000,
0xb6022cf0,
0xf2fd0124,
0x8effb205,
0x7e41a504,
0x7e00008f,
0xbd000216,
0x47fc8024,
0x0002f602,
0x2cf004bd,
0x0320b601,
0x024afc80,
0xbd0002f6,
0x01acf004,
0x0b06a5f0,
0x000c9800,
0x0e010d98,
0x013d7e00,
0x7e080a00,
0x7e0000ec,
0xf400020a,
0x0c0a1201,
0x0000b87e,
0x1d7e050f,
0x02f40007,
/* 0x093d: ctx_xfer_post */
0x7e020f2d,
0xbd0006ad,
0x06fe7ef4,
0x02277e00,
0x06bc7e00,
0x7ef4bd00,
0xf40006ad,
0x01981011,
0x0511fd40,
0x7e070bf4,
/* 0x0967: ctx_xfer_no_post_mmio */
/* 0x0967: ctx_xfer_done */
0xf8000833,
0x00000000,
0x00000000,
0x00000000,

View file

@ -441,7 +441,7 @@ static uint32_t gm107_grhub_code[] = {
0x020014fe,
0x12004002,
0xbd0002f6,
0x05c94104,
0x05ca4104,
0xbd0010fe,
0x07004024,
0xbd0002f6,
@ -460,423 +460,423 @@ static uint32_t gm107_grhub_code[] = {
0x01039204,
0x03090080,
0xbd0003f6,
0x87044204,
0xf6040040,
0x04bd0002,
0x00400402,
0x0002f603,
0x31f404bd,
0x96048e10,
0x00657e40,
0xc7feb200,
0x01b590f1,
0x1ff4f003,
0x01020fb5,
0x041fbb01,
0x800112b6,
0xf6010300,
0x04bd0001,
0x01040080,
0xbd0001f6,
0x01004104,
0xac7e020f,
0xbb7e0006,
0x100f0006,
0x0006fd7e,
0x98000e98,
0x207e010f,
0x14950001,
0xc0008008,
0x0004f601,
0x008004bd,
0x04f601c1,
0xb704bd00,
0xbb130030,
0xf5b6001f,
0xd3008002,
0x000ff601,
0x15b604bd,
0x0110b608,
0xb20814b6,
0x02687e1f,
0x001fbb00,
0x84020398,
/* 0x041f: init_gpc */
0xb8502000,
0x0008044e,
0x8f7e1fb2,
0x4eb80000,
0xbd00010c,
0x008f7ef4,
0x044eb800,
0x8f7e0001,
0x4eb80000,
0x0f000100,
0x008f7e02,
0x004eb800,
/* 0x044e: init_gpc_wait */
0x657e0008,
0xffc80000,
0xf90bf41f,
0x08044eb8,
0x00657e00,
0x001fbb00,
0x800040b7,
0xf40132b6,
0x000fb41b,
0x0006fd7e,
0xac7e000f,
0x00800006,
0x01f60201,
0xbd04bd00,
0x1f19f014,
0x02300080,
0xbd0001f6,
/* 0x0491: wait */
0x0028f404,
/* 0x0497: main */
0x0d0031f4,
0x00377e10,
0xf401f400,
0x4001e4b1,
0x00c71bf5,
0x99f094bd,
0x37008004,
0x0009f602,
0x008104bd,
0x11cf02c0,
0xc1008200,
0x0022cf02,
0xf41f13c8,
0x23c8770b,
0x550bf41f,
0x12b220f9,
0x99f094bd,
0x37008007,
0x0009f602,
0x32f404bd,
0x0231f401,
0x0008807e,
0x99f094bd,
0x17008007,
0x0009f602,
0x20fc04bd,
0x99f094bd,
0x37008006,
0x0009f602,
0x31f404bd,
0x08807e01,
0xf094bd00,
0x00800699,
0x09f60217,
0xf404bd00,
/* 0x0522: chsw_prev_no_next */
0x20f92f0e,
0x32f412b2,
0x0232f401,
0x0008807e,
0x008020fc,
0x02f602c0,
0xf404bd00,
/* 0x053e: chsw_no_prev */
0x23c8130e,
0x0d0bf41f,
0xf40131f4,
0x807e0232,
/* 0x054e: chsw_done */
0x01020008,
0x02c30080,
0x87048204,
0x04004000,
0xbd0002f6,
0xf094bd04,
0x00800499,
0x09f60217,
0xf504bd00,
/* 0x056b: main_not_ctx_switch */
0xb0ff300e,
0x1bf401e4,
0x7ef2b20c,
0xf4000820,
/* 0x057a: main_not_ctx_chan */
0xe4b0400e,
0x2c1bf402,
0x99f094bd,
0x37008007,
0x0009f602,
0x32f404bd,
0x0232f401,
0x0008807e,
0x99f094bd,
0x17008007,
0x0009f602,
0x0ef404bd,
/* 0x05a9: main_not_ctx_save */
0x10ef9411,
0x7e01f5f0,
0xf50002f8,
/* 0x05b7: main_done */
0xbdfee40e,
0x1f29f024,
0x02300080,
0xbd0002f6,
0xd20ef504,
/* 0x05c9: ih */
0xf900f9fe,
0x0188fe80,
0x90f980f9,
0xb0f9a0f9,
0xe0f9d0f9,
0x04bdf0f9,
0xcf02004a,
0xabc400aa,
0x230bf404,
0x004e100d,
0x00eecf1a,
0xcf19004f,
0x047e00ff,
0xb0b70000,
0x010e0400,
0xf61d0040,
0x04bd000e,
/* 0x060c: ih_no_fifo */
0x0100abe4,
0x0d0c0bf4,
0x40014e10,
0x0000047e,
/* 0x061c: ih_no_ctxsw */
0x0400abe4,
0x8e560bf4,
0x7e400708,
0xb2000065,
0x040080ff,
0x000ff602,
0x048e04bd,
0x657e4007,
0xffb20000,
0x02030080,
0xbd000ff6,
0x50fec704,
0x8f02ee94,
0xbb400700,
0x657e00ef,
0x00800000,
0x0ff60202,
0x0f04bd00,
0x02f87e03,
0x01004b00,
0x448ebfb2,
0x8f7e4001,
/* 0x0676: ih_no_fwmthd */
0x044b0000,
0xffb0bd05,
0x0bf4b4ab,
0x0700800c,
0x000bf603,
/* 0x068a: ih_no_other */
0x004004bd,
0x000af601,
0xf0fc04bd,
0xd0fce0fc,
0xa0fcb0fc,
0x80fc90fc,
0xfc0088fe,
0xf400fc80,
0x01f80032,
/* 0x06ac: ctx_4170s */
0xb210f5f0,
0x41708eff,
0x008f7e40,
/* 0x06bb: ctx_4170w */
0x8e00f800,
0x7e404170,
0xb2000065,
0x10f4f0ff,
0xf8f31bf4,
/* 0x06cd: ctx_redswitch */
0x02004e00,
0xf040e5f0,
0xe5f020e5,
0x85008010,
0x000ef601,
0x080f04bd,
/* 0x06e4: ctx_redswitch_delay */
0xf401f2b6,
0xe5f1fd1b,
0xe5f10400,
0x00800100,
0x0ef60185,
0xf804bd00,
/* 0x06fd: ctx_86c */
0x23008000,
0x000ff602,
0xffb204bd,
0x408a148e,
0x00008f7e,
0x8c8effb2,
0x8f7e41a8,
0x00f80000,
/* 0x071c: ctx_mem */
0x02840080,
0xbd000ff6,
/* 0x0725: ctx_mem_wait */
0x84008f04,
0x00ffcf02,
0xf405fffd,
0x00f8f61b,
/* 0x0734: ctx_load */
0x99f094bd,
0x37008005,
0x0009f602,
0x0c0a04bd,
0x0000b87e,
0x0080f4bd,
0x0ff60289,
0x40040204,
0x02f60300,
0xf404bd00,
0x048e1031,
0x657e4096,
0xfeb20000,
0xb590f1c7,
0xf4f00301,
0x020fb51f,
0x1fbb0101,
0x0112b604,
0x01030080,
0xbd0001f6,
0x04008004,
0x0001f601,
0x004104bd,
0x7e020f01,
0x7e0006ad,
0x0f0006bc,
0x06fe7e10,
0x000e9800,
0x7e010f98,
0x95000120,
0x00800814,
0x04f601c0,
0x8004bd00,
0xf602c100,
0x04bd0002,
0x02830080,
0xbd0002f6,
0x7e070f04,
0x8000071c,
0xf601c100,
0x04bd0004,
0x130030b7,
0xb6001fbb,
0x008002f5,
0x0ff601d3,
0xb604bd00,
0x10b60815,
0x0814b601,
0x687e1fb2,
0x1fbb0002,
0x02039800,
0x50200084,
/* 0x0420: init_gpc */
0x08044eb8,
0x7e1fb200,
0xb800008f,
0x00010c4e,
0x8f7ef4bd,
0x4eb80000,
0x7e000104,
0xb800008f,
0x0001004e,
0x8f7e020f,
0x4eb80000,
/* 0x044f: init_gpc_wait */
0x7e000800,
0xc8000065,
0x0bf41fff,
0x044eb8f9,
0x657e0008,
0x1fbb0000,
0x0040b700,
0x0132b680,
0x0fb41bf4,
0x06fe7e00,
0x7e000f00,
0x800006ad,
0xf6020100,
0x04bd0001,
0x19f014bd,
0x3000801f,
0x0001f602,
/* 0x0492: wait */
0x28f404bd,
0x0031f400,
/* 0x0498: main */
0x377e100d,
0x01f40000,
0x01e4b1f4,
0xc71bf540,
0xf094bd00,
0x00800499,
0x09f60237,
0x8104bd00,
0xcf02c000,
0x00820011,
0x22cf02c1,
0x1f13c800,
0xc8770bf4,
0x0bf41f23,
0xb220f955,
0xf094bd12,
0x00800799,
0x09f60237,
0xf404bd00,
0x31f40132,
0x08817e02,
0xf094bd00,
0x00800799,
0x09f60217,
0xfc04bd00,
0xf094bd20,
0x00800699,
0x09f60237,
0xf404bd00,
0x817e0131,
0x94bd0008,
0x800699f0,
0xf6021700,
0x04bd0009,
/* 0x0523: chsw_prev_no_next */
0xf92f0ef4,
0xf412b220,
0x32f40132,
0x08817e02,
0x8020fc00,
0xf602c000,
0x04bd0002,
0xf0000bfe,
0x24b61f2a,
0x0220b604,
0x99f094bd,
0x37008008,
0x0009f602,
0x008004bd,
0x02f60281,
0xd204bd00,
0x80000000,
0x800225f0,
0xf6028800,
0x04bd0002,
0x00421001,
0x0223f002,
0xf80512fa,
0xf094bd03,
0x00800899,
/* 0x053f: chsw_no_prev */
0xc8130ef4,
0x0bf41f23,
0x0131f40d,
0x7e0232f4,
/* 0x054f: chsw_done */
0x02000881,
0xc3008001,
0x0002f602,
0x94bd04bd,
0x800499f0,
0xf6021700,
0x04bd0009,
0xff300ef5,
/* 0x056c: main_not_ctx_switch */
0xf401e4b0,
0xf2b20c1b,
0x0008217e,
/* 0x057b: main_not_ctx_chan */
0xb0400ef4,
0x1bf402e4,
0xf094bd2c,
0x00800799,
0x09f60237,
0xf404bd00,
0x32f40132,
0x08817e02,
0xf094bd00,
0x00800799,
0x09f60217,
0x9804bd00,
0x14b68101,
0x80029818,
0xfd0825b6,
0x01b50512,
0xf094bd16,
0x00800999,
0xf404bd00,
/* 0x05aa: main_not_ctx_save */
0xef94110e,
0x01f5f010,
0x0002f87e,
0xfee40ef5,
/* 0x05b8: main_done */
0x29f024bd,
0x3000801f,
0x0002f602,
0x0ef504bd,
/* 0x05ca: ih */
0x00f9fed2,
0x88fe80f9,
0xf980f901,
0xf9a0f990,
0xf9d0f9b0,
0xbdf0f9e0,
0x02004a04,
0xc400aacf,
0x0bf404ab,
0x4e100d23,
0xeecf1a00,
0x19004f00,
0x7e00ffcf,
0xb7000004,
0x0e0400b0,
0x1d004001,
0xbd000ef6,
/* 0x060d: ih_no_fifo */
0x00abe404,
0x0c0bf401,
0x014e100d,
0x00047e40,
/* 0x061d: ih_no_ctxsw */
0x00abe400,
0x560bf404,
0x4007088e,
0x0000657e,
0x0080ffb2,
0x0ff60204,
0x8e04bd00,
0x7e400704,
0xb2000065,
0x030080ff,
0x000ff602,
0xfec704bd,
0x02ee9450,
0x4007008f,
0x7e00efbb,
0x80000065,
0xf6020200,
0x04bd000f,
0xf87e030f,
0x004b0002,
0x8ebfb201,
0x7e400144,
/* 0x0677: ih_no_fwmthd */
0x4b00008f,
0xb0bd0504,
0xf4b4abff,
0x00800c0b,
0x0bf60307,
/* 0x068b: ih_no_other */
0x4004bd00,
0x0af60100,
0xfc04bd00,
0xfce0fcf0,
0xfcb0fcd0,
0xfc90fca0,
0x0088fe80,
0x00fc80fc,
0xf80032f4,
/* 0x06ad: ctx_4170s */
0x10f5f001,
0x708effb2,
0x8f7e4041,
0x00f80000,
/* 0x06bc: ctx_4170w */
0x4041708e,
0x0000657e,
0xf4f0ffb2,
0xf31bf410,
/* 0x06ce: ctx_redswitch */
0x004e00f8,
0x40e5f002,
0xf020e5f0,
0x008010e5,
0x0ef60185,
0x0f04bd00,
/* 0x06e5: ctx_redswitch_delay */
0x01f2b608,
0xf1fd1bf4,
0xf10400e5,
0x800100e5,
0xf6018500,
0x04bd000e,
/* 0x06fe: ctx_86c */
0x008000f8,
0x0ff60223,
0xb204bd00,
0x8a148eff,
0x008f7e40,
0x8effb200,
0x7e41a88c,
0xf800008f,
/* 0x071d: ctx_mem */
0x84008000,
0x000ff602,
/* 0x0726: ctx_mem_wait */
0x008f04bd,
0xffcf0284,
0x05fffd00,
0xf8f61bf4,
/* 0x0735: ctx_load */
0xf094bd00,
0x00800599,
0x09f60237,
0x0a04bd00,
0x00b87e0c,
0x80f4bd00,
0xf6028900,
0x04bd000f,
0x02c10080,
0xbd0002f6,
0x83008004,
0x0002f602,
0x070f04bd,
0x00071d7e,
0x02c00080,
0xbd0002f6,
0x000bfe04,
0xb61f2af0,
0x20b60424,
0xf094bd02,
0x00800899,
0x09f60237,
0x8004bd00,
0xf6028100,
0x04bd0001,
0x00800102,
0x02f60288,
0x4104bd00,
0x13f00100,
0x0501fa06,
0x04bd0002,
0x000000d2,
0x0225f080,
0x02880080,
0xbd0002f6,
0x42100104,
0x23f00200,
0x0512fa02,
0x94bd03f8,
0x800999f0,
0x800899f0,
0xf6021700,
0x04bd0009,
0x99f094bd,
0x17008005,
0x0009f602,
0x00f804bd,
/* 0x0820: ctx_chan */
0x0007347e,
0xb87e0c0a,
0x050f0000,
0x00071c7e,
/* 0x0832: ctx_mmio_exec */
0x039800f8,
0x81008041,
0x0003f602,
0x34bd04bd,
/* 0x0840: ctx_mmio_loop */
0xf4ff34c4,
0x00450e1b,
0x0653f002,
0xf80535fa,
/* 0x0851: ctx_mmio_pull */
0x804e9803,
0x7e814f98,
0xb600008f,
0x12b60830,
0xdf1bf401,
/* 0x0864: ctx_mmio_done */
0x80160398,
0xf6028100,
0x04bd0003,
0x414000b5,
0x13f00100,
0x0601fa06,
0x00f803f8,
/* 0x0880: ctx_xfer */
0x0080040e,
0x0ef60302,
/* 0x088b: ctx_xfer_idle */
0x8e04bd00,
0xcf030000,
0xe4f100ee,
0x1bf42000,
0x0611f4f5,
/* 0x089f: ctx_xfer_pre */
0x0f0c02f4,
0x06fd7e10,
0x1b11f400,
/* 0x08a8: ctx_xfer_pre_load */
0xac7e020f,
0xbb7e0006,
0xcd7e0006,
0xf4bd0006,
0x0006ac7e,
0x0007347e,
/* 0x08c0: ctx_xfer_exec */
0xbd160198,
0x05008024,
0x0002f601,
0x1fb204bd,
0x41a5008e,
0x00008f7e,
0xf001fcf0,
0x24b6022c,
0x05f2fd01,
0x048effb2,
0x8f7e41a5,
0x167e0000,
0x24bd0002,
0x0247fc80,
0xbd0002f6,
0x012cf004,
0x800320b6,
0xf6024afc,
0xb6810198,
0x02981814,
0x0825b680,
0xb50512fd,
0x94bd1601,
0x800999f0,
0xf6023700,
0x04bd0009,
0x02810080,
0xbd0001f6,
0x80010204,
0xf6028800,
0x04bd0002,
0xf001acf0,
0x000b06a5,
0x98000c98,
0x000e010d,
0x00013d7e,
0xec7e080a,
0x0a7e0000,
0x01f40002,
0x7e0c0a12,
0xf0010041,
0x01fa0613,
0xbd03f805,
0x0999f094,
0x02170080,
0xbd0009f6,
0xf094bd04,
0x00800599,
0x09f60217,
0xf804bd00,
/* 0x0821: ctx_chan */
0x07357e00,
0x7e0c0a00,
0x0f0000b8,
0x071c7e05,
0x2d02f400,
/* 0x093c: ctx_xfer_post */
0xac7e020f,
0xf4bd0006,
0x0006fd7e,
0x0002277e,
0x0006bb7e,
0xac7ef4bd,
0x071d7e05,
/* 0x0833: ctx_mmio_exec */
0x9800f800,
0x00804103,
0x03f60281,
0xbd04bd00,
/* 0x0841: ctx_mmio_loop */
0xff34c434,
0x450e1bf4,
0x53f00200,
0x0535fa06,
/* 0x0852: ctx_mmio_pull */
0x4e9803f8,
0x814f9880,
0x00008f7e,
0xb60830b6,
0x1bf40112,
/* 0x0865: ctx_mmio_done */
0x160398df,
0x02810080,
0xbd0003f6,
0x4000b504,
0xf0010041,
0x01fa0613,
0xf803f806,
/* 0x0881: ctx_xfer */
0x80040e00,
0xf6030200,
0x04bd000e,
/* 0x088c: ctx_xfer_idle */
0x0300008e,
0xf100eecf,
0xf42000e4,
0x11f4f51b,
0x0c02f406,
/* 0x08a0: ctx_xfer_pre */
0xfe7e100f,
0x11f40006,
0x40019810,
0xf40511fd,
0x327e070b,
/* 0x0966: ctx_xfer_no_post_mmio */
/* 0x0966: ctx_xfer_done */
0x00f80008,
/* 0x08a9: ctx_xfer_pre_load */
0x7e020f1b,
0x7e0006ad,
0x7e0006bc,
0xbd0006ce,
0x06ad7ef4,
0x07357e00,
/* 0x08c1: ctx_xfer_exec */
0x16019800,
0x008024bd,
0x02f60105,
0xb204bd00,
0xa5008e1f,
0x008f7e41,
0x01fcf000,
0xb6022cf0,
0xf2fd0124,
0x8effb205,
0x7e41a504,
0x7e00008f,
0xbd000216,
0x47fc8024,
0x0002f602,
0x2cf004bd,
0x0320b601,
0x024afc80,
0xbd0002f6,
0x01acf004,
0x0b06a5f0,
0x000c9800,
0x0e010d98,
0x013d7e00,
0x7e080a00,
0x7e0000ec,
0xf400020a,
0x0c0a1201,
0x0000b87e,
0x1d7e050f,
0x02f40007,
/* 0x093d: ctx_xfer_post */
0x7e020f2d,
0xbd0006ad,
0x06fe7ef4,
0x02277e00,
0x06bc7e00,
0x7ef4bd00,
0xf40006ad,
0x01981011,
0x0511fd40,
0x7e070bf4,
/* 0x0967: ctx_xfer_no_post_mmio */
/* 0x0967: ctx_xfer_done */
0xf8000833,
0x00000000,
0x00000000,
0x00000000,

View file

@ -26,9 +26,9 @@
#include "fuc/os.h"
#include <core/client.h>
#include <core/option.h>
#include <core/firmware.h>
#include <subdev/secboot.h>
#include <core/option.h>
#include <subdev/acr.h>
#include <subdev/fb.h>
#include <subdev/mc.h>
#include <subdev/pmu.h>
@ -1636,7 +1636,7 @@ gf100_gr_intr(struct nvkm_gr *base)
static void
gf100_gr_init_fw(struct nvkm_falcon *falcon,
struct gf100_gr_fuc *code, struct gf100_gr_fuc *data)
struct nvkm_blob *code, struct nvkm_blob *data)
{
nvkm_falcon_load_dmem(falcon, data->data, 0x0, data->size, 0);
nvkm_falcon_load_imem(falcon, code->data, 0x0, code->size, 0, 0, false);
@ -1690,26 +1690,30 @@ gf100_gr_init_ctxctl_ext(struct gf100_gr *gr)
{
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
struct nvkm_secboot *sb = device->secboot;
u32 secboot_mask = 0;
u32 lsf_mask = 0;
int ret;
/* load fuc microcode */
nvkm_mc_unk260(device, 0);
/* securely-managed falcons must be reset using secure boot */
if (nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_FECS))
secboot_mask |= BIT(NVKM_SECBOOT_FALCON_FECS);
else
gf100_gr_init_fw(gr->fecs.falcon, &gr->fuc409c, &gr->fuc409d);
if (nvkm_secboot_is_managed(sb, NVKM_SECBOOT_FALCON_GPCCS))
secboot_mask |= BIT(NVKM_SECBOOT_FALCON_GPCCS);
else
gf100_gr_init_fw(gr->gpccs.falcon, &gr->fuc41ac, &gr->fuc41ad);
if (!nvkm_acr_managed_falcon(device, NVKM_ACR_LSF_FECS)) {
gf100_gr_init_fw(&gr->fecs.falcon, &gr->fecs.inst,
&gr->fecs.data);
} else {
lsf_mask |= BIT(NVKM_ACR_LSF_FECS);
}
if (secboot_mask != 0) {
int ret = nvkm_secboot_reset(sb, secboot_mask);
if (!nvkm_acr_managed_falcon(device, NVKM_ACR_LSF_GPCCS)) {
gf100_gr_init_fw(&gr->gpccs.falcon, &gr->gpccs.inst,
&gr->gpccs.data);
} else {
lsf_mask |= BIT(NVKM_ACR_LSF_GPCCS);
}
if (lsf_mask) {
ret = nvkm_acr_bootstrap_falcons(device, lsf_mask);
if (ret)
return ret;
}
@ -1721,8 +1725,8 @@ gf100_gr_init_ctxctl_ext(struct gf100_gr *gr)
nvkm_wr32(device, 0x41a10c, 0x00000000);
nvkm_wr32(device, 0x40910c, 0x00000000);
nvkm_falcon_start(gr->gpccs.falcon);
nvkm_falcon_start(gr->fecs.falcon);
nvkm_falcon_start(&gr->gpccs.falcon);
nvkm_falcon_start(&gr->fecs.falcon);
if (nvkm_msec(device, 2000,
if (nvkm_rd32(device, 0x409800) & 0x00000001)
@ -1784,18 +1788,18 @@ gf100_gr_init_ctxctl_int(struct gf100_gr *gr)
/* load HUB microcode */
nvkm_mc_unk260(device, 0);
nvkm_falcon_load_dmem(gr->fecs.falcon,
nvkm_falcon_load_dmem(&gr->fecs.falcon,
gr->func->fecs.ucode->data.data, 0x0,
gr->func->fecs.ucode->data.size, 0);
nvkm_falcon_load_imem(gr->fecs.falcon,
nvkm_falcon_load_imem(&gr->fecs.falcon,
gr->func->fecs.ucode->code.data, 0x0,
gr->func->fecs.ucode->code.size, 0, 0, false);
/* load GPC microcode */
nvkm_falcon_load_dmem(gr->gpccs.falcon,
nvkm_falcon_load_dmem(&gr->gpccs.falcon,
gr->func->gpccs.ucode->data.data, 0x0,
gr->func->gpccs.ucode->data.size, 0);
nvkm_falcon_load_imem(gr->gpccs.falcon,
nvkm_falcon_load_imem(&gr->gpccs.falcon,
gr->func->gpccs.ucode->code.data, 0x0,
gr->func->gpccs.ucode->code.size, 0, 0, false);
nvkm_mc_unk260(device, 1);
@ -1941,17 +1945,6 @@ gf100_gr_oneinit(struct nvkm_gr *base)
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
int i, j;
int ret;
ret = nvkm_falcon_v1_new(subdev, "FECS", 0x409000, &gr->fecs.falcon);
if (ret)
return ret;
mutex_init(&gr->fecs.mutex);
ret = nvkm_falcon_v1_new(subdev, "GPCCS", 0x41a000, &gr->gpccs.falcon);
if (ret)
return ret;
nvkm_pmu_pgob(device->pmu, false);
@ -1992,11 +1985,11 @@ gf100_gr_init_(struct nvkm_gr *base)
nvkm_pmu_pgob(gr->base.engine.subdev.device->pmu, false);
ret = nvkm_falcon_get(gr->fecs.falcon, subdev);
ret = nvkm_falcon_get(&gr->fecs.falcon, subdev);
if (ret)
return ret;
ret = nvkm_falcon_get(gr->gpccs.falcon, subdev);
ret = nvkm_falcon_get(&gr->gpccs.falcon, subdev);
if (ret)
return ret;
@ -2004,49 +1997,34 @@ gf100_gr_init_(struct nvkm_gr *base)
}
static int
gf100_gr_fini_(struct nvkm_gr *base, bool suspend)
gf100_gr_fini(struct nvkm_gr *base, bool suspend)
{
struct gf100_gr *gr = gf100_gr(base);
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
nvkm_falcon_put(gr->gpccs.falcon, subdev);
nvkm_falcon_put(gr->fecs.falcon, subdev);
nvkm_falcon_put(&gr->gpccs.falcon, subdev);
nvkm_falcon_put(&gr->fecs.falcon, subdev);
return 0;
}
void
gf100_gr_dtor_fw(struct gf100_gr_fuc *fuc)
{
kfree(fuc->data);
fuc->data = NULL;
}
static void
gf100_gr_dtor_init(struct gf100_gr_pack *pack)
{
vfree(pack);
}
void *
gf100_gr_dtor(struct nvkm_gr *base)
{
struct gf100_gr *gr = gf100_gr(base);
if (gr->func->dtor)
gr->func->dtor(gr);
kfree(gr->data);
nvkm_falcon_del(&gr->gpccs.falcon);
nvkm_falcon_del(&gr->fecs.falcon);
nvkm_falcon_dtor(&gr->gpccs.falcon);
nvkm_falcon_dtor(&gr->fecs.falcon);
gf100_gr_dtor_fw(&gr->fuc409c);
gf100_gr_dtor_fw(&gr->fuc409d);
gf100_gr_dtor_fw(&gr->fuc41ac);
gf100_gr_dtor_fw(&gr->fuc41ad);
nvkm_blob_dtor(&gr->fecs.inst);
nvkm_blob_dtor(&gr->fecs.data);
nvkm_blob_dtor(&gr->gpccs.inst);
nvkm_blob_dtor(&gr->gpccs.data);
gf100_gr_dtor_init(gr->fuc_bundle);
gf100_gr_dtor_init(gr->fuc_method);
gf100_gr_dtor_init(gr->fuc_sw_ctx);
gf100_gr_dtor_init(gr->fuc_sw_nonctx);
vfree(gr->bundle);
vfree(gr->method);
vfree(gr->sw_ctx);
vfree(gr->sw_nonctx);
return gr;
}
@ -2056,7 +2034,7 @@ gf100_gr_ = {
.dtor = gf100_gr_dtor,
.oneinit = gf100_gr_oneinit,
.init = gf100_gr_init_,
.fini = gf100_gr_fini_,
.fini = gf100_gr_fini,
.intr = gf100_gr_intr,
.units = gf100_gr_units,
.chan_new = gf100_gr_chan_new,
@ -2067,87 +2045,24 @@ gf100_gr_ = {
.ctxsw.inst = gf100_gr_ctxsw_inst,
};
int
gf100_gr_ctor_fw_legacy(struct gf100_gr *gr, const char *fwname,
struct gf100_gr_fuc *fuc, int ret)
{
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
const struct firmware *fw;
char f[32];
/* see if this firmware has a legacy path */
if (!strcmp(fwname, "fecs_inst"))
fwname = "fuc409c";
else if (!strcmp(fwname, "fecs_data"))
fwname = "fuc409d";
else if (!strcmp(fwname, "gpccs_inst"))
fwname = "fuc41ac";
else if (!strcmp(fwname, "gpccs_data"))
fwname = "fuc41ad";
else {
/* nope, let's just return the error we got */
nvkm_error(subdev, "failed to load %s\n", fwname);
return ret;
}
/* yes, try to load from the legacy path */
nvkm_debug(subdev, "%s: falling back to legacy path\n", fwname);
snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, fwname);
ret = request_firmware(&fw, f, device->dev);
if (ret) {
snprintf(f, sizeof(f), "nouveau/%s", fwname);
ret = request_firmware(&fw, f, device->dev);
if (ret) {
nvkm_error(subdev, "failed to load %s\n", fwname);
return ret;
}
}
fuc->size = fw->size;
fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
release_firmware(fw);
return (fuc->data != NULL) ? 0 : -ENOMEM;
}
static const struct nvkm_falcon_func
gf100_gr_flcn = {
.fbif = 0x600,
.load_imem = nvkm_falcon_v1_load_imem,
.load_dmem = nvkm_falcon_v1_load_dmem,
.read_dmem = nvkm_falcon_v1_read_dmem,
.bind_context = nvkm_falcon_v1_bind_context,
.wait_for_halt = nvkm_falcon_v1_wait_for_halt,
.clear_interrupt = nvkm_falcon_v1_clear_interrupt,
.set_start_addr = nvkm_falcon_v1_set_start_addr,
.start = nvkm_falcon_v1_start,
.enable = nvkm_falcon_v1_enable,
.disable = nvkm_falcon_v1_disable,
};
int
gf100_gr_ctor_fw(struct gf100_gr *gr, const char *fwname,
struct gf100_gr_fuc *fuc)
{
const struct firmware *fw;
int ret;
ret = nvkm_firmware_get(&gr->base.engine.subdev, fwname, &fw);
if (ret) {
ret = gf100_gr_ctor_fw_legacy(gr, fwname, fuc, ret);
if (ret)
return -ENODEV;
return 0;
}
fuc->size = fw->size;
fuc->data = kmemdup(fw->data, fuc->size, GFP_KERNEL);
nvkm_firmware_put(fw);
return (fuc->data != NULL) ? 0 : -ENOMEM;
}
int
gf100_gr_ctor(const struct gf100_gr_func *func, struct nvkm_device *device,
int index, struct gf100_gr *gr)
{
gr->func = func;
gr->firmware = nvkm_boolopt(device->cfgopt, "NvGrUseFW",
func->fecs.ucode == NULL);
return nvkm_gr_ctor(&gf100_gr_, device, index,
gr->firmware || func->fecs.ucode != NULL,
&gr->base);
}
int
gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device,
int index, struct nvkm_gr **pgr)
gf100_gr_new_(const struct gf100_gr_fwif *fwif,
struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
struct gf100_gr *gr;
int ret;
@ -2156,21 +2071,48 @@ gf100_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device,
return -ENOMEM;
*pgr = &gr->base;
ret = gf100_gr_ctor(func, device, index, gr);
ret = nvkm_gr_ctor(&gf100_gr_, device, index, true, &gr->base);
if (ret)
return ret;
if (gr->firmware) {
if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) ||
gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d) ||
gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) ||
gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad))
return -ENODEV;
}
fwif = nvkm_firmware_load(&gr->base.engine.subdev, fwif, "Gr", gr);
if (IS_ERR(fwif))
return -ENODEV;
gr->func = fwif->func;
ret = nvkm_falcon_ctor(&gf100_gr_flcn, &gr->base.engine.subdev,
"fecs", 0x409000, &gr->fecs.falcon);
if (ret)
return ret;
mutex_init(&gr->fecs.mutex);
ret = nvkm_falcon_ctor(&gf100_gr_flcn, &gr->base.engine.subdev,
"gpccs", 0x41a000, &gr->gpccs.falcon);
if (ret)
return ret;
return 0;
}
void
gf100_gr_init_num_tpc_per_gpc(struct gf100_gr *gr, bool pd, bool ds)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
int gpc, i, j;
u32 data;
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);
if (pd)
nvkm_wr32(device, 0x406028 + (i * 4), data);
if (ds)
nvkm_wr32(device, 0x405870 + (i * 4), data);
}
}
void
gf100_gr_init_400054(struct gf100_gr *gr)
{
@ -2295,8 +2237,8 @@ gf100_gr_init(struct gf100_gr *gr)
gr->func->init_gpc_mmu(gr);
if (gr->fuc_sw_nonctx)
gf100_gr_mmio(gr, gr->fuc_sw_nonctx);
if (gr->sw_nonctx)
gf100_gr_mmio(gr, gr->sw_nonctx);
else
gf100_gr_mmio(gr, gr->func->mmio);
@ -2320,6 +2262,8 @@ gf100_gr_init(struct gf100_gr *gr)
gr->func->init_bios_2(gr);
if (gr->func->init_swdx_pes_mask)
gr->func->init_swdx_pes_mask(gr);
if (gr->func->init_fs)
gr->func->init_fs(gr);
nvkm_wr32(device, 0x400500, 0x00010001);
@ -2338,8 +2282,8 @@ gf100_gr_init(struct gf100_gr *gr)
if (gr->func->init_40601c)
gr->func->init_40601c(gr);
nvkm_wr32(device, 0x404490, 0xc0000000);
nvkm_wr32(device, 0x406018, 0xc0000000);
nvkm_wr32(device, 0x404490, 0xc0000000);
if (gr->func->init_sked_hww_esr)
gr->func->init_sked_hww_esr(gr);
@ -2453,8 +2397,67 @@ gf100_gr = {
}
};
int
gf100_gr_nofw(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif)
{
gr->firmware = false;
return 0;
}
static int
gf100_gr_load_fw(struct gf100_gr *gr, const char *name,
struct nvkm_blob *blob)
{
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_device *device = subdev->device;
const struct firmware *fw;
char f[32];
int ret;
snprintf(f, sizeof(f), "nouveau/nv%02x_%s", device->chipset, name);
ret = request_firmware(&fw, f, device->dev);
if (ret) {
snprintf(f, sizeof(f), "nouveau/%s", name);
ret = request_firmware(&fw, f, device->dev);
if (ret) {
nvkm_error(subdev, "failed to load %s\n", name);
return ret;
}
}
blob->size = fw->size;
blob->data = kmemdup(fw->data, blob->size, GFP_KERNEL);
release_firmware(fw);
return (blob->data != NULL) ? 0 : -ENOMEM;
}
int
gf100_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
if (!nvkm_boolopt(device->cfgopt, "NvGrUseFW", false))
return -EINVAL;
if (gf100_gr_load_fw(gr, "fuc409c", &gr->fecs.inst) ||
gf100_gr_load_fw(gr, "fuc409d", &gr->fecs.data) ||
gf100_gr_load_fw(gr, "fuc41ac", &gr->gpccs.inst) ||
gf100_gr_load_fw(gr, "fuc41ad", &gr->gpccs.data))
return -ENOENT;
gr->firmware = true;
return 0;
}
static const struct gf100_gr_fwif
gf100_gr_fwif[] = {
{ -1, gf100_gr_load, &gf100_gr },
{ -1, gf100_gr_nofw, &gf100_gr },
{}
};
int
gf100_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gf100_gr, device, index, pgr);
return gf100_gr_new_(gf100_gr_fwif, device, index, pgr);
}

View file

@ -31,6 +31,8 @@
#include <subdev/mmu.h>
#include <engine/falcon.h>
struct nvkm_acr_lsfw;
#define GPC_MAX 32
#define TPC_MAX_PER_GPC 8
#define TPC_MAX (GPC_MAX * TPC_MAX_PER_GPC)
@ -55,11 +57,6 @@ struct gf100_gr_mmio {
int buffer;
};
struct gf100_gr_fuc {
u32 *data;
u32 size;
};
struct gf100_gr_zbc_color {
u32 format;
u32 ds[4];
@ -83,29 +80,30 @@ struct gf100_gr {
struct nvkm_gr base;
struct {
struct nvkm_falcon *falcon;
struct nvkm_falcon falcon;
struct nvkm_blob inst;
struct nvkm_blob data;
struct mutex mutex;
u32 disable;
} fecs;
struct {
struct nvkm_falcon *falcon;
struct nvkm_falcon falcon;
struct nvkm_blob inst;
struct nvkm_blob data;
} gpccs;
struct gf100_gr_fuc fuc409c;
struct gf100_gr_fuc fuc409d;
struct gf100_gr_fuc fuc41ac;
struct gf100_gr_fuc fuc41ad;
bool firmware;
/*
* Used if the register packs are loaded from NVIDIA fw instead of
* using hardcoded arrays. To be allocated with vzalloc().
*/
struct gf100_gr_pack *fuc_sw_nonctx;
struct gf100_gr_pack *fuc_sw_ctx;
struct gf100_gr_pack *fuc_bundle;
struct gf100_gr_pack *fuc_method;
struct gf100_gr_pack *sw_nonctx;
struct gf100_gr_pack *sw_ctx;
struct gf100_gr_pack *bundle;
struct gf100_gr_pack *method;
struct gf100_gr_zbc_color zbc_color[NVKM_LTC_MAX_ZBC_CNT];
struct gf100_gr_zbc_depth zbc_depth[NVKM_LTC_MAX_ZBC_CNT];
@ -140,12 +138,6 @@ struct gf100_gr {
u32 size_pm;
};
int gf100_gr_ctor(const struct gf100_gr_func *, struct nvkm_device *,
int, struct gf100_gr *);
int gf100_gr_new_(const struct gf100_gr_func *, struct nvkm_device *,
int, struct nvkm_gr **);
void *gf100_gr_dtor(struct nvkm_gr *);
int gf100_gr_fecs_bind_pointer(struct gf100_gr *, u32 inst);
struct gf100_gr_func_zbc {
@ -157,7 +149,6 @@ struct gf100_gr_func_zbc {
};
struct gf100_gr_func {
void (*dtor)(struct gf100_gr *);
void (*oneinit_tiles)(struct gf100_gr *);
void (*oneinit_sm_id)(struct gf100_gr *);
int (*init)(struct gf100_gr *);
@ -171,6 +162,7 @@ struct gf100_gr_func {
void (*init_rop_active_fbps)(struct gf100_gr *);
void (*init_bios_2)(struct gf100_gr *);
void (*init_swdx_pes_mask)(struct gf100_gr *);
void (*init_fs)(struct gf100_gr *);
void (*init_fecs_exceptions)(struct gf100_gr *);
void (*init_ds_hww_esr_2)(struct gf100_gr *);
void (*init_40601c)(struct gf100_gr *);
@ -217,6 +209,7 @@ void gf100_gr_init_419eb4(struct gf100_gr *);
void gf100_gr_init_tex_hww_esr(struct gf100_gr *, int, int);
void gf100_gr_init_shader_exceptions(struct gf100_gr *, int, int);
void gf100_gr_init_400054(struct gf100_gr *);
void gf100_gr_init_num_tpc_per_gpc(struct gf100_gr *, bool, bool);
extern const struct gf100_gr_func_zbc gf100_gr_zbc;
void gf117_gr_init_zcull(struct gf100_gr *);
@ -249,6 +242,13 @@ void gp100_gr_zbc_clear_depth(struct gf100_gr *, int);
void gp102_gr_init_swdx_pes_mask(struct gf100_gr *);
extern const struct gf100_gr_func_zbc gp102_gr_zbc;
extern const struct gf100_gr_func gp107_gr;
void gv100_gr_init_419bd8(struct gf100_gr *);
void gv100_gr_init_504430(struct gf100_gr *, int, int);
void gv100_gr_init_shader_exceptions(struct gf100_gr *, int, int);
void gv100_gr_trap_mp(struct gf100_gr *, int, int);
#define gf100_gr_chan(p) container_of((p), struct gf100_gr_chan, object)
#include <core/object.h>
@ -269,9 +269,6 @@ struct gf100_gr_chan {
void gf100_gr_ctxctl_debug(struct gf100_gr *);
void gf100_gr_dtor_fw(struct gf100_gr_fuc *);
int gf100_gr_ctor_fw(struct gf100_gr *, const char *,
struct gf100_gr_fuc *);
u64 gf100_gr_units(struct nvkm_gr *);
void gf100_gr_zbc_init(struct gf100_gr *);
@ -294,8 +291,8 @@ struct gf100_gr_pack {
for (init = pack->init; init && init->count; init++)
struct gf100_gr_ucode {
struct gf100_gr_fuc code;
struct gf100_gr_fuc data;
struct nvkm_blob code;
struct nvkm_blob data;
};
extern struct gf100_gr_ucode gf100_gr_fecs_ucode;
@ -310,17 +307,6 @@ void gf100_gr_icmd(struct gf100_gr *, const struct gf100_gr_pack *);
void gf100_gr_mthd(struct gf100_gr *, const struct gf100_gr_pack *);
int gf100_gr_init_ctxctl(struct gf100_gr *);
/* external bundles loading functions */
int gk20a_gr_av_to_init(struct gf100_gr *, const char *,
struct gf100_gr_pack **);
int gk20a_gr_aiv_to_init(struct gf100_gr *, const char *,
struct gf100_gr_pack **);
int gk20a_gr_av_to_method(struct gf100_gr *, const char *,
struct gf100_gr_pack **);
int gm200_gr_new_(const struct gf100_gr_func *, struct nvkm_device *, int,
struct nvkm_gr **);
/* register init value lists */
extern const struct gf100_gr_init gf100_gr_init_main_0[];
@ -403,4 +389,31 @@ extern const struct gf100_gr_init gm107_gr_init_cbm_0[];
void gm107_gr_init_bios(struct gf100_gr *);
void gm200_gr_init_gpc_mmu(struct gf100_gr *);
struct gf100_gr_fwif {
int version;
int (*load)(struct gf100_gr *, int ver, const struct gf100_gr_fwif *);
const struct gf100_gr_func *func;
const struct nvkm_acr_lsf_func *fecs;
const struct nvkm_acr_lsf_func *gpccs;
};
int gf100_gr_load(struct gf100_gr *, int, const struct gf100_gr_fwif *);
int gf100_gr_nofw(struct gf100_gr *, int, const struct gf100_gr_fwif *);
int gk20a_gr_load_sw(struct gf100_gr *, const char *path, int ver);
int gm200_gr_load(struct gf100_gr *, int, const struct gf100_gr_fwif *);
extern const struct nvkm_acr_lsf_func gm200_gr_gpccs_acr;
extern const struct nvkm_acr_lsf_func gm200_gr_fecs_acr;
extern const struct nvkm_acr_lsf_func gm20b_gr_fecs_acr;
void gm20b_gr_acr_bld_write(struct nvkm_acr *, u32, struct nvkm_acr_lsfw *);
void gm20b_gr_acr_bld_patch(struct nvkm_acr *, u32, s64);
extern const struct nvkm_acr_lsf_func gp108_gr_gpccs_acr;
extern const struct nvkm_acr_lsf_func gp108_gr_fecs_acr;
int gf100_gr_new_(const struct gf100_gr_fwif *, struct nvkm_device *, int,
struct nvkm_gr **);
#endif

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -489,8 +489,15 @@ gk104_gr = {
}
};
static const struct gf100_gr_fwif
gk104_gr_fwif[] = {
{ -1, gf100_gr_load, &gk104_gr },
{ -1, gf100_gr_nofw, &gk104_gr },
{}
};
int
gk104_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gk104_gr, device, index, pgr);
return gf100_gr_new_(gk104_gr_fwif, device, index, pgr);
}

View file

@ -385,8 +385,15 @@ gk110_gr = {
}
};
static const struct gf100_gr_fwif
gk110_gr_fwif[] = {
{ -1, gf100_gr_load, &gk110_gr },
{ -1, gf100_gr_nofw, &gk110_gr },
{}
};
int
gk110_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gk110_gr, device, index, pgr);
return gf100_gr_new_(gk110_gr_fwif, device, index, pgr);
}

View file

@ -136,8 +136,15 @@ gk110b_gr = {
}
};
static const struct gf100_gr_fwif
gk110b_gr_fwif[] = {
{ -1, gf100_gr_load, &gk110b_gr },
{ -1, gf100_gr_nofw, &gk110b_gr },
{}
};
int
gk110b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gk110b_gr, device, index, pgr);
return gf100_gr_new_(gk110b_gr_fwif, device, index, pgr);
}

View file

@ -194,8 +194,15 @@ gk208_gr = {
}
};
static const struct gf100_gr_fwif
gk208_gr_fwif[] = {
{ -1, gf100_gr_load, &gk208_gr },
{ -1, gf100_gr_nofw, &gk208_gr },
{}
};
int
gk208_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gk208_gr, device, index, pgr);
return gf100_gr_new_(gk208_gr_fwif, device, index, pgr);
}

View file

@ -22,6 +22,7 @@
#include "gf100.h"
#include "ctxgf100.h"
#include <core/firmware.h>
#include <subdev/timer.h>
#include <nvif/class.h>
@ -33,21 +34,22 @@ struct gk20a_fw_av
};
int
gk20a_gr_av_to_init(struct gf100_gr *gr, const char *fw_name,
struct gf100_gr_pack **ppack)
gk20a_gr_av_to_init(struct gf100_gr *gr, const char *path, const char *name,
int ver, struct gf100_gr_pack **ppack)
{
struct gf100_gr_fuc fuc;
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_blob blob;
struct gf100_gr_init *init;
struct gf100_gr_pack *pack;
int nent;
int ret;
int i;
ret = gf100_gr_ctor_fw(gr, fw_name, &fuc);
ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob);
if (ret)
return ret;
nent = (fuc.size / sizeof(struct gk20a_fw_av));
nent = (blob.size / sizeof(struct gk20a_fw_av));
pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1)));
if (!pack) {
ret = -ENOMEM;
@ -59,7 +61,7 @@ gk20a_gr_av_to_init(struct gf100_gr *gr, const char *fw_name,
for (i = 0; i < nent; i++) {
struct gf100_gr_init *ent = &init[i];
struct gk20a_fw_av *av = &((struct gk20a_fw_av *)fuc.data)[i];
struct gk20a_fw_av *av = &((struct gk20a_fw_av *)blob.data)[i];
ent->addr = av->addr;
ent->data = av->data;
@ -70,7 +72,7 @@ gk20a_gr_av_to_init(struct gf100_gr *gr, const char *fw_name,
*ppack = pack;
end:
gf100_gr_dtor_fw(&fuc);
nvkm_blob_dtor(&blob);
return ret;
}
@ -82,21 +84,22 @@ struct gk20a_fw_aiv
};
int
gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *fw_name,
struct gf100_gr_pack **ppack)
gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *path, const char *name,
int ver, struct gf100_gr_pack **ppack)
{
struct gf100_gr_fuc fuc;
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_blob blob;
struct gf100_gr_init *init;
struct gf100_gr_pack *pack;
int nent;
int ret;
int i;
ret = gf100_gr_ctor_fw(gr, fw_name, &fuc);
ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob);
if (ret)
return ret;
nent = (fuc.size / sizeof(struct gk20a_fw_aiv));
nent = (blob.size / sizeof(struct gk20a_fw_aiv));
pack = vzalloc((sizeof(*pack) * 2) + (sizeof(*init) * (nent + 1)));
if (!pack) {
ret = -ENOMEM;
@ -108,7 +111,7 @@ gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *fw_name,
for (i = 0; i < nent; i++) {
struct gf100_gr_init *ent = &init[i];
struct gk20a_fw_aiv *av = &((struct gk20a_fw_aiv *)fuc.data)[i];
struct gk20a_fw_aiv *av = &((struct gk20a_fw_aiv *)blob.data)[i];
ent->addr = av->addr;
ent->data = av->data;
@ -119,15 +122,16 @@ gk20a_gr_aiv_to_init(struct gf100_gr *gr, const char *fw_name,
*ppack = pack;
end:
gf100_gr_dtor_fw(&fuc);
nvkm_blob_dtor(&blob);
return ret;
}
int
gk20a_gr_av_to_method(struct gf100_gr *gr, const char *fw_name,
struct gf100_gr_pack **ppack)
gk20a_gr_av_to_method(struct gf100_gr *gr, const char *path, const char *name,
int ver, struct gf100_gr_pack **ppack)
{
struct gf100_gr_fuc fuc;
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
struct nvkm_blob blob;
struct gf100_gr_init *init;
struct gf100_gr_pack *pack;
/* We don't suppose we will initialize more than 16 classes here... */
@ -137,29 +141,30 @@ gk20a_gr_av_to_method(struct gf100_gr *gr, const char *fw_name,
int ret;
int i;
ret = gf100_gr_ctor_fw(gr, fw_name, &fuc);
ret = nvkm_firmware_load_blob(subdev, path, name, ver, &blob);
if (ret)
return ret;
nent = (fuc.size / sizeof(struct gk20a_fw_av));
nent = (blob.size / sizeof(struct gk20a_fw_av));
pack = vzalloc((sizeof(*pack) * max_classes) +
(sizeof(*init) * (nent + 1)));
pack = vzalloc((sizeof(*pack) * (max_classes + 1)) +
(sizeof(*init) * (nent + max_classes + 1)));
if (!pack) {
ret = -ENOMEM;
goto end;
}
init = (void *)(pack + max_classes);
init = (void *)(pack + max_classes + 1);
for (i = 0; i < nent; i++) {
struct gf100_gr_init *ent = &init[i];
struct gk20a_fw_av *av = &((struct gk20a_fw_av *)fuc.data)[i];
for (i = 0; i < nent; i++, init++) {
struct gk20a_fw_av *av = &((struct gk20a_fw_av *)blob.data)[i];
u32 class = av->addr & 0xffff;
u32 addr = (av->addr & 0xffff0000) >> 14;
if (prevclass != class) {
pack[classidx].init = ent;
if (prevclass) /* Add terminator to the method list. */
init++;
pack[classidx].init = init;
pack[classidx].type = class;
prevclass = class;
if (++classidx >= max_classes) {
@ -169,16 +174,16 @@ gk20a_gr_av_to_method(struct gf100_gr *gr, const char *fw_name,
}
}
ent->addr = addr;
ent->data = av->data;
ent->count = 1;
ent->pitch = 1;
init->addr = addr;
init->data = av->data;
init->count = 1;
init->pitch = 1;
}
*ppack = pack;
end:
gf100_gr_dtor_fw(&fuc);
nvkm_blob_dtor(&blob);
return ret;
}
@ -224,7 +229,7 @@ gk20a_gr_init(struct gf100_gr *gr)
/* Clear SCC RAM */
nvkm_wr32(device, 0x40802c, 0x1);
gf100_gr_mmio(gr, gr->fuc_sw_nonctx);
gf100_gr_mmio(gr, gr->sw_nonctx);
ret = gk20a_gr_wait_mem_scrubbing(gr);
if (ret)
@ -303,40 +308,45 @@ gk20a_gr = {
};
int
gk20a_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
gk20a_gr_load_sw(struct gf100_gr *gr, const char *path, int ver)
{
struct gf100_gr *gr;
int ret;
if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
return -ENOMEM;
*pgr = &gr->base;
ret = gf100_gr_ctor(&gk20a_gr, device, index, gr);
if (ret)
return ret;
if (gf100_gr_ctor_fw(gr, "fecs_inst", &gr->fuc409c) ||
gf100_gr_ctor_fw(gr, "fecs_data", &gr->fuc409d) ||
gf100_gr_ctor_fw(gr, "gpccs_inst", &gr->fuc41ac) ||
gf100_gr_ctor_fw(gr, "gpccs_data", &gr->fuc41ad))
return -ENODEV;
ret = gk20a_gr_av_to_init(gr, "sw_nonctx", &gr->fuc_sw_nonctx);
if (ret)
return ret;
ret = gk20a_gr_aiv_to_init(gr, "sw_ctx", &gr->fuc_sw_ctx);
if (ret)
return ret;
ret = gk20a_gr_av_to_init(gr, "sw_bundle_init", &gr->fuc_bundle);
if (ret)
return ret;
ret = gk20a_gr_av_to_method(gr, "sw_method_init", &gr->fuc_method);
if (ret)
return ret;
if (gk20a_gr_av_to_init(gr, path, "sw_nonctx", ver, &gr->sw_nonctx) ||
gk20a_gr_aiv_to_init(gr, path, "sw_ctx", ver, &gr->sw_ctx) ||
gk20a_gr_av_to_init(gr, path, "sw_bundle_init", ver, &gr->bundle) ||
gk20a_gr_av_to_method(gr, path, "sw_method_init", ver, &gr->method))
return -ENOENT;
return 0;
}
static int
gk20a_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif)
{
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
if (nvkm_firmware_load_blob(subdev, "", "fecs_inst", ver,
&gr->fecs.inst) ||
nvkm_firmware_load_blob(subdev, "", "fecs_data", ver,
&gr->fecs.data) ||
nvkm_firmware_load_blob(subdev, "", "gpccs_inst", ver,
&gr->gpccs.inst) ||
nvkm_firmware_load_blob(subdev, "", "gpccs_data", ver,
&gr->gpccs.data))
return -ENOENT;
gr->firmware = true;
return gk20a_gr_load_sw(gr, "", ver);
}
static const struct gf100_gr_fwif
gk20a_gr_fwif[] = {
{ -1, gk20a_gr_load, &gk20a_gr },
{}
};
int
gk20a_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(gk20a_gr_fwif, device, index, pgr);
}

View file

@ -429,8 +429,15 @@ gm107_gr = {
}
};
static const struct gf100_gr_fwif
gm107_gr_fwif[] = {
{ -1, gf100_gr_load, &gm107_gr },
{ -1, gf100_gr_nofw, &gm107_gr },
{}
};
int
gm107_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(&gm107_gr, device, index, pgr);
return gf100_gr_new_(gm107_gr_fwif, device, index, pgr);
}

View file

@ -24,14 +24,64 @@
#include "gf100.h"
#include "ctxgf100.h"
#include <core/firmware.h>
#include <subdev/acr.h>
#include <subdev/secboot.h>
#include <nvfw/flcn.h>
#include <nvif/class.h>
/*******************************************************************************
* PGRAPH engine/subdev functions
******************************************************************************/
static void
gm200_gr_acr_bld_patch(struct nvkm_acr *acr, u32 bld, s64 adjust)
{
struct flcn_bl_dmem_desc_v1 hdr;
nvkm_robj(acr->wpr, bld, &hdr, sizeof(hdr));
hdr.code_dma_base = hdr.code_dma_base + adjust;
hdr.data_dma_base = hdr.data_dma_base + adjust;
nvkm_wobj(acr->wpr, bld, &hdr, sizeof(hdr));
flcn_bl_dmem_desc_v1_dump(&acr->subdev, &hdr);
}
static void
gm200_gr_acr_bld_write(struct nvkm_acr *acr, u32 bld,
struct nvkm_acr_lsfw *lsfw)
{
const u64 base = lsfw->offset.img + lsfw->app_start_offset;
const u64 code = base + lsfw->app_resident_code_offset;
const u64 data = base + lsfw->app_resident_data_offset;
const struct flcn_bl_dmem_desc_v1 hdr = {
.ctx_dma = FALCON_DMAIDX_UCODE,
.code_dma_base = code,
.non_sec_code_off = lsfw->app_resident_code_offset,
.non_sec_code_size = lsfw->app_resident_code_size,
.code_entry_point = lsfw->app_imem_entry,
.data_dma_base = data,
.data_size = lsfw->app_resident_data_size,
};
nvkm_wobj(acr->wpr, bld, &hdr, sizeof(hdr));
}
const struct nvkm_acr_lsf_func
gm200_gr_gpccs_acr = {
.flags = NVKM_ACR_LSF_FORCE_PRIV_LOAD,
.bld_size = sizeof(struct flcn_bl_dmem_desc_v1),
.bld_write = gm200_gr_acr_bld_write,
.bld_patch = gm200_gr_acr_bld_patch,
};
const struct nvkm_acr_lsf_func
gm200_gr_fecs_acr = {
.bld_size = sizeof(struct flcn_bl_dmem_desc_v1),
.bld_write = gm200_gr_acr_bld_write,
.bld_patch = gm200_gr_acr_bld_patch,
};
int
gm200_gr_rops(struct gf100_gr *gr)
{
@ -124,44 +174,6 @@ gm200_gr_oneinit_tiles(struct gf100_gr *gr)
}
}
int
gm200_gr_new_(const struct gf100_gr_func *func, struct nvkm_device *device,
int index, struct nvkm_gr **pgr)
{
struct gf100_gr *gr;
int ret;
if (!(gr = kzalloc(sizeof(*gr), GFP_KERNEL)))
return -ENOMEM;
*pgr = &gr->base;
ret = gf100_gr_ctor(func, device, index, gr);
if (ret)
return ret;
/* Load firmwares for non-secure falcons */
if (!nvkm_secboot_is_managed(device->secboot,
NVKM_SECBOOT_FALCON_FECS)) {
if ((ret = gf100_gr_ctor_fw(gr, "gr/fecs_inst", &gr->fuc409c)) ||
(ret = gf100_gr_ctor_fw(gr, "gr/fecs_data", &gr->fuc409d)))
return ret;
}
if (!nvkm_secboot_is_managed(device->secboot,
NVKM_SECBOOT_FALCON_GPCCS)) {
if ((ret = gf100_gr_ctor_fw(gr, "gr/gpccs_inst", &gr->fuc41ac)) ||
(ret = gf100_gr_ctor_fw(gr, "gr/gpccs_data", &gr->fuc41ad)))
return ret;
}
if ((ret = gk20a_gr_av_to_init(gr, "gr/sw_nonctx", &gr->fuc_sw_nonctx)) ||
(ret = gk20a_gr_aiv_to_init(gr, "gr/sw_ctx", &gr->fuc_sw_ctx)) ||
(ret = gk20a_gr_av_to_init(gr, "gr/sw_bundle_init", &gr->fuc_bundle)) ||
(ret = gk20a_gr_av_to_method(gr, "gr/sw_method_init", &gr->fuc_method)))
return ret;
return 0;
}
static const struct gf100_gr_func
gm200_gr = {
.oneinit_tiles = gm200_gr_oneinit_tiles,
@ -197,8 +209,78 @@ gm200_gr = {
}
};
int
gm200_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif)
{
int ret;
ret = nvkm_acr_lsfw_load_bl_inst_data_sig(&gr->base.engine.subdev,
&gr->fecs.falcon,
NVKM_ACR_LSF_FECS,
"gr/fecs_", ver, fwif->fecs);
if (ret)
return ret;
ret = nvkm_acr_lsfw_load_bl_inst_data_sig(&gr->base.engine.subdev,
&gr->gpccs.falcon,
NVKM_ACR_LSF_GPCCS,
"gr/gpccs_", ver,
fwif->gpccs);
if (ret)
return ret;
gr->firmware = true;
return gk20a_gr_load_sw(gr, "gr/", ver);
}
MODULE_FIRMWARE("nvidia/gm200/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gm200/gr/sw_method_init.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gm204/gr/sw_method_init.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gm206/gr/sw_method_init.bin");
static const struct gf100_gr_fwif
gm200_gr_fwif[] = {
{ 0, gm200_gr_load, &gm200_gr, &gm200_gr_fecs_acr, &gm200_gr_gpccs_acr },
{}
};
int
gm200_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gm200_gr_new_(&gm200_gr, device, index, pgr);
return gf100_gr_new_(gm200_gr_fwif, device, index, pgr);
}

View file

@ -22,10 +22,61 @@
#include "gf100.h"
#include "ctxgf100.h"
#include <core/firmware.h>
#include <subdev/acr.h>
#include <subdev/timer.h>
#include <nvfw/flcn.h>
#include <nvif/class.h>
void
gm20b_gr_acr_bld_patch(struct nvkm_acr *acr, u32 bld, s64 adjust)
{
struct flcn_bl_dmem_desc hdr;
u64 addr;
nvkm_robj(acr->wpr, bld, &hdr, sizeof(hdr));
addr = ((u64)hdr.code_dma_base1 << 40 | hdr.code_dma_base << 8);
hdr.code_dma_base = lower_32_bits((addr + adjust) >> 8);
hdr.code_dma_base1 = upper_32_bits((addr + adjust) >> 8);
addr = ((u64)hdr.data_dma_base1 << 40 | hdr.data_dma_base << 8);
hdr.data_dma_base = lower_32_bits((addr + adjust) >> 8);
hdr.data_dma_base1 = upper_32_bits((addr + adjust) >> 8);
nvkm_wobj(acr->wpr, bld, &hdr, sizeof(hdr));
flcn_bl_dmem_desc_dump(&acr->subdev, &hdr);
}
void
gm20b_gr_acr_bld_write(struct nvkm_acr *acr, u32 bld,
struct nvkm_acr_lsfw *lsfw)
{
const u64 base = lsfw->offset.img + lsfw->app_start_offset;
const u64 code = (base + lsfw->app_resident_code_offset) >> 8;
const u64 data = (base + lsfw->app_resident_data_offset) >> 8;
const struct flcn_bl_dmem_desc hdr = {
.ctx_dma = FALCON_DMAIDX_UCODE,
.code_dma_base = lower_32_bits(code),
.non_sec_code_off = lsfw->app_resident_code_offset,
.non_sec_code_size = lsfw->app_resident_code_size,
.code_entry_point = lsfw->app_imem_entry,
.data_dma_base = lower_32_bits(data),
.data_size = lsfw->app_resident_data_size,
.code_dma_base1 = upper_32_bits(code),
.data_dma_base1 = upper_32_bits(data),
};
nvkm_wobj(acr->wpr, bld, &hdr, sizeof(hdr));
}
const struct nvkm_acr_lsf_func
gm20b_gr_fecs_acr = {
.bld_size = sizeof(struct flcn_bl_dmem_desc),
.bld_write = gm20b_gr_acr_bld_write,
.bld_patch = gm20b_gr_acr_bld_patch,
};
static void
gm20b_gr_init_gpc_mmu(struct gf100_gr *gr)
{
@ -33,7 +84,7 @@ gm20b_gr_init_gpc_mmu(struct gf100_gr *gr)
u32 val;
/* Bypass MMU check for non-secure boot */
if (!device->secboot) {
if (!device->acr) {
nvkm_wr32(device, 0x100ce4, 0xffffffff);
if (nvkm_rd32(device, 0x100ce4) != 0xffffffff)
@ -85,8 +136,51 @@ gm20b_gr = {
}
};
static int
gm20b_gr_load(struct gf100_gr *gr, int ver, const struct gf100_gr_fwif *fwif)
{
struct nvkm_subdev *subdev = &gr->base.engine.subdev;
int ret;
ret = nvkm_acr_lsfw_load_bl_inst_data_sig(subdev, &gr->fecs.falcon,
NVKM_ACR_LSF_FECS,
"gr/fecs_", ver, fwif->fecs);
if (ret)
return ret;
if (nvkm_firmware_load_blob(subdev, "gr/", "gpccs_inst", ver,
&gr->gpccs.inst) ||
nvkm_firmware_load_blob(subdev, "gr/", "gpccs_data", ver,
&gr->gpccs.data))
return -ENOENT;
gr->firmware = true;
return gk20a_gr_load_sw(gr, "gr/", ver);
}
#if IS_ENABLED(CONFIG_ARCH_TEGRA_210_SOC)
MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gm20b/gr/sw_method_init.bin");
#endif
static const struct gf100_gr_fwif
gm20b_gr_fwif[] = {
{ 0, gm20b_gr_load, &gm20b_gr, &gm20b_gr_fecs_acr },
{}
};
int
gm20b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gm200_gr_new_(&gm20b_gr, device, index, pgr);
return gf100_gr_new_(gm20b_gr_fwif, device, index, pgr);
}

View file

@ -135,8 +135,27 @@ gp100_gr = {
}
};
MODULE_FIRMWARE("nvidia/gp100/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gp100/gr/sw_method_init.bin");
static const struct gf100_gr_fwif
gp100_gr_fwif[] = {
{ 0, gm200_gr_load, &gp100_gr, &gm200_gr_fecs_acr, &gm200_gr_gpccs_acr },
{}
};
int
gp100_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gm200_gr_new_(&gp100_gr, device, index, pgr);
return gf100_gr_new_(gp100_gr_fwif, device, index, pgr);
}

View file

@ -131,8 +131,27 @@ gp102_gr = {
}
};
MODULE_FIRMWARE("nvidia/gp102/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gp102/gr/sw_method_init.bin");
static const struct gf100_gr_fwif
gp102_gr_fwif[] = {
{ 0, gm200_gr_load, &gp102_gr, &gm200_gr_fecs_acr, &gm200_gr_gpccs_acr },
{}
};
int
gp102_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gm200_gr_new_(&gp102_gr, device, index, pgr);
return gf100_gr_new_(gp102_gr_fwif, device, index, pgr);
}

View file

@ -59,8 +59,40 @@ gp104_gr = {
}
};
MODULE_FIRMWARE("nvidia/gp104/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gp104/gr/sw_method_init.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gp106/gr/sw_method_init.bin");
static const struct gf100_gr_fwif
gp104_gr_fwif[] = {
{ 0, gm200_gr_load, &gp104_gr, &gm200_gr_fecs_acr, &gm200_gr_gpccs_acr },
{}
};
int
gp104_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gm200_gr_new_(&gp104_gr, device, index, pgr);
return gf100_gr_new_(gp104_gr_fwif, device, index, pgr);
}

View file

@ -26,7 +26,7 @@
#include <nvif/class.h>
static const struct gf100_gr_func
const struct gf100_gr_func
gp107_gr = {
.oneinit_tiles = gm200_gr_oneinit_tiles,
.oneinit_sm_id = gm200_gr_oneinit_sm_id,
@ -61,8 +61,27 @@ gp107_gr = {
}
};
MODULE_FIRMWARE("nvidia/gp107/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gp107/gr/sw_method_init.bin");
static const struct gf100_gr_fwif
gp107_gr_fwif[] = {
{ 0, gm200_gr_load, &gp107_gr, &gm200_gr_fecs_acr, &gm200_gr_gpccs_acr },
{}
};
int
gp107_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gm200_gr_new_(&gp107_gr, device, index, pgr);
return gf100_gr_new_(gp107_gr_fwif, device, index, pgr);
}

View file

@ -0,0 +1,97 @@
/*
* 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 "gf100.h"
#include <subdev/acr.h>
#include <nvfw/flcn.h>
static void
gp108_gr_acr_bld_patch(struct nvkm_acr *acr, u32 bld, s64 adjust)
{
struct flcn_bl_dmem_desc_v2 hdr;
nvkm_robj(acr->wpr, bld, &hdr, sizeof(hdr));
hdr.code_dma_base = hdr.code_dma_base + adjust;
hdr.data_dma_base = hdr.data_dma_base + adjust;
nvkm_wobj(acr->wpr, bld, &hdr, sizeof(hdr));
flcn_bl_dmem_desc_v2_dump(&acr->subdev, &hdr);
}
static void
gp108_gr_acr_bld_write(struct nvkm_acr *acr, u32 bld,
struct nvkm_acr_lsfw *lsfw)
{
const u64 base = lsfw->offset.img + lsfw->app_start_offset;
const u64 code = base + lsfw->app_resident_code_offset;
const u64 data = base + lsfw->app_resident_data_offset;
const struct flcn_bl_dmem_desc_v2 hdr = {
.ctx_dma = FALCON_DMAIDX_UCODE,
.code_dma_base = code,
.non_sec_code_off = lsfw->app_resident_code_offset,
.non_sec_code_size = lsfw->app_resident_code_size,
.code_entry_point = lsfw->app_imem_entry,
.data_dma_base = data,
.data_size = lsfw->app_resident_data_size,
};
nvkm_wobj(acr->wpr, bld, &hdr, sizeof(hdr));
}
const struct nvkm_acr_lsf_func
gp108_gr_gpccs_acr = {
.flags = NVKM_ACR_LSF_FORCE_PRIV_LOAD,
.bld_size = sizeof(struct flcn_bl_dmem_desc_v2),
.bld_write = gp108_gr_acr_bld_write,
.bld_patch = gp108_gr_acr_bld_patch,
};
const struct nvkm_acr_lsf_func
gp108_gr_fecs_acr = {
.bld_size = sizeof(struct flcn_bl_dmem_desc_v2),
.bld_write = gp108_gr_acr_bld_write,
.bld_patch = gp108_gr_acr_bld_patch,
};
MODULE_FIRMWARE("nvidia/gp108/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gp108/gr/sw_method_init.bin");
static const struct gf100_gr_fwif
gp108_gr_fwif[] = {
{ 0, gm200_gr_load, &gp107_gr, &gp108_gr_fecs_acr, &gp108_gr_gpccs_acr },
{}
};
int
gp108_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(gp108_gr_fwif, device, index, pgr);
}

View file

@ -23,8 +23,20 @@
#include "gf100.h"
#include "ctxgf100.h"
#include <subdev/acr.h>
#include <nvif/class.h>
#include <nvfw/flcn.h>
static const struct nvkm_acr_lsf_func
gp10b_gr_gpccs_acr = {
.flags = NVKM_ACR_LSF_FORCE_PRIV_LOAD,
.bld_size = sizeof(struct flcn_bl_dmem_desc),
.bld_write = gm20b_gr_acr_bld_write,
.bld_patch = gm20b_gr_acr_bld_patch,
};
static const struct gf100_gr_func
gp10b_gr = {
.oneinit_tiles = gm200_gr_oneinit_tiles,
@ -59,8 +71,29 @@ gp10b_gr = {
}
};
#if IS_ENABLED(CONFIG_ARCH_TEGRA_186_SOC)
MODULE_FIRMWARE("nvidia/gp10b/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gp10b/gr/sw_method_init.bin");
#endif
static const struct gf100_gr_fwif
gp10b_gr_fwif[] = {
{ 0, gm200_gr_load, &gp10b_gr, &gm20b_gr_fecs_acr, &gp10b_gr_gpccs_acr },
{}
};
int
gp10b_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gm200_gr_new_(&gp10b_gr, device, index, pgr);
return gf100_gr_new_(gp10b_gr_fwif, device, index, pgr);
}

View file

@ -45,7 +45,7 @@ gv100_gr_trap_sm(struct gf100_gr *gr, int gpc, int tpc, int sm)
nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x734 + sm * 0x80), gerr);
}
static void
void
gv100_gr_trap_mp(struct gf100_gr *gr, int gpc, int tpc)
{
gv100_gr_trap_sm(gr, gpc, tpc, 0);
@ -59,7 +59,7 @@ gv100_gr_init_4188a4(struct gf100_gr *gr)
nvkm_mask(device, 0x4188a4, 0x03000000, 0x03000000);
}
static void
void
gv100_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
@ -71,14 +71,14 @@ gv100_gr_init_shader_exceptions(struct gf100_gr *gr, int gpc, int tpc)
}
}
static void
void
gv100_gr_init_504430(struct gf100_gr *gr, int gpc, int tpc)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
nvkm_wr32(device, TPC_UNIT(gpc, tpc, 0x430), 0x403f0000);
}
static void
void
gv100_gr_init_419bd8(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
@ -120,8 +120,27 @@ gv100_gr = {
}
};
MODULE_FIRMWARE("nvidia/gv100/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/gv100/gr/sw_method_init.bin");
static const struct gf100_gr_fwif
gv100_gr_fwif[] = {
{ 0, gm200_gr_load, &gv100_gr, &gp108_gr_fecs_acr, &gp108_gr_gpccs_acr },
{}
};
int
gv100_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gm200_gr_new_(&gv100_gr, device, index, pgr);
return gf100_gr_new_(gv100_gr_fwif, device, index, pgr);
}

View file

@ -0,0 +1,177 @@
/*
* 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 "gf100.h"
#include "ctxgf100.h"
#include <nvif/class.h>
static void
tu102_gr_init_fecs_exceptions(struct gf100_gr *gr)
{
nvkm_wr32(gr->base.engine.subdev.device, 0x409c24, 0x006f0002);
}
static void
tu102_gr_init_fs(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
int sm;
gp100_grctx_generate_smid_config(gr);
gk104_grctx_generate_gpc_tpc_nr(gr);
for (sm = 0; sm < gr->sm_nr; sm++) {
nvkm_wr32(device, GPC_UNIT(gr->sm[sm].gpc, 0x0c10 +
gr->sm[sm].tpc * 4), sm);
}
gm200_grctx_generate_dist_skip_table(gr);
gf100_gr_init_num_tpc_per_gpc(gr, true, true);
}
static void
tu102_gr_init_zcull(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
const u32 magicgpc918 = DIV_ROUND_UP(0x00800000, gr->tpc_total);
const u8 tile_nr = ALIGN(gr->tpc_total, 64);
u8 bank[GPC_MAX] = {}, gpc, i, j;
u32 data;
for (i = 0; i < tile_nr; i += 8) {
for (data = 0, j = 0; j < 8 && i + j < gr->tpc_total; j++) {
data |= bank[gr->tile[i + j]] << (j * 4);
bank[gr->tile[i + j]]++;
}
nvkm_wr32(device, GPC_BCAST(0x0980 + ((i / 8) * 4)), data);
}
for (gpc = 0; gpc < gr->gpc_nr; gpc++) {
nvkm_wr32(device, GPC_UNIT(gpc, 0x0914),
gr->screen_tile_row_offset << 8 | gr->tpc_nr[gpc]);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0910), 0x00040000 |
gr->tpc_total);
nvkm_wr32(device, GPC_UNIT(gpc, 0x0918), magicgpc918);
}
nvkm_wr32(device, GPC_BCAST(0x3fd4), magicgpc918);
}
static void
tu102_gr_init_gpc_mmu(struct gf100_gr *gr)
{
struct nvkm_device *device = gr->base.engine.subdev.device;
nvkm_wr32(device, 0x418880, nvkm_rd32(device, 0x100c80) & 0xf8001fff);
nvkm_wr32(device, 0x418890, 0x00000000);
nvkm_wr32(device, 0x418894, 0x00000000);
nvkm_wr32(device, 0x4188b4, nvkm_rd32(device, 0x100cc8));
nvkm_wr32(device, 0x4188b8, nvkm_rd32(device, 0x100ccc));
nvkm_wr32(device, 0x4188b0, nvkm_rd32(device, 0x100cc4));
}
static const struct gf100_gr_func
tu102_gr = {
.oneinit_tiles = gm200_gr_oneinit_tiles,
.oneinit_sm_id = gm200_gr_oneinit_sm_id,
.init = gf100_gr_init,
.init_419bd8 = gv100_gr_init_419bd8,
.init_gpc_mmu = tu102_gr_init_gpc_mmu,
.init_vsc_stream_master = gk104_gr_init_vsc_stream_master,
.init_zcull = tu102_gr_init_zcull,
.init_num_active_ltcs = gf100_gr_init_num_active_ltcs,
.init_rop_active_fbps = gp100_gr_init_rop_active_fbps,
.init_swdx_pes_mask = gp102_gr_init_swdx_pes_mask,
.init_fs = tu102_gr_init_fs,
.init_fecs_exceptions = tu102_gr_init_fecs_exceptions,
.init_ds_hww_esr_2 = gm200_gr_init_ds_hww_esr_2,
.init_sked_hww_esr = gk104_gr_init_sked_hww_esr,
.init_ppc_exceptions = gk104_gr_init_ppc_exceptions,
.init_504430 = gv100_gr_init_504430,
.init_shader_exceptions = gv100_gr_init_shader_exceptions,
.trap_mp = gv100_gr_trap_mp,
.rops = gm200_gr_rops,
.gpc_nr = 6,
.tpc_nr = 5,
.ppc_nr = 3,
.grctx = &tu102_grctx,
.zbc = &gp102_gr_zbc,
.sclass = {
{ -1, -1, FERMI_TWOD_A },
{ -1, -1, KEPLER_INLINE_TO_MEMORY_B },
{ -1, -1, TURING_A, &gf100_fermi },
{ -1, -1, TURING_COMPUTE_A },
{}
}
};
MODULE_FIRMWARE("nvidia/tu102/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/tu102/gr/sw_method_init.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/tu104/gr/sw_method_init.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/fecs_bl.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/fecs_inst.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/fecs_data.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/fecs_sig.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/gpccs_bl.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/gpccs_inst.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/gpccs_data.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/gpccs_sig.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/sw_ctx.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/sw_nonctx.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/sw_bundle_init.bin");
MODULE_FIRMWARE("nvidia/tu106/gr/sw_method_init.bin");
static const struct gf100_gr_fwif
tu102_gr_fwif[] = {
{ 0, gm200_gr_load, &tu102_gr, &gp108_gr_fecs_acr, &gp108_gr_gpccs_acr },
{}
};
int
tu102_gr_new(struct nvkm_device *device, int index, struct nvkm_gr **pgr)
{
return gf100_gr_new_(tu102_gr_fwif, device, index, pgr);
}

View file

@ -1,3 +1,3 @@
# 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

View file

@ -20,48 +20,42 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "priv.h"
#include <subdev/top.h>
#include <engine/falcon.h>
static int
nvkm_nvdec_oneinit(struct nvkm_engine *engine)
{
struct nvkm_nvdec *nvdec = nvkm_nvdec(engine);
struct nvkm_subdev *subdev = &nvdec->engine.subdev;
nvdec->addr = nvkm_top_addr(subdev->device, subdev->index);
if (!nvdec->addr)
return -EINVAL;
/*XXX: fix naming of this when adding support for multiple-NVDEC */
return nvkm_falcon_v1_new(subdev, "NVDEC", nvdec->addr,
&nvdec->falcon);
}
#include <core/firmware.h>
static void *
nvkm_nvdec_dtor(struct nvkm_engine *engine)
{
struct nvkm_nvdec *nvdec = nvkm_nvdec(engine);
nvkm_falcon_del(&nvdec->falcon);
nvkm_falcon_dtor(&nvdec->falcon);
return nvdec;
}
static const struct nvkm_engine_func
nvkm_nvdec = {
.dtor = nvkm_nvdec_dtor,
.oneinit = nvkm_nvdec_oneinit,
};
int
nvkm_nvdec_new_(struct nvkm_device *device, int index,
struct nvkm_nvdec **pnvdec)
nvkm_nvdec_new_(const struct nvkm_nvdec_fwif *fwif, struct nvkm_device *device,
int index, struct nvkm_nvdec **pnvdec)
{
struct nvkm_nvdec *nvdec;
int ret;
if (!(nvdec = *pnvdec = kzalloc(sizeof(*nvdec), GFP_KERNEL)))
return -ENOMEM;
return nvkm_engine_ctor(&nvkm_nvdec, device, index, true,
&nvdec->engine);
ret = nvkm_engine_ctor(&nvkm_nvdec, device, index, true,
&nvdec->engine);
if (ret)
return ret;
fwif = nvkm_firmware_load(&nvdec->engine.subdev, fwif, "Nvdec", nvdec);
if (IS_ERR(fwif))
return -ENODEV;
nvdec->func = fwif->func;
return nvkm_falcon_ctor(nvdec->func->flcn, &nvdec->engine.subdev,
nvkm_subdev_name[index], 0, &nvdec->falcon);
};

View file

@ -19,12 +19,45 @@
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "priv.h"
static const struct nvkm_falcon_func
gm107_nvdec_flcn = {
.debug = 0xd00,
.fbif = 0x600,
.load_imem = nvkm_falcon_v1_load_imem,
.load_dmem = nvkm_falcon_v1_load_dmem,
.read_dmem = nvkm_falcon_v1_read_dmem,
.bind_context = nvkm_falcon_v1_bind_context,
.wait_for_halt = nvkm_falcon_v1_wait_for_halt,
.clear_interrupt = nvkm_falcon_v1_clear_interrupt,
.set_start_addr = nvkm_falcon_v1_set_start_addr,
.start = nvkm_falcon_v1_start,
.enable = nvkm_falcon_v1_enable,
.disable = nvkm_falcon_v1_disable,
};
static const struct nvkm_nvdec_func
gm107_nvdec = {
.flcn = &gm107_nvdec_flcn,
};
static int
gm107_nvdec_nofw(struct nvkm_nvdec *nvdec, int ver,
const struct nvkm_nvdec_fwif *fwif)
{
return 0;
}
static const struct nvkm_nvdec_fwif
gm107_nvdec_fwif[] = {
{ -1, gm107_nvdec_nofw, &gm107_nvdec },
{}
};
int
gp102_nvdec_new(struct nvkm_device *device, int index,
gm107_nvdec_new(struct nvkm_device *device, int index,
struct nvkm_nvdec **pnvdec)
{
return nvkm_nvdec_new_(device, index, pnvdec);
return nvkm_nvdec_new_(gm107_nvdec_fwif, device, index, pnvdec);
}

View file

@ -3,5 +3,17 @@
#define __NVKM_NVDEC_PRIV_H__
#include <engine/nvdec.h>
int nvkm_nvdec_new_(struct nvkm_device *, int, struct nvkm_nvdec **);
struct nvkm_nvdec_func {
const struct nvkm_falcon_func *flcn;
};
struct nvkm_nvdec_fwif {
int version;
int (*load)(struct nvkm_nvdec *, int ver,
const struct nvkm_nvdec_fwif *);
const struct nvkm_nvdec_func *func;
};
int nvkm_nvdec_new_(const struct nvkm_nvdec_fwif *fwif,
struct nvkm_device *, int, struct nvkm_nvdec **);
#endif

View file

@ -1,2 +1,3 @@
# SPDX-License-Identifier: MIT
#nvkm-y += nvkm/engine/nvenc/base.o
nvkm-y += nvkm/engine/nvenc/base.o
nvkm-y += nvkm/engine/nvenc/gm107.o

View file

@ -0,0 +1,63 @@
/*
* Copyright 2019 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "priv.h"
#include "priv.h"
#include <core/firmware.h>
static void *
nvkm_nvenc_dtor(struct nvkm_engine *engine)
{
struct nvkm_nvenc *nvenc = nvkm_nvenc(engine);
nvkm_falcon_dtor(&nvenc->falcon);
return nvenc;
}
static const struct nvkm_engine_func
nvkm_nvenc = {
.dtor = nvkm_nvenc_dtor,
};
int
nvkm_nvenc_new_(const struct nvkm_nvenc_fwif *fwif, struct nvkm_device *device,
int index, struct nvkm_nvenc **pnvenc)
{
struct nvkm_nvenc *nvenc;
int ret;
if (!(nvenc = *pnvenc = kzalloc(sizeof(*nvenc), GFP_KERNEL)))
return -ENOMEM;
ret = nvkm_engine_ctor(&nvkm_nvenc, device, index, true,
&nvenc->engine);
if (ret)
return ret;
fwif = nvkm_firmware_load(&nvenc->engine.subdev, fwif, "Nvenc", nvenc);
if (IS_ERR(fwif))
return -ENODEV;
nvenc->func = fwif->func;
return nvkm_falcon_ctor(nvenc->func->flcn, &nvenc->engine.subdev,
nvkm_subdev_name[index], 0, &nvenc->falcon);
};

View file

@ -0,0 +1,63 @@
/*
* Copyright 2019 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "priv.h"
static const struct nvkm_falcon_func
gm107_nvenc_flcn = {
.fbif = 0x800,
.load_imem = nvkm_falcon_v1_load_imem,
.load_dmem = nvkm_falcon_v1_load_dmem,
.read_dmem = nvkm_falcon_v1_read_dmem,
.bind_context = nvkm_falcon_v1_bind_context,
.wait_for_halt = nvkm_falcon_v1_wait_for_halt,
.clear_interrupt = nvkm_falcon_v1_clear_interrupt,
.set_start_addr = nvkm_falcon_v1_set_start_addr,
.start = nvkm_falcon_v1_start,
.enable = nvkm_falcon_v1_enable,
.disable = nvkm_falcon_v1_disable,
};
static const struct nvkm_nvenc_func
gm107_nvenc = {
.flcn = &gm107_nvenc_flcn,
};
static int
gm107_nvenc_nofw(struct nvkm_nvenc *nvenc, int ver,
const struct nvkm_nvenc_fwif *fwif)
{
return 0;
}
static const struct nvkm_nvenc_fwif
gm107_nvenc_fwif[] = {
{ -1, gm107_nvenc_nofw, &gm107_nvenc },
{}
};
int
gm107_nvenc_new(struct nvkm_device *device, int index,
struct nvkm_nvenc **pnvenc)
{
return nvkm_nvenc_new_(gm107_nvenc_fwif, device, index, pnvenc);
}

View file

@ -0,0 +1,19 @@
/* SPDX-License-Identifier: MIT */
#ifndef __NVKM_NVENC_PRIV_H__
#define __NVKM_NVENC_PRIV_H__
#include <engine/nvenc.h>
struct nvkm_nvenc_func {
const struct nvkm_falcon_func *flcn;
};
struct nvkm_nvenc_fwif {
int version;
int (*load)(struct nvkm_nvenc *, int ver,
const struct nvkm_nvenc_fwif *);
const struct nvkm_nvenc_func *func;
};
int nvkm_nvenc_new_(const struct nvkm_nvenc_fwif *, struct nvkm_device *,
int, struct nvkm_nvenc **pnvenc);
#endif

View file

@ -1,4 +1,5 @@
# SPDX-License-Identifier: MIT
nvkm-y += nvkm/engine/sec2/base.o
nvkm-y += nvkm/engine/sec2/gp102.o
nvkm-y += nvkm/engine/sec2/gp108.o
nvkm-y += nvkm/engine/sec2/tu102.o

Some files were not shown because too many files have changed in this diff Show more