13863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs/* 23863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * Copyright 2012 Red Hat Inc. 33863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * 43863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * Permission is hereby granted, free of charge, to any person obtaining a 53863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * copy of this software and associated documentation files (the "Software"), 63863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * to deal in the Software without restriction, including without limitation 73863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense, 83863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * and/or sell copies of the Software, and to permit persons to whom the 93863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * Software is furnished to do so, subject to the following conditions: 103863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * 113863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * The above copyright notice and this permission notice shall be included in 123863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * all copies or substantial portions of the Software. 133863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * 143863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 153863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 163863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 173863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 183863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 193863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 203863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * OTHER DEALINGS IN THE SOFTWARE. 213863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * 223863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs * Authors: Ben Skeggs 233863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs */ 243863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 2524a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs#include "priv.h" 263863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 27ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs/****************************************************************************** 28ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs * instmem object base implementation 29ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs *****************************************************************************/ 30ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs 31ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggsvoid 32ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs_nouveau_instobj_dtor(struct nouveau_object *object) 33ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs{ 34ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs struct nouveau_instmem *imem = (void *)object->engine; 35ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs struct nouveau_instobj *iobj = (void *)object; 36ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs 37ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs mutex_lock(&nv_subdev(imem)->mutex); 38ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs list_del(&iobj->head); 39ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs mutex_unlock(&nv_subdev(imem)->mutex); 40ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs 41ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs return nouveau_object_destroy(&iobj->base); 42ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs} 43ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs 443863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 453863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsnouveau_instobj_create_(struct nouveau_object *parent, 463863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_object *engine, 473863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_oclass *oclass, 483863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs int length, void **pobject) 493863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 503863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instmem *imem = (void *)engine; 513863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instobj *iobj; 523863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs int ret; 533863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 543863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs ret = nouveau_object_create_(parent, engine, oclass, NV_MEMOBJ_CLASS, 553863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs length, pobject); 563863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs iobj = *pobject; 573863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (ret) 583863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return ret; 593863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 604c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz mutex_lock(&imem->base.mutex); 613863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs list_add(&iobj->head, &imem->list); 624c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz mutex_unlock(&imem->base.mutex); 633863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return 0; 643863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 653863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 6624a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs/****************************************************************************** 6724a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs * instmem subdev base implementation 6824a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs *****************************************************************************/ 693863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 7024a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggsstatic int 7124a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggsnouveau_instmem_alloc(struct nouveau_instmem *imem, 7224a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_object *parent, u32 size, u32 align, 7324a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_object **pobject) 743863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 7524a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_object *engine = nv_object(imem); 7624a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_instmem_impl *impl = (void *)engine->oclass; 77ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs struct nouveau_instobj_args args = { .size = size, .align = align }; 78ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs return nouveau_object_ctor(parent, engine, impl->instobj, &args, 79ab606194d1f5821b0052823fc6b6330a029b3d95Ben Skeggs sizeof(args), pobject); 803863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 813863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 823863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 8324a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs_nouveau_instmem_fini(struct nouveau_object *object, bool suspend) 843863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 8524a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_instmem *imem = (void *)object; 863863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instobj *iobj; 874c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz int i, ret = 0; 883863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 893863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (suspend) { 904c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz mutex_lock(&imem->base.mutex); 914c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz 923863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs list_for_each_entry(iobj, &imem->list, head) { 933863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs iobj->suspend = vmalloc(iobj->size); 944c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz if (!iobj->suspend) { 954c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz ret = -ENOMEM; 964c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz break; 974c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz } 984c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz 994c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz for (i = 0; i < iobj->size; i += 4) 1004c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz iobj->suspend[i / 4] = nv_ro32(iobj, i); 1013863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs } 1024c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz 1034c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz mutex_unlock(&imem->base.mutex); 1044c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz 1054c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz if (ret) 1064c4101d29fb6c63f78791d02c437702b11e1d4f0Marcin Slusarz return ret; 1073863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs } 1083863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1093863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return nouveau_subdev_fini(&imem->base, suspend); 1103863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 1113863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1123863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 1133863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs_nouveau_instmem_init(struct nouveau_object *object) 1143863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 1153863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instmem *imem = (void *)object; 11624a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_instobj *iobj; 11724a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs int ret, i; 11824a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs 11924a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs ret = nouveau_subdev_init(&imem->base); 12024a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs if (ret) 12124a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs return ret; 12224a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs 12324a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs mutex_lock(&imem->base.mutex); 12424a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs 12524a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs list_for_each_entry(iobj, &imem->list, head) { 12624a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs if (iobj->suspend) { 12724a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs for (i = 0; i < iobj->size; i += 4) 12824a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs nv_wo32(iobj, i, iobj->suspend[i / 4]); 12924a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs vfree(iobj->suspend); 13024a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs iobj->suspend = NULL; 13124a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs } 13224a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs } 13324a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs 13424a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs mutex_unlock(&imem->base.mutex); 13524a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs 13624a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs return 0; 1373863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 1383863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1393863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 14024a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggsnouveau_instmem_create_(struct nouveau_object *parent, 14124a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_object *engine, 14224a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_oclass *oclass, 14324a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs int length, void **pobject) 1443863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 14524a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs struct nouveau_instmem *imem; 14624a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs int ret; 14724a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs 14824a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs ret = nouveau_subdev_create_(parent, engine, oclass, 0, 14924a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs "INSTMEM", "instmem", length, pobject); 15024a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs imem = *pobject; 15124a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs if (ret) 15224a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs return ret; 15324a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs 15424a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs INIT_LIST_HEAD(&imem->list); 15524a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs imem->alloc = nouveau_instmem_alloc; 15624a4ae86de89b5cbbf8530c371007383de9f2d58Ben Skeggs return 0; 1573863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 158