base.c revision 3863c9bc887e9638a9d905d55f6038641ece78d6
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 253863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs#include <subdev/instmem.h> 263863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 273863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 283863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsnouveau_instobj_create_(struct nouveau_object *parent, 293863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_object *engine, 303863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_oclass *oclass, 313863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs int length, void **pobject) 323863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 333863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instmem *imem = (void *)engine; 343863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instobj *iobj; 353863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs int ret; 363863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 373863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs ret = nouveau_object_create_(parent, engine, oclass, NV_MEMOBJ_CLASS, 383863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs length, pobject); 393863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs iobj = *pobject; 403863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (ret) 413863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return ret; 423863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 433863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs list_add(&iobj->head, &imem->list); 443863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return 0; 453863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 463863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 473863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsvoid 483863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsnouveau_instobj_destroy(struct nouveau_instobj *iobj) 493863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 503863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (iobj->head.prev) 513863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs list_del(&iobj->head); 523863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return nouveau_object_destroy(&iobj->base); 533863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 543863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 553863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsvoid 563863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs_nouveau_instobj_dtor(struct nouveau_object *object) 573863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 583863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instobj *iobj = (void *)object; 593863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return nouveau_instobj_destroy(iobj); 603863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 613863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 623863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 633863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsnouveau_instmem_create_(struct nouveau_object *parent, 643863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_object *engine, 653863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_oclass *oclass, 663863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs int length, void **pobject) 673863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 683863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instmem *imem; 693863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs int ret; 703863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 713863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs ret = nouveau_subdev_create_(parent, engine, oclass, 0, 723863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs "INSTMEM", "instmem", length, pobject); 733863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs imem = *pobject; 743863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (ret) 753863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return ret; 763863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 773863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs INIT_LIST_HEAD(&imem->list); 783863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return 0; 793863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 803863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 813863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 823863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsnouveau_instmem_init(struct nouveau_instmem *imem) 833863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 843863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instobj *iobj; 853863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs int ret, i; 863863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 873863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs ret = nouveau_subdev_init(&imem->base); 883863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (ret) 893863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return ret; 903863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 913863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs list_for_each_entry(iobj, &imem->list, head) { 923863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (iobj->suspend) { 933863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs for (i = 0; i < iobj->size; i += 4) 943863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs nv_wo32(iobj, i, iobj->suspend[i / 4]); 953863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs vfree(iobj->suspend); 963863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs iobj->suspend = NULL; 973863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs } 983863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs } 993863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1003863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return 0; 1013863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 1023863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1033863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 1043863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsnouveau_instmem_fini(struct nouveau_instmem *imem, bool suspend) 1053863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 1063863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instobj *iobj; 1073863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs int i; 1083863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1093863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (suspend) { 1103863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs list_for_each_entry(iobj, &imem->list, head) { 1113863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs iobj->suspend = vmalloc(iobj->size); 1123863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs if (iobj->suspend) { 1133863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs for (i = 0; i < iobj->size; i += 4) 1143863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs iobj->suspend[i / 4] = nv_ro32(iobj, i); 1153863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs } else 1163863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return -ENOMEM; 1173863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs } 1183863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs } 1193863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1203863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return nouveau_subdev_fini(&imem->base, suspend); 1213863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 1223863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1233863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 1243863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs_nouveau_instmem_init(struct nouveau_object *object) 1253863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 1263863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instmem *imem = (void *)object; 1273863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return nouveau_instmem_init(imem); 1283863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 1293863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs 1303863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggsint 1313863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs_nouveau_instmem_fini(struct nouveau_object *object, bool suspend) 1323863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs{ 1333863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs struct nouveau_instmem *imem = (void *)object; 1343863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs return nouveau_instmem_fini(imem, suspend); 1353863c9bc887e9638a9d905d55f6038641ece78d6Ben Skeggs} 136