msm_audio_ion.c 19 KB

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