msm_audio_ion.c 22 KB

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