0037-vc_mem-Add-vc_mem-driver.patch 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991
  1. From f5cce853dbe19f479d61c2d91a009edbea5735fc Mon Sep 17 00:00:00 2001
  2. From: popcornmix <popcornmix@gmail.com>
  3. Date: Wed, 17 Jun 2015 16:07:06 +0100
  4. Subject: [PATCH 037/381] vc_mem: Add vc_mem driver
  5. MIME-Version: 1.0
  6. Content-Type: text/plain; charset=UTF-8
  7. Content-Transfer-Encoding: 8bit
  8. Signed-off-by: popcornmix <popcornmix@gmail.com>
  9. BCM270x: Move vc_mem
  10. Make the vc_mem module available for ARCH_BCM2835 by moving it.
  11. Signed-off-by: Noralf Trønnes <noralf@tronnes.org>
  12. ---
  13. arch/arm/mach-bcm2709/include/mach/vc_mem.h | 35 ---
  14. arch/arm/mach-bcm2709/vc_mem.c | 431 ----------------------------
  15. drivers/char/broadcom/Kconfig | 12 +-
  16. drivers/char/broadcom/Makefile | 1 +
  17. drivers/char/broadcom/vc_mem.c | 422 +++++++++++++++++++++++++++
  18. include/linux/broadcom/vc_mem.h | 35 +++
  19. 6 files changed, 469 insertions(+), 467 deletions(-)
  20. delete mode 100644 arch/arm/mach-bcm2709/include/mach/vc_mem.h
  21. delete mode 100644 arch/arm/mach-bcm2709/vc_mem.c
  22. create mode 100644 drivers/char/broadcom/vc_mem.c
  23. create mode 100644 include/linux/broadcom/vc_mem.h
  24. --- a/arch/arm/mach-bcm2709/include/mach/vc_mem.h
  25. +++ /dev/null
  26. @@ -1,35 +0,0 @@
  27. -/*****************************************************************************
  28. -* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved.
  29. -*
  30. -* Unless you and Broadcom execute a separate written software license
  31. -* agreement governing use of this software, this software is licensed to you
  32. -* under the terms of the GNU General Public License version 2, available at
  33. -* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
  34. -*
  35. -* Notwithstanding the above, under no circumstances may you combine this
  36. -* software in any way with any other Broadcom software provided under a
  37. -* license other than the GPL, without Broadcom's express prior written
  38. -* consent.
  39. -*****************************************************************************/
  40. -
  41. -#if !defined( VC_MEM_H )
  42. -#define VC_MEM_H
  43. -
  44. -#include <linux/ioctl.h>
  45. -
  46. -#define VC_MEM_IOC_MAGIC 'v'
  47. -
  48. -#define VC_MEM_IOC_MEM_PHYS_ADDR _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long )
  49. -#define VC_MEM_IOC_MEM_SIZE _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int )
  50. -#define VC_MEM_IOC_MEM_BASE _IOR( VC_MEM_IOC_MAGIC, 2, unsigned int )
  51. -#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int )
  52. -
  53. -#if defined( __KERNEL__ )
  54. -#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF
  55. -
  56. -extern unsigned long mm_vc_mem_phys_addr;
  57. -extern unsigned int mm_vc_mem_size;
  58. -extern int vc_mem_get_current_size( void );
  59. -#endif
  60. -
  61. -#endif /* VC_MEM_H */
  62. --- a/arch/arm/mach-bcm2709/vc_mem.c
  63. +++ /dev/null
  64. @@ -1,431 +0,0 @@
  65. -/*****************************************************************************
  66. -* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved.
  67. -*
  68. -* Unless you and Broadcom execute a separate written software license
  69. -* agreement governing use of this software, this software is licensed to you
  70. -* under the terms of the GNU General Public License version 2, available at
  71. -* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
  72. -*
  73. -* Notwithstanding the above, under no circumstances may you combine this
  74. -* software in any way with any other Broadcom software provided under a
  75. -* license other than the GPL, without Broadcom's express prior written
  76. -* consent.
  77. -*****************************************************************************/
  78. -
  79. -#include <linux/kernel.h>
  80. -#include <linux/module.h>
  81. -#include <linux/fs.h>
  82. -#include <linux/device.h>
  83. -#include <linux/cdev.h>
  84. -#include <linux/mm.h>
  85. -#include <linux/slab.h>
  86. -#include <linux/debugfs.h>
  87. -#include <asm/uaccess.h>
  88. -#include <linux/dma-mapping.h>
  89. -#include <linux/platform_data/mailbox-bcm2708.h>
  90. -
  91. -#ifdef CONFIG_ARCH_KONA
  92. -#include <chal/chal_ipc.h>
  93. -#elif defined(CONFIG_ARCH_BCM2708) || defined(CONFIG_ARCH_BCM2709)
  94. -#else
  95. -#include <csp/chal_ipc.h>
  96. -#endif
  97. -
  98. -#include "mach/vc_mem.h"
  99. -
  100. -#define DRIVER_NAME "vc-mem"
  101. -
  102. -// Device (/dev) related variables
  103. -static dev_t vc_mem_devnum = 0;
  104. -static struct class *vc_mem_class = NULL;
  105. -static struct cdev vc_mem_cdev;
  106. -static int vc_mem_inited = 0;
  107. -
  108. -#ifdef CONFIG_DEBUG_FS
  109. -static struct dentry *vc_mem_debugfs_entry;
  110. -#endif
  111. -
  112. -/*
  113. - * Videocore memory addresses and size
  114. - *
  115. - * Drivers that wish to know the videocore memory addresses and sizes should
  116. - * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in
  117. - * headers. This allows the other drivers to not be tied down to a a certain
  118. - * address/size at compile time.
  119. - *
  120. - * In the future, the goal is to have the videocore memory virtual address and
  121. - * size be calculated at boot time rather than at compile time. The decision of
  122. - * where the videocore memory resides and its size would be in the hands of the
  123. - * bootloader (and/or kernel). When that happens, the values of these variables
  124. - * would be calculated and assigned in the init function.
  125. - */
  126. -// in the 2835 VC in mapped above ARM, but ARM has full access to VC space
  127. -unsigned long mm_vc_mem_phys_addr = 0x00000000;
  128. -unsigned int mm_vc_mem_size = 0;
  129. -unsigned int mm_vc_mem_base = 0;
  130. -
  131. -EXPORT_SYMBOL(mm_vc_mem_phys_addr);
  132. -EXPORT_SYMBOL(mm_vc_mem_size);
  133. -EXPORT_SYMBOL(mm_vc_mem_base);
  134. -
  135. -static uint phys_addr = 0;
  136. -static uint mem_size = 0;
  137. -static uint mem_base = 0;
  138. -
  139. -
  140. -/****************************************************************************
  141. -*
  142. -* vc_mem_open
  143. -*
  144. -***************************************************************************/
  145. -
  146. -static int
  147. -vc_mem_open(struct inode *inode, struct file *file)
  148. -{
  149. - (void) inode;
  150. - (void) file;
  151. -
  152. - pr_debug("%s: called file = 0x%p\n", __func__, file);
  153. -
  154. - return 0;
  155. -}
  156. -
  157. -/****************************************************************************
  158. -*
  159. -* vc_mem_release
  160. -*
  161. -***************************************************************************/
  162. -
  163. -static int
  164. -vc_mem_release(struct inode *inode, struct file *file)
  165. -{
  166. - (void) inode;
  167. - (void) file;
  168. -
  169. - pr_debug("%s: called file = 0x%p\n", __func__, file);
  170. -
  171. - return 0;
  172. -}
  173. -
  174. -/****************************************************************************
  175. -*
  176. -* vc_mem_get_size
  177. -*
  178. -***************************************************************************/
  179. -
  180. -static void
  181. -vc_mem_get_size(void)
  182. -{
  183. -}
  184. -
  185. -/****************************************************************************
  186. -*
  187. -* vc_mem_get_base
  188. -*
  189. -***************************************************************************/
  190. -
  191. -static void
  192. -vc_mem_get_base(void)
  193. -{
  194. -}
  195. -
  196. -/****************************************************************************
  197. -*
  198. -* vc_mem_get_current_size
  199. -*
  200. -***************************************************************************/
  201. -
  202. -int
  203. -vc_mem_get_current_size(void)
  204. -{
  205. - return mm_vc_mem_size;
  206. -}
  207. -
  208. -EXPORT_SYMBOL_GPL(vc_mem_get_current_size);
  209. -
  210. -/****************************************************************************
  211. -*
  212. -* vc_mem_ioctl
  213. -*
  214. -***************************************************************************/
  215. -
  216. -static long
  217. -vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  218. -{
  219. - int rc = 0;
  220. -
  221. - (void) cmd;
  222. - (void) arg;
  223. -
  224. - pr_debug("%s: called file = 0x%p\n", __func__, file);
  225. -
  226. - switch (cmd) {
  227. - case VC_MEM_IOC_MEM_PHYS_ADDR:
  228. - {
  229. - pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n",
  230. - __func__, (void *) mm_vc_mem_phys_addr);
  231. -
  232. - if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr,
  233. - sizeof (mm_vc_mem_phys_addr)) != 0) {
  234. - rc = -EFAULT;
  235. - }
  236. - break;
  237. - }
  238. - case VC_MEM_IOC_MEM_SIZE:
  239. - {
  240. - // Get the videocore memory size first
  241. - vc_mem_get_size();
  242. -
  243. - pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__,
  244. - mm_vc_mem_size);
  245. -
  246. - if (copy_to_user((void *) arg, &mm_vc_mem_size,
  247. - sizeof (mm_vc_mem_size)) != 0) {
  248. - rc = -EFAULT;
  249. - }
  250. - break;
  251. - }
  252. - case VC_MEM_IOC_MEM_BASE:
  253. - {
  254. - // Get the videocore memory base
  255. - vc_mem_get_base();
  256. -
  257. - pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__,
  258. - mm_vc_mem_base);
  259. -
  260. - if (copy_to_user((void *) arg, &mm_vc_mem_base,
  261. - sizeof (mm_vc_mem_base)) != 0) {
  262. - rc = -EFAULT;
  263. - }
  264. - break;
  265. - }
  266. - case VC_MEM_IOC_MEM_LOAD:
  267. - {
  268. - // Get the videocore memory base
  269. - vc_mem_get_base();
  270. -
  271. - pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __func__,
  272. - mm_vc_mem_base);
  273. -
  274. - if (copy_to_user((void *) arg, &mm_vc_mem_base,
  275. - sizeof (mm_vc_mem_base)) != 0) {
  276. - rc = -EFAULT;
  277. - }
  278. - break;
  279. - }
  280. - default:
  281. - {
  282. - return -ENOTTY;
  283. - }
  284. - }
  285. - pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc);
  286. -
  287. - return rc;
  288. -}
  289. -
  290. -/****************************************************************************
  291. -*
  292. -* vc_mem_mmap
  293. -*
  294. -***************************************************************************/
  295. -
  296. -static int
  297. -vc_mem_mmap(struct file *filp, struct vm_area_struct *vma)
  298. -{
  299. - int rc = 0;
  300. - unsigned long length = vma->vm_end - vma->vm_start;
  301. - unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  302. -
  303. - pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n",
  304. - __func__, (long) vma->vm_start, (long) vma->vm_end,
  305. - (long) vma->vm_pgoff);
  306. -
  307. - if (offset + length > mm_vc_mem_size) {
  308. - pr_err("%s: length %ld is too big\n", __func__, length);
  309. - return -EINVAL;
  310. - }
  311. - // Do not cache the memory map
  312. - vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  313. -
  314. - rc = remap_pfn_range(vma, vma->vm_start,
  315. - (mm_vc_mem_phys_addr >> PAGE_SHIFT) +
  316. - vma->vm_pgoff, length, vma->vm_page_prot);
  317. - if (rc != 0) {
  318. - pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc);
  319. - }
  320. -
  321. - return rc;
  322. -}
  323. -
  324. -/****************************************************************************
  325. -*
  326. -* File Operations for the driver.
  327. -*
  328. -***************************************************************************/
  329. -
  330. -static const struct file_operations vc_mem_fops = {
  331. - .owner = THIS_MODULE,
  332. - .open = vc_mem_open,
  333. - .release = vc_mem_release,
  334. - .unlocked_ioctl = vc_mem_ioctl,
  335. - .mmap = vc_mem_mmap,
  336. -};
  337. -
  338. -#ifdef CONFIG_DEBUG_FS
  339. -static void vc_mem_debugfs_deinit(void)
  340. -{
  341. - debugfs_remove_recursive(vc_mem_debugfs_entry);
  342. - vc_mem_debugfs_entry = NULL;
  343. -}
  344. -
  345. -
  346. -static int vc_mem_debugfs_init(
  347. - struct device *dev)
  348. -{
  349. - vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL);
  350. - if (!vc_mem_debugfs_entry) {
  351. - dev_warn(dev, "could not create debugfs entry\n");
  352. - return -EFAULT;
  353. - }
  354. -
  355. - if (!debugfs_create_x32("vc_mem_phys_addr",
  356. - 0444,
  357. - vc_mem_debugfs_entry,
  358. - (u32 *)&mm_vc_mem_phys_addr)) {
  359. - dev_warn(dev, "%s:could not create vc_mem_phys entry\n",
  360. - __func__);
  361. - goto fail;
  362. - }
  363. -
  364. - if (!debugfs_create_x32("vc_mem_size",
  365. - 0444,
  366. - vc_mem_debugfs_entry,
  367. - (u32 *)&mm_vc_mem_size)) {
  368. - dev_warn(dev, "%s:could not create vc_mem_size entry\n",
  369. - __func__);
  370. - goto fail;
  371. - }
  372. -
  373. - if (!debugfs_create_x32("vc_mem_base",
  374. - 0444,
  375. - vc_mem_debugfs_entry,
  376. - (u32 *)&mm_vc_mem_base)) {
  377. - dev_warn(dev, "%s:could not create vc_mem_base entry\n",
  378. - __func__);
  379. - goto fail;
  380. - }
  381. -
  382. - return 0;
  383. -
  384. -fail:
  385. - vc_mem_debugfs_deinit();
  386. - return -EFAULT;
  387. -}
  388. -
  389. -#endif /* CONFIG_DEBUG_FS */
  390. -
  391. -
  392. -/****************************************************************************
  393. -*
  394. -* vc_mem_init
  395. -*
  396. -***************************************************************************/
  397. -
  398. -static int __init
  399. -vc_mem_init(void)
  400. -{
  401. - int rc = -EFAULT;
  402. - struct device *dev;
  403. -
  404. - pr_debug("%s: called\n", __func__);
  405. -
  406. - mm_vc_mem_phys_addr = phys_addr;
  407. - mm_vc_mem_size = mem_size;
  408. - mm_vc_mem_base = mem_base;
  409. -
  410. - vc_mem_get_size();
  411. -
  412. - pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n",
  413. - mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024));
  414. -
  415. - if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) {
  416. - pr_err("%s: alloc_chrdev_region failed (rc=%d)\n",
  417. - __func__, rc);
  418. - goto out_err;
  419. - }
  420. -
  421. - cdev_init(&vc_mem_cdev, &vc_mem_fops);
  422. - if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) {
  423. - pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc);
  424. - goto out_unregister;
  425. - }
  426. -
  427. - vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME);
  428. - if (IS_ERR(vc_mem_class)) {
  429. - rc = PTR_ERR(vc_mem_class);
  430. - pr_err("%s: class_create failed (rc=%d)\n", __func__, rc);
  431. - goto out_cdev_del;
  432. - }
  433. -
  434. - dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL,
  435. - DRIVER_NAME);
  436. - if (IS_ERR(dev)) {
  437. - rc = PTR_ERR(dev);
  438. - pr_err("%s: device_create failed (rc=%d)\n", __func__, rc);
  439. - goto out_class_destroy;
  440. - }
  441. -
  442. -#ifdef CONFIG_DEBUG_FS
  443. - /* don't fail if the debug entries cannot be created */
  444. - vc_mem_debugfs_init(dev);
  445. -#endif
  446. -
  447. - vc_mem_inited = 1;
  448. - return 0;
  449. -
  450. - device_destroy(vc_mem_class, vc_mem_devnum);
  451. -
  452. - out_class_destroy:
  453. - class_destroy(vc_mem_class);
  454. - vc_mem_class = NULL;
  455. -
  456. - out_cdev_del:
  457. - cdev_del(&vc_mem_cdev);
  458. -
  459. - out_unregister:
  460. - unregister_chrdev_region(vc_mem_devnum, 1);
  461. -
  462. - out_err:
  463. - return -1;
  464. -}
  465. -
  466. -/****************************************************************************
  467. -*
  468. -* vc_mem_exit
  469. -*
  470. -***************************************************************************/
  471. -
  472. -static void __exit
  473. -vc_mem_exit(void)
  474. -{
  475. - pr_debug("%s: called\n", __func__);
  476. -
  477. - if (vc_mem_inited) {
  478. -#if CONFIG_DEBUG_FS
  479. - vc_mem_debugfs_deinit();
  480. -#endif
  481. - device_destroy(vc_mem_class, vc_mem_devnum);
  482. - class_destroy(vc_mem_class);
  483. - cdev_del(&vc_mem_cdev);
  484. - unregister_chrdev_region(vc_mem_devnum, 1);
  485. - }
  486. -}
  487. -
  488. -module_init(vc_mem_init);
  489. -module_exit(vc_mem_exit);
  490. -MODULE_LICENSE("GPL");
  491. -MODULE_AUTHOR("Broadcom Corporation");
  492. -
  493. -module_param(phys_addr, uint, 0644);
  494. -module_param(mem_size, uint, 0644);
  495. -module_param(mem_base, uint, 0644);
  496. --- a/drivers/char/broadcom/Kconfig
  497. +++ b/drivers/char/broadcom/Kconfig
  498. @@ -7,9 +7,19 @@ menuconfig BRCM_CHAR_DRIVERS
  499. help
  500. Broadcom's char drivers
  501. +if BRCM_CHAR_DRIVERS
  502. +
  503. config BCM_VC_CMA
  504. bool "Videocore CMA"
  505. - depends on CMA && BRCM_CHAR_DRIVERS && BCM2708_VCHIQ
  506. + depends on CMA && BCM2708_VCHIQ
  507. default n
  508. help
  509. Helper for videocore CMA access.
  510. +
  511. +config BCM2708_VCMEM
  512. + bool "Videocore Memory"
  513. + default y
  514. + help
  515. + Helper for videocore memory access and total size allocation.
  516. +
  517. +endif
  518. --- a/drivers/char/broadcom/Makefile
  519. +++ b/drivers/char/broadcom/Makefile
  520. @@ -1 +1,2 @@
  521. obj-$(CONFIG_BCM_VC_CMA) += vc_cma/
  522. +obj-$(CONFIG_BCM2708_VCMEM) += vc_mem.o
  523. --- /dev/null
  524. +++ b/drivers/char/broadcom/vc_mem.c
  525. @@ -0,0 +1,422 @@
  526. +/*****************************************************************************
  527. +* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved.
  528. +*
  529. +* Unless you and Broadcom execute a separate written software license
  530. +* agreement governing use of this software, this software is licensed to you
  531. +* under the terms of the GNU General Public License version 2, available at
  532. +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
  533. +*
  534. +* Notwithstanding the above, under no circumstances may you combine this
  535. +* software in any way with any other Broadcom software provided under a
  536. +* license other than the GPL, without Broadcom's express prior written
  537. +* consent.
  538. +*****************************************************************************/
  539. +
  540. +#include <linux/kernel.h>
  541. +#include <linux/module.h>
  542. +#include <linux/fs.h>
  543. +#include <linux/device.h>
  544. +#include <linux/cdev.h>
  545. +#include <linux/mm.h>
  546. +#include <linux/slab.h>
  547. +#include <linux/debugfs.h>
  548. +#include <asm/uaccess.h>
  549. +#include <linux/dma-mapping.h>
  550. +#include <linux/broadcom/vc_mem.h>
  551. +
  552. +#define DRIVER_NAME "vc-mem"
  553. +
  554. +// Device (/dev) related variables
  555. +static dev_t vc_mem_devnum = 0;
  556. +static struct class *vc_mem_class = NULL;
  557. +static struct cdev vc_mem_cdev;
  558. +static int vc_mem_inited = 0;
  559. +
  560. +#ifdef CONFIG_DEBUG_FS
  561. +static struct dentry *vc_mem_debugfs_entry;
  562. +#endif
  563. +
  564. +/*
  565. + * Videocore memory addresses and size
  566. + *
  567. + * Drivers that wish to know the videocore memory addresses and sizes should
  568. + * use these variables instead of the MM_IO_BASE and MM_ADDR_IO defines in
  569. + * headers. This allows the other drivers to not be tied down to a a certain
  570. + * address/size at compile time.
  571. + *
  572. + * In the future, the goal is to have the videocore memory virtual address and
  573. + * size be calculated at boot time rather than at compile time. The decision of
  574. + * where the videocore memory resides and its size would be in the hands of the
  575. + * bootloader (and/or kernel). When that happens, the values of these variables
  576. + * would be calculated and assigned in the init function.
  577. + */
  578. +// in the 2835 VC in mapped above ARM, but ARM has full access to VC space
  579. +unsigned long mm_vc_mem_phys_addr = 0x00000000;
  580. +unsigned int mm_vc_mem_size = 0;
  581. +unsigned int mm_vc_mem_base = 0;
  582. +
  583. +EXPORT_SYMBOL(mm_vc_mem_phys_addr);
  584. +EXPORT_SYMBOL(mm_vc_mem_size);
  585. +EXPORT_SYMBOL(mm_vc_mem_base);
  586. +
  587. +static uint phys_addr = 0;
  588. +static uint mem_size = 0;
  589. +static uint mem_base = 0;
  590. +
  591. +
  592. +/****************************************************************************
  593. +*
  594. +* vc_mem_open
  595. +*
  596. +***************************************************************************/
  597. +
  598. +static int
  599. +vc_mem_open(struct inode *inode, struct file *file)
  600. +{
  601. + (void) inode;
  602. + (void) file;
  603. +
  604. + pr_debug("%s: called file = 0x%p\n", __func__, file);
  605. +
  606. + return 0;
  607. +}
  608. +
  609. +/****************************************************************************
  610. +*
  611. +* vc_mem_release
  612. +*
  613. +***************************************************************************/
  614. +
  615. +static int
  616. +vc_mem_release(struct inode *inode, struct file *file)
  617. +{
  618. + (void) inode;
  619. + (void) file;
  620. +
  621. + pr_debug("%s: called file = 0x%p\n", __func__, file);
  622. +
  623. + return 0;
  624. +}
  625. +
  626. +/****************************************************************************
  627. +*
  628. +* vc_mem_get_size
  629. +*
  630. +***************************************************************************/
  631. +
  632. +static void
  633. +vc_mem_get_size(void)
  634. +{
  635. +}
  636. +
  637. +/****************************************************************************
  638. +*
  639. +* vc_mem_get_base
  640. +*
  641. +***************************************************************************/
  642. +
  643. +static void
  644. +vc_mem_get_base(void)
  645. +{
  646. +}
  647. +
  648. +/****************************************************************************
  649. +*
  650. +* vc_mem_get_current_size
  651. +*
  652. +***************************************************************************/
  653. +
  654. +int
  655. +vc_mem_get_current_size(void)
  656. +{
  657. + return mm_vc_mem_size;
  658. +}
  659. +
  660. +EXPORT_SYMBOL_GPL(vc_mem_get_current_size);
  661. +
  662. +/****************************************************************************
  663. +*
  664. +* vc_mem_ioctl
  665. +*
  666. +***************************************************************************/
  667. +
  668. +static long
  669. +vc_mem_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
  670. +{
  671. + int rc = 0;
  672. +
  673. + (void) cmd;
  674. + (void) arg;
  675. +
  676. + pr_debug("%s: called file = 0x%p\n", __func__, file);
  677. +
  678. + switch (cmd) {
  679. + case VC_MEM_IOC_MEM_PHYS_ADDR:
  680. + {
  681. + pr_debug("%s: VC_MEM_IOC_MEM_PHYS_ADDR=0x%p\n",
  682. + __func__, (void *) mm_vc_mem_phys_addr);
  683. +
  684. + if (copy_to_user((void *) arg, &mm_vc_mem_phys_addr,
  685. + sizeof (mm_vc_mem_phys_addr)) != 0) {
  686. + rc = -EFAULT;
  687. + }
  688. + break;
  689. + }
  690. + case VC_MEM_IOC_MEM_SIZE:
  691. + {
  692. + // Get the videocore memory size first
  693. + vc_mem_get_size();
  694. +
  695. + pr_debug("%s: VC_MEM_IOC_MEM_SIZE=%u\n", __func__,
  696. + mm_vc_mem_size);
  697. +
  698. + if (copy_to_user((void *) arg, &mm_vc_mem_size,
  699. + sizeof (mm_vc_mem_size)) != 0) {
  700. + rc = -EFAULT;
  701. + }
  702. + break;
  703. + }
  704. + case VC_MEM_IOC_MEM_BASE:
  705. + {
  706. + // Get the videocore memory base
  707. + vc_mem_get_base();
  708. +
  709. + pr_debug("%s: VC_MEM_IOC_MEM_BASE=%u\n", __func__,
  710. + mm_vc_mem_base);
  711. +
  712. + if (copy_to_user((void *) arg, &mm_vc_mem_base,
  713. + sizeof (mm_vc_mem_base)) != 0) {
  714. + rc = -EFAULT;
  715. + }
  716. + break;
  717. + }
  718. + case VC_MEM_IOC_MEM_LOAD:
  719. + {
  720. + // Get the videocore memory base
  721. + vc_mem_get_base();
  722. +
  723. + pr_debug("%s: VC_MEM_IOC_MEM_LOAD=%u\n", __func__,
  724. + mm_vc_mem_base);
  725. +
  726. + if (copy_to_user((void *) arg, &mm_vc_mem_base,
  727. + sizeof (mm_vc_mem_base)) != 0) {
  728. + rc = -EFAULT;
  729. + }
  730. + break;
  731. + }
  732. + default:
  733. + {
  734. + return -ENOTTY;
  735. + }
  736. + }
  737. + pr_debug("%s: file = 0x%p returning %d\n", __func__, file, rc);
  738. +
  739. + return rc;
  740. +}
  741. +
  742. +/****************************************************************************
  743. +*
  744. +* vc_mem_mmap
  745. +*
  746. +***************************************************************************/
  747. +
  748. +static int
  749. +vc_mem_mmap(struct file *filp, struct vm_area_struct *vma)
  750. +{
  751. + int rc = 0;
  752. + unsigned long length = vma->vm_end - vma->vm_start;
  753. + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
  754. +
  755. + pr_debug("%s: vm_start = 0x%08lx vm_end = 0x%08lx vm_pgoff = 0x%08lx\n",
  756. + __func__, (long) vma->vm_start, (long) vma->vm_end,
  757. + (long) vma->vm_pgoff);
  758. +
  759. + if (offset + length > mm_vc_mem_size) {
  760. + pr_err("%s: length %ld is too big\n", __func__, length);
  761. + return -EINVAL;
  762. + }
  763. + // Do not cache the memory map
  764. + vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
  765. +
  766. + rc = remap_pfn_range(vma, vma->vm_start,
  767. + (mm_vc_mem_phys_addr >> PAGE_SHIFT) +
  768. + vma->vm_pgoff, length, vma->vm_page_prot);
  769. + if (rc != 0) {
  770. + pr_err("%s: remap_pfn_range failed (rc=%d)\n", __func__, rc);
  771. + }
  772. +
  773. + return rc;
  774. +}
  775. +
  776. +/****************************************************************************
  777. +*
  778. +* File Operations for the driver.
  779. +*
  780. +***************************************************************************/
  781. +
  782. +static const struct file_operations vc_mem_fops = {
  783. + .owner = THIS_MODULE,
  784. + .open = vc_mem_open,
  785. + .release = vc_mem_release,
  786. + .unlocked_ioctl = vc_mem_ioctl,
  787. + .mmap = vc_mem_mmap,
  788. +};
  789. +
  790. +#ifdef CONFIG_DEBUG_FS
  791. +static void vc_mem_debugfs_deinit(void)
  792. +{
  793. + debugfs_remove_recursive(vc_mem_debugfs_entry);
  794. + vc_mem_debugfs_entry = NULL;
  795. +}
  796. +
  797. +
  798. +static int vc_mem_debugfs_init(
  799. + struct device *dev)
  800. +{
  801. + vc_mem_debugfs_entry = debugfs_create_dir(DRIVER_NAME, NULL);
  802. + if (!vc_mem_debugfs_entry) {
  803. + dev_warn(dev, "could not create debugfs entry\n");
  804. + return -EFAULT;
  805. + }
  806. +
  807. + if (!debugfs_create_x32("vc_mem_phys_addr",
  808. + 0444,
  809. + vc_mem_debugfs_entry,
  810. + (u32 *)&mm_vc_mem_phys_addr)) {
  811. + dev_warn(dev, "%s:could not create vc_mem_phys entry\n",
  812. + __func__);
  813. + goto fail;
  814. + }
  815. +
  816. + if (!debugfs_create_x32("vc_mem_size",
  817. + 0444,
  818. + vc_mem_debugfs_entry,
  819. + (u32 *)&mm_vc_mem_size)) {
  820. + dev_warn(dev, "%s:could not create vc_mem_size entry\n",
  821. + __func__);
  822. + goto fail;
  823. + }
  824. +
  825. + if (!debugfs_create_x32("vc_mem_base",
  826. + 0444,
  827. + vc_mem_debugfs_entry,
  828. + (u32 *)&mm_vc_mem_base)) {
  829. + dev_warn(dev, "%s:could not create vc_mem_base entry\n",
  830. + __func__);
  831. + goto fail;
  832. + }
  833. +
  834. + return 0;
  835. +
  836. +fail:
  837. + vc_mem_debugfs_deinit();
  838. + return -EFAULT;
  839. +}
  840. +
  841. +#endif /* CONFIG_DEBUG_FS */
  842. +
  843. +
  844. +/****************************************************************************
  845. +*
  846. +* vc_mem_init
  847. +*
  848. +***************************************************************************/
  849. +
  850. +static int __init
  851. +vc_mem_init(void)
  852. +{
  853. + int rc = -EFAULT;
  854. + struct device *dev;
  855. +
  856. + pr_debug("%s: called\n", __func__);
  857. +
  858. + mm_vc_mem_phys_addr = phys_addr;
  859. + mm_vc_mem_size = mem_size;
  860. + mm_vc_mem_base = mem_base;
  861. +
  862. + vc_mem_get_size();
  863. +
  864. + pr_info("vc-mem: phys_addr:0x%08lx mem_base=0x%08x mem_size:0x%08x(%u MiB)\n",
  865. + mm_vc_mem_phys_addr, mm_vc_mem_base, mm_vc_mem_size, mm_vc_mem_size / (1024 * 1024));
  866. +
  867. + if ((rc = alloc_chrdev_region(&vc_mem_devnum, 0, 1, DRIVER_NAME)) < 0) {
  868. + pr_err("%s: alloc_chrdev_region failed (rc=%d)\n",
  869. + __func__, rc);
  870. + goto out_err;
  871. + }
  872. +
  873. + cdev_init(&vc_mem_cdev, &vc_mem_fops);
  874. + if ((rc = cdev_add(&vc_mem_cdev, vc_mem_devnum, 1)) != 0) {
  875. + pr_err("%s: cdev_add failed (rc=%d)\n", __func__, rc);
  876. + goto out_unregister;
  877. + }
  878. +
  879. + vc_mem_class = class_create(THIS_MODULE, DRIVER_NAME);
  880. + if (IS_ERR(vc_mem_class)) {
  881. + rc = PTR_ERR(vc_mem_class);
  882. + pr_err("%s: class_create failed (rc=%d)\n", __func__, rc);
  883. + goto out_cdev_del;
  884. + }
  885. +
  886. + dev = device_create(vc_mem_class, NULL, vc_mem_devnum, NULL,
  887. + DRIVER_NAME);
  888. + if (IS_ERR(dev)) {
  889. + rc = PTR_ERR(dev);
  890. + pr_err("%s: device_create failed (rc=%d)\n", __func__, rc);
  891. + goto out_class_destroy;
  892. + }
  893. +
  894. +#ifdef CONFIG_DEBUG_FS
  895. + /* don't fail if the debug entries cannot be created */
  896. + vc_mem_debugfs_init(dev);
  897. +#endif
  898. +
  899. + vc_mem_inited = 1;
  900. + return 0;
  901. +
  902. + device_destroy(vc_mem_class, vc_mem_devnum);
  903. +
  904. + out_class_destroy:
  905. + class_destroy(vc_mem_class);
  906. + vc_mem_class = NULL;
  907. +
  908. + out_cdev_del:
  909. + cdev_del(&vc_mem_cdev);
  910. +
  911. + out_unregister:
  912. + unregister_chrdev_region(vc_mem_devnum, 1);
  913. +
  914. + out_err:
  915. + return -1;
  916. +}
  917. +
  918. +/****************************************************************************
  919. +*
  920. +* vc_mem_exit
  921. +*
  922. +***************************************************************************/
  923. +
  924. +static void __exit
  925. +vc_mem_exit(void)
  926. +{
  927. + pr_debug("%s: called\n", __func__);
  928. +
  929. + if (vc_mem_inited) {
  930. +#if CONFIG_DEBUG_FS
  931. + vc_mem_debugfs_deinit();
  932. +#endif
  933. + device_destroy(vc_mem_class, vc_mem_devnum);
  934. + class_destroy(vc_mem_class);
  935. + cdev_del(&vc_mem_cdev);
  936. + unregister_chrdev_region(vc_mem_devnum, 1);
  937. + }
  938. +}
  939. +
  940. +module_init(vc_mem_init);
  941. +module_exit(vc_mem_exit);
  942. +MODULE_LICENSE("GPL");
  943. +MODULE_AUTHOR("Broadcom Corporation");
  944. +
  945. +module_param(phys_addr, uint, 0644);
  946. +module_param(mem_size, uint, 0644);
  947. +module_param(mem_base, uint, 0644);
  948. --- /dev/null
  949. +++ b/include/linux/broadcom/vc_mem.h
  950. @@ -0,0 +1,35 @@
  951. +/*****************************************************************************
  952. +* Copyright 2010 - 2011 Broadcom Corporation. All rights reserved.
  953. +*
  954. +* Unless you and Broadcom execute a separate written software license
  955. +* agreement governing use of this software, this software is licensed to you
  956. +* under the terms of the GNU General Public License version 2, available at
  957. +* http://www.broadcom.com/licenses/GPLv2.php (the "GPL").
  958. +*
  959. +* Notwithstanding the above, under no circumstances may you combine this
  960. +* software in any way with any other Broadcom software provided under a
  961. +* license other than the GPL, without Broadcom's express prior written
  962. +* consent.
  963. +*****************************************************************************/
  964. +
  965. +#ifndef _VC_MEM_H
  966. +#define _VC_MEM_H
  967. +
  968. +#include <linux/ioctl.h>
  969. +
  970. +#define VC_MEM_IOC_MAGIC 'v'
  971. +
  972. +#define VC_MEM_IOC_MEM_PHYS_ADDR _IOR( VC_MEM_IOC_MAGIC, 0, unsigned long )
  973. +#define VC_MEM_IOC_MEM_SIZE _IOR( VC_MEM_IOC_MAGIC, 1, unsigned int )
  974. +#define VC_MEM_IOC_MEM_BASE _IOR( VC_MEM_IOC_MAGIC, 2, unsigned int )
  975. +#define VC_MEM_IOC_MEM_LOAD _IOR( VC_MEM_IOC_MAGIC, 3, unsigned int )
  976. +
  977. +#if defined( __KERNEL__ )
  978. +#define VC_MEM_TO_ARM_ADDR_MASK 0x3FFFFFFF
  979. +
  980. +extern unsigned long mm_vc_mem_phys_addr;
  981. +extern unsigned int mm_vc_mem_size;
  982. +extern int vc_mem_get_current_size( void );
  983. +#endif
  984. +
  985. +#endif /* _VC_MEM_H */