adreno_compat.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
  4. * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  5. */
  6. #include "adreno.h"
  7. #include "adreno_compat.h"
  8. #include "kgsl_compat.h"
  9. int adreno_getproperty_compat(struct kgsl_device *device,
  10. struct kgsl_device_getproperty *param)
  11. {
  12. int status = -EINVAL;
  13. struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
  14. switch (param->type) {
  15. case KGSL_PROP_DEVICE_INFO:
  16. {
  17. struct kgsl_devinfo_compat devinfo;
  18. if (param->sizebytes != sizeof(devinfo)) {
  19. status = -EINVAL;
  20. break;
  21. }
  22. memset(&devinfo, 0, sizeof(devinfo));
  23. devinfo.device_id = device->id + 1;
  24. devinfo.chip_id = adreno_dev->chipid;
  25. devinfo.mmu_enabled =
  26. kgsl_mmu_has_feature(device, KGSL_MMU_PAGED);
  27. devinfo.gmem_gpubaseaddr = 0;
  28. devinfo.gmem_sizebytes =
  29. adreno_dev->gpucore->gmem_size;
  30. if (copy_to_user(param->value, &devinfo,
  31. sizeof(devinfo))) {
  32. status = -EFAULT;
  33. break;
  34. }
  35. status = 0;
  36. }
  37. break;
  38. case KGSL_PROP_DEVICE_SHADOW:
  39. {
  40. struct kgsl_shadowprop_compat shadowprop;
  41. if (param->sizebytes != sizeof(shadowprop)) {
  42. status = -EINVAL;
  43. break;
  44. }
  45. memset(&shadowprop, 0, sizeof(shadowprop));
  46. if (device->memstore->hostptr) {
  47. /* Give a token address to identify memstore */
  48. shadowprop.gpuaddr = (unsigned int)
  49. KGSL_MEMSTORE_TOKEN_ADDRESS;
  50. shadowprop.size =
  51. (unsigned int) device->memstore->size;
  52. /*
  53. * GSL needs this to be set, even if it
  54. * appears to be meaningless
  55. */
  56. shadowprop.flags = KGSL_FLAGS_INITIALIZED |
  57. KGSL_FLAGS_PER_CONTEXT_TIMESTAMPS;
  58. }
  59. if (copy_to_user(param->value, &shadowprop,
  60. sizeof(shadowprop))) {
  61. status = -EFAULT;
  62. break;
  63. }
  64. status = 0;
  65. }
  66. break;
  67. default:
  68. status = device->ftbl->getproperty(device, param);
  69. }
  70. return status;
  71. }
  72. int adreno_setproperty_compat(struct kgsl_device_private *dev_priv,
  73. unsigned int type,
  74. void __user *value,
  75. unsigned int sizebytes)
  76. {
  77. int status = -EINVAL;
  78. struct kgsl_device *device = dev_priv->device;
  79. switch (type) {
  80. case KGSL_PROP_PWR_CONSTRAINT:
  81. case KGSL_PROP_L3_PWR_CONSTRAINT: {
  82. struct kgsl_device_constraint_compat constraint32;
  83. struct kgsl_device_constraint constraint;
  84. struct kgsl_context *context;
  85. if (sizebytes != sizeof(constraint32))
  86. break;
  87. if (copy_from_user(&constraint32, value,
  88. sizeof(constraint32))) {
  89. status = -EFAULT;
  90. break;
  91. }
  92. /* Populate the real constraint type from the compat */
  93. constraint.type = constraint32.type;
  94. constraint.context_id = constraint32.context_id;
  95. constraint.data = compat_ptr(constraint32.data);
  96. constraint.size = (size_t)constraint32.size;
  97. context = kgsl_context_get_owner(dev_priv,
  98. constraint.context_id);
  99. if (context == NULL)
  100. break;
  101. status = adreno_set_constraint(device, context,
  102. &constraint);
  103. kgsl_context_put(context);
  104. }
  105. break;
  106. default:
  107. /*
  108. * Call adreno_setproperty in case the property type was
  109. * KGSL_PROP_PWRCTRL
  110. */
  111. status = device->ftbl->setproperty(dev_priv, type, value,
  112. sizebytes);
  113. }
  114. return status;
  115. }
  116. static long adreno_ioctl_perfcounter_query_compat(
  117. struct kgsl_device_private *dev_priv, unsigned int cmd,
  118. void *data)
  119. {
  120. struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_priv->device);
  121. struct kgsl_perfcounter_query_compat *query32 = data;
  122. struct kgsl_perfcounter_query query;
  123. long result;
  124. query.groupid = query32->groupid;
  125. query.countables = compat_ptr(query32->countables);
  126. query.count = query32->count;
  127. query.max_counters = query32->max_counters;
  128. result = adreno_perfcounter_query_group(adreno_dev,
  129. query.groupid, query.countables,
  130. query.count, &query.max_counters);
  131. query32->max_counters = query.max_counters;
  132. return result;
  133. }
  134. static long adreno_ioctl_perfcounter_read_compat(
  135. struct kgsl_device_private *dev_priv, unsigned int cmd,
  136. void *data)
  137. {
  138. struct adreno_device *adreno_dev = ADRENO_DEVICE(dev_priv->device);
  139. struct kgsl_perfcounter_read_compat *read32 = data;
  140. struct kgsl_perfcounter_read read;
  141. /*
  142. * When performance counter zapping is enabled, the counters are cleared
  143. * across context switches. Reading the counters when they are zapped is
  144. * not permitted.
  145. */
  146. if (!adreno_dev->perfcounter)
  147. return -EPERM;
  148. read.reads = (struct kgsl_perfcounter_read_group __user *)
  149. (uintptr_t)read32->reads;
  150. read.count = read32->count;
  151. return adreno_perfcounter_read_group(adreno_dev, read.reads,
  152. read.count);
  153. }
  154. static struct kgsl_ioctl adreno_compat_ioctl_funcs[] = {
  155. { IOCTL_KGSL_PERFCOUNTER_GET, adreno_ioctl_perfcounter_get },
  156. { IOCTL_KGSL_PERFCOUNTER_PUT, adreno_ioctl_perfcounter_put },
  157. { IOCTL_KGSL_PERFCOUNTER_QUERY_COMPAT,
  158. adreno_ioctl_perfcounter_query_compat },
  159. { IOCTL_KGSL_PERFCOUNTER_READ_COMPAT,
  160. adreno_ioctl_perfcounter_read_compat },
  161. };
  162. long adreno_compat_ioctl(struct kgsl_device_private *dev_priv,
  163. unsigned int cmd, unsigned long arg)
  164. {
  165. return adreno_ioctl_helper(dev_priv, cmd, arg,
  166. adreno_compat_ioctl_funcs,
  167. ARRAY_SIZE(adreno_compat_ioctl_funcs));
  168. }