msm_audio_ion_vm.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (c) 2013-2020, The Linux Foundation. All rights reserved.
  4. */
  5. #include <linux/init.h>
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/err.h>
  9. #include <linux/delay.h>
  10. #include <linux/slab.h>
  11. #include <linux/mutex.h>
  12. #include <linux/list.h>
  13. #include <linux/dma-mapping.h>
  14. #include <linux/dma-buf.h>
  15. #include <linux/iommu.h>
  16. #include <linux/platform_device.h>
  17. #include <linux/of_device.h>
  18. #include <linux/export.h>
  19. #include <linux/ion.h>
  20. #include <ipc/apr.h>
  21. #include <dsp/msm_audio_ion.h>
  22. #include <linux/habmm.h>
  23. #define MSM_AUDIO_ION_PROBED (1 << 0)
  24. #define MSM_AUDIO_ION_PHYS_ADDR(alloc_data) \
  25. alloc_data->table->sgl->dma_address
  26. #define MSM_AUDIO_SMMU_VM_CMD_MAP 0x00000001
  27. #define MSM_AUDIO_SMMU_VM_CMD_UNMAP 0x00000002
  28. #define MSM_AUDIO_SMMU_VM_HAB_MINOR_ID 1
  29. struct msm_audio_ion_private {
  30. bool smmu_enabled;
  31. struct device *cb_dev;
  32. struct device *cb_cma_dev;
  33. u8 device_status;
  34. struct list_head alloc_list;
  35. struct mutex list_mutex;
  36. };
  37. struct msm_audio_alloc_data {
  38. size_t len;
  39. void *vaddr;
  40. struct dma_buf *dma_buf;
  41. struct dma_buf_attachment *attach;
  42. struct sg_table *table;
  43. struct list_head list;
  44. u32 export_id;
  45. };
  46. struct msm_audio_smmu_vm_map_cmd {
  47. int cmd_id;
  48. u32 export_id;
  49. u32 buf_size;
  50. };
  51. struct msm_audio_smmu_vm_map_cmd_rsp {
  52. int status;
  53. u64 addr;
  54. };
  55. struct msm_audio_smmu_vm_unmap_cmd {
  56. int cmd_id;
  57. u32 export_id;
  58. };
  59. struct msm_audio_smmu_vm_unmap_cmd_rsp {
  60. int status;
  61. };
  62. static struct msm_audio_ion_private msm_audio_ion_data = {0,};
  63. static u32 msm_audio_ion_hab_handle;
  64. static void msm_audio_ion_add_allocation(
  65. struct msm_audio_ion_private *msm_audio_ion_data,
  66. struct msm_audio_alloc_data *alloc_data)
  67. {
  68. /*
  69. * Since these APIs can be invoked by multiple
  70. * clients, there is need to make sure the list
  71. * of allocations is always protected
  72. */
  73. mutex_lock(&(msm_audio_ion_data->list_mutex));
  74. list_add_tail(&(alloc_data->list),
  75. &(msm_audio_ion_data->alloc_list));
  76. mutex_unlock(&(msm_audio_ion_data->list_mutex));
  77. }
  78. static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
  79. dma_addr_t *addr, size_t *len,
  80. bool cma_mem)
  81. {
  82. struct msm_audio_alloc_data *alloc_data;
  83. struct device *cb_dev;
  84. unsigned long ionflag = 0;
  85. int rc = 0;
  86. if (cma_mem)
  87. cb_dev = msm_audio_ion_data.cb_cma_dev;
  88. else
  89. cb_dev = msm_audio_ion_data.cb_dev;
  90. /* Data required per buffer mapping */
  91. alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
  92. if (!alloc_data)
  93. return -ENOMEM;
  94. alloc_data->dma_buf = dma_buf;
  95. alloc_data->len = dma_buf->size;
  96. *len = dma_buf->size;
  97. /* Attach the dma_buf to context bank device */
  98. alloc_data->attach = dma_buf_attach(alloc_data->dma_buf,
  99. cb_dev);
  100. if (IS_ERR(alloc_data->attach)) {
  101. rc = PTR_ERR(alloc_data->attach);
  102. dev_err(cb_dev,
  103. "%s: Fail to attach dma_buf to CB, rc = %d\n",
  104. __func__, rc);
  105. goto free_alloc_data;
  106. }
  107. /* For uncached buffers, avoid cache maintanance */
  108. rc = dma_buf_get_flags(alloc_data->dma_buf, &ionflag);
  109. if (rc) {
  110. dev_err(cb_dev, "%s: dma_buf_get_flags failed: %d\n",
  111. __func__, rc);
  112. goto detach_dma_buf;
  113. }
  114. if (!(ionflag & ION_FLAG_CACHED))
  115. alloc_data->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
  116. /*
  117. * Get the scatter-gather list.
  118. * There is no info as this is a write buffer or
  119. * read buffer, hence the request is bi-directional
  120. * to accommodate both read and write mappings.
  121. */
  122. alloc_data->table = dma_buf_map_attachment(alloc_data->attach,
  123. DMA_BIDIRECTIONAL);
  124. if (IS_ERR(alloc_data->table)) {
  125. rc = PTR_ERR(alloc_data->table);
  126. dev_err(cb_dev,
  127. "%s: Fail to map attachment, rc = %d\n",
  128. __func__, rc);
  129. goto detach_dma_buf;
  130. }
  131. /* physical address from mapping */
  132. *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data);
  133. msm_audio_ion_add_allocation(&msm_audio_ion_data,
  134. alloc_data);
  135. return rc;
  136. detach_dma_buf:
  137. dma_buf_detach(alloc_data->dma_buf,
  138. alloc_data->attach);
  139. free_alloc_data:
  140. kfree(alloc_data);
  141. return rc;
  142. }
  143. static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf, bool cma_mem)
  144. {
  145. int rc = 0;
  146. struct msm_audio_alloc_data *alloc_data = NULL;
  147. struct list_head *ptr, *next;
  148. struct device *cb_dev;
  149. bool found = false;
  150. if (cma_mem)
  151. cb_dev = msm_audio_ion_data.cb_cma_dev;
  152. else
  153. cb_dev = msm_audio_ion_data.cb_dev;
  154. /*
  155. * Though list_for_each_safe is delete safe, lock
  156. * should be explicitly acquired to avoid race condition
  157. * on adding elements to the list.
  158. */
  159. mutex_lock(&(msm_audio_ion_data.list_mutex));
  160. list_for_each_safe(ptr, next,
  161. &(msm_audio_ion_data.alloc_list)) {
  162. alloc_data = list_entry(ptr, struct msm_audio_alloc_data,
  163. list);
  164. if (alloc_data->dma_buf == dma_buf) {
  165. found = true;
  166. dma_buf_unmap_attachment(alloc_data->attach,
  167. alloc_data->table,
  168. DMA_BIDIRECTIONAL);
  169. dma_buf_detach(alloc_data->dma_buf,
  170. alloc_data->attach);
  171. dma_buf_put(alloc_data->dma_buf);
  172. list_del(&(alloc_data->list));
  173. kfree(alloc_data);
  174. break;
  175. }
  176. }
  177. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  178. if (!found) {
  179. dev_err(cb_dev,
  180. "%s: cannot find allocation, dma_buf %pK",
  181. __func__, dma_buf);
  182. rc = -EINVAL;
  183. }
  184. return rc;
  185. }
  186. static int msm_audio_ion_smmu_map(struct dma_buf *dma_buf,
  187. dma_addr_t *paddr, size_t *len)
  188. {
  189. int rc;
  190. u32 export_id;
  191. u32 cmd_rsp_size;
  192. bool found = false;
  193. bool exported = false;
  194. struct msm_audio_smmu_vm_map_cmd smmu_map_cmd;
  195. struct msm_audio_smmu_vm_map_cmd_rsp cmd_rsp;
  196. struct msm_audio_alloc_data *alloc_data = NULL;
  197. unsigned long delay = jiffies + (HZ / 2);
  198. *len = dma_buf->size;
  199. mutex_lock(&(msm_audio_ion_data.list_mutex));
  200. list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
  201. list) {
  202. if (alloc_data->dma_buf == dma_buf) {
  203. found = true;
  204. /* Export the buffer to physical VM */
  205. rc = habmm_export(msm_audio_ion_hab_handle, dma_buf, *len,
  206. &export_id, HABMM_EXPIMP_FLAGS_DMABUF);
  207. if (rc) {
  208. pr_err("%s: habmm_export failed dma_buf = %pK, len = %zd, rc = %d\n",
  209. __func__, dma_buf, *len, rc);
  210. goto err;
  211. }
  212. exported = true;
  213. smmu_map_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_MAP;
  214. smmu_map_cmd.export_id = export_id;
  215. smmu_map_cmd.buf_size = *len;
  216. rc = habmm_socket_send(msm_audio_ion_hab_handle,
  217. (void *)&smmu_map_cmd, sizeof(smmu_map_cmd), 0);
  218. if (rc) {
  219. pr_err("%s: habmm_socket_send failed %d\n",
  220. __func__, rc);
  221. goto err;
  222. }
  223. do {
  224. cmd_rsp_size = sizeof(cmd_rsp);
  225. rc = habmm_socket_recv(msm_audio_ion_hab_handle,
  226. (void *)&cmd_rsp,
  227. &cmd_rsp_size,
  228. 0xFFFFFFFF,
  229. 0);
  230. } while (time_before(jiffies, delay) && (rc == -EINTR) &&
  231. (cmd_rsp_size == 0));
  232. if (rc) {
  233. pr_err("%s: habmm_socket_recv failed %d\n",
  234. __func__, rc);
  235. goto err;
  236. }
  237. if (cmd_rsp_size != sizeof(cmd_rsp)) {
  238. pr_err("%s: invalid size for cmd rsp %u, expected %zu\n",
  239. __func__, cmd_rsp_size, sizeof(cmd_rsp));
  240. rc = -EIO;
  241. goto err;
  242. }
  243. if (cmd_rsp.status) {
  244. pr_err("%s: SMMU map command failed %d\n",
  245. __func__, cmd_rsp.status);
  246. rc = cmd_rsp.status;
  247. goto err;
  248. }
  249. *paddr = (dma_addr_t)cmd_rsp.addr;
  250. alloc_data->export_id = export_id;
  251. break;
  252. }
  253. }
  254. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  255. if (!found) {
  256. pr_err("%s: cannot find allocation, dma_buf %pK", __func__, dma_buf);
  257. return -EINVAL;
  258. }
  259. return 0;
  260. err:
  261. if (exported)
  262. (void)habmm_unexport(msm_audio_ion_hab_handle, export_id, 0);
  263. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  264. return rc;
  265. }
  266. static int msm_audio_ion_smmu_unmap(struct dma_buf *dma_buf)
  267. {
  268. int rc;
  269. bool found = false;
  270. u32 cmd_rsp_size;
  271. struct msm_audio_smmu_vm_unmap_cmd smmu_unmap_cmd;
  272. struct msm_audio_smmu_vm_unmap_cmd_rsp cmd_rsp;
  273. struct msm_audio_alloc_data *alloc_data, *next;
  274. unsigned long delay = jiffies + (HZ / 2);
  275. /*
  276. * Though list_for_each_entry_safe is delete safe, lock
  277. * should be explicitly acquired to avoid race condition
  278. * on adding elements to the list.
  279. */
  280. mutex_lock(&(msm_audio_ion_data.list_mutex));
  281. list_for_each_entry_safe(alloc_data, next,
  282. &(msm_audio_ion_data.alloc_list), list) {
  283. if (alloc_data->dma_buf == dma_buf) {
  284. found = true;
  285. smmu_unmap_cmd.cmd_id = MSM_AUDIO_SMMU_VM_CMD_UNMAP;
  286. smmu_unmap_cmd.export_id = alloc_data->export_id;
  287. rc = habmm_socket_send(msm_audio_ion_hab_handle,
  288. (void *)&smmu_unmap_cmd,
  289. sizeof(smmu_unmap_cmd), 0);
  290. if (rc) {
  291. pr_err("%s: habmm_socket_send failed %d\n",
  292. __func__, rc);
  293. goto err;
  294. }
  295. do {
  296. cmd_rsp_size = sizeof(cmd_rsp);
  297. rc = habmm_socket_recv(msm_audio_ion_hab_handle,
  298. (void *)&cmd_rsp,
  299. &cmd_rsp_size,
  300. 0xFFFFFFFF,
  301. 0);
  302. } while (time_before(jiffies, delay) &&
  303. (rc == -EINTR) && (cmd_rsp_size == 0));
  304. if (rc) {
  305. pr_err("%s: habmm_socket_recv failed %d\n",
  306. __func__, rc);
  307. goto err;
  308. }
  309. if (cmd_rsp_size != sizeof(cmd_rsp)) {
  310. pr_err("%s: invalid size for cmd rsp %u\n",
  311. __func__, cmd_rsp_size);
  312. rc = -EIO;
  313. goto err;
  314. }
  315. if (cmd_rsp.status) {
  316. pr_err("%s: SMMU unmap command failed %d\n",
  317. __func__, cmd_rsp.status);
  318. rc = cmd_rsp.status;
  319. goto err;
  320. }
  321. rc = habmm_unexport(msm_audio_ion_hab_handle,
  322. alloc_data->export_id, 0xFFFFFFFF);
  323. if (rc) {
  324. pr_err("%s: habmm_unexport failed export_id = %d, rc = %d\n",
  325. __func__, alloc_data->export_id, rc);
  326. }
  327. break;
  328. }
  329. }
  330. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  331. if (!found) {
  332. pr_err("%s: cannot find allocation, dma_buf %pK\n", __func__, dma_buf);
  333. rc = -EINVAL;
  334. }
  335. return rc;
  336. err:
  337. if (found) {
  338. (void)habmm_unexport(msm_audio_ion_hab_handle,
  339. alloc_data->export_id, 0xFFFFFFFF);
  340. list_del(&(alloc_data->list));
  341. kfree(alloc_data);
  342. }
  343. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  344. return rc;
  345. }
  346. static int msm_audio_ion_get_phys(struct dma_buf *dma_buf,
  347. dma_addr_t *addr, size_t *len)
  348. {
  349. int rc = 0;
  350. rc = msm_audio_dma_buf_map(dma_buf, addr, len, false);
  351. if (rc) {
  352. pr_err("%s: failed to map DMA buf, err = %d\n",
  353. __func__, rc);
  354. goto err;
  355. }
  356. pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc);
  357. err:
  358. return rc;
  359. }
  360. static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf)
  361. {
  362. int rc = 0;
  363. void *addr = NULL;
  364. struct msm_audio_alloc_data *alloc_data = NULL;
  365. rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
  366. if (rc) {
  367. pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__);
  368. goto exit;
  369. }
  370. addr = dma_buf_vmap(dma_buf);
  371. if (!addr) {
  372. pr_err("%s: kernel mapping of dma_buf failed\n",
  373. __func__);
  374. goto exit;
  375. }
  376. /*
  377. * TBD: remove the below section once new API
  378. * for mapping kernel virtual address is available.
  379. */
  380. mutex_lock(&(msm_audio_ion_data.list_mutex));
  381. list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
  382. list) {
  383. if (alloc_data->dma_buf == dma_buf) {
  384. alloc_data->vaddr = addr;
  385. break;
  386. }
  387. }
  388. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  389. exit:
  390. return addr;
  391. }
  392. static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf)
  393. {
  394. int rc = 0;
  395. void *vaddr = NULL;
  396. struct msm_audio_alloc_data *alloc_data = NULL;
  397. struct device *cb_dev = msm_audio_ion_data.cb_dev;
  398. /*
  399. * TBD: remove the below section once new API
  400. * for unmapping kernel virtual address is available.
  401. */
  402. mutex_lock(&(msm_audio_ion_data.list_mutex));
  403. list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
  404. list) {
  405. if (alloc_data->dma_buf == dma_buf) {
  406. vaddr = alloc_data->vaddr;
  407. break;
  408. }
  409. }
  410. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  411. if (!vaddr) {
  412. dev_err(cb_dev,
  413. "%s: cannot find allocation for dma_buf %pK",
  414. __func__, dma_buf);
  415. rc = -EINVAL;
  416. goto err;
  417. }
  418. dma_buf_vunmap(dma_buf, vaddr);
  419. rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
  420. if (rc) {
  421. dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n",
  422. __func__);
  423. goto err;
  424. }
  425. err:
  426. return rc;
  427. }
  428. static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
  429. size_t *plen, void **vaddr)
  430. {
  431. int rc = 0;
  432. rc = msm_audio_ion_get_phys(dma_buf, paddr, plen);
  433. if (rc) {
  434. pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
  435. __func__, rc);
  436. dma_buf_put(dma_buf);
  437. goto err;
  438. }
  439. *vaddr = msm_audio_ion_map_kernel(dma_buf);
  440. if (IS_ERR_OR_NULL(*vaddr)) {
  441. pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
  442. rc = -ENOMEM;
  443. msm_audio_dma_buf_unmap(dma_buf, false);
  444. goto err;
  445. }
  446. if (msm_audio_ion_data.smmu_enabled) {
  447. rc = msm_audio_ion_smmu_map(dma_buf, paddr, plen);
  448. if (rc) {
  449. pr_err("%s: failed to do smmu map, err = %d\n",
  450. __func__, rc);
  451. msm_audio_dma_buf_unmap(dma_buf, false);
  452. goto err;
  453. }
  454. }
  455. err:
  456. return rc;
  457. }
  458. /**
  459. * msm_audio_ion_alloc -
  460. * Allocs ION memory for given client name
  461. *
  462. * @dma_buf: dma_buf for the ION memory
  463. * @bufsz: buffer size
  464. * @paddr: Physical address to be assigned with allocated region
  465. * @plen: length of allocated region to be assigned
  466. * vaddr: virtual address to be assigned
  467. *
  468. * Returns 0 on success or error on failure
  469. */
  470. int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz,
  471. dma_addr_t *paddr, size_t *plen, void **vaddr)
  472. {
  473. int rc = -EINVAL;
  474. unsigned long err_ion_ptr = 0;
  475. if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
  476. pr_debug("%s:probe is not done, deferred\n", __func__);
  477. return -EPROBE_DEFER;
  478. }
  479. if (!dma_buf || !paddr || !vaddr || !bufsz || !plen) {
  480. pr_err("%s: Invalid params\n", __func__);
  481. return -EINVAL;
  482. }
  483. pr_debug("%s: audio heap is used\n", __func__);
  484. if (msm_audio_ion_data.smmu_enabled == true) {
  485. *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
  486. if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
  487. if (IS_ERR((void *)(*dma_buf)))
  488. err_ion_ptr = PTR_ERR((int *)(*dma_buf));
  489. pr_debug("%s: ION alloc failed for audio heap err ptr=%ld, smmu_enabled=%d,"
  490. "trying system heap..\n",
  491. __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled);
  492. *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
  493. }
  494. } else {
  495. *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
  496. }
  497. if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
  498. if (IS_ERR((void *)(*dma_buf)))
  499. err_ion_ptr = PTR_ERR((int *)(*dma_buf));
  500. pr_err("%s: ION alloc fail err ptr=%ld, smmu_enabled=%d\n",
  501. __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled);
  502. rc = -ENOMEM;
  503. goto err;
  504. }
  505. rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
  506. if (rc) {
  507. pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
  508. goto err;
  509. }
  510. pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
  511. *vaddr, bufsz);
  512. memset(*vaddr, 0, bufsz);
  513. err:
  514. return rc;
  515. }
  516. EXPORT_SYMBOL(msm_audio_ion_alloc);
  517. int msm_audio_ion_phys_free(void *handle,
  518. dma_addr_t *paddr,
  519. size_t *pa_len,
  520. u8 assign_type,
  521. int id,
  522. int key)
  523. {
  524. handle = NULL;
  525. return 0;
  526. }
  527. EXPORT_SYMBOL(msm_audio_ion_phys_free);
  528. int msm_audio_ion_phys_assign(void **handle, int fd,
  529. dma_addr_t *paddr, size_t *pa_len, u8 assign_type, int id)
  530. {
  531. *handle = NULL;
  532. return 0;
  533. }
  534. EXPORT_SYMBOL(msm_audio_ion_phys_assign);
  535. bool msm_audio_is_hypervisor_supported(void)
  536. {
  537. return false;
  538. }
  539. EXPORT_SYMBOL(msm_audio_is_hypervisor_supported);
  540. /**
  541. * msm_audio_ion_import-
  542. * Import ION buffer with given file descriptor
  543. *
  544. * @dma_buf: dma_buf for the ION memory
  545. * @fd: file descriptor for the ION memory
  546. * @ionflag: flags associated with ION buffer
  547. * @bufsz: buffer size
  548. * @paddr: Physical address to be assigned with allocated region
  549. * @plen: length of allocated region to be assigned
  550. * @vaddr: virtual address to be assigned
  551. *
  552. * Returns 0 on success or error on failure
  553. */
  554. int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
  555. unsigned long *ionflag, size_t bufsz,
  556. dma_addr_t *paddr, size_t *plen, void **vaddr)
  557. {
  558. int rc = 0;
  559. if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
  560. pr_debug("%s: probe is not done, deferred\n", __func__);
  561. return -EPROBE_DEFER;
  562. }
  563. if (!dma_buf || !paddr || !vaddr || !plen) {
  564. pr_err("%s: Invalid params\n", __func__);
  565. return -EINVAL;
  566. }
  567. /* bufsz should be 0 and fd shouldn't be 0 as of now */
  568. *dma_buf = dma_buf_get(fd);
  569. pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
  570. if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
  571. pr_err("%s: dma_buf_get failed\n", __func__);
  572. rc = -EINVAL;
  573. goto err;
  574. }
  575. if (ionflag != NULL) {
  576. rc = dma_buf_get_flags(*dma_buf, ionflag);
  577. if (rc) {
  578. pr_err("%s: could not get flags for the dma_buf\n",
  579. __func__);
  580. goto err_ion_flag;
  581. }
  582. }
  583. rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
  584. if (rc) {
  585. pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
  586. goto err;
  587. }
  588. pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
  589. *vaddr, bufsz);
  590. return 0;
  591. err_ion_flag:
  592. dma_buf_put(*dma_buf);
  593. err:
  594. *dma_buf = NULL;
  595. return rc;
  596. }
  597. EXPORT_SYMBOL(msm_audio_ion_import);
  598. /**
  599. * msm_audio_ion_import_cma-
  600. * Import ION buffer with given file descriptor
  601. *
  602. * @dma_buf: dma_buf for the ION memory
  603. * @fd: file descriptor for the ION memory
  604. * @ionflag: flags associated with ION buffer
  605. * @bufsz: buffer size
  606. * @paddr: Physical address to be assigned with allocated region
  607. * @plen: length of allocated region to be assigned
  608. * @vaddr: virtual address to be assigned
  609. *
  610. * Returns 0 on success or error on failure
  611. */
  612. int msm_audio_ion_import_cma(struct dma_buf **dma_buf, int fd,
  613. unsigned long *ionflag, size_t bufsz,
  614. dma_addr_t *paddr, size_t *plen, void **vaddr)
  615. {
  616. int rc = 0;
  617. if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
  618. pr_debug("%s: probe is not done, deferred\n", __func__);
  619. return -EPROBE_DEFER;
  620. }
  621. if (!dma_buf || !paddr || !vaddr || !plen ||
  622. !msm_audio_ion_data.cb_cma_dev) {
  623. pr_err("%s: Invalid params\n", __func__);
  624. return -EINVAL;
  625. }
  626. /* bufsz should be 0 and fd shouldn't be 0 as of now */
  627. *dma_buf = dma_buf_get(fd);
  628. pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
  629. if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
  630. pr_err("%s: dma_buf_get failed\n", __func__);
  631. rc = -EINVAL;
  632. goto err;
  633. }
  634. if (ionflag != NULL) {
  635. rc = dma_buf_get_flags(*dma_buf, ionflag);
  636. if (rc) {
  637. pr_err("%s: could not get flags for the dma_buf\n",
  638. __func__);
  639. goto err_ion_flag;
  640. }
  641. }
  642. msm_audio_dma_buf_map(*dma_buf, paddr, plen, true);
  643. return 0;
  644. err_ion_flag:
  645. dma_buf_put(*dma_buf);
  646. err:
  647. *dma_buf = NULL;
  648. return rc;
  649. }
  650. EXPORT_SYMBOL(msm_audio_ion_import_cma);
  651. /**
  652. * msm_audio_ion_free -
  653. * fress ION memory for given client and handle
  654. *
  655. * @dma_buf: dma_buf for the ION memory
  656. *
  657. * Returns 0 on success or error on failure
  658. */
  659. int msm_audio_ion_free(struct dma_buf *dma_buf)
  660. {
  661. int ret = 0;
  662. if (!dma_buf) {
  663. pr_err("%s: dma_buf invalid\n", __func__);
  664. return -EINVAL;
  665. }
  666. ret = msm_audio_ion_unmap_kernel(dma_buf);
  667. if (ret)
  668. return ret;
  669. if (msm_audio_ion_data.smmu_enabled) {
  670. ret = msm_audio_ion_smmu_unmap(dma_buf);
  671. if (ret)
  672. pr_err("%s: smmu unmap failed with ret %d\n",
  673. __func__, ret);
  674. }
  675. msm_audio_dma_buf_unmap(dma_buf, false);
  676. return 0;
  677. }
  678. EXPORT_SYMBOL(msm_audio_ion_free);
  679. /**
  680. * msm_audio_ion_free_cma -
  681. * fress ION memory for given client and handle
  682. *
  683. * @dma_buf: dma_buf for the ION memory
  684. *
  685. * Returns 0 on success or error on failure
  686. */
  687. int msm_audio_ion_free_cma(struct dma_buf *dma_buf)
  688. {
  689. if (!dma_buf) {
  690. pr_err("%s: dma_buf invalid\n", __func__);
  691. return -EINVAL;
  692. }
  693. msm_audio_dma_buf_unmap(dma_buf, true);
  694. return 0;
  695. }
  696. EXPORT_SYMBOL(msm_audio_ion_free_cma);
  697. /**
  698. * msm_audio_ion_mmap -
  699. * Audio ION memory map
  700. *
  701. * @abuff: audio buf pointer
  702. * @vma: virtual mem area
  703. *
  704. * Returns 0 on success or error on failure
  705. */
  706. int msm_audio_ion_mmap(struct audio_buffer *abuff,
  707. struct vm_area_struct *vma)
  708. {
  709. struct msm_audio_alloc_data *alloc_data = NULL;
  710. struct sg_table *table;
  711. unsigned long addr = vma->vm_start;
  712. unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
  713. struct scatterlist *sg;
  714. unsigned int i;
  715. struct page *page;
  716. int ret = 0;
  717. bool found = false;
  718. struct device *cb_dev = msm_audio_ion_data.cb_dev;
  719. mutex_lock(&(msm_audio_ion_data.list_mutex));
  720. list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
  721. list) {
  722. if (alloc_data->dma_buf == abuff->dma_buf) {
  723. found = true;
  724. table = alloc_data->table;
  725. break;
  726. }
  727. }
  728. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  729. if (!found) {
  730. dev_err(cb_dev,
  731. "%s: cannot find allocation, dma_buf %pK",
  732. __func__, abuff->dma_buf);
  733. return -EINVAL;
  734. }
  735. /* uncached */
  736. vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  737. /* We need to check if a page is associated with this sg list because:
  738. * If the allocation came from a carveout we currently don't have
  739. * pages associated with carved out memory. This might change in the
  740. * future and we can remove this check and the else statement.
  741. */
  742. page = sg_page(table->sgl);
  743. if (page) {
  744. pr_debug("%s: page is NOT null\n", __func__);
  745. for_each_sg(table->sgl, sg, table->nents, i) {
  746. unsigned long remainder = vma->vm_end - addr;
  747. unsigned long len = sg->length;
  748. page = sg_page(sg);
  749. if (offset >= len) {
  750. offset -= len;
  751. continue;
  752. } else if (offset) {
  753. page += offset / PAGE_SIZE;
  754. len -= offset;
  755. offset = 0;
  756. }
  757. len = min(len, remainder);
  758. pr_debug("vma=%pK, addr=%x len=%ld vm_start=%x vm_end=%x vm_page_prot=%lu\n",
  759. vma, (unsigned int)addr, len,
  760. (unsigned int)vma->vm_start,
  761. (unsigned int)vma->vm_end,
  762. (unsigned long)pgprot_val(vma->vm_page_prot));
  763. remap_pfn_range(vma, addr, page_to_pfn(page), len,
  764. vma->vm_page_prot);
  765. addr += len;
  766. if (addr >= vma->vm_end)
  767. return 0;
  768. }
  769. } else {
  770. pr_debug("%s: page is NULL\n", __func__);
  771. ret = -EINVAL;
  772. }
  773. return ret;
  774. }
  775. EXPORT_SYMBOL(msm_audio_ion_mmap);
  776. /**
  777. * msm_audio_populate_upper_32_bits -
  778. * retrieve upper 32bits of 64bit address
  779. *
  780. * @pa: 64bit physical address
  781. *
  782. */
  783. u32 msm_audio_populate_upper_32_bits(dma_addr_t pa)
  784. {
  785. return upper_32_bits(pa);
  786. }
  787. EXPORT_SYMBOL(msm_audio_populate_upper_32_bits);
  788. static const struct of_device_id msm_audio_ion_dt_match[] = {
  789. { .compatible = "qcom,msm-audio-ion" },
  790. { .compatible = "qcom,msm-audio-ion-cma"},
  791. { }
  792. };
  793. MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
  794. static int msm_audio_ion_probe(struct platform_device *pdev)
  795. {
  796. int rc = 0;
  797. const char *msm_audio_ion_dt = "qcom,smmu-enabled";
  798. bool smmu_enabled;
  799. struct device *dev = &pdev->dev;
  800. if (dev->of_node == NULL) {
  801. dev_err(dev,
  802. "%s: device tree is not found\n",
  803. __func__);
  804. msm_audio_ion_data.smmu_enabled = 0;
  805. return 0;
  806. }
  807. if (of_device_is_compatible(dev->of_node, "qcom,msm-audio-ion-cma")) {
  808. msm_audio_ion_data.cb_cma_dev = dev;
  809. return 0;
  810. }
  811. smmu_enabled = of_property_read_bool(dev->of_node,
  812. msm_audio_ion_dt);
  813. msm_audio_ion_data.smmu_enabled = smmu_enabled;
  814. if (!smmu_enabled) {
  815. dev_dbg(dev, "%s: SMMU is Disabled\n", __func__);
  816. goto exit;
  817. }
  818. rc = habmm_socket_open(&msm_audio_ion_hab_handle,
  819. HAB_MMID_CREATE(MM_AUD_3,
  820. MSM_AUDIO_SMMU_VM_HAB_MINOR_ID),
  821. 0xFFFFFFFF,
  822. HABMM_SOCKET_OPEN_FLAGS_SINGLE_BE_SINGLE_FE);
  823. if (rc) {
  824. dev_err(dev, "%s: habmm_socket_open failed %d\n",
  825. __func__, rc);
  826. return rc;
  827. }
  828. dev_info(dev, "%s: msm_audio_ion_hab_handle %x\n",
  829. __func__, msm_audio_ion_hab_handle);
  830. INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list);
  831. mutex_init(&(msm_audio_ion_data.list_mutex));
  832. exit:
  833. if (!rc)
  834. msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED;
  835. msm_audio_ion_data.cb_dev = dev;
  836. return rc;
  837. }
  838. static int msm_audio_ion_remove(struct platform_device *pdev)
  839. {
  840. if (msm_audio_ion_data.smmu_enabled) {
  841. if (msm_audio_ion_hab_handle)
  842. habmm_socket_close(msm_audio_ion_hab_handle);
  843. mutex_destroy(&(msm_audio_ion_data.list_mutex));
  844. }
  845. msm_audio_ion_data.smmu_enabled = 0;
  846. msm_audio_ion_data.device_status = 0;
  847. return 0;
  848. }
  849. static struct platform_driver msm_audio_ion_driver = {
  850. .driver = {
  851. .name = "msm-audio-ion",
  852. .owner = THIS_MODULE,
  853. .of_match_table = msm_audio_ion_dt_match,
  854. },
  855. .probe = msm_audio_ion_probe,
  856. .remove = msm_audio_ion_remove,
  857. };
  858. int __init msm_audio_ion_init(void)
  859. {
  860. return platform_driver_register(&msm_audio_ion_driver);
  861. }
  862. void msm_audio_ion_exit(void)
  863. {
  864. platform_driver_unregister(&msm_audio_ion_driver);
  865. }
  866. MODULE_DESCRIPTION("MSM Audio ION VM module");
  867. MODULE_LICENSE("GPL v2");