msm_audio_ion.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830
  1. /*
  2. * Copyright (c) 2013-2018, The Linux Foundation. All rights reserved.
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License version 2 and
  6. * only version 2 as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU General Public License for more details.
  12. */
  13. #include <linux/init.h>
  14. #include <linux/kernel.h>
  15. #include <linux/module.h>
  16. #include <linux/err.h>
  17. #include <linux/delay.h>
  18. #include <linux/slab.h>
  19. #include <linux/mutex.h>
  20. #include <linux/list.h>
  21. #include <linux/dma-mapping.h>
  22. #include <linux/dma-buf.h>
  23. #include <linux/iommu.h>
  24. #include <linux/platform_device.h>
  25. #include <linux/of_device.h>
  26. #include <linux/export.h>
  27. #include <linux/ion_kernel.h>
  28. #include <ipc/apr.h>
  29. #include <asm/dma-iommu.h>
  30. #include <dsp/msm_audio_ion.h>
  31. #define MSM_AUDIO_ION_PROBED (1 << 0)
  32. #define MSM_AUDIO_ION_PHYS_ADDR(alloc_data) \
  33. alloc_data->table->sgl->dma_address
  34. #define MSM_AUDIO_ION_VA_START 0x10000000
  35. #define MSM_AUDIO_ION_VA_LEN 0x0FFFFFFF
  36. #define MSM_AUDIO_SMMU_SID_OFFSET 32
  37. struct msm_audio_ion_private {
  38. bool smmu_enabled;
  39. struct device *cb_dev;
  40. struct dma_iommu_mapping *mapping;
  41. u8 device_status;
  42. struct list_head alloc_list;
  43. struct mutex list_mutex;
  44. u64 smmu_sid_bits;
  45. u32 smmu_version;
  46. };
  47. struct msm_audio_alloc_data {
  48. size_t len;
  49. void *vaddr;
  50. struct dma_buf *dma_buf;
  51. struct dma_buf_attachment *attach;
  52. struct sg_table *table;
  53. struct list_head list;
  54. };
  55. static struct msm_audio_ion_private msm_audio_ion_data = {0,};
  56. static void msm_audio_ion_add_allocation(
  57. struct msm_audio_ion_private *msm_audio_ion_data,
  58. struct msm_audio_alloc_data *alloc_data)
  59. {
  60. /*
  61. * Since these APIs can be invoked by multiple
  62. * clients, there is need to make sure the list
  63. * of allocations is always protected
  64. */
  65. mutex_lock(&(msm_audio_ion_data->list_mutex));
  66. list_add_tail(&(alloc_data->list),
  67. &(msm_audio_ion_data->alloc_list));
  68. mutex_unlock(&(msm_audio_ion_data->list_mutex));
  69. }
  70. static int msm_audio_dma_buf_map(struct dma_buf *dma_buf,
  71. dma_addr_t *addr, size_t *len)
  72. {
  73. struct msm_audio_alloc_data *alloc_data;
  74. struct device *cb_dev;
  75. unsigned long ionflag = 0;
  76. int rc = 0;
  77. cb_dev = msm_audio_ion_data.cb_dev;
  78. /* Data required per buffer mapping */
  79. alloc_data = kzalloc(sizeof(*alloc_data), GFP_KERNEL);
  80. if (!alloc_data)
  81. return -ENOMEM;
  82. alloc_data->dma_buf = dma_buf;
  83. alloc_data->len = dma_buf->size;
  84. *len = dma_buf->size;
  85. /* Attach the dma_buf to context bank device */
  86. alloc_data->attach = dma_buf_attach(alloc_data->dma_buf,
  87. cb_dev);
  88. if (IS_ERR(alloc_data->attach)) {
  89. rc = PTR_ERR(alloc_data->attach);
  90. dev_err(cb_dev,
  91. "%s: Fail to attach dma_buf to CB, rc = %d\n",
  92. __func__, rc);
  93. goto free_alloc_data;
  94. }
  95. /* For uncached buffers, avoid cache maintanance */
  96. rc = dma_buf_get_flags(alloc_data->dma_buf, &ionflag);
  97. if (rc) {
  98. dev_err(cb_dev, "%s: dma_buf_get_flags failed: %d\n",
  99. __func__, rc);
  100. goto detach_dma_buf;
  101. }
  102. if (!(ionflag & ION_FLAG_CACHED))
  103. alloc_data->attach->dma_map_attrs |= DMA_ATTR_SKIP_CPU_SYNC;
  104. /*
  105. * Get the scatter-gather list.
  106. * There is no info as this is a write buffer or
  107. * read buffer, hence the request is bi-directional
  108. * to accommodate both read and write mappings.
  109. */
  110. alloc_data->table = dma_buf_map_attachment(alloc_data->attach,
  111. DMA_BIDIRECTIONAL);
  112. if (IS_ERR(alloc_data->table)) {
  113. rc = PTR_ERR(alloc_data->table);
  114. dev_err(cb_dev,
  115. "%s: Fail to map attachment, rc = %d\n",
  116. __func__, rc);
  117. goto detach_dma_buf;
  118. }
  119. /* physical address from mapping */
  120. *addr = MSM_AUDIO_ION_PHYS_ADDR(alloc_data);
  121. msm_audio_ion_add_allocation(&msm_audio_ion_data,
  122. alloc_data);
  123. return rc;
  124. detach_dma_buf:
  125. dma_buf_detach(alloc_data->dma_buf,
  126. alloc_data->attach);
  127. free_alloc_data:
  128. kfree(alloc_data);
  129. return rc;
  130. }
  131. static int msm_audio_dma_buf_unmap(struct dma_buf *dma_buf)
  132. {
  133. int rc = 0;
  134. struct msm_audio_alloc_data *alloc_data = NULL;
  135. struct list_head *ptr, *next;
  136. struct device *cb_dev = msm_audio_ion_data.cb_dev;
  137. bool found = false;
  138. /*
  139. * Though list_for_each_safe is delete safe, lock
  140. * should be explicitly acquired to avoid race condition
  141. * on adding elements to the list.
  142. */
  143. mutex_lock(&(msm_audio_ion_data.list_mutex));
  144. list_for_each_safe(ptr, next,
  145. &(msm_audio_ion_data.alloc_list)) {
  146. alloc_data = list_entry(ptr, struct msm_audio_alloc_data,
  147. list);
  148. if (alloc_data->dma_buf == dma_buf) {
  149. found = true;
  150. dma_buf_unmap_attachment(alloc_data->attach,
  151. alloc_data->table,
  152. DMA_BIDIRECTIONAL);
  153. dma_buf_detach(alloc_data->dma_buf,
  154. alloc_data->attach);
  155. dma_buf_put(alloc_data->dma_buf);
  156. list_del(&(alloc_data->list));
  157. kfree(alloc_data);
  158. break;
  159. }
  160. }
  161. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  162. if (!found) {
  163. dev_err(cb_dev,
  164. "%s: cannot find allocation, dma_buf %pK",
  165. __func__, dma_buf);
  166. rc = -EINVAL;
  167. }
  168. return rc;
  169. }
  170. static int msm_audio_ion_get_phys(struct dma_buf *dma_buf,
  171. dma_addr_t *addr, size_t *len)
  172. {
  173. int rc = 0;
  174. rc = msm_audio_dma_buf_map(dma_buf, addr, len);
  175. if (rc) {
  176. pr_err("%s: failed to map DMA buf, err = %d\n",
  177. __func__, rc);
  178. goto err;
  179. }
  180. if (msm_audio_ion_data.smmu_enabled) {
  181. /* Append the SMMU SID information to the IOVA address */
  182. *addr |= msm_audio_ion_data.smmu_sid_bits;
  183. }
  184. pr_debug("phys=%pK, len=%zd, rc=%d\n", &(*addr), *len, rc);
  185. err:
  186. return rc;
  187. }
  188. int msm_audio_ion_get_smmu_info(struct device **cb_dev,
  189. u64 *smmu_sid)
  190. {
  191. if (!cb_dev || !smmu_sid) {
  192. pr_err("%s: Invalid params\n",
  193. __func__);
  194. return -EINVAL;
  195. }
  196. if (!msm_audio_ion_data.cb_dev ||
  197. !msm_audio_ion_data.smmu_sid_bits) {
  198. pr_err("%s: Params not initialized\n",
  199. __func__);
  200. return -EINVAL;
  201. }
  202. *cb_dev = msm_audio_ion_data.cb_dev;
  203. *smmu_sid = msm_audio_ion_data.smmu_sid_bits;
  204. return 0;
  205. }
  206. static void *msm_audio_ion_map_kernel(struct dma_buf *dma_buf)
  207. {
  208. int rc = 0;
  209. void *addr = NULL;
  210. struct msm_audio_alloc_data *alloc_data = NULL;
  211. rc = dma_buf_begin_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
  212. if (rc) {
  213. pr_err("%s: kmap dma_buf_begin_cpu_access fail\n", __func__);
  214. goto exit;
  215. }
  216. addr = dma_buf_vmap(dma_buf);
  217. if (!addr) {
  218. pr_err("%s: kernel mapping of dma_buf failed\n",
  219. __func__);
  220. goto exit;
  221. }
  222. /*
  223. * TBD: remove the below section once new API
  224. * for mapping kernel virtual address is available.
  225. */
  226. mutex_lock(&(msm_audio_ion_data.list_mutex));
  227. list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
  228. list) {
  229. if (alloc_data->dma_buf == dma_buf) {
  230. alloc_data->vaddr = addr;
  231. break;
  232. }
  233. }
  234. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  235. exit:
  236. return addr;
  237. }
  238. static int msm_audio_ion_unmap_kernel(struct dma_buf *dma_buf)
  239. {
  240. int rc = 0;
  241. void *vaddr = NULL;
  242. struct msm_audio_alloc_data *alloc_data = NULL;
  243. struct device *cb_dev = msm_audio_ion_data.cb_dev;
  244. /*
  245. * TBD: remove the below section once new API
  246. * for unmapping kernel virtual address is available.
  247. */
  248. mutex_lock(&(msm_audio_ion_data.list_mutex));
  249. list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
  250. list) {
  251. if (alloc_data->dma_buf == dma_buf) {
  252. vaddr = alloc_data->vaddr;
  253. break;
  254. }
  255. }
  256. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  257. if (!vaddr) {
  258. dev_err(cb_dev,
  259. "%s: cannot find allocation for dma_buf %pK",
  260. __func__, dma_buf);
  261. rc = -EINVAL;
  262. goto err;
  263. }
  264. dma_buf_vunmap(dma_buf, vaddr);
  265. rc = dma_buf_end_cpu_access(dma_buf, DMA_BIDIRECTIONAL);
  266. if (rc) {
  267. dev_err(cb_dev, "%s: kmap dma_buf_end_cpu_access fail\n",
  268. __func__);
  269. goto err;
  270. }
  271. err:
  272. return rc;
  273. }
  274. static int msm_audio_ion_map_buf(struct dma_buf *dma_buf, dma_addr_t *paddr,
  275. size_t *plen, void **vaddr)
  276. {
  277. int rc = 0;
  278. rc = msm_audio_ion_get_phys(dma_buf, paddr, plen);
  279. if (rc) {
  280. pr_err("%s: ION Get Physical for AUDIO failed, rc = %d\n",
  281. __func__, rc);
  282. goto err;
  283. }
  284. *vaddr = msm_audio_ion_map_kernel(dma_buf);
  285. if (IS_ERR_OR_NULL(*vaddr)) {
  286. pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
  287. rc = -ENOMEM;
  288. goto err;
  289. }
  290. err:
  291. return rc;
  292. }
  293. static u32 msm_audio_ion_get_smmu_sid_mode32(void)
  294. {
  295. if (msm_audio_ion_data.smmu_enabled)
  296. return upper_32_bits(msm_audio_ion_data.smmu_sid_bits);
  297. else
  298. return 0;
  299. }
  300. /**
  301. * msm_audio_ion_alloc -
  302. * Allocs ION memory for given client name
  303. *
  304. * @dma_buf: dma_buf for the ION memory
  305. * @bufsz: buffer size
  306. * @paddr: Physical address to be assigned with allocated region
  307. * @plen: length of allocated region to be assigned
  308. * vaddr: virtual address to be assigned
  309. *
  310. * Returns 0 on success or error on failure
  311. */
  312. int msm_audio_ion_alloc(struct dma_buf **dma_buf, size_t bufsz,
  313. dma_addr_t *paddr, size_t *plen, void **vaddr)
  314. {
  315. int rc = -EINVAL;
  316. unsigned long err_ion_ptr = 0;
  317. if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
  318. pr_debug("%s:probe is not done, deferred\n", __func__);
  319. return -EPROBE_DEFER;
  320. }
  321. if (!dma_buf || !paddr || !vaddr || !bufsz || !plen) {
  322. pr_err("%s: Invalid params\n", __func__);
  323. return -EINVAL;
  324. }
  325. if (msm_audio_ion_data.smmu_enabled == true) {
  326. pr_debug("%s: system heap is used\n", __func__);
  327. *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_SYSTEM_HEAP_ID), 0);
  328. } else {
  329. pr_debug("%s: audio heap is used\n", __func__);
  330. *dma_buf = ion_alloc(bufsz, ION_HEAP(ION_AUDIO_HEAP_ID), 0);
  331. }
  332. if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
  333. if (IS_ERR((void *)(*dma_buf)))
  334. err_ion_ptr = PTR_ERR((int *)(*dma_buf));
  335. pr_err("%s: ION alloc fail err ptr=%ld, smmu_enabled=%d\n",
  336. __func__, err_ion_ptr, msm_audio_ion_data.smmu_enabled);
  337. rc = -ENOMEM;
  338. goto err;
  339. }
  340. rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
  341. if (rc) {
  342. pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
  343. goto err_dma_buf;
  344. }
  345. pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
  346. *vaddr, bufsz);
  347. memset(*vaddr, 0, bufsz);
  348. return rc;
  349. err_dma_buf:
  350. dma_buf_put(*dma_buf);
  351. err:
  352. return rc;
  353. }
  354. EXPORT_SYMBOL(msm_audio_ion_alloc);
  355. /**
  356. * msm_audio_ion_import-
  357. * Import ION buffer with given file descriptor
  358. *
  359. * @dma_buf: dma_buf for the ION memory
  360. * @fd: file descriptor for the ION memory
  361. * @ionflag: flags associated with ION buffer
  362. * @bufsz: buffer size
  363. * @paddr: Physical address to be assigned with allocated region
  364. * @plen: length of allocated region to be assigned
  365. * vaddr: virtual address to be assigned
  366. *
  367. * Returns 0 on success or error on failure
  368. */
  369. int msm_audio_ion_import(struct dma_buf **dma_buf, int fd,
  370. unsigned long *ionflag, size_t bufsz,
  371. dma_addr_t *paddr, size_t *plen, void **vaddr)
  372. {
  373. int rc = 0;
  374. if (!(msm_audio_ion_data.device_status & MSM_AUDIO_ION_PROBED)) {
  375. pr_debug("%s: probe is not done, deferred\n", __func__);
  376. return -EPROBE_DEFER;
  377. }
  378. if (!dma_buf || !paddr || !vaddr || !plen) {
  379. pr_err("%s: Invalid params\n", __func__);
  380. return -EINVAL;
  381. }
  382. /* bufsz should be 0 and fd shouldn't be 0 as of now */
  383. *dma_buf = dma_buf_get(fd);
  384. pr_debug("%s: dma_buf =%pK, fd=%d\n", __func__, *dma_buf, fd);
  385. if (IS_ERR_OR_NULL((void *)(*dma_buf))) {
  386. pr_err("%s: dma_buf_get failed\n", __func__);
  387. rc = -EINVAL;
  388. goto err;
  389. }
  390. if (ionflag != NULL) {
  391. rc = dma_buf_get_flags(*dma_buf, ionflag);
  392. if (rc) {
  393. pr_err("%s: could not get flags for the dma_buf\n",
  394. __func__);
  395. goto err_ion_flag;
  396. }
  397. }
  398. rc = msm_audio_ion_map_buf(*dma_buf, paddr, plen, vaddr);
  399. if (rc) {
  400. pr_err("%s: failed to map ION buf, rc = %d\n", __func__, rc);
  401. goto err_ion_flag;
  402. }
  403. pr_debug("%s: mapped address = %pK, size=%zd\n", __func__,
  404. *vaddr, bufsz);
  405. return 0;
  406. err_ion_flag:
  407. dma_buf_put(*dma_buf);
  408. err:
  409. *dma_buf = NULL;
  410. return rc;
  411. }
  412. EXPORT_SYMBOL(msm_audio_ion_import);
  413. /**
  414. * msm_audio_ion_free -
  415. * fress ION memory for given client and handle
  416. *
  417. * @dma_buf: dma_buf for the ION memory
  418. *
  419. * Returns 0 on success or error on failure
  420. */
  421. int msm_audio_ion_free(struct dma_buf *dma_buf)
  422. {
  423. int ret = 0;
  424. if (!dma_buf) {
  425. pr_err("%s: dma_buf invalid\n", __func__);
  426. return -EINVAL;
  427. }
  428. ret = msm_audio_ion_unmap_kernel(dma_buf);
  429. if (ret)
  430. return ret;
  431. msm_audio_dma_buf_unmap(dma_buf);
  432. return 0;
  433. }
  434. EXPORT_SYMBOL(msm_audio_ion_free);
  435. /**
  436. * msm_audio_ion_mmap -
  437. * Audio ION memory map
  438. *
  439. * @abuff: audio buf pointer
  440. * @vma: virtual mem area
  441. *
  442. * Returns 0 on success or error on failure
  443. */
  444. int msm_audio_ion_mmap(struct audio_buffer *abuff,
  445. struct vm_area_struct *vma)
  446. {
  447. struct msm_audio_alloc_data *alloc_data = NULL;
  448. struct sg_table *table;
  449. unsigned long addr = vma->vm_start;
  450. unsigned long offset = vma->vm_pgoff * PAGE_SIZE;
  451. struct scatterlist *sg;
  452. unsigned int i;
  453. struct page *page;
  454. int ret = 0;
  455. bool found = false;
  456. struct device *cb_dev = msm_audio_ion_data.cb_dev;
  457. mutex_lock(&(msm_audio_ion_data.list_mutex));
  458. list_for_each_entry(alloc_data, &(msm_audio_ion_data.alloc_list),
  459. list) {
  460. if (alloc_data->dma_buf == abuff->dma_buf) {
  461. found = true;
  462. table = alloc_data->table;
  463. break;
  464. }
  465. }
  466. mutex_unlock(&(msm_audio_ion_data.list_mutex));
  467. if (!found) {
  468. dev_err(cb_dev,
  469. "%s: cannot find allocation, dma_buf %pK",
  470. __func__, abuff->dma_buf);
  471. return -EINVAL;
  472. }
  473. /* uncached */
  474. vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
  475. /* We need to check if a page is associated with this sg list because:
  476. * If the allocation came from a carveout we currently don't have
  477. * pages associated with carved out memory. This might change in the
  478. * future and we can remove this check and the else statement.
  479. */
  480. page = sg_page(table->sgl);
  481. if (page) {
  482. pr_debug("%s: page is NOT null\n", __func__);
  483. for_each_sg(table->sgl, sg, table->nents, i) {
  484. unsigned long remainder = vma->vm_end - addr;
  485. unsigned long len = sg->length;
  486. page = sg_page(sg);
  487. if (offset >= len) {
  488. offset -= len;
  489. continue;
  490. } else if (offset) {
  491. page += offset / PAGE_SIZE;
  492. len -= offset;
  493. offset = 0;
  494. }
  495. len = min(len, remainder);
  496. pr_debug("vma=%pK, addr=%x len=%ld vm_start=%x vm_end=%x vm_page_prot=%lu\n",
  497. vma, (unsigned int)addr, len,
  498. (unsigned int)vma->vm_start,
  499. (unsigned int)vma->vm_end,
  500. (unsigned long)pgprot_val(vma->vm_page_prot));
  501. remap_pfn_range(vma, addr, page_to_pfn(page), len,
  502. vma->vm_page_prot);
  503. addr += len;
  504. if (addr >= vma->vm_end)
  505. return 0;
  506. }
  507. } else {
  508. pr_debug("%s: page is NULL\n", __func__);
  509. ret = -EINVAL;
  510. }
  511. return ret;
  512. }
  513. EXPORT_SYMBOL(msm_audio_ion_mmap);
  514. /**
  515. * msm_audio_ion_cache_operations-
  516. * Cache operations on cached Audio ION buffers
  517. *
  518. * @abuff: audio buf pointer
  519. * @cache_op: cache operation to be performed
  520. *
  521. * Returns 0 on success or error on failure
  522. */
  523. int msm_audio_ion_cache_operations(struct audio_buffer *abuff, int cache_op)
  524. {
  525. unsigned long ionflag = 0;
  526. int rc = 0;
  527. if (!abuff) {
  528. pr_err("%s: Invalid params: %pK\n", __func__, abuff);
  529. return -EINVAL;
  530. }
  531. rc = dma_buf_get_flags(abuff->dma_buf, &ionflag);
  532. if (rc) {
  533. pr_err("%s: dma_buf_get_flags failed: %d\n", __func__, rc);
  534. goto cache_op_failed;
  535. }
  536. /* Has to be CACHED */
  537. if (ionflag & ION_FLAG_CACHED) {
  538. /* MSM_AUDIO_ION_INV_CACHES or MSM_AUDIO_ION_CLEAN_CACHES */
  539. switch (cache_op) {
  540. case MSM_AUDIO_ION_INV_CACHES:
  541. case MSM_AUDIO_ION_CLEAN_CACHES:
  542. dma_buf_begin_cpu_access(abuff->dma_buf,
  543. DMA_BIDIRECTIONAL);
  544. dma_buf_end_cpu_access(abuff->dma_buf,
  545. DMA_BIDIRECTIONAL);
  546. break;
  547. default:
  548. pr_err("%s: Invalid cache operation %d\n",
  549. __func__, cache_op);
  550. }
  551. } else {
  552. pr_err("%s: Cache ops called on uncached buffer: %pK\n",
  553. __func__, abuff->dma_buf);
  554. rc = -EINVAL;
  555. }
  556. cache_op_failed:
  557. return rc;
  558. }
  559. EXPORT_SYMBOL(msm_audio_ion_cache_operations);
  560. /**
  561. * msm_audio_populate_upper_32_bits -
  562. * retrieve upper 32bits of 64bit address
  563. *
  564. * @pa: 64bit physical address
  565. *
  566. */
  567. u32 msm_audio_populate_upper_32_bits(dma_addr_t pa)
  568. {
  569. if (sizeof(dma_addr_t) == sizeof(u32))
  570. return msm_audio_ion_get_smmu_sid_mode32();
  571. else
  572. return upper_32_bits(pa);
  573. }
  574. EXPORT_SYMBOL(msm_audio_populate_upper_32_bits);
  575. static int msm_audio_smmu_init(struct device *dev)
  576. {
  577. struct dma_iommu_mapping *mapping;
  578. int ret;
  579. mapping = arm_iommu_create_mapping(&platform_bus_type,
  580. MSM_AUDIO_ION_VA_START,
  581. MSM_AUDIO_ION_VA_LEN);
  582. if (IS_ERR(mapping))
  583. return PTR_ERR(mapping);
  584. ret = arm_iommu_attach_device(dev, mapping);
  585. if (ret) {
  586. dev_err(dev, "%s: Attach failed, err = %d\n",
  587. __func__, ret);
  588. goto fail_attach;
  589. }
  590. msm_audio_ion_data.mapping = mapping;
  591. INIT_LIST_HEAD(&msm_audio_ion_data.alloc_list);
  592. mutex_init(&(msm_audio_ion_data.list_mutex));
  593. return 0;
  594. fail_attach:
  595. arm_iommu_release_mapping(mapping);
  596. return ret;
  597. }
  598. static const struct of_device_id msm_audio_ion_dt_match[] = {
  599. { .compatible = "qcom,msm-audio-ion" },
  600. { }
  601. };
  602. MODULE_DEVICE_TABLE(of, msm_audio_ion_dt_match);
  603. static int msm_audio_ion_probe(struct platform_device *pdev)
  604. {
  605. int rc = 0;
  606. u64 smmu_sid = 0;
  607. u64 smmu_sid_mask = 0;
  608. const char *msm_audio_ion_dt = "qcom,smmu-enabled";
  609. const char *msm_audio_ion_smmu = "qcom,smmu-version";
  610. const char *msm_audio_ion_smmu_sid_mask = "qcom,smmu-sid-mask";
  611. bool smmu_enabled;
  612. enum apr_subsys_state q6_state;
  613. struct device *dev = &pdev->dev;
  614. struct of_phandle_args iommuspec;
  615. if (dev->of_node == NULL) {
  616. dev_err(dev,
  617. "%s: device tree is not found\n",
  618. __func__);
  619. msm_audio_ion_data.smmu_enabled = 0;
  620. return 0;
  621. }
  622. smmu_enabled = of_property_read_bool(dev->of_node,
  623. msm_audio_ion_dt);
  624. msm_audio_ion_data.smmu_enabled = smmu_enabled;
  625. if (!smmu_enabled) {
  626. dev_dbg(dev, "%s: SMMU is Disabled\n", __func__);
  627. goto exit;
  628. }
  629. q6_state = apr_get_q6_state();
  630. if (q6_state == APR_SUBSYS_DOWN) {
  631. dev_dbg(dev,
  632. "defering %s, adsp_state %d\n",
  633. __func__, q6_state);
  634. return -EPROBE_DEFER;
  635. }
  636. dev_dbg(dev, "%s: adsp is ready\n", __func__);
  637. rc = of_property_read_u32(dev->of_node,
  638. msm_audio_ion_smmu,
  639. &msm_audio_ion_data.smmu_version);
  640. if (rc) {
  641. dev_err(dev,
  642. "%s: qcom,smmu_version missing in DT node\n",
  643. __func__);
  644. return rc;
  645. }
  646. dev_dbg(dev, "%s: SMMU is Enabled. SMMU version is (%d)",
  647. __func__, msm_audio_ion_data.smmu_version);
  648. /* Get SMMU SID information from Devicetree */
  649. rc = of_property_read_u64(dev->of_node,
  650. msm_audio_ion_smmu_sid_mask,
  651. &smmu_sid_mask);
  652. if (rc) {
  653. dev_err(dev,
  654. "%s: qcom,smmu-sid-mask missing in DT node, using default\n",
  655. __func__);
  656. smmu_sid_mask = 0xFFFFFFFFFFFFFFFF;
  657. }
  658. rc = of_parse_phandle_with_args(dev->of_node, "iommus",
  659. "#iommu-cells", 0, &iommuspec);
  660. if (rc)
  661. dev_err(dev, "%s: could not get smmu SID, ret = %d\n",
  662. __func__, rc);
  663. else
  664. smmu_sid = (iommuspec.args[0] & smmu_sid_mask);
  665. msm_audio_ion_data.smmu_sid_bits =
  666. smmu_sid << MSM_AUDIO_SMMU_SID_OFFSET;
  667. if (msm_audio_ion_data.smmu_version == 0x2) {
  668. rc = msm_audio_smmu_init(dev);
  669. } else {
  670. dev_err(dev, "%s: smmu version invalid %d\n",
  671. __func__, msm_audio_ion_data.smmu_version);
  672. rc = -EINVAL;
  673. }
  674. if (rc)
  675. dev_err(dev, "%s: smmu init failed, err = %d\n",
  676. __func__, rc);
  677. exit:
  678. if (!rc)
  679. msm_audio_ion_data.device_status |= MSM_AUDIO_ION_PROBED;
  680. msm_audio_ion_data.cb_dev = dev;
  681. return rc;
  682. }
  683. static int msm_audio_ion_remove(struct platform_device *pdev)
  684. {
  685. struct dma_iommu_mapping *mapping;
  686. struct device *audio_cb_dev;
  687. mapping = msm_audio_ion_data.mapping;
  688. audio_cb_dev = msm_audio_ion_data.cb_dev;
  689. if (audio_cb_dev && mapping) {
  690. arm_iommu_detach_device(audio_cb_dev);
  691. arm_iommu_release_mapping(mapping);
  692. }
  693. msm_audio_ion_data.smmu_enabled = 0;
  694. msm_audio_ion_data.device_status = 0;
  695. return 0;
  696. }
  697. static struct platform_driver msm_audio_ion_driver = {
  698. .driver = {
  699. .name = "msm-audio-ion",
  700. .owner = THIS_MODULE,
  701. .of_match_table = msm_audio_ion_dt_match,
  702. },
  703. .probe = msm_audio_ion_probe,
  704. .remove = msm_audio_ion_remove,
  705. };
  706. int __init msm_audio_ion_init(void)
  707. {
  708. return platform_driver_register(&msm_audio_ion_driver);
  709. }
  710. void msm_audio_ion_exit(void)
  711. {
  712. platform_driver_unregister(&msm_audio_ion_driver);
  713. }
  714. MODULE_DESCRIPTION("MSM Audio ION module");
  715. MODULE_LICENSE("GPL v2");