Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
There's really not a great deal this time due to me spending most of this window on Maxwell. But, here's the random bits and pieces that's currently queued. * 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: (25 commits) drm/gk208/gr: add missing registers to grctx init drm/nouveau/kms/nv04-nv40: fix pageflip events via special case. drm/nv50-/mc: fix kms pageflip events by reordering irq handling order. drm/nouveau/disp/nv04-nv40: abort scanoutpos query on vga analog. drm/nv50-/kms: wait for enough ring space in crtc_prepare() drm/nouveau/disp/dp: support training pattern 3 drm/nouveau/disp/dp: support aux read interval during link training drm/gk104/gpio: fix incorrect interrupt register usage drm/nouveau/core: punt all object state change messages to trace level drm/nouveau/clk: allow end-user reclocking for nv40, nvaa, and nve0 clock types drm/nouveau/fb: default NvMemExec to on, turning it off is used for debugging only drm/nouveau/bios: fix a potential NULL deref in the PROM shadowing function drm/nouveau/i2c: bump the i2c delay for the adt7473 drm/nouveau/therm/fan/tach: default to 2 pulses per revolution drm/nvf0/device: enable video decoding engines on gk110/gk208 drm/nvf1/device: add support for 0xf1 (gk110b) drm/nouveau/device: support for probing GK20A drm/nouveau/graph: add GK20A support drm/nouveau/graph: pad firmware code at load time drm/nouveau/graph: enable when using external fw ...
This commit is contained in:
commit
b06c47a13c
|
@ -102,6 +102,7 @@ nouveau-y += core/subdev/fb/nvaa.o
|
|||
nouveau-y += core/subdev/fb/nvaf.o
|
||||
nouveau-y += core/subdev/fb/nvc0.o
|
||||
nouveau-y += core/subdev/fb/nve0.o
|
||||
nouveau-y += core/subdev/fb/gk20a.o
|
||||
nouveau-y += core/subdev/fb/gm107.o
|
||||
nouveau-y += core/subdev/fb/ramnv04.o
|
||||
nouveau-y += core/subdev/fb/ramnv10.o
|
||||
|
@ -117,6 +118,7 @@ nouveau-y += core/subdev/fb/ramnva3.o
|
|||
nouveau-y += core/subdev/fb/ramnvaa.o
|
||||
nouveau-y += core/subdev/fb/ramnvc0.o
|
||||
nouveau-y += core/subdev/fb/ramnve0.o
|
||||
nouveau-y += core/subdev/fb/ramgk20a.o
|
||||
nouveau-y += core/subdev/fb/ramgm107.o
|
||||
nouveau-y += core/subdev/fb/sddr3.o
|
||||
nouveau-y += core/subdev/fb/gddr5.o
|
||||
|
@ -136,6 +138,7 @@ nouveau-y += core/subdev/i2c/nv94.o
|
|||
nouveau-y += core/subdev/i2c/nvd0.o
|
||||
nouveau-y += core/subdev/ibus/nvc0.o
|
||||
nouveau-y += core/subdev/ibus/nve0.o
|
||||
nouveau-y += core/subdev/ibus/gk20a.o
|
||||
nouveau-y += core/subdev/instmem/base.o
|
||||
nouveau-y += core/subdev/instmem/nv04.o
|
||||
nouveau-y += core/subdev/instmem/nv40.o
|
||||
|
@ -245,6 +248,7 @@ nouveau-y += core/engine/fifo/nv50.o
|
|||
nouveau-y += core/engine/fifo/nv84.o
|
||||
nouveau-y += core/engine/fifo/nvc0.o
|
||||
nouveau-y += core/engine/fifo/nve0.o
|
||||
nouveau-y += core/engine/fifo/gk20a.o
|
||||
nouveau-y += core/engine/fifo/nv108.o
|
||||
nouveau-y += core/engine/graph/ctxnv40.o
|
||||
nouveau-y += core/engine/graph/ctxnv50.o
|
||||
|
@ -255,6 +259,7 @@ nouveau-y += core/engine/graph/ctxnvc8.o
|
|||
nouveau-y += core/engine/graph/ctxnvd7.o
|
||||
nouveau-y += core/engine/graph/ctxnvd9.o
|
||||
nouveau-y += core/engine/graph/ctxnve4.o
|
||||
nouveau-y += core/engine/graph/ctxgk20a.o
|
||||
nouveau-y += core/engine/graph/ctxnvf0.o
|
||||
nouveau-y += core/engine/graph/ctxnv108.o
|
||||
nouveau-y += core/engine/graph/ctxgm107.o
|
||||
|
@ -275,6 +280,7 @@ nouveau-y += core/engine/graph/nvc8.o
|
|||
nouveau-y += core/engine/graph/nvd7.o
|
||||
nouveau-y += core/engine/graph/nvd9.o
|
||||
nouveau-y += core/engine/graph/nve4.o
|
||||
nouveau-y += core/engine/graph/gk20a.o
|
||||
nouveau-y += core/engine/graph/nvf0.o
|
||||
nouveau-y += core/engine/graph/nv108.o
|
||||
nouveau-y += core/engine/graph/gm107.o
|
||||
|
|
|
@ -156,7 +156,7 @@ nouveau_object_ctor(struct nouveau_object *parent,
|
|||
}
|
||||
|
||||
if (ret == 0) {
|
||||
nv_debug(object, "created\n");
|
||||
nv_trace(object, "created\n");
|
||||
atomic_set(&object->refcount, 1);
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ nouveau_object_ctor(struct nouveau_object *parent,
|
|||
static void
|
||||
nouveau_object_dtor(struct nouveau_object *object)
|
||||
{
|
||||
nv_debug(object, "destroying\n");
|
||||
nv_trace(object, "destroying\n");
|
||||
nv_ofuncs(object)->dtor(object);
|
||||
}
|
||||
|
||||
|
@ -337,7 +337,7 @@ nouveau_object_inc(struct nouveau_object *object)
|
|||
goto fail_self;
|
||||
}
|
||||
|
||||
nv_debug(object, "initialised\n");
|
||||
nv_trace(object, "initialised\n");
|
||||
return 0;
|
||||
|
||||
fail_self:
|
||||
|
@ -375,7 +375,7 @@ nouveau_object_decf(struct nouveau_object *object)
|
|||
if (object->parent)
|
||||
nouveau_object_dec(object->parent, false);
|
||||
|
||||
nv_debug(object, "stopped\n");
|
||||
nv_trace(object, "stopped\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -411,7 +411,7 @@ nouveau_object_decs(struct nouveau_object *object)
|
|||
}
|
||||
}
|
||||
|
||||
nv_debug(object, "suspended\n");
|
||||
nv_trace(object, "suspended\n");
|
||||
return 0;
|
||||
|
||||
fail_parent:
|
||||
|
|
|
@ -156,6 +156,23 @@ nve0_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
|
||||
break;
|
||||
case 0xea:
|
||||
device->cname = "GK20A";
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_FB ] = gk20a_fb_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_IBUS ] = &gk20a_ibus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
|
||||
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = gk20a_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
device->oclass[NVDEV_ENGINE_GR ] = gk20a_graph_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
|
||||
device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
|
||||
break;
|
||||
case 0xf0:
|
||||
device->cname = "GK110";
|
||||
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
|
||||
|
@ -184,11 +201,42 @@ nve0_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
|
||||
#if 0
|
||||
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
||||
#endif
|
||||
device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
|
||||
break;
|
||||
case 0xf1:
|
||||
device->cname = "GK110B";
|
||||
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_LTCG ] = gf100_ltcg_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
|
||||
device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass;
|
||||
device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
|
||||
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
|
||||
break;
|
||||
case 0x108:
|
||||
|
@ -219,11 +267,9 @@ nve0_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass;
|
||||
device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
|
||||
#if 0
|
||||
device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
nv_fatal(device, "unknown Kepler chipset\n");
|
||||
|
|
|
@ -48,7 +48,7 @@ struct dp_state {
|
|||
u8 version;
|
||||
struct nouveau_i2c_port *aux;
|
||||
int head;
|
||||
u8 dpcd[4];
|
||||
u8 dpcd[16];
|
||||
int link_nr;
|
||||
u32 link_bw;
|
||||
u8 stat[6];
|
||||
|
@ -149,7 +149,10 @@ dp_link_train_update(struct dp_state *dp, u32 delay)
|
|||
{
|
||||
int ret;
|
||||
|
||||
udelay(delay);
|
||||
if (dp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL])
|
||||
mdelay(dp->dpcd[DPCD_RC0E_AUX_RD_INTERVAL] * 4);
|
||||
else
|
||||
udelay(delay);
|
||||
|
||||
ret = nv_rdaux(dp->aux, DPCD_LS02, dp->stat, 6);
|
||||
if (ret)
|
||||
|
@ -199,7 +202,10 @@ dp_link_train_eq(struct dp_state *dp)
|
|||
bool eq_done = false, cr_done = true;
|
||||
int tries = 0, i;
|
||||
|
||||
dp_set_training_pattern(dp, 2);
|
||||
if (dp->dpcd[2] & DPCD_RC02_TPS3_SUPPORTED)
|
||||
dp_set_training_pattern(dp, 3);
|
||||
else
|
||||
dp_set_training_pattern(dp, 2);
|
||||
|
||||
do {
|
||||
if (dp_link_train_update(dp, 400))
|
||||
|
@ -313,8 +319,10 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func,
|
|||
}
|
||||
|
||||
/* bring capabilities within encoder limits */
|
||||
if (nv_oclass(disp)->handle < NV_ENGINE(DISP, 0x90))
|
||||
dp->dpcd[2] &= ~DPCD_RC02_TPS3_SUPPORTED;
|
||||
if ((dp->dpcd[2] & 0x1f) > dp->outp->dpconf.link_nr) {
|
||||
dp->dpcd[2] &= ~0x1f;
|
||||
dp->dpcd[2] &= ~DPCD_RC02_MAX_LANE_COUNT;
|
||||
dp->dpcd[2] |= dp->outp->dpconf.link_nr;
|
||||
}
|
||||
if (dp->dpcd[1] > dp->outp->dpconf.link_bw)
|
||||
|
|
|
@ -2,15 +2,15 @@
|
|||
#define __NVKM_DISP_DPORT_H__
|
||||
|
||||
/* DPCD Receiver Capabilities */
|
||||
#define DPCD_RC00 0x00000
|
||||
#define DPCD_RC00_DPCD_REV 0xff
|
||||
#define DPCD_RC01 0x00001
|
||||
#define DPCD_RC01_MAX_LINK_RATE 0xff
|
||||
#define DPCD_RC00_DPCD_REV 0x00000
|
||||
#define DPCD_RC01_MAX_LINK_RATE 0x00001
|
||||
#define DPCD_RC02 0x00002
|
||||
#define DPCD_RC02_ENHANCED_FRAME_CAP 0x80
|
||||
#define DPCD_RC02_TPS3_SUPPORTED 0x40
|
||||
#define DPCD_RC02_MAX_LANE_COUNT 0x1f
|
||||
#define DPCD_RC03 0x00003
|
||||
#define DPCD_RC03_MAX_DOWNSPREAD 0x01
|
||||
#define DPCD_RC0E_AUX_RD_INTERVAL 0x0000e
|
||||
|
||||
/* DPCD Link Configuration */
|
||||
#define DPCD_LC00 0x00100
|
||||
|
|
|
@ -51,6 +51,14 @@ nv04_disp_scanoutpos(struct nouveau_object *object, u32 mthd,
|
|||
args->htotal = nv_rd32(priv, 0x680824 + (head * 0x2000)) & 0xffff;
|
||||
args->hblanke = args->htotal - 1;
|
||||
|
||||
/*
|
||||
* If output is vga instead of digital then vtotal/htotal is invalid
|
||||
* so we have to give up and trigger the timestamping fallback in the
|
||||
* drm core.
|
||||
*/
|
||||
if (!args->vtotal || !args->htotal)
|
||||
return -ENOTSUPP;
|
||||
|
||||
args->time[0] = ktime_to_ns(ktime_get());
|
||||
line = nv_rd32(priv, 0x600868 + (head * 0x2000));
|
||||
args->time[1] = ktime_to_ns(ktime_get());
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
#include "nve0.h"
|
||||
|
||||
struct nouveau_oclass *
|
||||
gk20a_fifo_oclass = &(struct nve0_fifo_impl) {
|
||||
.base.handle = NV_ENGINE(FIFO, 0xea),
|
||||
.base.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = nve0_fifo_ctor,
|
||||
.dtor = nve0_fifo_dtor,
|
||||
.init = nve0_fifo_init,
|
||||
.fini = nve0_fifo_fini,
|
||||
},
|
||||
.channels = 128,
|
||||
}.base;
|
|
@ -8,6 +8,7 @@ int nve0_fifo_ctor(struct nouveau_object *, struct nouveau_object *,
|
|||
struct nouveau_object **);
|
||||
void nve0_fifo_dtor(struct nouveau_object *);
|
||||
int nve0_fifo_init(struct nouveau_object *);
|
||||
int nve0_fifo_fini(struct nouveau_object *, bool);
|
||||
|
||||
struct nve0_fifo_impl {
|
||||
struct nouveau_oclass base;
|
||||
|
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
#include "ctxnvc0.h"
|
||||
|
||||
static const struct nvc0_graph_pack
|
||||
gk20a_grctx_pack_mthd[] = {
|
||||
{ nve4_grctx_init_a097_0, 0xa297 },
|
||||
{ nvc0_grctx_init_902d_0, 0x902d },
|
||||
{}
|
||||
};
|
||||
|
||||
struct nouveau_oclass *
|
||||
gk20a_grctx_oclass = &(struct nvc0_grctx_oclass) {
|
||||
.base.handle = NV_ENGCTX(GR, 0xea),
|
||||
.base.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = nvc0_graph_context_ctor,
|
||||
.dtor = nvc0_graph_context_dtor,
|
||||
.init = _nouveau_graph_context_init,
|
||||
.fini = _nouveau_graph_context_fini,
|
||||
.rd32 = _nouveau_graph_context_rd32,
|
||||
.wr32 = _nouveau_graph_context_wr32,
|
||||
},
|
||||
.main = nve4_grctx_generate_main,
|
||||
.mods = nve4_grctx_generate_mods,
|
||||
.unkn = nve4_grctx_generate_unkn,
|
||||
.hub = nve4_grctx_pack_hub,
|
||||
.gpc = nve4_grctx_pack_gpc,
|
||||
.zcull = nvc0_grctx_pack_zcull,
|
||||
.tpc = nve4_grctx_pack_tpc,
|
||||
.ppc = nve4_grctx_pack_ppc,
|
||||
.icmd = nve4_grctx_pack_icmd,
|
||||
.mthd = gk20a_grctx_pack_mthd,
|
||||
}.base;
|
|
@ -545,10 +545,12 @@ nv108_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
|
|||
mmio_list(0x408010, 0x80000000, 0, 0);
|
||||
mmio_list(0x419004, 0x00000000, 8, 1);
|
||||
mmio_list(0x419008, 0x00000000, 0, 0);
|
||||
mmio_list(0x4064cc, 0x80000000, 0, 0);
|
||||
mmio_list(0x408004, 0x00000000, 8, 0);
|
||||
mmio_list(0x408008, 0x80000030, 0, 0);
|
||||
mmio_list(0x418808, 0x00000000, 8, 0);
|
||||
mmio_list(0x41880c, 0x80000030, 0, 0);
|
||||
mmio_list(0x4064c8, 0x00c20200, 0, 0);
|
||||
mmio_list(0x418810, 0x80000000, 12, 2);
|
||||
mmio_list(0x419848, 0x10000000, 12, 2);
|
||||
|
||||
|
|
|
@ -69,7 +69,9 @@ extern struct nouveau_oclass *nvd7_grctx_oclass;
|
|||
extern struct nouveau_oclass *nvd9_grctx_oclass;
|
||||
|
||||
extern struct nouveau_oclass *nve4_grctx_oclass;
|
||||
extern struct nouveau_oclass *gk20a_grctx_oclass;
|
||||
void nve4_grctx_generate_main(struct nvc0_graph_priv *, struct nvc0_grctx *);
|
||||
void nve4_grctx_generate_mods(struct nvc0_graph_priv *, struct nvc0_grctx *);
|
||||
void nve4_grctx_generate_unkn(struct nvc0_graph_priv *);
|
||||
void nve4_grctx_generate_r418bb8(struct nvc0_graph_priv *);
|
||||
|
||||
|
@ -151,6 +153,13 @@ extern const struct nvc0_graph_init nve4_grctx_init_gpm_0[];
|
|||
|
||||
extern const struct nvc0_graph_init nve4_grctx_init_pes_0[];
|
||||
|
||||
extern const struct nvc0_graph_pack nve4_grctx_pack_hub[];
|
||||
extern const struct nvc0_graph_pack nve4_grctx_pack_gpc[];
|
||||
extern const struct nvc0_graph_pack nve4_grctx_pack_tpc[];
|
||||
extern const struct nvc0_graph_pack nve4_grctx_pack_ppc[];
|
||||
extern const struct nvc0_graph_pack nve4_grctx_pack_icmd[];
|
||||
extern const struct nvc0_graph_init nve4_grctx_init_a097_0[];
|
||||
|
||||
extern const struct nvc0_graph_pack nvf0_grctx_pack_mthd[];
|
||||
|
||||
extern const struct nvc0_graph_init nvf0_grctx_init_pri_0[];
|
||||
|
|
|
@ -272,13 +272,13 @@ nve4_grctx_init_icmd_0[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct nvc0_graph_pack
|
||||
const struct nvc0_graph_pack
|
||||
nve4_grctx_pack_icmd[] = {
|
||||
{ nve4_grctx_init_icmd_0 },
|
||||
{}
|
||||
};
|
||||
|
||||
static const struct nvc0_graph_init
|
||||
const struct nvc0_graph_init
|
||||
nve4_grctx_init_a097_0[] = {
|
||||
{ 0x000800, 8, 0x40, 0x00000000 },
|
||||
{ 0x000804, 8, 0x40, 0x00000000 },
|
||||
|
@ -697,7 +697,7 @@ nve4_grctx_init_be_0[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct nvc0_graph_pack
|
||||
const struct nvc0_graph_pack
|
||||
nve4_grctx_pack_hub[] = {
|
||||
{ nvc0_grctx_init_main_0 },
|
||||
{ nve4_grctx_init_fe_0 },
|
||||
|
@ -737,7 +737,7 @@ nve4_grctx_init_gpm_0[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct nvc0_graph_pack
|
||||
const struct nvc0_graph_pack
|
||||
nve4_grctx_pack_gpc[] = {
|
||||
{ nvc0_grctx_init_gpc_unk_0 },
|
||||
{ nvd9_grctx_init_prop_0 },
|
||||
|
@ -802,7 +802,7 @@ nve4_grctx_init_sm_0[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct nvc0_graph_pack
|
||||
const struct nvc0_graph_pack
|
||||
nve4_grctx_pack_tpc[] = {
|
||||
{ nvd7_grctx_init_pe_0 },
|
||||
{ nve4_grctx_init_tex_0 },
|
||||
|
@ -826,7 +826,7 @@ nve4_grctx_init_cbm_0[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct nvc0_graph_pack
|
||||
const struct nvc0_graph_pack
|
||||
nve4_grctx_pack_ppc[] = {
|
||||
{ nve4_grctx_init_pes_0 },
|
||||
{ nve4_grctx_init_cbm_0 },
|
||||
|
@ -838,7 +838,7 @@ nve4_grctx_pack_ppc[] = {
|
|||
* PGRAPH context implementation
|
||||
******************************************************************************/
|
||||
|
||||
static void
|
||||
void
|
||||
nve4_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info)
|
||||
{
|
||||
u32 magic[GPC_MAX][2];
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
#include "nvc0.h"
|
||||
#include "ctxnvc0.h"
|
||||
|
||||
static struct nouveau_oclass
|
||||
gk20a_graph_sclass[] = {
|
||||
{ 0x902d, &nouveau_object_ofuncs },
|
||||
{ 0xa040, &nouveau_object_ofuncs },
|
||||
{ 0xa297, &nouveau_object_ofuncs },
|
||||
{ 0xa0c0, &nouveau_object_ofuncs },
|
||||
{}
|
||||
};
|
||||
|
||||
struct nouveau_oclass *
|
||||
gk20a_graph_oclass = &(struct nvc0_graph_oclass) {
|
||||
.base.handle = NV_ENGINE(GR, 0xea),
|
||||
.base.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = nvc0_graph_ctor,
|
||||
.dtor = nvc0_graph_dtor,
|
||||
.init = nve4_graph_init,
|
||||
.fini = nve4_graph_fini,
|
||||
},
|
||||
.cclass = &gk20a_grctx_oclass,
|
||||
.sclass = gk20a_graph_sclass,
|
||||
.mmio = nve4_graph_pack_mmio,
|
||||
}.base;
|
|
@ -894,6 +894,10 @@ nvc0_graph_init_fw(struct nvc0_graph_priv *priv, u32 fuc_base,
|
|||
nv_wr32(priv, fuc_base + 0x0188, i >> 6);
|
||||
nv_wr32(priv, fuc_base + 0x0184, code->data[i]);
|
||||
}
|
||||
|
||||
/* code must be padded to 0x40 words */
|
||||
for (; i & 0x3f; i++)
|
||||
nv_wr32(priv, fuc_base + 0x0184, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1259,10 +1263,14 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nvc0_graph_oclass *oclass = (void *)bclass;
|
||||
struct nouveau_device *device = nv_device(parent);
|
||||
struct nvc0_graph_priv *priv;
|
||||
bool use_ext_fw, enable;
|
||||
int ret, i;
|
||||
|
||||
ret = nouveau_graph_create(parent, engine, bclass,
|
||||
(oclass->fecs.ucode != NULL), &priv);
|
||||
use_ext_fw = nouveau_boolopt(device->cfgopt, "NvGrUseFW",
|
||||
oclass->fecs.ucode == NULL);
|
||||
enable = use_ext_fw || oclass->fecs.ucode != NULL;
|
||||
|
||||
ret = nouveau_graph_create(parent, engine, bclass, enable, &priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -1272,7 +1280,7 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
|
||||
priv->base.units = nvc0_graph_units;
|
||||
|
||||
if (nouveau_boolopt(device->cfgopt, "NvGrUseFW", false)) {
|
||||
if (use_ext_fw) {
|
||||
nv_info(priv, "using external firmware\n");
|
||||
if (nvc0_graph_ctor_fw(priv, "fuc409c", &priv->fuc409c) ||
|
||||
nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
|
||||
|
|
|
@ -116,6 +116,7 @@ int nvc0_graph_ctor(struct nouveau_object *, struct nouveau_object *,
|
|||
struct nouveau_object **);
|
||||
void nvc0_graph_dtor(struct nouveau_object *);
|
||||
int nvc0_graph_init(struct nouveau_object *);
|
||||
int nve4_graph_fini(struct nouveau_object *, bool);
|
||||
int nve4_graph_init(struct nouveau_object *);
|
||||
|
||||
extern struct nouveau_oclass nvc0_graph_sclass[];
|
||||
|
@ -217,6 +218,7 @@ extern const struct nvc0_graph_init nve4_graph_init_main_0[];
|
|||
extern const struct nvc0_graph_init nve4_graph_init_tpccs_0[];
|
||||
extern const struct nvc0_graph_init nve4_graph_init_pe_0[];
|
||||
extern const struct nvc0_graph_init nve4_graph_init_be_0[];
|
||||
extern const struct nvc0_graph_pack nve4_graph_pack_mmio[];
|
||||
|
||||
extern const struct nvc0_graph_init nvf0_graph_init_fe_0[];
|
||||
extern const struct nvc0_graph_init nvf0_graph_init_sked_0[];
|
||||
|
|
|
@ -151,7 +151,7 @@ nve4_graph_init_be_0[] = {
|
|||
{}
|
||||
};
|
||||
|
||||
static const struct nvc0_graph_pack
|
||||
const struct nvc0_graph_pack
|
||||
nve4_graph_pack_mmio[] = {
|
||||
{ nve4_graph_init_main_0 },
|
||||
{ nvc0_graph_init_fe_0 },
|
||||
|
@ -189,7 +189,7 @@ nve4_graph_pack_mmio[] = {
|
|||
* PGRAPH engine/subdev functions
|
||||
******************************************************************************/
|
||||
|
||||
static int
|
||||
int
|
||||
nve4_graph_fini(struct nouveau_object *object, bool suspend)
|
||||
{
|
||||
struct nvc0_graph_priv *priv = (void *)object;
|
||||
|
|
|
@ -109,6 +109,7 @@ extern struct nouveau_oclass *nv50_fifo_oclass;
|
|||
extern struct nouveau_oclass *nv84_fifo_oclass;
|
||||
extern struct nouveau_oclass *nvc0_fifo_oclass;
|
||||
extern struct nouveau_oclass *nve0_fifo_oclass;
|
||||
extern struct nouveau_oclass *gk20a_fifo_oclass;
|
||||
extern struct nouveau_oclass *nv108_fifo_oclass;
|
||||
|
||||
void nv04_fifo_intr(struct nouveau_subdev *);
|
||||
|
|
|
@ -68,6 +68,7 @@ extern struct nouveau_oclass *nvc8_graph_oclass;
|
|||
extern struct nouveau_oclass *nvd7_graph_oclass;
|
||||
extern struct nouveau_oclass *nvd9_graph_oclass;
|
||||
extern struct nouveau_oclass *nve4_graph_oclass;
|
||||
extern struct nouveau_oclass *gk20a_graph_oclass;
|
||||
extern struct nouveau_oclass *nvf0_graph_oclass;
|
||||
extern struct nouveau_oclass *nv108_graph_oclass;
|
||||
extern struct nouveau_oclass *gm107_graph_oclass;
|
||||
|
|
|
@ -77,6 +77,8 @@ struct nouveau_clock {
|
|||
int tstate; /* thermal adjustment (max-) */
|
||||
int dstate; /* display adjustment (min+) */
|
||||
|
||||
bool allow_reclock;
|
||||
|
||||
int (*read)(struct nouveau_clock *, enum nv_clk_src);
|
||||
int (*calc)(struct nouveau_clock *, struct nouveau_cstate *);
|
||||
int (*prog)(struct nouveau_clock *);
|
||||
|
@ -106,8 +108,8 @@ struct nouveau_clocks {
|
|||
int mdiv;
|
||||
};
|
||||
|
||||
#define nouveau_clock_create(p,e,o,i,d) \
|
||||
nouveau_clock_create_((p), (e), (o), (i), sizeof(**d), (void **)d)
|
||||
#define nouveau_clock_create(p,e,o,i,r,d) \
|
||||
nouveau_clock_create_((p), (e), (o), (i), (r), sizeof(**d), (void **)d)
|
||||
#define nouveau_clock_destroy(p) ({ \
|
||||
struct nouveau_clock *clk = (p); \
|
||||
_nouveau_clock_dtor(nv_object(clk)); \
|
||||
|
@ -121,7 +123,7 @@ struct nouveau_clocks {
|
|||
|
||||
int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *,
|
||||
struct nouveau_oclass *,
|
||||
struct nouveau_clocks *, int, void **);
|
||||
struct nouveau_clocks *, bool, int, void **);
|
||||
void _nouveau_clock_dtor(struct nouveau_object *);
|
||||
int _nouveau_clock_init(struct nouveau_object *);
|
||||
#define _nouveau_clock_fini _nouveau_subdev_fini
|
||||
|
|
|
@ -105,6 +105,7 @@ extern struct nouveau_oclass *nvaa_fb_oclass;
|
|||
extern struct nouveau_oclass *nvaf_fb_oclass;
|
||||
extern struct nouveau_oclass *nvc0_fb_oclass;
|
||||
extern struct nouveau_oclass *nve0_fb_oclass;
|
||||
extern struct nouveau_oclass *gk20a_fb_oclass;
|
||||
extern struct nouveau_oclass *gm107_fb_oclass;
|
||||
|
||||
#include <subdev/bios/ramcfg.h>
|
||||
|
|
|
@ -30,5 +30,6 @@ nouveau_ibus(void *obj)
|
|||
|
||||
extern struct nouveau_oclass nvc0_ibus_oclass;
|
||||
extern struct nouveau_oclass nve0_ibus_oclass;
|
||||
extern struct nouveau_oclass gk20a_ibus_oclass;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -118,8 +118,10 @@ nouveau_bar_create_(struct nouveau_object *parent,
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
bar->iomem = ioremap(nv_device_resource_start(device, 3),
|
||||
nv_device_resource_len(device, 3));
|
||||
if (nv_device_resource_len(device, 3) != 0)
|
||||
bar->iomem = ioremap(nv_device_resource_start(device, 3),
|
||||
nv_device_resource_len(device, 3));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,14 +30,16 @@
|
|||
|
||||
#include "priv.h"
|
||||
|
||||
struct nvc0_bar_priv_vm {
|
||||
struct nouveau_gpuobj *mem;
|
||||
struct nouveau_gpuobj *pgd;
|
||||
struct nouveau_vm *vm;
|
||||
};
|
||||
|
||||
struct nvc0_bar_priv {
|
||||
struct nouveau_bar base;
|
||||
spinlock_t lock;
|
||||
struct {
|
||||
struct nouveau_gpuobj *mem;
|
||||
struct nouveau_gpuobj *pgd;
|
||||
struct nouveau_vm *vm;
|
||||
} bar[2];
|
||||
struct nvc0_bar_priv_vm bar[2];
|
||||
};
|
||||
|
||||
static int
|
||||
|
@ -78,6 +80,59 @@ nvc0_bar_unmap(struct nouveau_bar *bar, struct nouveau_vma *vma)
|
|||
nouveau_vm_put(vma);
|
||||
}
|
||||
|
||||
static int
|
||||
nvc0_bar_init_vm(struct nvc0_bar_priv *priv, struct nvc0_bar_priv_vm *bar_vm,
|
||||
int bar_nr)
|
||||
{
|
||||
struct nouveau_device *device = nv_device(&priv->base);
|
||||
struct nouveau_vm *vm;
|
||||
resource_size_t bar_len;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
|
||||
&bar_vm->mem);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
|
||||
&bar_vm->pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
bar_len = nv_device_resource_len(device, bar_nr);
|
||||
|
||||
ret = nouveau_vm_new(device, 0, bar_len, 0, &vm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
|
||||
|
||||
/*
|
||||
* Bootstrap page table lookup.
|
||||
*/
|
||||
if (bar_nr == 3) {
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL,
|
||||
(bar_len >> 12) * 8, 0x1000,
|
||||
NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&vm->pgt[0].obj[0]);
|
||||
vm->pgt[0].refcount[0] = 1;
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = nouveau_vm_ref(vm, &bar_vm->vm, bar_vm->pgd);
|
||||
nouveau_vm_ref(NULL, &vm, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_wo32(bar_vm->mem, 0x0200, lower_32_bits(bar_vm->pgd->addr));
|
||||
nv_wo32(bar_vm->mem, 0x0204, upper_32_bits(bar_vm->pgd->addr));
|
||||
nv_wo32(bar_vm->mem, 0x0208, lower_32_bits(bar_len - 1));
|
||||
nv_wo32(bar_vm->mem, 0x020c, upper_32_bits(bar_len - 1));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass, void *data, u32 size,
|
||||
|
@ -85,8 +140,7 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
{
|
||||
struct nouveau_device *device = nv_device(parent);
|
||||
struct nvc0_bar_priv *priv;
|
||||
struct nouveau_gpuobj *mem;
|
||||
struct nouveau_vm *vm;
|
||||
bool has_bar3 = nv_device_resource_len(device, 3) != 0;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_bar_create(parent, engine, oclass, &priv);
|
||||
|
@ -95,71 +149,19 @@ nvc0_bar_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
return ret;
|
||||
|
||||
/* BAR3 */
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
|
||||
&priv->bar[0].mem);
|
||||
mem = priv->bar[0].mem;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
|
||||
&priv->bar[0].pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 3), 0, &vm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
|
||||
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL,
|
||||
(nv_device_resource_len(device, 3) >> 12) * 8,
|
||||
0x1000, NVOBJ_FLAG_ZERO_ALLOC,
|
||||
&vm->pgt[0].obj[0]);
|
||||
vm->pgt[0].refcount[0] = 1;
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_vm_ref(vm, &priv->bar[0].vm, priv->bar[0].pgd);
|
||||
nouveau_vm_ref(NULL, &vm, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[0].pgd->addr));
|
||||
nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[0].pgd->addr));
|
||||
nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 3) - 1));
|
||||
nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 3) - 1));
|
||||
if (has_bar3) {
|
||||
ret = nvc0_bar_init_vm(priv, &priv->bar[0], 3);
|
||||
if (ret)
|
||||
return ret;
|
||||
priv->base.alloc = nouveau_bar_alloc;
|
||||
priv->base.kmap = nvc0_bar_kmap;
|
||||
}
|
||||
|
||||
/* BAR1 */
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x1000, 0, 0,
|
||||
&priv->bar[1].mem);
|
||||
mem = priv->bar[1].mem;
|
||||
ret = nvc0_bar_init_vm(priv, &priv->bar[1], 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_gpuobj_new(nv_object(priv), NULL, 0x8000, 0, 0,
|
||||
&priv->bar[1].pgd);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = nouveau_vm_new(device, 0, nv_device_resource_len(device, 1), 0, &vm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
atomic_inc(&vm->engref[NVDEV_SUBDEV_BAR]);
|
||||
|
||||
ret = nouveau_vm_ref(vm, &priv->bar[1].vm, priv->bar[1].pgd);
|
||||
nouveau_vm_ref(NULL, &vm, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_wo32(mem, 0x0200, lower_32_bits(priv->bar[1].pgd->addr));
|
||||
nv_wo32(mem, 0x0204, upper_32_bits(priv->bar[1].pgd->addr));
|
||||
nv_wo32(mem, 0x0208, lower_32_bits(nv_device_resource_len(device, 1) - 1));
|
||||
nv_wo32(mem, 0x020c, upper_32_bits(nv_device_resource_len(device, 1) - 1));
|
||||
|
||||
priv->base.alloc = nouveau_bar_alloc;
|
||||
priv->base.kmap = nvc0_bar_kmap;
|
||||
priv->base.umap = nvc0_bar_umap;
|
||||
priv->base.unmap = nvc0_bar_unmap;
|
||||
priv->base.flush = nv84_bar_flush;
|
||||
|
@ -201,7 +203,9 @@ nvc0_bar_init(struct nouveau_object *object)
|
|||
nv_mask(priv, 0x100c80, 0x00000001, 0x00000000);
|
||||
|
||||
nv_wr32(priv, 0x001704, 0x80000000 | priv->bar[1].mem->addr >> 12);
|
||||
nv_wr32(priv, 0x001714, 0xc0000000 | priv->bar[0].mem->addr >> 12);
|
||||
if (priv->bar[0].mem)
|
||||
nv_wr32(priv, 0x001714,
|
||||
0xc0000000 | priv->bar[0].mem->addr >> 12);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -183,10 +183,11 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios)
|
|||
goto out;
|
||||
|
||||
bios->data = kmalloc(bios->size, GFP_KERNEL);
|
||||
if (bios->data) {
|
||||
for (i = 0; i < bios->size; i += 4)
|
||||
((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i);
|
||||
}
|
||||
if (!bios->data)
|
||||
goto out;
|
||||
|
||||
for (i = 0; i < bios->size; i += 4)
|
||||
((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i);
|
||||
|
||||
/* check the PCI record header */
|
||||
pcir = nv_ro16(bios, 0x0018);
|
||||
|
|
|
@ -346,8 +346,8 @@ nouveau_clock_ustate_update(struct nouveau_clock *clk, int req)
|
|||
struct nouveau_pstate *pstate;
|
||||
int i = 0;
|
||||
|
||||
/* YKW repellant */
|
||||
return -ENOSYS;
|
||||
if (!clk->allow_reclock)
|
||||
return -ENOSYS;
|
||||
|
||||
if (req != -1 && req != -2) {
|
||||
list_for_each_entry(pstate, &clk->states, head) {
|
||||
|
@ -456,6 +456,7 @@ nouveau_clock_create_(struct nouveau_object *parent,
|
|||
struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass,
|
||||
struct nouveau_clocks *clocks,
|
||||
bool allow_reclock,
|
||||
int length, void **object)
|
||||
{
|
||||
struct nouveau_device *device = nv_device(parent);
|
||||
|
@ -478,6 +479,8 @@ nouveau_clock_create_(struct nouveau_object *parent,
|
|||
ret = nouveau_pstate_new(clk, idx++);
|
||||
} while (ret == 0);
|
||||
|
||||
clk->allow_reclock = allow_reclock;
|
||||
|
||||
mode = nouveau_stropt(device->cfgopt, "NvClkMode", &arglen);
|
||||
if (mode) {
|
||||
if (!strncasecmpz(mode, "disabled", arglen)) {
|
||||
|
|
|
@ -82,7 +82,8 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nv04_clock_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, &priv);
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, false,
|
||||
&priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -213,7 +213,8 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nv40_clock_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, &priv);
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, true,
|
||||
&priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -507,7 +507,7 @@ nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
int ret;
|
||||
|
||||
ret = nouveau_clock_create(parent, engine, oclass, pclass->domains,
|
||||
&priv);
|
||||
false, &priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -302,7 +302,8 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nva3_clock_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, &priv);
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, false,
|
||||
&priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -421,7 +421,8 @@ nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nvaa_clock_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, &priv);
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, true,
|
||||
&priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -437,7 +437,8 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nvc0_clock_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, &priv);
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, false,
|
||||
&priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -473,7 +473,8 @@ nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
|||
struct nve0_clock_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, &priv);
|
||||
ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, true,
|
||||
&priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
#include "nvc0.h"
|
||||
|
||||
struct gk20a_fb_priv {
|
||||
struct nouveau_fb base;
|
||||
};
|
||||
|
||||
static int
|
||||
gk20a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass, void *data, u32 size,
|
||||
struct nouveau_object **pobject)
|
||||
{
|
||||
struct gk20a_fb_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_fb_create(parent, engine, oclass, &priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nouveau_oclass *
|
||||
gk20a_fb_oclass = &(struct nouveau_fb_impl) {
|
||||
.base.handle = NV_SUBDEV(FB, 0xea),
|
||||
.base.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = gk20a_fb_ctor,
|
||||
.dtor = _nouveau_fb_dtor,
|
||||
.init = _nouveau_fb_init,
|
||||
.fini = _nouveau_fb_fini,
|
||||
},
|
||||
.memtype = nvc0_fb_memtype_valid,
|
||||
.ram = &gk20a_ram_oclass,
|
||||
}.base;
|
|
@ -32,6 +32,7 @@ extern struct nouveau_oclass nva3_ram_oclass;
|
|||
extern struct nouveau_oclass nvaa_ram_oclass;
|
||||
extern struct nouveau_oclass nvc0_ram_oclass;
|
||||
extern struct nouveau_oclass nve0_ram_oclass;
|
||||
extern struct nouveau_oclass gk20a_ram_oclass;
|
||||
extern struct nouveau_oclass gm107_ram_oclass;
|
||||
|
||||
int nouveau_sddr3_calc(struct nouveau_ram *ram);
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
#include "priv.h"
|
||||
|
||||
#include <subdev/fb.h>
|
||||
|
||||
struct gk20a_mem {
|
||||
struct nouveau_mem base;
|
||||
void *cpuaddr;
|
||||
dma_addr_t handle;
|
||||
};
|
||||
#define to_gk20a_mem(m) container_of(m, struct gk20a_mem, base)
|
||||
|
||||
static void
|
||||
gk20a_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem)
|
||||
{
|
||||
struct device *dev = nv_device_base(nv_device(pfb));
|
||||
struct gk20a_mem *mem = to_gk20a_mem(*pmem);
|
||||
|
||||
*pmem = NULL;
|
||||
if (unlikely(mem == NULL))
|
||||
return;
|
||||
|
||||
if (likely(mem->cpuaddr))
|
||||
dma_free_coherent(dev, mem->base.size << PAGE_SHIFT,
|
||||
mem->cpuaddr, mem->handle);
|
||||
|
||||
kfree(mem->base.pages);
|
||||
kfree(mem);
|
||||
}
|
||||
|
||||
static int
|
||||
gk20a_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
|
||||
u32 memtype, struct nouveau_mem **pmem)
|
||||
{
|
||||
struct device *dev = nv_device_base(nv_device(pfb));
|
||||
struct gk20a_mem *mem;
|
||||
u32 type = memtype & 0xff;
|
||||
u32 npages, order;
|
||||
int i;
|
||||
|
||||
nv_debug(pfb, "%s: size: %llx align: %x, ncmin: %x\n", __func__, size,
|
||||
align, ncmin);
|
||||
|
||||
npages = size >> PAGE_SHIFT;
|
||||
if (npages == 0)
|
||||
npages = 1;
|
||||
|
||||
if (align == 0)
|
||||
align = PAGE_SIZE;
|
||||
align >>= PAGE_SHIFT;
|
||||
|
||||
/* round alignment to the next power of 2, if needed */
|
||||
order = fls(align);
|
||||
if ((align & (align - 1)) == 0)
|
||||
order--;
|
||||
align = BIT(order);
|
||||
|
||||
/* ensure returned address is correctly aligned */
|
||||
npages = max(align, npages);
|
||||
|
||||
mem = kzalloc(sizeof(*mem), GFP_KERNEL);
|
||||
if (!mem)
|
||||
return -ENOMEM;
|
||||
|
||||
mem->base.size = npages;
|
||||
mem->base.memtype = type;
|
||||
|
||||
mem->base.pages = kzalloc(sizeof(dma_addr_t) * npages, GFP_KERNEL);
|
||||
if (!mem->base.pages) {
|
||||
kfree(mem);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*pmem = &mem->base;
|
||||
|
||||
mem->cpuaddr = dma_alloc_coherent(dev, npages << PAGE_SHIFT,
|
||||
&mem->handle, GFP_KERNEL);
|
||||
if (!mem->cpuaddr) {
|
||||
nv_error(pfb, "%s: cannot allocate memory!\n", __func__);
|
||||
gk20a_ram_put(pfb, pmem);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
align <<= PAGE_SHIFT;
|
||||
|
||||
/* alignment check */
|
||||
if (unlikely(mem->handle & (align - 1)))
|
||||
nv_warn(pfb, "memory not aligned as requested: %pad (0x%x)\n",
|
||||
&mem->handle, align);
|
||||
|
||||
nv_debug(pfb, "alloc size: 0x%x, align: 0x%x, paddr: %pad, vaddr: %p\n",
|
||||
npages << PAGE_SHIFT, align, &mem->handle, mem->cpuaddr);
|
||||
|
||||
for (i = 0; i < npages; i++)
|
||||
mem->base.pages[i] = mem->handle + (PAGE_SIZE * i);
|
||||
|
||||
mem->base.offset = (u64)mem->base.pages[0];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gk20a_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass, void *data, u32 datasize,
|
||||
struct nouveau_object **pobject)
|
||||
{
|
||||
struct nouveau_ram *ram;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_ram_create(parent, engine, oclass, &ram);
|
||||
*pobject = nv_object(ram);
|
||||
if (ret)
|
||||
return ret;
|
||||
ram->type = NV_MEM_TYPE_STOLEN;
|
||||
ram->size = get_num_physpages() << PAGE_SHIFT;
|
||||
|
||||
ram->get = gk20a_ram_get;
|
||||
ram->put = gk20a_ram_put;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nouveau_oclass
|
||||
gk20a_ram_oclass = {
|
||||
.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = gk20a_ram_ctor,
|
||||
.dtor = _nouveau_ram_dtor,
|
||||
.init = _nouveau_ram_init,
|
||||
.fini = _nouveau_ram_fini,
|
||||
},
|
||||
};
|
|
@ -211,7 +211,7 @@ nv50_ram_prog(struct nouveau_fb *pfb)
|
|||
struct nv50_ram *ram = (void *)pfb->ram;
|
||||
struct nv50_ramseq *hwsq = &ram->hwsq;
|
||||
|
||||
ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
|
||||
ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -309,7 +309,7 @@ nva3_ram_prog(struct nouveau_fb *pfb)
|
|||
struct nouveau_device *device = nv_device(pfb);
|
||||
struct nva3_ram *ram = (void *)pfb->ram;
|
||||
struct nva3_ramfuc *fuc = &ram->fuc;
|
||||
ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
|
||||
ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -408,7 +408,7 @@ nvc0_ram_prog(struct nouveau_fb *pfb)
|
|||
struct nouveau_device *device = nv_device(pfb);
|
||||
struct nvc0_ram *ram = (void *)pfb->ram;
|
||||
struct nvc0_ramfuc *fuc = &ram->fuc;
|
||||
ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
|
||||
ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -1111,7 +1111,7 @@ nve0_ram_prog(struct nouveau_fb *pfb)
|
|||
struct nouveau_device *device = nv_device(pfb);
|
||||
struct nve0_ram *ram = (void *)pfb->ram;
|
||||
struct nve0_ramfuc *fuc = &ram->fuc;
|
||||
ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false));
|
||||
ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true));
|
||||
return (ram->base.next == &ram->base.xition);
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ nve0_gpio_intr(struct nouveau_subdev *subdev)
|
|||
}
|
||||
|
||||
nv_wr32(priv, 0xdc00, intr0);
|
||||
nv_wr32(priv, 0xdc88, intr1);
|
||||
nv_wr32(priv, 0xdc80, intr1);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -52,8 +52,8 @@ nve0_gpio_intr_enable(struct nouveau_event *event, int line)
|
|||
{
|
||||
const u32 addr = line < 16 ? 0xdc00 : 0xdc80;
|
||||
const u32 mask = 0x00010001 << (line & 0xf);
|
||||
nv_wr32(event->priv, addr + 0x08, mask);
|
||||
nv_mask(event->priv, addr + 0x00, mask, mask);
|
||||
nv_wr32(event->priv, addr + 0x00, mask);
|
||||
nv_mask(event->priv, addr + 0x08, mask, mask);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -61,8 +61,8 @@ nve0_gpio_intr_disable(struct nouveau_event *event, int line)
|
|||
{
|
||||
const u32 addr = line < 16 ? 0xdc00 : 0xdc80;
|
||||
const u32 mask = 0x00010001 << (line & 0xf);
|
||||
nv_wr32(event->priv, addr + 0x08, mask);
|
||||
nv_mask(event->priv, addr + 0x00, mask, 0x00000000);
|
||||
nv_mask(event->priv, addr + 0x08, mask, 0x00000000);
|
||||
nv_wr32(event->priv, addr + 0x00, mask);
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
* Copyright (c) 2014, 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.
|
||||
*/
|
||||
|
||||
#include <subdev/ibus.h>
|
||||
#include <subdev/timer.h>
|
||||
|
||||
struct gk20a_ibus_priv {
|
||||
struct nouveau_ibus base;
|
||||
};
|
||||
|
||||
static void
|
||||
gk20a_ibus_init_priv_ring(struct gk20a_ibus_priv *priv)
|
||||
{
|
||||
nv_mask(priv, 0x137250, 0x3f, 0);
|
||||
|
||||
nv_mask(priv, 0x000200, 0x20, 0);
|
||||
usleep_range(20, 30);
|
||||
nv_mask(priv, 0x000200, 0x20, 0x20);
|
||||
|
||||
nv_wr32(priv, 0x12004c, 0x4);
|
||||
nv_wr32(priv, 0x122204, 0x2);
|
||||
nv_rd32(priv, 0x122204);
|
||||
}
|
||||
|
||||
static void
|
||||
gk20a_ibus_intr(struct nouveau_subdev *subdev)
|
||||
{
|
||||
struct gk20a_ibus_priv *priv = (void *)subdev;
|
||||
u32 status0 = nv_rd32(priv, 0x120058);
|
||||
|
||||
if (status0 & 0x7) {
|
||||
nv_debug(priv, "resetting priv ring\n");
|
||||
gk20a_ibus_init_priv_ring(priv);
|
||||
}
|
||||
|
||||
/* Acknowledge interrupt */
|
||||
nv_mask(priv, 0x12004c, 0x2, 0x2);
|
||||
|
||||
if (!nv_wait(subdev, 0x12004c, 0x3f, 0x00))
|
||||
nv_warn(priv, "timeout waiting for ringmaster ack\n");
|
||||
}
|
||||
|
||||
static int
|
||||
gk20a_ibus_init(struct nouveau_object *object)
|
||||
{
|
||||
struct gk20a_ibus_priv *priv = (void *)object;
|
||||
int ret;
|
||||
|
||||
ret = _nouveau_ibus_init(object);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
gk20a_ibus_init_priv_ring(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
gk20a_ibus_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
|
||||
struct nouveau_oclass *oclass, void *data, u32 size,
|
||||
struct nouveau_object **pobject)
|
||||
{
|
||||
struct gk20a_ibus_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_ibus_create(parent, engine, oclass, &priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
nv_subdev(priv)->intr = gk20a_ibus_intr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nouveau_oclass
|
||||
gk20a_ibus_oclass = {
|
||||
.handle = NV_SUBDEV(IBUS, 0xea),
|
||||
.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = gk20a_ibus_ctor,
|
||||
.dtor = _nouveau_ibus_dtor,
|
||||
.init = gk20a_ibus_init,
|
||||
.fini = _nouveau_ibus_fini,
|
||||
},
|
||||
};
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
const struct nouveau_mc_intr
|
||||
nv50_mc_intr[] = {
|
||||
{ 0x04000000, NVDEV_ENGINE_DISP }, /* DISP before FIFO, so pageflip-timestamping works! */
|
||||
{ 0x00000001, NVDEV_ENGINE_MPEG },
|
||||
{ 0x00000100, NVDEV_ENGINE_FIFO },
|
||||
{ 0x00001000, NVDEV_ENGINE_GR },
|
||||
|
@ -34,7 +35,6 @@ nv50_mc_intr[] = {
|
|||
{ 0x00020000, NVDEV_ENGINE_VP }, /* NV84- */
|
||||
{ 0x00100000, NVDEV_SUBDEV_TIMER },
|
||||
{ 0x00200000, NVDEV_SUBDEV_GPIO },
|
||||
{ 0x04000000, NVDEV_ENGINE_DISP },
|
||||
{ 0x10000000, NVDEV_SUBDEV_BUS },
|
||||
{ 0x80000000, NVDEV_ENGINE_SW },
|
||||
{ 0x0002d101, NVDEV_SUBDEV_FB },
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
static const struct nouveau_mc_intr
|
||||
nv98_mc_intr[] = {
|
||||
{ 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work */
|
||||
{ 0x00000001, NVDEV_ENGINE_PPP },
|
||||
{ 0x00000100, NVDEV_ENGINE_FIFO },
|
||||
{ 0x00001000, NVDEV_ENGINE_GR },
|
||||
|
@ -37,7 +38,6 @@ nv98_mc_intr[] = {
|
|||
{ 0x00100000, NVDEV_SUBDEV_TIMER },
|
||||
{ 0x00200000, NVDEV_SUBDEV_GPIO },
|
||||
{ 0x00400000, NVDEV_ENGINE_COPY0 }, /* NVA3- */
|
||||
{ 0x04000000, NVDEV_ENGINE_DISP },
|
||||
{ 0x10000000, NVDEV_SUBDEV_BUS },
|
||||
{ 0x80000000, NVDEV_ENGINE_SW },
|
||||
{ 0x0042d101, NVDEV_SUBDEV_FB },
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
|
||||
const struct nouveau_mc_intr
|
||||
nvc0_mc_intr[] = {
|
||||
{ 0x04000000, NVDEV_ENGINE_DISP }, /* DISP first, so pageflip timestamps work. */
|
||||
{ 0x00000001, NVDEV_ENGINE_PPP },
|
||||
{ 0x00000020, NVDEV_ENGINE_COPY0 },
|
||||
{ 0x00000040, NVDEV_ENGINE_COPY1 },
|
||||
|
@ -40,7 +41,6 @@ nvc0_mc_intr[] = {
|
|||
{ 0x00200000, NVDEV_SUBDEV_GPIO },
|
||||
{ 0x01000000, NVDEV_SUBDEV_PWR },
|
||||
{ 0x02000000, NVDEV_SUBDEV_LTCG },
|
||||
{ 0x04000000, NVDEV_ENGINE_DISP },
|
||||
{ 0x08000000, NVDEV_SUBDEV_FB },
|
||||
{ 0x10000000, NVDEV_SUBDEV_BUS },
|
||||
{ 0x40000000, NVDEV_SUBDEV_IBUS },
|
||||
|
|
|
@ -60,9 +60,9 @@ static struct nouveau_i2c_board_info
|
|||
nv_board_infos[] = {
|
||||
{ { I2C_BOARD_INFO("w83l785ts", 0x2d) }, 0 },
|
||||
{ { I2C_BOARD_INFO("w83781d", 0x2d) }, 0 },
|
||||
{ { I2C_BOARD_INFO("adt7473", 0x2e) }, 20 },
|
||||
{ { I2C_BOARD_INFO("adt7473", 0x2d) }, 20 },
|
||||
{ { I2C_BOARD_INFO("adt7473", 0x2c) }, 20 },
|
||||
{ { I2C_BOARD_INFO("adt7473", 0x2e) }, 40 },
|
||||
{ { I2C_BOARD_INFO("adt7473", 0x2d) }, 40 },
|
||||
{ { I2C_BOARD_INFO("adt7473", 0x2c) }, 40 },
|
||||
{ { I2C_BOARD_INFO("f75375", 0x2e) }, 0 },
|
||||
{ { I2C_BOARD_INFO("lm99", 0x4c) }, 0 },
|
||||
{ { I2C_BOARD_INFO("lm90", 0x4c) }, 0 },
|
||||
|
|
|
@ -36,7 +36,7 @@ nva3_therm_fan_sense(struct nouveau_therm *therm)
|
|||
u32 tach = nv_rd32(therm, 0x00e728) & 0x0000ffff;
|
||||
u32 ctrl = nv_rd32(therm, 0x00e720);
|
||||
if (ctrl & 0x00000001)
|
||||
return tach * 60;
|
||||
return tach * 60 / 2;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
|
@ -798,6 +798,7 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
|
|||
struct drm_device *dev = drm->dev;
|
||||
struct nouveau_page_flip_state *s;
|
||||
unsigned long flags;
|
||||
int crtcid = -1;
|
||||
|
||||
spin_lock_irqsave(&dev->event_lock, flags);
|
||||
|
||||
|
@ -808,8 +809,13 @@ nouveau_finish_page_flip(struct nouveau_channel *chan,
|
|||
}
|
||||
|
||||
s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head);
|
||||
if (s->event)
|
||||
drm_send_vblank_event(dev, s->crtc, s->event);
|
||||
if (s->event) {
|
||||
/* Vblank timestamps/counts are only correct on >= NV-50 */
|
||||
if (nv_device(drm->device)->card_type >= NV_50)
|
||||
crtcid = s->crtc;
|
||||
|
||||
drm_send_vblank_event(dev, crtcid, s->event);
|
||||
}
|
||||
|
||||
list_del(&s->head);
|
||||
if (ps)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/*
|
||||
/*
|
||||
* Copyright 2011 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
|
@ -957,7 +957,7 @@ nv50_crtc_prepare(struct drm_crtc *crtc)
|
|||
|
||||
nv50_display_flip_stop(crtc);
|
||||
|
||||
push = evo_wait(mast, 2);
|
||||
push = evo_wait(mast, 6);
|
||||
if (push) {
|
||||
if (nv50_vers(mast) < NV84_DISP_MAST_CLASS) {
|
||||
evo_mthd(push, 0x0874 + (nv_crtc->index * 0x400), 1);
|
||||
|
|
Loading…
Reference in New Issue