diff options
author | Dave Airlie <airlied@redhat.com> | 2013-09-04 14:28:53 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2013-09-04 14:28:53 +1000 |
commit | d30645ae1830f458b3a4908a2f869dd53e0c179b (patch) | |
tree | 1bebcf449ab043da0fd5a90ee466131bc0f6ee47 | |
parent | ef25bd84edba73f78ce7397ef3d7b97e2774ed07 (diff) | |
parent | c859074e7d804a254f318bb55ba1b39893247fc7 (diff) |
Merge branch 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
Nothing major ready for merging yet, so mostly bug fixes below, in addition to VP3 enablement from Ilia.
* 'drm-nouveau-next' of git://anongit.freedesktop.org/git/nouveau/linux-2.6:
drm/nouveau: fix command submission to use vmalloc for big allocations
drm/nouveau/bios/therm: handle vbioses with duplicate entries (mostly nva5)
drm/nouveau: use MSI interrupts
drm/nv50-/kms: assume analog display connected if load on any pin
drm/nv50/disp: prevent false output detection on the original nv50
drm/nouveau/i2c: pass the function pointers in at creation time
drm/nouveau/therm: survive to suspend/resume cycles
drm/nouveau/timer: add a way to cancel alarms
drm/nouveau/timer: restore the time on resume
drm/nouveau/fan: restore pwm value on resume when in manual/auto mode
drm/nouveau/therm: Set the correct pwm_mode upon resume
drm/nouveau: require contiguous bo for framebuffer
drm/nv50-/disp: use the number of dac, sor, pior rather than hardcoded values
drm/nouveau: remove duplicate copy of nv44_graph_class
drm/nouveau/vdec: implement support for VP3 engines
drm/nouveau/core: get rid of math.h, replace log2i with order_base_2
37 files changed, 323 insertions, 145 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/ramht.c b/drivers/gpu/drm/nouveau/core/core/ramht.c index 86a64045dd60..f3b9bddc3875 100644 --- a/drivers/gpu/drm/nouveau/core/core/ramht.c +++ b/drivers/gpu/drm/nouveau/core/core/ramht.c @@ -24,3 +24,2 @@ #include <core/ramht.h> -#include <core/math.h> @@ -106,3 +105,3 @@ nouveau_ramht_new(struct nouveau_object *parent, struct nouveau_object *pargpu, - ramht->bits = log2i(nv_gpuobj(ramht)->size >> 3); + ramht->bits = order_base_2(nv_gpuobj(ramht)->size >> 3); return 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c b/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c index 8bf92b0e6d82..6b089e022fd2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c +++ b/drivers/gpu/drm/nouveau/core/engine/bsp/nv98.c @@ -21,8 +21,6 @@ * - * Authors: Ben Skeggs + * Authors: Ben Skeggs, Maarten Lankhorst, Ilia Mirkin */ -#include <core/engctx.h> -#include <core/class.h> - +#include <engine/falcon.h> #include <engine/bsp.h> @@ -30,3 +28,3 @@ struct nv98_bsp_priv { - struct nouveau_engine base; + struct nouveau_falcon base; }; @@ -39,2 +37,5 @@ static struct nouveau_oclass nv98_bsp_sclass[] = { + { 0x88b1, &nouveau_object_ofuncs }, + { 0x85b1, &nouveau_object_ofuncs }, + { 0x86b1, &nouveau_object_ofuncs }, {}, @@ -43,3 +44,3 @@ nv98_bsp_sclass[] = { /******************************************************************************* - * BSP context + * PBSP context ******************************************************************************/ @@ -50,8 +51,8 @@ nv98_bsp_cclass = { .ofuncs = &(struct nouveau_ofuncs) { - .ctor = _nouveau_engctx_ctor, - .dtor = _nouveau_engctx_dtor, - .init = _nouveau_engctx_init, - .fini = _nouveau_engctx_fini, - .rd32 = _nouveau_engctx_rd32, - .wr32 = _nouveau_engctx_wr32, + .ctor = _nouveau_falcon_context_ctor, + .dtor = _nouveau_falcon_context_dtor, + .init = _nouveau_falcon_context_init, + .fini = _nouveau_falcon_context_fini, + .rd32 = _nouveau_falcon_context_rd32, + .wr32 = _nouveau_falcon_context_wr32, }, @@ -60,3 +61,3 @@ nv98_bsp_cclass = { /******************************************************************************* - * BSP engine/subdev functions + * PBSP engine/subdev functions ******************************************************************************/ @@ -64,2 +65,17 @@ nv98_bsp_cclass = { static int +nv98_bsp_init(struct nouveau_object *object) +{ + struct nv98_bsp_priv *priv = (void *)object; + int ret; + + ret = nouveau_falcon_init(&priv->base); + if (ret) + return ret; + + nv_wr32(priv, 0x084010, 0x0000ffd2); + nv_wr32(priv, 0x08401c, 0x0000fff2); + return 0; +} + +static int nv98_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -71,3 +87,3 @@ nv98_bsp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_engine_create(parent, engine, oclass, true, + ret = nouveau_falcon_create(parent, engine, oclass, 0x084000, true, "PBSP", "bsp", &priv); @@ -88,5 +104,7 @@ nv98_bsp_oclass = { .ctor = nv98_bsp_ctor, - .dtor = _nouveau_engine_dtor, - .init = _nouveau_engine_init, - .fini = _nouveau_engine_fini, + .dtor = _nouveau_falcon_dtor, + .init = nv98_bsp_init, + .fini = _nouveau_falcon_fini, + .rd32 = _nouveau_falcon_rd32, + .wr32 = _nouveau_falcon_wr32, }, diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c index f02fd9f443ff..a66b27c0fcab 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c @@ -51,5 +51,6 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) const u32 doff = (or * 0x800); - int load = -EINVAL; + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); + nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); @@ -57,8 +58,12 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) udelay(500); - nv_wr32(priv, 0x61a00c + doff, 0x80000000); - load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; - nv_wr32(priv, 0x61a00c + doff, 0x00000000); + loadval = nv_mask(priv, 0x61a00c + doff, 0xffffffff, 0x00000000); + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); - return load; + + nv_debug(priv, "DAC%d sense: 0x%08x\n", or, loadval); + if (!(loadval & 0x80000000)) + return -ETIMEDOUT; + + return (loadval & 0x38000000) >> 27; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 7ffe2f309f12..c168ae3eaa97 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c @@ -630,3 +630,3 @@ nv50_disp_base_init(struct nouveau_object *object) /* ... PIOR caps */ - for (i = 0; i < 3; i++) { + for (i = 0; i < priv->pior.nr; i++) { tmp = nv_rd32(priv, 0x61e000 + (i * 0x800)); @@ -836,2 +836,3 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) u32 ctrl = 0x00000000; + u32 reg; int i; @@ -839,3 +840,3 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) /* DAC */ - for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) + for (i = 0; !(ctrl & (1 << head)) && i < priv->dac.nr; i++) ctrl = nv_rd32(priv, 0x610b5c + (i * 8)); @@ -847,10 +848,9 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) nv_device(priv)->chipset == 0xa0) { - for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) - ctrl = nv_rd32(priv, 0x610b74 + (i * 8)); - i += 4; + reg = 0x610b74; } else { - for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) - ctrl = nv_rd32(priv, 0x610798 + (i * 8)); - i += 4; + reg = 0x610798; } + for (i = 0; !(ctrl & (1 << head)) && i < priv->sor.nr; i++) + ctrl = nv_rd32(priv, reg + (i * 8)); + i += 4; } @@ -859,3 +859,3 @@ exec_script(struct nv50_disp_priv *priv, int head, int id) if (!(ctrl & (1 << head))) { - for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) + for (i = 0; !(ctrl & (1 << head)) && i < priv->pior.nr; i++) ctrl = nv_rd32(priv, 0x610b84 + (i * 8)); @@ -895,2 +895,3 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, u32 data, conf = ~0; + u32 reg; int i; @@ -898,3 +899,3 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, /* DAC */ - for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) + for (i = 0; !(ctrl & (1 << head)) && i < priv->dac.nr; i++) ctrl = nv_rd32(priv, 0x610b58 + (i * 8)); @@ -906,10 +907,9 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, nv_device(priv)->chipset == 0xa0) { - for (i = 0; !(ctrl & (1 << head)) && i < 2; i++) - ctrl = nv_rd32(priv, 0x610b70 + (i * 8)); - i += 4; + reg = 0x610b70; } else { - for (i = 0; !(ctrl & (1 << head)) && i < 4; i++) - ctrl = nv_rd32(priv, 0x610794 + (i * 8)); - i += 4; + reg = 0x610794; } + for (i = 0; !(ctrl & (1 << head)) && i < priv->sor.nr; i++) + ctrl = nv_rd32(priv, reg + (i * 8)); + i += 4; } @@ -918,3 +918,3 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk, if (!(ctrl & (1 << head))) { - for (i = 0; !(ctrl & (1 << head)) && i < 3; i++) + for (i = 0; !(ctrl & (1 << head)) && i < priv->pior.nr; i++) ctrl = nv_rd32(priv, 0x610b80 + (i * 8)); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index e9b8217d0075..7e5dff51d3c5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -28,3 +28,2 @@ #include <core/class.h> -#include <core/math.h> @@ -280,3 +279,3 @@ nv50_fifo_chan_ctor_ind(struct nouveau_object *parent, ioffset = args->ioffset; - ilength = log2i(args->ilength / 8); + ilength = order_base_2(args->ilength / 8); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c index 7f53196cff52..91a87cd7195a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -30,3 +30,2 @@ #include <core/class.h> -#include <core/math.h> @@ -59,2 +58,3 @@ nv84_fifo_context_attach(struct nouveau_object *parent, case NVDEV_ENGINE_VP : addr = 0x0040; break; + case NVDEV_ENGINE_PPP : case NVDEV_ENGINE_MPEG : addr = 0x0060; break; @@ -94,2 +94,3 @@ nv84_fifo_context_detach(struct nouveau_object *parent, bool suspend, case NVDEV_ENGINE_VP : engn = 3; addr = 0x0040; break; + case NVDEV_ENGINE_PPP : case NVDEV_ENGINE_MPEG : engn = 1; addr = 0x0060; break; @@ -260,3 +261,3 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent, ioffset = args->ioffset; - ilength = log2i(args->ilength / 8); + ilength = order_base_2(args->ilength / 8); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 46dfa68c47bb..ce92f289e751 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -31,3 +31,2 @@ #include <core/class.h> -#include <core/math.h> #include <core/enum.h> @@ -202,3 +201,3 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent, ioffset = args->ioffset; - ilength = log2i(args->ilength / 8); + ilength = order_base_2(args->ilength / 8); diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 09644fa9602c..8e8121abe31b 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -31,3 +31,2 @@ #include <core/class.h> -#include <core/math.h> #include <core/enum.h> @@ -242,3 +241,3 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent, ioffset = args->ioffset; - ilength = log2i(args->ilength / 8); + ilength = order_base_2(args->ilength / 8); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h index 7da35a4e7970..ad8209377529 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv40.h @@ -3,2 +3,5 @@ +#include <core/device.h> +#include <core/gpuobj.h> + /* returns 1 if device is one of the nv4x using the 0x4497 object class, diff --git a/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c b/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c index 5a5b2a773ed7..13bf31c40aa1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c +++ b/drivers/gpu/drm/nouveau/core/engine/ppp/nv98.c @@ -21,9 +21,6 @@ * - * Authors: Ben Skeggs + * Authors: Ben Skeggs, Maarten Lankhorst, Ilia Mirkin */ -#include <core/engine.h> -#include <core/engctx.h> -#include <core/class.h> - +#include <engine/falcon.h> #include <engine/ppp.h> @@ -31,7 +28,3 @@ struct nv98_ppp_priv { - struct nouveau_engine base; -}; - -struct nv98_ppp_chan { - struct nouveau_engctx base; + struct nouveau_falcon base; }; @@ -44,2 +37,4 @@ static struct nouveau_oclass nv98_ppp_sclass[] = { + { 0x88b3, &nouveau_object_ofuncs }, + { 0x85b3, &nouveau_object_ofuncs }, {}, @@ -55,8 +50,8 @@ nv98_ppp_cclass = { .ofuncs = &(struct nouveau_ofuncs) { - .ctor = _nouveau_engctx_ctor, - .dtor = _nouveau_engctx_dtor, - .init = _nouveau_engctx_init, - .fini = _nouveau_engctx_fini, - .rd32 = _nouveau_engctx_rd32, - .wr32 = _nouveau_engctx_wr32, + .ctor = _nouveau_falcon_context_ctor, + .dtor = _nouveau_falcon_context_dtor, + .init = _nouveau_falcon_context_init, + .fini = _nouveau_falcon_context_fini, + .rd32 = _nouveau_falcon_context_rd32, + .wr32 = _nouveau_falcon_context_wr32, }, @@ -69,2 +64,17 @@ nv98_ppp_cclass = { static int +nv98_ppp_init(struct nouveau_object *object) +{ + struct nv98_ppp_priv *priv = (void *)object; + int ret; + + ret = nouveau_falcon_init(&priv->base); + if (ret) + return ret; + + nv_wr32(priv, 0x086010, 0x0000ffd2); + nv_wr32(priv, 0x08601c, 0x0000fff2); + return 0; +} + +static int nv98_ppp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -76,3 +86,3 @@ nv98_ppp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_engine_create(parent, engine, oclass, true, + ret = nouveau_falcon_create(parent, engine, oclass, 0x086000, true, "PPPP", "ppp", &priv); @@ -93,5 +103,7 @@ nv98_ppp_oclass = { .ctor = nv98_ppp_ctor, - .dtor = _nouveau_engine_dtor, - .init = _nouveau_engine_init, - .fini = _nouveau_engine_fini, + .dtor = _nouveau_falcon_dtor, + .init = nv98_ppp_init, + .fini = _nouveau_falcon_fini, + .rd32 = _nouveau_falcon_rd32, + .wr32 = _nouveau_falcon_wr32, }, diff --git a/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c b/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c index 8a8236bc84de..fc9ae0ff1ef5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c +++ b/drivers/gpu/drm/nouveau/core/engine/vp/nv98.c @@ -21,8 +21,6 @@ * - * Authors: Ben Skeggs + * Authors: Ben Skeggs, Maarten Lankhorst, Ilia Mirkin */ -#include <core/engctx.h> -#include <core/class.h> - +#include <engine/falcon.h> #include <engine/vp.h> @@ -30,3 +28,3 @@ struct nv98_vp_priv { - struct nouveau_engine base; + struct nouveau_falcon base; }; @@ -39,2 +37,4 @@ static struct nouveau_oclass nv98_vp_sclass[] = { + { 0x88b2, &nouveau_object_ofuncs }, + { 0x85b2, &nouveau_object_ofuncs }, {}, @@ -50,8 +50,8 @@ nv98_vp_cclass = { .ofuncs = &(struct nouveau_ofuncs) { - .ctor = _nouveau_engctx_ctor, - .dtor = _nouveau_engctx_dtor, - .init = _nouveau_engctx_init, - .fini = _nouveau_engctx_fini, - .rd32 = _nouveau_engctx_rd32, - .wr32 = _nouveau_engctx_wr32, + .ctor = _nouveau_falcon_context_ctor, + .dtor = _nouveau_falcon_context_dtor, + .init = _nouveau_falcon_context_init, + .fini = _nouveau_falcon_context_fini, + .rd32 = _nouveau_falcon_context_rd32, + .wr32 = _nouveau_falcon_context_wr32, }, @@ -64,2 +64,17 @@ nv98_vp_cclass = { static int +nv98_vp_init(struct nouveau_object *object) +{ + struct nv98_vp_priv *priv = (void *)object; + int ret; + + ret = nouveau_falcon_init(&priv->base); + if (ret) + return ret; + + nv_wr32(priv, 0x085010, 0x0000ffd2); + nv_wr32(priv, 0x08501c, 0x0000fff2); + return 0; +} + +static int nv98_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -71,3 +86,3 @@ nv98_vp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - ret = nouveau_engine_create(parent, engine, oclass, true, + ret = nouveau_falcon_create(parent, engine, oclass, 0x085000, true, "PVP", "vp", &priv); @@ -88,5 +103,7 @@ nv98_vp_oclass = { .ctor = nv98_vp_ctor, - .dtor = _nouveau_engine_dtor, - .init = _nouveau_engine_init, - .fini = _nouveau_engine_fini, + .dtor = _nouveau_falcon_dtor, + .init = nv98_vp_init, + .fini = _nouveau_falcon_fini, + .rd32 = _nouveau_falcon_rd32, + .wr32 = _nouveau_falcon_wr32, }, diff --git a/drivers/gpu/drm/nouveau/core/include/core/math.h b/drivers/gpu/drm/nouveau/core/include/core/math.h deleted file mode 100644 index f808131c5cd8..000000000000 --- a/drivers/gpu/drm/nouveau/core/include/core/math.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef __NOUVEAU_MATH_H__ -#define __NOUVEAU_MATH_H__ - -static inline int -log2i(u64 base) -{ - u64 temp = base >> 1; - int log2; - - for (log2 = 0; temp; log2++, temp >>= 1) { - } - - return (base & (base - 1)) ? log2 + 1: log2; -} - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h index 888384c0bed8..7e4e2775f249 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h @@ -41,4 +41,4 @@ struct nouveau_i2c_func { -#define nouveau_i2c_port_create(p,e,o,i,a,d) \ - nouveau_i2c_port_create_((p), (e), (o), (i), (a), \ +#define nouveau_i2c_port_create(p,e,o,i,a,f,d) \ + nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f), \ sizeof(**d), (void **)d) @@ -55,3 +55,5 @@ int nouveau_i2c_port_create_(struct nouveau_object *, struct nouveau_object *, struct nouveau_oclass *, u8, - const struct i2c_algorithm *, int, void **); + const struct i2c_algorithm *, + const struct nouveau_i2c_func *, + int, void **); void _nouveau_i2c_port_dtor(struct nouveau_object *); diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h index 9d2cd2006250..ce6569f365a7 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h @@ -14,2 +14,3 @@ struct nouveau_mc { const struct nouveau_mc_intr *intr_map; + bool use_msi; }; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h index e465d158d352..9ab70dfe5b02 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/timer.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/timer.h @@ -24,2 +24,3 @@ bool nouveau_timer_wait_cb(void *, u64 nsec, bool (*func)(void *), void *data); void nouveau_timer_alarm(void *, u32 nsec, struct nouveau_alarm *); +void nouveau_timer_alarm_cancel(void *, struct nouveau_alarm *); @@ -37,2 +38,3 @@ struct nouveau_timer { void (*alarm)(struct nouveau_timer *, u64 time, struct nouveau_alarm *); + void (*alarm_cancel)(struct nouveau_timer *, struct nouveau_alarm *); }; diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h index 3bd9be2ab37f..191e739f30d1 100644 --- a/drivers/gpu/drm/nouveau/core/os.h +++ b/drivers/gpu/drm/nouveau/core/os.h @@ -15,4 +15,4 @@ #include <linux/io-mapping.h> -#include <linux/vmalloc.h> #include <linux/acpi.h> +#include <linux/vmalloc.h> #include <linux/dmi.h> @@ -20,2 +20,4 @@ #include <linux/interrupt.h> +#include <linux/log2.h> +#include <linux/pm_runtime.h> diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c index 22a20573ed1b..22ac6dbd6c8f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/therm.c @@ -186,3 +186,4 @@ nvbios_therm_fan_parse(struct nouveau_bios *bios, case 0x26: - fan->pwm_freq = value; + if (!fan->pwm_freq) + fan->pwm_freq = value; break; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c index dec94e9d776a..4b195ac4da66 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/anx9805.c @@ -120,3 +120,4 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent, ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_aux_algo, &chan); + &nouveau_i2c_aux_algo, &anx9805_aux_func, + &chan); *pobject = nv_object(chan); @@ -142,4 +143,2 @@ anx9805_aux_chan_ctor(struct nouveau_object *parent, } - - chan->base.func = &anx9805_aux_func; return 0; @@ -236,3 +235,4 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent, ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &anx9805_i2c_algo, &port); + &anx9805_i2c_algo, &anx9805_i2c_func, + &port); *pobject = nv_object(port); @@ -258,4 +258,2 @@ anx9805_ddc_port_ctor(struct nouveau_object *parent, } - - port->base.func = &anx9805_i2c_func; return 0; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index 8ae2625415e1..2895c19bb152 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -97,2 +97,3 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, const struct i2c_algorithm *algo, + const struct nouveau_i2c_func *func, int size, void **pobject) @@ -114,2 +115,3 @@ nouveau_i2c_port_create_(struct nouveau_object *parent, port->index = index; + port->func = func; i2c_set_adapdata(&port->adapter, i2c); diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c index 2ad18840fe63..860d5d2365da 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv04.c @@ -93,3 +93,4 @@ nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); + &nouveau_i2c_bit_algo, &nv04_i2c_func, + &port); *pobject = nv_object(port); @@ -98,3 +99,2 @@ nv04_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - port->base.func = &nv04_i2c_func; port->drive = info->drive; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c index f501ae25dbb3..0c2655a03bb4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv4e.c @@ -86,3 +86,4 @@ nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); + &nouveau_i2c_bit_algo, &nv4e_i2c_func, + &port); *pobject = nv_object(port); @@ -91,3 +92,2 @@ nv4e_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - port->base.func = &nv4e_i2c_func; port->addr = 0x600800 + info->drive; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c index 378dfa324e5f..a8d67a287704 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.c @@ -87,3 +87,4 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); + &nouveau_i2c_bit_algo, &nv50_i2c_func, + &port); *pobject = nv_object(port); @@ -95,3 +96,2 @@ nv50_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - port->base.func = &nv50_i2c_func; port->state = 0x00000007; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c index 61b771670bfe..df6d3e4b68be 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c @@ -188,3 +188,4 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); + &nouveau_i2c_bit_algo, &nv94_i2c_func, + &port); *pobject = nv_object(port); @@ -196,3 +197,2 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - port->base.func = &nv94_i2c_func; port->state = 7; @@ -223,3 +223,4 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_aux_algo, &port); + &nouveau_i2c_aux_algo, &nv94_aux_func, + &port); *pobject = nv_object(port); @@ -228,3 +229,2 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - port->base.func = &nv94_aux_func; port->addr = info->drive; diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c index f761b8a610f1..29967d30f97c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c @@ -62,3 +62,4 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, ret = nouveau_i2c_port_create(parent, engine, oclass, index, - &nouveau_i2c_bit_algo, &port); + &nouveau_i2c_bit_algo, &nvd0_i2c_func, + &port); *pobject = nv_object(port); @@ -67,3 +68,2 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - port->base.func = &nvd0_i2c_func; port->state = 0x00000007; diff --git a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c index 716bf41bc3c1..b10a143787a7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/instmem/nv40.c @@ -24,11 +24,5 @@ -#include "nv04.h" +#include <engine/graph/nv40.h> -static inline int -nv44_graph_class(struct nv04_instmem_priv *priv) -{ - if ((nv_device(priv)->chipset & 0xf0) == 0x60) - return 1; - return !(0x0baf & (1 << (nv_device(priv)->chipset & 0x0f))); -} +#include "nv04.h" diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c index 20f9a538746e..37712a6df923 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c @@ -25,3 +25,3 @@ #include <subdev/mc.h> -#include <linux/pm_runtime.h> +#include <core/option.h> @@ -49,2 +49,5 @@ nouveau_mc_intr(int irq, void *arg) + if (pmc->use_msi) + nv_wr08(pmc->base.base.parent, 0x00088068, 0xff); + if (intr) { @@ -83,2 +86,4 @@ _nouveau_mc_dtor(struct nouveau_object *object) free_irq(device->pdev->irq, pmc); + if (pmc->use_msi) + pci_disable_msi(device->pdev); nouveau_subdev_destroy(&pmc->base); @@ -104,2 +109,19 @@ nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine, + switch (device->pdev->device & 0x0ff0) { + case 0x00f0: /* BR02? */ + case 0x02e0: /* BR02? */ + pmc->use_msi = false; + break; + default: + pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", true); + if (pmc->use_msi) { + pmc->use_msi = pci_enable_msi(device->pdev) == 0; + if (pmc->use_msi) { + nv_info(pmc, "MSI interrupts enabled\n"); + nv_wr08(device, 0x00088068, 0xff); + } + } + break; + } + ret = request_irq(device->pdev->irq, nouveau_mc_intr, diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c index 0d57b4d3e001..06710419a59b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c @@ -37,2 +37,3 @@ nv98_mc_intr[] = { { 0x00008000, NVDEV_ENGINE_BSP }, + { 0x00020000, NVDEV_ENGINE_VP }, { 0x00080000, NVDEV_SUBDEV_THERM }, /* NVA3:NVC0 */ @@ -44,3 +45,3 @@ nv98_mc_intr[] = { { 0x80000000, NVDEV_ENGINE_SW }, - { 0x0040d101, NVDEV_SUBDEV_FB }, + { 0x0042d101, NVDEV_SUBDEV_FB }, {}, diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index a00a5a76e2d6..f1de7a9c572b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -97,2 +97,3 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode) spin_lock_irqsave(&priv->lock, flags); + nv_debug(therm, "FAN speed check\n"); if (mode < 0) @@ -103,2 +104,3 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode) case NOUVEAU_THERM_CTRL_MANUAL: + ptimer->alarm_cancel(ptimer, &priv->alarm); duty = nouveau_therm_fan_get(therm); @@ -115,2 +117,3 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode) default: + ptimer->alarm_cancel(ptimer, &priv->alarm); goto done; @@ -124,2 +127,4 @@ done: ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm); + else if (!list_empty(&priv->alarm.head)) + nv_debug(therm, "therm fan alarm list is not empty\n"); spin_unlock_irqrestore(&priv->lock, flags); @@ -269,5 +274,11 @@ _nouveau_therm_init(struct nouveau_object *object) - if (priv->suspend >= 0) - nouveau_therm_fan_mode(therm, priv->mode); - priv->sensor.program_alarms(therm); + if (priv->suspend >= 0) { + /* restore the pwm value only when on manual or auto mode */ + if (priv->suspend > 0) + nouveau_therm_fan_set(therm, true, priv->fan->percent); + + nouveau_therm_fan_mode(therm, priv->suspend); + } + nouveau_therm_sensor_init(therm); + nouveau_therm_fan_init(therm); return 0; @@ -281,2 +292,4 @@ _nouveau_therm_fini(struct nouveau_object *object, bool suspend) + nouveau_therm_fan_fini(therm, suspend); + nouveau_therm_sensor_fini(therm, suspend); if (suspend) { diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c index c728380d3d62..39f47b950ad1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c @@ -206,2 +206,19 @@ nouveau_therm_fan_safety_checks(struct nouveau_therm *therm) int +nouveau_therm_fan_init(struct nouveau_therm *therm) +{ + return 0; +} + +int +nouveau_therm_fan_fini(struct nouveau_therm *therm, bool suspend) +{ + struct nouveau_therm_priv *priv = (void *)therm; + struct nouveau_timer *ptimer = nouveau_timer(therm); + + if (suspend) + ptimer->alarm_cancel(ptimer, &priv->fan->alarm); + return 0; +} + +int nouveau_therm_fan_ctor(struct nouveau_therm *therm) @@ -236,2 +253,5 @@ nouveau_therm_fan_ctor(struct nouveau_therm *therm) + /* read the current speed, it is useful when resuming */ + priv->fan->percent = nouveau_therm_fan_get(therm); + /* attempt to detect a tachometer connection */ diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index 15ca64e481f1..dd38529262fb 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -115,2 +115,4 @@ int nouveau_therm_sensor_ctor(struct nouveau_therm *therm); int nouveau_therm_fan_ctor(struct nouveau_therm *therm); +int nouveau_therm_fan_init(struct nouveau_therm *therm); +int nouveau_therm_fan_fini(struct nouveau_therm *therm, bool suspend); int nouveau_therm_fan_get(struct nouveau_therm *therm); @@ -124,2 +126,4 @@ int nouveau_therm_preinit(struct nouveau_therm *); +int nouveau_therm_sensor_init(struct nouveau_therm *therm); +int nouveau_therm_sensor_fini(struct nouveau_therm *therm, bool suspend); void nouveau_therm_sensor_preinit(struct nouveau_therm *); diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index dde746c78c8a..b80a33011b93 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -182,2 +182,4 @@ alarm_timer_callback(struct nouveau_alarm *alarm) + nv_debug(therm, "polling the internal temperature\n"); + nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_fan_boost, @@ -218,2 +220,21 @@ nouveau_therm_program_alarms_polling(struct nouveau_therm *therm) +int +nouveau_therm_sensor_init(struct nouveau_therm *therm) +{ + struct nouveau_therm_priv *priv = (void *)therm; + priv->sensor.program_alarms(therm); + return 0; +} + +int +nouveau_therm_sensor_fini(struct nouveau_therm *therm, bool suspend) +{ + struct nouveau_therm_priv *priv = (void *)therm; + struct nouveau_timer *ptimer = nouveau_timer(therm); + + if (suspend) + ptimer->alarm_cancel(ptimer, &priv->sensor.therm_poll_alarm); + return 0; +} + void diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/base.c b/drivers/gpu/drm/nouveau/core/subdev/timer/base.c index 5d417cc9949b..cf8a0e0f8ee3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/timer/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/base.c @@ -87 +87,8 @@ nouveau_timer_alarm(void *obj, u32 nsec, struct nouveau_alarm *alarm) } + +void +nouveau_timer_alarm_cancel(void *obj, struct nouveau_alarm *alarm) +{ + struct nouveau_timer *ptimer = nouveau_timer(obj); + ptimer->alarm_cancel(ptimer, alarm); +} diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c index 9469b8275675..57711ecb566c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c @@ -38,2 +38,3 @@ struct nv04_timer_priv { spinlock_t lock; + u64 suspend_time; }; @@ -115,2 +116,21 @@ nv04_timer_alarm(struct nouveau_timer *ptimer, u64 time, static void +nv04_timer_alarm_cancel(struct nouveau_timer *ptimer, + struct nouveau_alarm *alarm) +{ + struct nv04_timer_priv *priv = (void *)ptimer; + unsigned long flags; + + /* avoid deleting an entry while the alarm intr is running */ + spin_lock_irqsave(&priv->lock, flags); + + /* delete the alarm from the list */ + list_del(&alarm->head); + + /* reset the head so as list_empty returns 1 */ + INIT_LIST_HEAD(&alarm->head); + + spin_unlock_irqrestore(&priv->lock, flags); +} + +static void nv04_timer_intr(struct nouveau_subdev *subdev) @@ -148,2 +168,4 @@ nv04_timer_ctor(struct nouveau_object *parent, struct nouveau_object *engine, priv->base.alarm = nv04_timer_alarm; + priv->base.alarm_cancel = nv04_timer_alarm_cancel; + priv->suspend_time = 0; @@ -166,3 +188,3 @@ nv04_timer_init(struct nouveau_object *object) struct nv04_timer_priv *priv = (void *)object; - u32 m = 1, f, n, d; + u32 m = 1, f, n, d, lo, hi; int ret; @@ -223,2 +245,6 @@ nv04_timer_init(struct nouveau_object *object) + /* restore the time before suspend */ + lo = priv->suspend_time; + hi = (priv->suspend_time >> 32); + nv_debug(priv, "input frequency : %dHz\n", f); @@ -228,2 +254,4 @@ nv04_timer_init(struct nouveau_object *object) nv_debug(priv, "timer frequency : %dHz\n", (f * m) * d / n); + nv_debug(priv, "time low : 0x%08x\n", lo); + nv_debug(priv, "time high : 0x%08x\n", hi); @@ -233,2 +261,5 @@ nv04_timer_init(struct nouveau_object *object) nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); + nv_wr32(priv, NV04_PTIMER_TIME_1, hi); + nv_wr32(priv, NV04_PTIMER_TIME_0, lo); + return 0; @@ -240,2 +271,4 @@ nv04_timer_fini(struct nouveau_object *object, bool suspend) struct nv04_timer_priv *priv = (void *)object; + if (suspend) + priv->suspend_time = nv04_timer_read(&priv->base); nv_wr32(priv, NV04_PTIMER_INTR_EN_0, 0x00000000); diff --git a/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c index 07dd1fe2d6fb..a4aa81a2173b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/vm/nv50.c @@ -176,2 +176,3 @@ nv50_vm_flush(struct nouveau_vm *vm) case NVDEV_SUBDEV_BAR : vme = 0x06; break; + case NVDEV_ENGINE_PPP : case NVDEV_ENGINE_MPEG : vme = 0x08; break; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 77ffded68837..d2712e6e5d31 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -109,2 +109,7 @@ nouveau_framebuffer_init(struct drm_device *dev, + if (nvbo->tile_flags & NOUVEAU_GEM_TILE_NONCONTIG) { + NV_ERROR(drm, "framebuffer requires contiguous bo\n"); + return -EINVAL; + } + if (nv_device(drm->device)->chipset == 0x50) diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 487242fb3fdc..f32b71238c03 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -581,2 +581,11 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, +static inline void +u_free(void *addr) +{ + if (!is_vmalloc_addr(addr)) + kfree(addr); + else + vfree(addr); +} + static inline void * @@ -587,3 +596,7 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size) - mem = kmalloc(nmemb * size, GFP_KERNEL); + size *= nmemb; + + mem = kmalloc(size, GFP_KERNEL | __GFP_NOWARN); + if (!mem) + mem = vmalloc(size); if (!mem) @@ -591,4 +604,4 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size) - if (DRM_COPY_FROM_USER(mem, userptr, nmemb * size)) { - kfree(mem); + if (DRM_COPY_FROM_USER(mem, userptr, size)) { + u_free(mem); return ERR_PTR(-EFAULT); @@ -678,3 +691,3 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli, - kfree(reloc); + u_free(reloc); return ret; @@ -740,3 +753,3 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, if (IS_ERR(bo)) { - kfree(push); + u_free(push); return nouveau_abi16_put(abi16, PTR_ERR(bo)); @@ -851,4 +864,4 @@ out: out_prevalid: - kfree(bo); - kfree(push); + u_free(bo); + u_free(push); diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 9d2092a5ed38..f8e66c08b11a 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1585,3 +1585,3 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); - if (ret || load != 7) + if (ret || !load) return connector_status_disconnected; |