Merge branch 'drm-nouveau-fixes' of git://anongit.freedesktop.org/git/nouveau/linux-2.6 into drm-next
Regression fixes since rework mostly. * 'drm-nouveau-fixes' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: drm/nvc0/fb: fix crash when different mutex is used to protect same list drm/nouveau/clock: fix support for more than 2 monitors on nve0 drm/nv50/disp: fix selection of bios script for analog outputs drm/nv17-50: restore fence buffer on resume drm/nouveau: fix blank LVDS screen regression on pre-nv50 cards drm/nouveau: fix nouveau_client allocation failure path drm/nouveau: don't return freed object from nouveau_handle_create drm/nouveau/vm: fix memory corruption when pgt allocation fails drm/nouveau: add locking around instobj list operations drm/nouveau: do not forcibly power on lvds panels drm/nouveau/devinit: ensure legacy vga control is enabled during post
This commit is contained in:
commit
94bc70a8e7
@ -66,10 +66,8 @@ nouveau_client_create_(const char *name, u64 devname, const char *cfg,
|
|||||||
|
|
||||||
ret = nouveau_handle_create(nv_object(client), ~0, ~0,
|
ret = nouveau_handle_create(nv_object(client), ~0, ~0,
|
||||||
nv_object(client), &client->root);
|
nv_object(client), &client->root);
|
||||||
if (ret) {
|
if (ret)
|
||||||
nouveau_namedb_destroy(&client->base);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
|
||||||
|
|
||||||
/* prevent init/fini being called, os in in charge of this */
|
/* prevent init/fini being called, os in in charge of this */
|
||||||
atomic_set(&nv_object(client)->usecount, 2);
|
atomic_set(&nv_object(client)->usecount, 2);
|
||||||
|
@ -109,7 +109,7 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
|
|||||||
while (!nv_iclass(namedb, NV_NAMEDB_CLASS))
|
while (!nv_iclass(namedb, NV_NAMEDB_CLASS))
|
||||||
namedb = namedb->parent;
|
namedb = namedb->parent;
|
||||||
|
|
||||||
handle = *phandle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
handle = kzalloc(sizeof(*handle), GFP_KERNEL);
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -146,6 +146,9 @@ nouveau_handle_create(struct nouveau_object *parent, u32 _parent, u32 _handle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
hprintk(handle, TRACE, "created\n");
|
hprintk(handle, TRACE, "created\n");
|
||||||
|
|
||||||
|
*phandle = handle;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -851,20 +851,23 @@ exec_script(struct nv50_disp_priv *priv, int head, int id)
|
|||||||
for (i = 0; !(ctrl & (1 << head)) && i < 3; i++)
|
for (i = 0; !(ctrl & (1 << head)) && i < 3; i++)
|
||||||
ctrl = nv_rd32(priv, 0x610b5c + (i * 8));
|
ctrl = nv_rd32(priv, 0x610b5c + (i * 8));
|
||||||
|
|
||||||
if (nv_device(priv)->chipset < 0x90 ||
|
if (!(ctrl & (1 << head))) {
|
||||||
nv_device(priv)->chipset == 0x92 ||
|
if (nv_device(priv)->chipset < 0x90 ||
|
||||||
nv_device(priv)->chipset == 0xa0) {
|
nv_device(priv)->chipset == 0x92 ||
|
||||||
for (i = 0; !(ctrl & (1 << head)) && i < 2; i++)
|
nv_device(priv)->chipset == 0xa0) {
|
||||||
ctrl = nv_rd32(priv, 0x610b74 + (i * 8));
|
for (i = 0; !(ctrl & (1 << head)) && i < 2; i++)
|
||||||
i += 3;
|
ctrl = nv_rd32(priv, 0x610b74 + (i * 8));
|
||||||
} else {
|
i += 4;
|
||||||
for (i = 0; !(ctrl & (1 << head)) && i < 4; i++)
|
} else {
|
||||||
ctrl = nv_rd32(priv, 0x610798 + (i * 8));
|
for (i = 0; !(ctrl & (1 << head)) && i < 4; i++)
|
||||||
i += 3;
|
ctrl = nv_rd32(priv, 0x610798 + (i * 8));
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ctrl & (1 << head)))
|
if (!(ctrl & (1 << head)))
|
||||||
return false;
|
return false;
|
||||||
|
i--;
|
||||||
|
|
||||||
data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info);
|
data = exec_lookup(priv, head, i, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info);
|
||||||
if (data) {
|
if (data) {
|
||||||
@ -898,20 +901,23 @@ exec_clkcmp(struct nv50_disp_priv *priv, int head, int id, u32 pclk,
|
|||||||
for (i = 0; !(ctrl & (1 << head)) && i < 3; i++)
|
for (i = 0; !(ctrl & (1 << head)) && i < 3; i++)
|
||||||
ctrl = nv_rd32(priv, 0x610b58 + (i * 8));
|
ctrl = nv_rd32(priv, 0x610b58 + (i * 8));
|
||||||
|
|
||||||
if (nv_device(priv)->chipset < 0x90 ||
|
if (!(ctrl & (1 << head))) {
|
||||||
nv_device(priv)->chipset == 0x92 ||
|
if (nv_device(priv)->chipset < 0x90 ||
|
||||||
nv_device(priv)->chipset == 0xa0) {
|
nv_device(priv)->chipset == 0x92 ||
|
||||||
for (i = 0; !(ctrl & (1 << head)) && i < 2; i++)
|
nv_device(priv)->chipset == 0xa0) {
|
||||||
ctrl = nv_rd32(priv, 0x610b70 + (i * 8));
|
for (i = 0; !(ctrl & (1 << head)) && i < 2; i++)
|
||||||
i += 3;
|
ctrl = nv_rd32(priv, 0x610b70 + (i * 8));
|
||||||
} else {
|
i += 4;
|
||||||
for (i = 0; !(ctrl & (1 << head)) && i < 4; i++)
|
} else {
|
||||||
ctrl = nv_rd32(priv, 0x610794 + (i * 8));
|
for (i = 0; !(ctrl & (1 << head)) && i < 4; i++)
|
||||||
i += 3;
|
ctrl = nv_rd32(priv, 0x610794 + (i * 8));
|
||||||
|
i += 4;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(ctrl & (1 << head)))
|
if (!(ctrl & (1 << head)))
|
||||||
return 0x0000;
|
return 0x0000;
|
||||||
|
i--;
|
||||||
|
|
||||||
data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1);
|
data = exec_lookup(priv, head, i, ctrl, outp, &ver, &hdr, &cnt, &len, &info1);
|
||||||
if (!data)
|
if (!data)
|
||||||
|
@ -36,6 +36,9 @@ nouveau_client(void *obj)
|
|||||||
|
|
||||||
int nouveau_client_create_(const char *name, u64 device, const char *cfg,
|
int nouveau_client_create_(const char *name, u64 device, const char *cfg,
|
||||||
const char *dbg, int, void **);
|
const char *dbg, int, void **);
|
||||||
|
#define nouveau_client_destroy(p) \
|
||||||
|
nouveau_namedb_destroy(&(p)->base)
|
||||||
|
|
||||||
int nouveau_client_init(struct nouveau_client *);
|
int nouveau_client_init(struct nouveau_client *);
|
||||||
int nouveau_client_fini(struct nouveau_client *, bool suspend);
|
int nouveau_client_fini(struct nouveau_client *, bool suspend);
|
||||||
|
|
||||||
|
@ -38,6 +38,8 @@ enum nvbios_pll_type {
|
|||||||
PLL_UNK42 = 0x42,
|
PLL_UNK42 = 0x42,
|
||||||
PLL_VPLL0 = 0x80,
|
PLL_VPLL0 = 0x80,
|
||||||
PLL_VPLL1 = 0x81,
|
PLL_VPLL1 = 0x81,
|
||||||
|
PLL_VPLL2 = 0x82,
|
||||||
|
PLL_VPLL3 = 0x83,
|
||||||
PLL_MAX = 0xff
|
PLL_MAX = 0xff
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1534,7 +1534,6 @@ init_io(struct nvbios_init *init)
|
|||||||
mdelay(10);
|
mdelay(10);
|
||||||
init_wr32(init, 0x614100, 0x10000018);
|
init_wr32(init, 0x614100, 0x10000018);
|
||||||
init_wr32(init, 0x614900, 0x10000018);
|
init_wr32(init, 0x614900, 0x10000018);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
value = init_rdport(init, port) & mask;
|
value = init_rdport(init, port) & mask;
|
||||||
|
@ -52,6 +52,8 @@ nvc0_clock_pll_set(struct nouveau_clock *clk, u32 type, u32 freq)
|
|||||||
switch (info.type) {
|
switch (info.type) {
|
||||||
case PLL_VPLL0:
|
case PLL_VPLL0:
|
||||||
case PLL_VPLL1:
|
case PLL_VPLL1:
|
||||||
|
case PLL_VPLL2:
|
||||||
|
case PLL_VPLL3:
|
||||||
nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
|
nv_mask(priv, info.reg + 0x0c, 0x00000000, 0x00000100);
|
||||||
nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
|
nv_wr32(priv, info.reg + 0x04, (P << 16) | (N << 8) | M);
|
||||||
nv_wr32(priv, info.reg + 0x10, fN << 16);
|
nv_wr32(priv, info.reg + 0x10, fN << 16);
|
||||||
|
@ -145,14 +145,14 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
|
|||||||
mem->memtype = type;
|
mem->memtype = type;
|
||||||
mem->size = size;
|
mem->size = size;
|
||||||
|
|
||||||
mutex_lock(&mm->mutex);
|
mutex_lock(&pfb->base.mutex);
|
||||||
do {
|
do {
|
||||||
if (back)
|
if (back)
|
||||||
ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
|
ret = nouveau_mm_tail(mm, 1, size, ncmin, align, &r);
|
||||||
else
|
else
|
||||||
ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
|
ret = nouveau_mm_head(mm, 1, size, ncmin, align, &r);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
mutex_unlock(&mm->mutex);
|
mutex_unlock(&pfb->base.mutex);
|
||||||
pfb->ram.put(pfb, &mem);
|
pfb->ram.put(pfb, &mem);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ nvc0_fb_vram_new(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin,
|
|||||||
list_add_tail(&r->rl_entry, &mem->regions);
|
list_add_tail(&r->rl_entry, &mem->regions);
|
||||||
size -= r->length;
|
size -= r->length;
|
||||||
} while (size);
|
} while (size);
|
||||||
mutex_unlock(&mm->mutex);
|
mutex_unlock(&pfb->base.mutex);
|
||||||
|
|
||||||
r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
|
r = list_first_entry(&mem->regions, struct nouveau_mm_node, rl_entry);
|
||||||
mem->offset = (u64)r->offset << 12;
|
mem->offset = (u64)r->offset << 12;
|
||||||
|
@ -40,15 +40,21 @@ nouveau_instobj_create_(struct nouveau_object *parent,
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
mutex_lock(&imem->base.mutex);
|
||||||
list_add(&iobj->head, &imem->list);
|
list_add(&iobj->head, &imem->list);
|
||||||
|
mutex_unlock(&imem->base.mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nouveau_instobj_destroy(struct nouveau_instobj *iobj)
|
nouveau_instobj_destroy(struct nouveau_instobj *iobj)
|
||||||
{
|
{
|
||||||
if (iobj->head.prev)
|
struct nouveau_subdev *subdev = nv_subdev(iobj->base.engine);
|
||||||
list_del(&iobj->head);
|
|
||||||
|
mutex_lock(&subdev->mutex);
|
||||||
|
list_del(&iobj->head);
|
||||||
|
mutex_unlock(&subdev->mutex);
|
||||||
|
|
||||||
return nouveau_object_destroy(&iobj->base);
|
return nouveau_object_destroy(&iobj->base);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,6 +94,8 @@ nouveau_instmem_init(struct nouveau_instmem *imem)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
mutex_lock(&imem->base.mutex);
|
||||||
|
|
||||||
list_for_each_entry(iobj, &imem->list, head) {
|
list_for_each_entry(iobj, &imem->list, head) {
|
||||||
if (iobj->suspend) {
|
if (iobj->suspend) {
|
||||||
for (i = 0; i < iobj->size; i += 4)
|
for (i = 0; i < iobj->size; i += 4)
|
||||||
@ -97,6 +105,8 @@ nouveau_instmem_init(struct nouveau_instmem *imem)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&imem->base.mutex);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,17 +114,26 @@ int
|
|||||||
nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend)
|
nouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend)
|
||||||
{
|
{
|
||||||
struct nouveau_instobj *iobj;
|
struct nouveau_instobj *iobj;
|
||||||
int i;
|
int i, ret = 0;
|
||||||
|
|
||||||
if (suspend) {
|
if (suspend) {
|
||||||
|
mutex_lock(&imem->base.mutex);
|
||||||
|
|
||||||
list_for_each_entry(iobj, &imem->list, head) {
|
list_for_each_entry(iobj, &imem->list, head) {
|
||||||
iobj->suspend = vmalloc(iobj->size);
|
iobj->suspend = vmalloc(iobj->size);
|
||||||
if (iobj->suspend) {
|
if (!iobj->suspend) {
|
||||||
for (i = 0; i < iobj->size; i += 4)
|
ret = -ENOMEM;
|
||||||
iobj->suspend[i / 4] = nv_ro32(iobj, i);
|
break;
|
||||||
} else
|
}
|
||||||
return -ENOMEM;
|
|
||||||
|
for (i = 0; i < iobj->size; i += 4)
|
||||||
|
iobj->suspend[i / 4] = nv_ro32(iobj, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&imem->base.mutex);
|
||||||
|
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nouveau_subdev_fini(&imem->base, suspend);
|
return nouveau_subdev_fini(&imem->base, suspend);
|
||||||
|
@ -352,7 +352,7 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
|
|||||||
u64 mm_length = (offset + length) - mm_offset;
|
u64 mm_length = (offset + length) - mm_offset;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
vm = *pvm = kzalloc(sizeof(*vm), GFP_KERNEL);
|
vm = kzalloc(sizeof(*vm), GFP_KERNEL);
|
||||||
if (!vm)
|
if (!vm)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
@ -376,6 +376,8 @@ nouveau_vm_create(struct nouveau_vmmgr *vmm, u64 offset, u64 length,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*pvm = vm;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,12 +127,26 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
|
|||||||
struct nouveau_encoder **pnv_encoder)
|
struct nouveau_encoder **pnv_encoder)
|
||||||
{
|
{
|
||||||
struct drm_device *dev = connector->dev;
|
struct drm_device *dev = connector->dev;
|
||||||
|
struct nouveau_connector *nv_connector = nouveau_connector(connector);
|
||||||
struct nouveau_drm *drm = nouveau_drm(dev);
|
struct nouveau_drm *drm = nouveau_drm(dev);
|
||||||
|
struct nouveau_gpio *gpio = nouveau_gpio(drm->device);
|
||||||
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
|
struct nouveau_i2c *i2c = nouveau_i2c(drm->device);
|
||||||
int i;
|
struct nouveau_i2c_port *port = NULL;
|
||||||
|
int i, panel = -ENODEV;
|
||||||
|
|
||||||
|
/* eDP panels need powering on by us (if the VBIOS doesn't default it
|
||||||
|
* to on) before doing any AUX channel transactions. LVDS panel power
|
||||||
|
* is handled by the SOR itself, and not required for LVDS DDC.
|
||||||
|
*/
|
||||||
|
if (nv_connector->type == DCB_CONNECTOR_eDP) {
|
||||||
|
panel = gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff);
|
||||||
|
if (panel == 0) {
|
||||||
|
gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
|
||||||
|
msleep(300);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
for (i = 0; i < DRM_CONNECTOR_MAX_ENCODER; i++) {
|
||||||
struct nouveau_i2c_port *port = NULL;
|
|
||||||
struct nouveau_encoder *nv_encoder;
|
struct nouveau_encoder *nv_encoder;
|
||||||
struct drm_mode_object *obj;
|
struct drm_mode_object *obj;
|
||||||
int id;
|
int id;
|
||||||
@ -150,11 +164,19 @@ nouveau_connector_ddc_detect(struct drm_connector *connector,
|
|||||||
port = i2c->find(i2c, nv_encoder->dcb->i2c_index);
|
port = i2c->find(i2c, nv_encoder->dcb->i2c_index);
|
||||||
if (port && nv_probe_i2c(port, 0x50)) {
|
if (port && nv_probe_i2c(port, 0x50)) {
|
||||||
*pnv_encoder = nv_encoder;
|
*pnv_encoder = nv_encoder;
|
||||||
return port;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
port = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
/* eDP panel not detected, restore panel power GPIO to previous
|
||||||
|
* state to avoid confusing the SOR for other output types.
|
||||||
|
*/
|
||||||
|
if (!port && panel == 0)
|
||||||
|
gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, panel);
|
||||||
|
|
||||||
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct nouveau_encoder *
|
static struct nouveau_encoder *
|
||||||
|
@ -225,15 +225,6 @@ nouveau_display_init(struct drm_device *dev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
/* power on internal panel if it's not already. the init tables of
|
|
||||||
* some vbios default this to off for some reason, causing the
|
|
||||||
* panel to not work after resume
|
|
||||||
*/
|
|
||||||
if (gpio && gpio->get(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff) == 0) {
|
|
||||||
gpio->set(gpio, 0, DCB_GPIO_PANEL_POWER, 0xff, 1);
|
|
||||||
msleep(300);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* enable polling for external displays */
|
/* enable polling for external displays */
|
||||||
drm_kms_helper_poll_enable(dev);
|
drm_kms_helper_poll_enable(dev);
|
||||||
|
|
||||||
|
@ -84,11 +84,16 @@ nouveau_cli_create(struct pci_dev *pdev, const char *name,
|
|||||||
struct nouveau_cli *cli;
|
struct nouveau_cli *cli;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
*pcli = NULL;
|
||||||
ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config,
|
ret = nouveau_client_create_(name, nouveau_name(pdev), nouveau_config,
|
||||||
nouveau_debug, size, pcli);
|
nouveau_debug, size, pcli);
|
||||||
cli = *pcli;
|
cli = *pcli;
|
||||||
if (ret)
|
if (ret) {
|
||||||
|
if (cli)
|
||||||
|
nouveau_client_destroy(&cli->base);
|
||||||
|
*pcli = NULL;
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
mutex_init(&cli->mutex);
|
mutex_init(&cli->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -60,6 +60,7 @@ u32 nv10_fence_read(struct nouveau_channel *);
|
|||||||
void nv10_fence_context_del(struct nouveau_channel *);
|
void nv10_fence_context_del(struct nouveau_channel *);
|
||||||
void nv10_fence_destroy(struct nouveau_drm *);
|
void nv10_fence_destroy(struct nouveau_drm *);
|
||||||
int nv10_fence_create(struct nouveau_drm *);
|
int nv10_fence_create(struct nouveau_drm *);
|
||||||
|
void nv17_fence_resume(struct nouveau_drm *drm);
|
||||||
|
|
||||||
int nv50_fence_create(struct nouveau_drm *);
|
int nv50_fence_create(struct nouveau_drm *);
|
||||||
int nv84_fence_create(struct nouveau_drm *);
|
int nv84_fence_create(struct nouveau_drm *);
|
||||||
|
@ -505,7 +505,7 @@ static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode)
|
|||||||
|
|
||||||
static inline bool is_powersaving_dpms(int mode)
|
static inline bool is_powersaving_dpms(int mode)
|
||||||
{
|
{
|
||||||
return (mode != DRM_MODE_DPMS_ON);
|
return mode != DRM_MODE_DPMS_ON && mode != NV_DPMS_CLEARED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
|
static void nv04_lvds_dpms(struct drm_encoder *encoder, int mode)
|
||||||
|
@ -162,6 +162,13 @@ nv10_fence_destroy(struct nouveau_drm *drm)
|
|||||||
kfree(priv);
|
kfree(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void nv17_fence_resume(struct nouveau_drm *drm)
|
||||||
|
{
|
||||||
|
struct nv10_fence_priv *priv = drm->fence;
|
||||||
|
|
||||||
|
nouveau_bo_wr32(priv->bo, 0, priv->sequence);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
nv10_fence_create(struct nouveau_drm *drm)
|
nv10_fence_create(struct nouveau_drm *drm)
|
||||||
{
|
{
|
||||||
@ -197,6 +204,7 @@ nv10_fence_create(struct nouveau_drm *drm)
|
|||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
|
nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
|
||||||
priv->base.sync = nv17_fence_sync;
|
priv->base.sync = nv17_fence_sync;
|
||||||
|
priv->base.resume = nv17_fence_resume;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,6 +122,7 @@ nv50_fence_create(struct nouveau_drm *drm)
|
|||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
|
nouveau_bo_wr32(priv->bo, 0x000, 0x00000000);
|
||||||
priv->base.sync = nv17_fence_sync;
|
priv->base.sync = nv17_fence_sync;
|
||||||
|
priv->base.resume = nv17_fence_resume;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user