base.c 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the "Software"),
  6. * to deal in the Software without restriction, including without limitation
  7. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8. * and/or sell copies of the Software, and to permit persons to whom the
  9. * Software is furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  17. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  20. * DEALINGS IN THE SOFTWARE.
  21. */
  22. #include "priv.h"
  23. #include <core/msgqueue.h>
  24. #include <engine/falcon.h>
  25. static void *
  26. nvkm_sec2_dtor(struct nvkm_engine *engine)
  27. {
  28. struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
  29. nvkm_msgqueue_del(&sec2->queue);
  30. nvkm_falcon_del(&sec2->falcon);
  31. return sec2;
  32. }
  33. static void
  34. nvkm_sec2_intr(struct nvkm_engine *engine)
  35. {
  36. struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
  37. struct nvkm_subdev *subdev = &engine->subdev;
  38. struct nvkm_device *device = subdev->device;
  39. u32 disp = nvkm_rd32(device, 0x8701c);
  40. u32 intr = nvkm_rd32(device, 0x87008) & disp & ~(disp >> 16);
  41. if (intr & 0x00000040) {
  42. schedule_work(&sec2->work);
  43. nvkm_wr32(device, 0x87004, 0x00000040);
  44. intr &= ~0x00000040;
  45. }
  46. if (intr) {
  47. nvkm_error(subdev, "unhandled intr %08x\n", intr);
  48. nvkm_wr32(device, 0x87004, intr);
  49. }
  50. }
  51. static void
  52. nvkm_sec2_recv(struct work_struct *work)
  53. {
  54. struct nvkm_sec2 *sec2 = container_of(work, typeof(*sec2), work);
  55. if (!sec2->queue) {
  56. nvkm_warn(&sec2->engine.subdev,
  57. "recv function called while no firmware set!\n");
  58. return;
  59. }
  60. nvkm_msgqueue_recv(sec2->queue);
  61. }
  62. static int
  63. nvkm_sec2_oneinit(struct nvkm_engine *engine)
  64. {
  65. struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
  66. return nvkm_falcon_v1_new(&sec2->engine.subdev, "SEC2", 0x87000,
  67. &sec2->falcon);
  68. }
  69. static int
  70. nvkm_sec2_fini(struct nvkm_engine *engine, bool suspend)
  71. {
  72. struct nvkm_sec2 *sec2 = nvkm_sec2(engine);
  73. flush_work(&sec2->work);
  74. return 0;
  75. }
  76. static const struct nvkm_engine_func
  77. nvkm_sec2 = {
  78. .dtor = nvkm_sec2_dtor,
  79. .oneinit = nvkm_sec2_oneinit,
  80. .fini = nvkm_sec2_fini,
  81. .intr = nvkm_sec2_intr,
  82. };
  83. int
  84. nvkm_sec2_new_(struct nvkm_device *device, int index,
  85. struct nvkm_sec2 **psec2)
  86. {
  87. struct nvkm_sec2 *sec2;
  88. if (!(sec2 = *psec2 = kzalloc(sizeof(*sec2), GFP_KERNEL)))
  89. return -ENOMEM;
  90. INIT_WORK(&sec2->work, nvkm_sec2_recv);
  91. return nvkm_engine_ctor(&nvkm_sec2, device, index, true, &sec2->engine);
  92. };