jpu.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039
  1. //--=========================================================================--
  2. // This file is linux device driver for JPU.
  3. //-----------------------------------------------------------------------------
  4. //
  5. // This confidential and proprietary software may be used only
  6. // as authorized by a licensing agreement from Chips&Media Inc.
  7. // In the event of publication, the following notice is applicable:
  8. //
  9. // (C) COPYRIGHT 2006 - 2016 CHIPS&MEDIA INC.
  10. // ALL RIGHTS RESERVED
  11. //
  12. // The entire notice above must be reproduced on all authorized
  13. // copies.
  14. //
  15. //--=========================================================================-
  16. #include <linux/kernel.h>
  17. #include <linux/device.h>
  18. #include <linux/mm.h>
  19. #include <linux/interrupt.h>
  20. #include <linux/ioport.h>
  21. #include <linux/module.h>
  22. #include <linux/platform_device.h>
  23. #include <linux/dma-mapping.h>
  24. #include <linux/of.h>
  25. #include <linux/of_address.h>
  26. #include <linux/wait.h>
  27. #include <linux/list.h>
  28. #include <linux/clk.h>
  29. #include <linux/delay.h>
  30. #include <linux/uaccess.h>
  31. #include <linux/cdev.h>
  32. #include <linux/slab.h>
  33. #include <linux/sched.h>
  34. #include <linux/sched/signal.h>
  35. #include <linux/version.h>
  36. #include <soc/starfive/vic7100.h>
  37. #include "../../../jpuapi/jpuconfig.h"
  38. #include "jpu.h"
  39. //#define ENABLE_DEBUG_MSG
  40. #ifdef ENABLE_DEBUG_MSG
  41. #define DPRINTK(args...) printk(KERN_INFO args);
  42. #else
  43. #define DPRINTK(args...)
  44. #endif
  45. /* definitions to be changed as customer configuration */
  46. /* if you want to have clock gating scheme frame by frame */
  47. #define JPU_SUPPORT_CLOCK_CONTROL
  48. #define JPU_SUPPORT_ISR
  49. //#define JPU_IRQ_CONTROL
  50. /* if the platform driver knows the name of this driver */
  51. /* JPU_PLATFORM_DEVICE_NAME */
  52. #define JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  53. /* if this driver knows the dedicated video memory address */
  54. //#define JPU_SUPPORT_RESERVED_VIDEO_MEMORY //if this driver knows the dedicated video memory address
  55. #define JPU_PLATFORM_DEVICE_NAME "cnm_jpu"
  56. #define JPU_CLK_NAME "jpege"
  57. #define JPU_DEV_NAME "jpu"
  58. #define JPU_REG_BASE_ADDR 0x11900000
  59. #define JPU_REG_SIZE 0x300
  60. #ifdef JPU_SUPPORT_ISR
  61. #define JPU_IRQ_NUM 24
  62. /* if the driver want to disable and enable IRQ whenever interrupt asserted. */
  63. /*#define JPU_IRQ_CONTROL*/
  64. #endif
  65. #ifndef VM_RESERVED /*for kernel up to 3.7.0 version*/
  66. #define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
  67. #endif
  68. struct device *jpu_dev;
  69. typedef struct jpu_drv_context_t {
  70. struct fasync_struct *async_queue;
  71. u32 open_count; /*!<< device reference count. Not instance count */
  72. u32 interrupt_reason[MAX_NUM_INSTANCE];
  73. } jpu_drv_context_t;
  74. /* To track the allocated memory buffer */
  75. typedef struct jpudrv_buffer_pool_t {
  76. struct list_head list;
  77. struct jpudrv_buffer_t jb;
  78. struct file* filp;
  79. } jpudrv_buffer_pool_t;
  80. /* To track the instance index and buffer in instance pool */
  81. typedef struct jpudrv_instance_list_t {
  82. struct list_head list;
  83. unsigned long inst_idx;
  84. struct file* filp;
  85. } jpudrv_instance_list_t;
  86. typedef struct jpudrv_instance_pool_t {
  87. unsigned char codecInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE];
  88. } jpudrv_instance_pool_t;
  89. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  90. #include "jmm.h"
  91. static jpu_mm_t s_jmem;
  92. static jpudrv_buffer_t s_video_memory = {0};
  93. #endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
  94. static int jpu_hw_reset(void);
  95. static void jpu_clk_disable(struct clk *clk);
  96. static int jpu_clk_enable(struct clk *clk);
  97. static struct clk *jpu_clk_get(struct device *dev);
  98. static void jpu_clk_put(struct clk *clk);
  99. // end customer definition
  100. static jpudrv_buffer_t s_instance_pool = {0};
  101. static jpu_drv_context_t s_jpu_drv_context;
  102. static int s_jpu_major;
  103. static struct cdev s_jpu_cdev;
  104. static struct clk *s_jpu_clk;
  105. static int s_jpu_open_ref_count;
  106. #ifdef JPU_SUPPORT_ISR
  107. static int s_jpu_irq = JPU_IRQ_NUM;
  108. #endif
  109. static jpudrv_buffer_t s_jpu_register = {0};
  110. static int s_interrupt_flag[MAX_NUM_INSTANCE];
  111. static wait_queue_head_t s_interrupt_wait_q[MAX_NUM_INSTANCE];
  112. static spinlock_t s_jpu_lock = __SPIN_LOCK_UNLOCKED(s_jpu_lock);
  113. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
  114. static DECLARE_MUTEX(s_jpu_sem);
  115. #else
  116. static DEFINE_SEMAPHORE(s_jpu_sem);
  117. #endif
  118. static struct list_head s_jbp_head = LIST_HEAD_INIT(s_jbp_head);
  119. static struct list_head s_inst_list_head = LIST_HEAD_INIT(s_inst_list_head);
  120. #ifdef CONFIG_PM
  121. /* implement to power management functions */
  122. #endif
  123. #define NPT_BASE 0x0000
  124. #define NPT_REG_SIZE 0x300
  125. #define MJPEG_PIC_STATUS_REG(_inst_no) (NPT_BASE + (_inst_no*NPT_REG_SIZE) + 0x004)
  126. #define ReadJpuRegister(addr) *(volatile unsigned int *)(s_jpu_register.virt_addr + addr)
  127. #define WriteJpuRegister(addr, val) *(volatile unsigned int *)(s_jpu_register.virt_addr + addr) = (unsigned int)val
  128. #define WriteJpu(addr, val) *(volatile unsigned int *)(addr) = (unsigned int)val;
  129. static int jpu_alloc_dma_buffer(jpudrv_buffer_t *jb)
  130. {
  131. if (!jb)
  132. return -1;
  133. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  134. jb->phys_addr = (unsigned long long)jmem_alloc(&s_jmem, jb->size, 0);
  135. if ((unsigned long)jb->phys_addr == (unsigned long)-1) {
  136. printk(KERN_ERR "[JPUDRV] Physical memory allocation error size=%d\n", jb->size);
  137. return -1;
  138. }
  139. jb->base = (unsigned long)(s_video_memory.base + (jb->phys_addr - s_video_memory.phys_addr));
  140. #else
  141. jb->base = (unsigned long)dma_alloc_coherent(jpu_dev, PAGE_ALIGN(jb->size), (dma_addr_t *) (&jb->phys_addr), GFP_DMA | GFP_KERNEL);
  142. if ((void *)(jb->base) == NULL) {
  143. printk(KERN_ERR "[JPUDRV] Physical memory allocation error size=%d\n", jb->size);
  144. return -1;
  145. }
  146. starfive_flush_dcache(jb->phys_addr,PAGE_ALIGN(jb->size));
  147. #endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
  148. return 0;
  149. }
  150. static void jpu_free_dma_buffer(jpudrv_buffer_t *jb)
  151. {
  152. if (!jb) {
  153. return;
  154. }
  155. if (jb->base)
  156. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  157. jmem_free(&s_jmem, jb->phys_addr, 0);
  158. #else
  159. dma_free_coherent(jpu_dev, PAGE_ALIGN(jb->size), (void *)jb->base, jb->phys_addr);
  160. #endif /* JPUR_SUPPORT_RESERVED_VIDEO_MEMORY */
  161. }
  162. static int jpu_free_instances(struct file *filp)
  163. {
  164. jpudrv_instance_list_t *vil, *n;
  165. jpudrv_instance_pool_t *vip;
  166. void *vip_base;
  167. int instance_pool_size_per_core;
  168. void *jdi_mutexes_base;
  169. const int PTHREAD_MUTEX_T_DESTROY_VALUE = 0xdead10cc;
  170. DPRINTK("[JPUDRV] jpu_free_instances\n");
  171. instance_pool_size_per_core = (s_instance_pool.size/MAX_NUM_JPU_CORE); /* s_instance_pool.size assigned to the size of all core once call JDI_IOCTL_GET_INSTANCE_POOL by user. */
  172. list_for_each_entry_safe(vil, n, &s_inst_list_head, list)
  173. {
  174. if (vil->filp == filp) {
  175. vip_base = (void *)(s_instance_pool.base + instance_pool_size_per_core);
  176. DPRINTK("[JPUDRV] jpu_free_instances detect instance crash instIdx=%d, vip_base=%p, instance_pool_size_per_core=%d\n", (int)vil->inst_idx, vip_base, (int)instance_pool_size_per_core);
  177. vip = (jpudrv_instance_pool_t *)vip_base;
  178. if (vip) {
  179. memset(&vip->codecInstPool[vil->inst_idx], 0x00, 4); /* only first 4 byte is key point(inUse of CodecInst in jpuapi) to free the corresponding instance. */
  180. #define PTHREAD_MUTEX_T_HANDLE_SIZE 4
  181. jdi_mutexes_base = (vip_base + (instance_pool_size_per_core - PTHREAD_MUTEX_T_HANDLE_SIZE*4));
  182. DPRINTK("[JPUDRV] jpu_free_instances : force to destroy jdi_mutexes_base=%p in userspace \n", jdi_mutexes_base);
  183. if (jdi_mutexes_base) {
  184. int i;
  185. for (i = 0; i < 4; i++) {
  186. memcpy(jdi_mutexes_base, &PTHREAD_MUTEX_T_DESTROY_VALUE, PTHREAD_MUTEX_T_HANDLE_SIZE);
  187. jdi_mutexes_base += PTHREAD_MUTEX_T_HANDLE_SIZE;
  188. }
  189. }
  190. }
  191. s_jpu_open_ref_count--;
  192. list_del(&vil->list);
  193. kfree(vil);
  194. }
  195. }
  196. return 1;
  197. }
  198. static int jpu_free_buffers(struct file *filp)
  199. {
  200. jpudrv_buffer_pool_t *pool, *n;
  201. jpudrv_buffer_t jb;
  202. DPRINTK("[JPUDRV] jpu_free_buffers\n");
  203. list_for_each_entry_safe(pool, n, &s_jbp_head, list)
  204. {
  205. if (pool->filp == filp) {
  206. jb = pool->jb;
  207. if (jb.base) {
  208. jpu_free_dma_buffer(&jb);
  209. list_del(&pool->list);
  210. kfree(pool);
  211. }
  212. }
  213. }
  214. return 0;
  215. }
  216. static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
  217. {
  218. jpu_drv_context_t* dev = (jpu_drv_context_t *)dev_id;
  219. int i;
  220. u32 flag;
  221. DPRINTK("[JPUDRV][+]%s\n", __func__);
  222. #ifdef JPU_IRQ_CONTROL
  223. disable_irq_nosync(s_jpu_irq);
  224. #endif
  225. for (i=0; i<MAX_NUM_INSTANCE; i++) {
  226. flag = ReadJpuRegister(MJPEG_PIC_STATUS_REG(i));
  227. if (flag != 0) {
  228. break;
  229. }
  230. }
  231. dev->interrupt_reason[i] = flag;
  232. s_interrupt_flag[i] = 1;
  233. DPRINTK("[JPUDRV][%d] INTERRUPT FLAG: %08x, %08x\n", i, dev->interrupt_reason[i], MJPEG_PIC_STATUS_REG(i));
  234. if (dev->async_queue)
  235. kill_fasync(&dev->async_queue, SIGIO, POLL_IN); // notify the interrupt to userspace
  236. #ifndef JPU_IRQ_CONTROL
  237. WriteJpuRegister(MJPEG_PIC_STATUS_REG(i),flag); //clear interrut
  238. #endif
  239. wake_up_interruptible(&s_interrupt_wait_q[i]);
  240. DPRINTK("[JPUDRV][-]%s\n", __func__);
  241. return IRQ_HANDLED;
  242. }
  243. static int jpu_open(struct inode *inode, struct file *filp)
  244. {
  245. DPRINTK("[JPUDRV][+] %s\n", __func__);
  246. spin_lock(&s_jpu_lock);
  247. s_jpu_drv_context.open_count++;
  248. filp->private_data = (void *)(&s_jpu_drv_context);
  249. spin_unlock(&s_jpu_lock);
  250. DPRINTK("[JPUDRV][-] %s\n", __func__);
  251. return 0;
  252. }
  253. static long jpu_ioctl(struct file *filp, u_int cmd, u_long arg)
  254. {
  255. int ret = 0;
  256. switch (cmd)
  257. {
  258. case JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY:
  259. {
  260. jpudrv_buffer_pool_t *jbp;
  261. DPRINTK("[JPUDRV][+]JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
  262. if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
  263. jbp = kzalloc(sizeof(jpudrv_buffer_pool_t), GFP_KERNEL);
  264. if (!jbp) {
  265. up(&s_jpu_sem);
  266. return -ENOMEM;
  267. }
  268. ret = copy_from_user(&(jbp->jb), (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
  269. if (ret)
  270. {
  271. kfree(jbp);
  272. up(&s_jpu_sem);
  273. return -EFAULT;
  274. }
  275. ret = jpu_alloc_dma_buffer(&(jbp->jb));
  276. if (ret == -1)
  277. {
  278. ret = -ENOMEM;
  279. kfree(jbp);
  280. up(&s_jpu_sem);
  281. break;
  282. }
  283. ret = copy_to_user((void __user *)arg, &(jbp->jb), sizeof(jpudrv_buffer_t));
  284. if (ret)
  285. {
  286. kfree(jbp);
  287. ret = -EFAULT;
  288. up(&s_jpu_sem);
  289. break;
  290. }
  291. jbp->filp = filp;
  292. spin_lock(&s_jpu_lock);
  293. list_add(&jbp->list, &s_jbp_head);
  294. spin_unlock(&s_jpu_lock);
  295. up(&s_jpu_sem);
  296. }
  297. DPRINTK("[JPUDRV][-]JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
  298. }
  299. break;
  300. case JDI_IOCTL_FREE_PHYSICALMEMORY:
  301. {
  302. jpudrv_buffer_pool_t *jbp, *n;
  303. jpudrv_buffer_t jb;
  304. DPRINTK("[JPUDRV][+]VDI_IOCTL_FREE_PHYSICALMEMORY\n");
  305. if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
  306. ret = copy_from_user(&jb, (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
  307. if (ret) {
  308. up(&s_jpu_sem);
  309. return -EACCES;
  310. }
  311. if (jb.base)
  312. jpu_free_dma_buffer(&jb);
  313. spin_lock(&s_jpu_lock);
  314. list_for_each_entry_safe(jbp, n, &s_jbp_head, list) {
  315. if (jbp->jb.base == jb.base) {
  316. list_del(&jbp->list);
  317. kfree(jbp);
  318. break;
  319. }
  320. }
  321. spin_unlock(&s_jpu_lock);
  322. up(&s_jpu_sem);
  323. }
  324. DPRINTK("[JPUDRV][-]VDI_IOCTL_FREE_PHYSICALMEMORY\n");
  325. }
  326. break;
  327. case JDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO:
  328. {
  329. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  330. if (s_video_memory.base != 0) {
  331. ret = copy_to_user((void __user *)arg, &s_video_memory, sizeof(jpudrv_buffer_t));
  332. if (ret != 0)
  333. ret = -EFAULT;
  334. } else {
  335. ret = -EFAULT;
  336. }
  337. #endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
  338. }
  339. break;
  340. case JDI_IOCTL_WAIT_INTERRUPT:
  341. {
  342. jpudrv_intr_info_t info;
  343. struct jpu_drv_context_t *dev = (struct jpu_drv_context_t *)filp->private_data;
  344. u32 instance_no;
  345. DPRINTK("[JPUDRV][+]JDI_IOCTL_WAIT_INTERRUPT\n");
  346. ret = copy_from_user(&info, (jpudrv_intr_info_t *)arg, sizeof(jpudrv_intr_info_t));
  347. if (ret != 0)
  348. return -EFAULT;
  349. instance_no = info.inst_idx;
  350. DPRINTK("[JPUDRV] INSTANCE NO: %d\n", instance_no);
  351. ret = wait_event_interruptible_timeout(s_interrupt_wait_q[instance_no], s_interrupt_flag[instance_no] != 0, msecs_to_jiffies(info.timeout));
  352. if (!ret) {
  353. DPRINTK("[JPUDRV] INSTANCE NO: %d ETIME\n", instance_no);
  354. ret = -ETIME;
  355. break;
  356. }
  357. if (signal_pending(current)) {
  358. ret = -ERESTARTSYS;
  359. DPRINTK("[JPUDRV] INSTANCE NO: %d ERESTARTSYS\n", instance_no);
  360. break;
  361. }
  362. DPRINTK("[JPUDRV] INST(%d) s_interrupt_flag(%d), reason(0x%08x)\n", instance_no, s_interrupt_flag[instance_no], dev->interrupt_reason[instance_no]);
  363. info.intr_reason = dev->interrupt_reason[instance_no];
  364. s_interrupt_flag[instance_no] = 0;
  365. dev->interrupt_reason[instance_no] = 0;
  366. ret = copy_to_user((void __user *)arg, &info, sizeof(jpudrv_intr_info_t));
  367. #ifdef JPU_IRQ_CONTROL
  368. enable_irq(s_jpu_irq);
  369. #endif
  370. DPRINTK("[VPUDRV][-]VDI_IOCTL_WAIT_INTERRUPT\n");
  371. if (ret != 0)
  372. return -EFAULT;
  373. }
  374. break;
  375. case JDI_IOCTL_SET_CLOCK_GATE:
  376. {
  377. u32 clkgate;
  378. if (get_user(clkgate, (u32 __user *) arg))
  379. return -EFAULT;
  380. #ifdef JPU_SUPPORT_CLOCK_CONTROL
  381. if (clkgate)
  382. jpu_clk_enable(s_jpu_clk);
  383. else
  384. jpu_clk_disable(s_jpu_clk);
  385. #endif /* JPU_SUPPORT_CLOCK_CONTROL */
  386. }
  387. break;
  388. case JDI_IOCTL_GET_INSTANCE_POOL:
  389. DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_INSTANCE_POOL\n");
  390. if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
  391. if (s_instance_pool.base != 0) {
  392. ret = copy_to_user((void __user *)arg, &s_instance_pool, sizeof(jpudrv_buffer_t));
  393. } else {
  394. ret = copy_from_user(&s_instance_pool, (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
  395. if (ret == 0) {
  396. s_instance_pool.size = PAGE_ALIGN(s_instance_pool.size);
  397. s_instance_pool.base = (unsigned long)vmalloc(s_instance_pool.size);
  398. s_instance_pool.phys_addr = s_instance_pool.base;
  399. if (s_instance_pool.base != 0) {
  400. memset((void *)s_instance_pool.base, 0x0, s_instance_pool.size); /*clearing memory*/
  401. ret = copy_to_user((void __user *)arg, &s_instance_pool, sizeof(jpudrv_buffer_t));
  402. if (ret == 0) {
  403. /* success to get memory for instance pool */
  404. up(&s_jpu_sem);
  405. break;
  406. }
  407. }
  408. ret = -EFAULT;
  409. }
  410. }
  411. up(&s_jpu_sem);
  412. }
  413. DPRINTK("[JPUDRV][-]JDI_IOCTL_GET_INSTANCE_POOL: %s base: %lx, size: %d\n",
  414. (ret==0 ? "OK" : "NG"), s_instance_pool.base, s_instance_pool.size);
  415. break;
  416. case JDI_IOCTL_OPEN_INSTANCE:
  417. {
  418. jpudrv_inst_info_t inst_info;
  419. if (copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t)))
  420. return -EFAULT;
  421. spin_lock(&s_jpu_lock);
  422. s_jpu_open_ref_count++; /* flag just for that jpu is in opened or closed */
  423. inst_info.inst_open_count = s_jpu_open_ref_count;
  424. spin_unlock(&s_jpu_lock);
  425. if (copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t))) {
  426. return -EFAULT;
  427. }
  428. DPRINTK("[JPUDRV] JDI_IOCTL_OPEN_INSTANCE inst_idx=%d, s_jpu_open_ref_count=%d, inst_open_count=%d\n",
  429. (int)inst_info.inst_idx, s_jpu_open_ref_count, inst_info.inst_open_count);
  430. }
  431. break;
  432. case JDI_IOCTL_CLOSE_INSTANCE:
  433. {
  434. jpudrv_inst_info_t inst_info;
  435. DPRINTK("[JPUDRV][+]JDI_IOCTL_CLOSE_INSTANCE\n");
  436. if (copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t)))
  437. return -EFAULT;
  438. spin_lock(&s_jpu_lock);
  439. s_jpu_open_ref_count--; /* flag just for that jpu is in opened or closed */
  440. inst_info.inst_open_count = s_jpu_open_ref_count;
  441. spin_unlock(&s_jpu_lock);
  442. if (copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t)))
  443. return -EFAULT;
  444. DPRINTK("[JPUDRV] JDI_IOCTL_CLOSE_INSTANCE inst_idx=%d, s_jpu_open_ref_count=%d, inst_open_count=%d\n",
  445. (int)inst_info.inst_idx, s_jpu_open_ref_count, inst_info.inst_open_count);
  446. }
  447. break;
  448. case JDI_IOCTL_GET_INSTANCE_NUM:
  449. {
  450. jpudrv_inst_info_t inst_info;
  451. DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_INSTANCE_NUM\n");
  452. ret = copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t));
  453. if (ret != 0)
  454. break;
  455. spin_lock(&s_jpu_lock);
  456. inst_info.inst_open_count = s_jpu_open_ref_count;
  457. spin_unlock(&s_jpu_lock);
  458. ret = copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t));
  459. DPRINTK("[JPUDRV] JDI_IOCTL_GET_INSTANCE_NUM inst_idx=%d, open_count=%d\n", (int)inst_info.inst_idx, inst_info.inst_open_count);
  460. }
  461. break;
  462. case JDI_IOCTL_RESET:
  463. jpu_hw_reset();
  464. break;
  465. case JDI_IOCTL_GET_REGISTER_INFO:
  466. DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_REGISTER_INFO\n");
  467. ret = copy_to_user((void __user *)arg, &s_jpu_register, sizeof(jpudrv_buffer_t));
  468. if (ret != 0)
  469. ret = -EFAULT;
  470. DPRINTK("[JPUDRV][-]JDI_IOCTL_GET_REGISTER_INFO s_jpu_register.phys_addr=0x%lx, s_jpu_register.virt_addr=0x%lx, s_jpu_register.size=%d\n",
  471. s_jpu_register.phys_addr , s_jpu_register.virt_addr, s_jpu_register.size);
  472. break;
  473. case JDI_IOCTL_FLUSH_DCACHE:
  474. {
  475. jpudrv_flush_cache_t cache_info;
  476. //DPRINTK("[JPUDRV][+]JDI_IOCTL_FLUSH_DCACHE\n");
  477. ret = copy_from_user(&cache_info, (jpudrv_flush_cache_t *)arg, sizeof(jpudrv_flush_cache_t));
  478. if (ret != 0)
  479. ret = -EFAULT;
  480. if(cache_info.flag)
  481. starfive_flush_dcache(cache_info.start,cache_info.size);
  482. //DPRINTK("[JPUDRV][-]JDI_IOCTL_FLUSH_DCACHE\n");
  483. break;
  484. }
  485. default:
  486. {
  487. printk(KERN_ERR "No such IOCTL, cmd is %d\n", cmd);
  488. }
  489. break;
  490. }
  491. return ret;
  492. }
  493. static ssize_t jpu_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
  494. {
  495. return -1;
  496. }
  497. static ssize_t jpu_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
  498. {
  499. /* DPRINTK("[VPUDRV] vpu_write len=%d\n", (int)len); */
  500. if (!buf) {
  501. printk(KERN_ERR "[VPUDRV] vpu_write buf = NULL error \n");
  502. return -EFAULT;
  503. }
  504. return -1;
  505. }
  506. static int jpu_release(struct inode *inode, struct file *filp)
  507. {
  508. int ret = 0;
  509. u32 open_count;
  510. DPRINTK("[JPUDRV][+] jpu_release\n");
  511. if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
  512. /* found and free the not handled buffer by user applications */
  513. jpu_free_buffers(filp);
  514. /* found and free the not closed instance by user applications */
  515. jpu_free_instances(filp);
  516. DPRINTK("[JPUDRV] open_count: %d\n", s_jpu_drv_context.open_count);
  517. spin_lock(&s_jpu_lock);
  518. s_jpu_drv_context.open_count--;
  519. open_count = s_jpu_drv_context.open_count;
  520. spin_unlock(&s_jpu_lock);
  521. if (open_count == 0) {
  522. if (s_instance_pool.base) {
  523. DPRINTK("[JPUDRV] free instance pool\n");
  524. vfree((const void *)s_instance_pool.base);
  525. s_instance_pool.base = 0;
  526. }
  527. }
  528. }
  529. up(&s_jpu_sem);
  530. DPRINTK("[JPUDRV][-] jpu_release\n");
  531. return 0;
  532. }
  533. static int jpu_fasync(int fd, struct file *filp, int mode)
  534. {
  535. struct jpu_drv_context_t *dev = (struct jpu_drv_context_t *)filp->private_data;
  536. return fasync_helper(fd, filp, mode, &dev->async_queue);
  537. }
  538. static int jpu_map_to_register(struct file *fp, struct vm_area_struct *vm)
  539. {
  540. unsigned long pfn;
  541. vm->vm_flags |= VM_IO | VM_RESERVED;
  542. vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
  543. pfn = s_jpu_register.phys_addr >> PAGE_SHIFT;
  544. return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end-vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0;
  545. }
  546. static int jpu_map_to_physical_memory(struct file *fp, struct vm_area_struct *vm)
  547. {
  548. vm->vm_flags |= VM_IO | VM_RESERVED;
  549. vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
  550. return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, vm->vm_end-vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0;
  551. }
  552. static int jpu_map_to_instance_pool_memory(struct file *fp, struct vm_area_struct *vm)
  553. {
  554. int ret;
  555. long length = vm->vm_end - vm->vm_start;
  556. unsigned long start = vm->vm_start;
  557. char *vmalloc_area_ptr = (char *)s_instance_pool.base;
  558. unsigned long pfn;
  559. vm->vm_flags |= VM_RESERVED;
  560. /* loop over all pages, map it page individually */
  561. while (length > 0) {
  562. pfn = vmalloc_to_pfn(vmalloc_area_ptr);
  563. if ((ret = remap_pfn_range(vm, start, pfn, PAGE_SIZE, PAGE_SHARED)) < 0) {
  564. return ret;
  565. }
  566. start += PAGE_SIZE;
  567. vmalloc_area_ptr += PAGE_SIZE;
  568. length -= PAGE_SIZE;
  569. }
  570. return 0;
  571. }
  572. /*!
  573. * @brief memory map interface for jpu file operation
  574. * @return 0 on success or negative error code on error
  575. */
  576. static int jpu_mmap(struct file *fp, struct vm_area_struct *vm)
  577. {
  578. if (vm->vm_pgoff == 0)
  579. return jpu_map_to_instance_pool_memory(fp, vm);
  580. if (vm->vm_pgoff == (s_jpu_register.phys_addr>>PAGE_SHIFT))
  581. return jpu_map_to_register(fp, vm);
  582. return jpu_map_to_physical_memory(fp, vm);
  583. }
  584. struct file_operations jpu_fops = {
  585. .owner = THIS_MODULE,
  586. .open = jpu_open,
  587. .read = jpu_read,
  588. .write = jpu_write,
  589. .unlocked_ioctl = jpu_ioctl,
  590. .release = jpu_release,
  591. .fasync = jpu_fasync,
  592. .mmap = jpu_mmap,
  593. };
  594. static int jpu_probe(struct platform_device *pdev)
  595. {
  596. int err = 0;
  597. struct resource *res = NULL;
  598. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  599. struct resource res_cma;
  600. struct device_node *node;
  601. #endif
  602. DPRINTK("[JPUDRV] jpu_probe\n");
  603. if (pdev) {
  604. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  605. }
  606. if (res) {/* if platform driver is implemented */
  607. s_jpu_register.phys_addr = res->start;
  608. s_jpu_register.virt_addr = (unsigned long)ioremap(res->start, res->end - res->start);
  609. s_jpu_register.size = res->end - res->start;
  610. DPRINTK("[JPUDRV] : jpu base address get from platform driver physical base addr==0x%lx, virtual base=0x%lx\n", s_jpu_register.phys_addr , s_jpu_register.virt_addr);
  611. } else {
  612. s_jpu_register.phys_addr = JPU_REG_BASE_ADDR;
  613. s_jpu_register.virt_addr = (unsigned long)ioremap(s_jpu_register.phys_addr, JPU_REG_SIZE);
  614. s_jpu_register.size = JPU_REG_SIZE;
  615. DPRINTK("[JPUDRV] : jpu base address get from defined value physical base addr==0x%lx, virtual base=0x%lx\n", s_jpu_register.phys_addr, s_jpu_register.virt_addr);
  616. }
  617. if (pdev) {
  618. jpu_dev = &pdev->dev;
  619. //jpu_dev->dma_ops = NULL;
  620. dev_info(jpu_dev,"init device.\n");
  621. }
  622. /* get the major number of the character device */
  623. if ((alloc_chrdev_region(&s_jpu_major, 0, 1, JPU_DEV_NAME)) < 0) {
  624. err = -EBUSY;
  625. printk(KERN_ERR "could not allocate major number\n");
  626. goto ERROR_PROVE_DEVICE;
  627. }
  628. /* initialize the device structure and register the device with the kernel */
  629. cdev_init(&s_jpu_cdev, &jpu_fops);
  630. if ((cdev_add(&s_jpu_cdev, s_jpu_major, 1)) < 0) {
  631. err = -EBUSY;
  632. printk(KERN_ERR "could not allocate chrdev\n");
  633. goto ERROR_PROVE_DEVICE;
  634. }
  635. if (pdev)
  636. s_jpu_clk = jpu_clk_get(&pdev->dev);
  637. else
  638. s_jpu_clk = jpu_clk_get(NULL);
  639. if (!s_jpu_clk) {
  640. printk(KERN_ERR "[JPUDRV] : not support clock controller.\n");
  641. }
  642. else {
  643. DPRINTK("[JPUDRV] : get clock controller s_jpu_clk=%p\n", s_jpu_clk);
  644. }
  645. #ifdef JPU_SUPPORT_CLOCK_CONTROL
  646. #else
  647. jpu_clk_enable(s_jpu_clk);
  648. #endif
  649. #ifdef JPU_SUPPORT_ISR
  650. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  651. if(pdev)
  652. res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  653. if (res) {/* if platform driver is implemented */
  654. s_jpu_irq = res->start;
  655. DPRINTK("[JPUDRV] : jpu irq number get from platform driver irq=0x%x\n", s_jpu_irq );
  656. } else {
  657. DPRINTK("[JPUDRV] : jpu irq number get from defined value irq=0x%x\n", s_jpu_irq );
  658. }
  659. #else
  660. DPRINTK("[JPUDRV] : jpu irq number get from defined value irq=0x%x\n", s_jpu_irq);
  661. #endif
  662. err = request_irq(s_jpu_irq, jpu_irq_handler, 0, "JPU_CODEC_IRQ", (void *)(&s_jpu_drv_context));
  663. if (err) {
  664. printk(KERN_ERR "[JPUDRV] : fail to register interrupt handler\n");
  665. goto ERROR_PROVE_DEVICE;
  666. }
  667. #endif
  668. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  669. node = of_parse_phandle(jpu_dev->of_node, "memory-region", 0);
  670. if(node){
  671. dev_info(jpu_dev, "Get mem form memory-region\n");
  672. of_address_to_resource(node, 0, &res_cma);
  673. s_video_memory.size = resource_size(&res_cma);
  674. s_video_memory.phys_addr = res_cma.start;
  675. }else{
  676. dev_info(jpu_dev, "Get mem form reserved memory failed.please check the dts file.\n");
  677. return 0;
  678. }
  679. s_video_memory.base = (unsigned long)ioremap(MEM2SYS(s_video_memory.phys_addr), PAGE_ALIGN(s_video_memory.size));
  680. if (!s_video_memory.base) {
  681. printk(KERN_ERR "[JPUDRV] : fail to remap video memory physical phys_addr=0x%lx, base=0x%lx, size=%d\n", MEM2SYS(s_video_memory.phys_addr), s_video_memory.base, s_video_memory.size);
  682. goto ERROR_PROVE_DEVICE;
  683. }
  684. if (jmem_init(&s_jmem, s_video_memory.phys_addr, s_video_memory.size) < 0) {
  685. printk(KERN_ERR "[JPUDRV] : fail to init vmem system\n");
  686. goto ERROR_PROVE_DEVICE;
  687. }
  688. DPRINTK("[JPUDRV] success to probe jpu device with reserved video memory phys_addr=0x%lx, base=0x%lx\n", s_video_memory.phys_addr, s_video_memory.base);
  689. #else
  690. DPRINTK("[JPUDRV] success to probe jpu device with non reserved video memory\n");
  691. #endif
  692. return 0;
  693. ERROR_PROVE_DEVICE:
  694. if (s_jpu_major)
  695. unregister_chrdev_region(s_jpu_major, 1);
  696. if (s_jpu_register.virt_addr)
  697. iounmap((void *)s_jpu_register.virt_addr);
  698. return err;
  699. }
  700. static int jpu_remove(struct platform_device *pdev)
  701. {
  702. DPRINTK("[JPUDRV] jpu_remove\n");
  703. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  704. if (s_instance_pool.base) {
  705. vfree((const void *)s_instance_pool.base);
  706. s_instance_pool.base = 0;
  707. }
  708. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  709. if (s_video_memory.base) {
  710. iounmap((void *)s_video_memory.base);
  711. s_video_memory.base = 0;
  712. jmem_exit(&s_jmem);
  713. }
  714. #endif
  715. if (s_jpu_major > 0) {
  716. cdev_del(&s_jpu_cdev);
  717. unregister_chrdev_region(s_jpu_major, 1);
  718. s_jpu_major = 0;
  719. }
  720. #ifdef JPU_SUPPORT_ISR
  721. if (s_jpu_irq)
  722. free_irq(s_jpu_irq, &s_jpu_drv_context);
  723. #endif
  724. if (s_jpu_register.virt_addr)
  725. iounmap((void*)s_jpu_register.virt_addr);
  726. jpu_clk_put(s_jpu_clk);
  727. #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  728. return 0;
  729. }
  730. #ifdef CONFIG_PM
  731. static int jpu_suspend(struct platform_device *pdev, pm_message_t state)
  732. {
  733. jpu_clk_disable(s_jpu_clk);
  734. return 0;
  735. }
  736. static int jpu_resume(struct platform_device *pdev)
  737. {
  738. jpu_clk_enable(s_jpu_clk);
  739. return 0;
  740. }
  741. #else
  742. #define jpu_suspend NULL
  743. #define jpu_resume NULL
  744. #endif /* !CONFIG_PM */
  745. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  746. static const struct of_device_id jpu_of_id_table[] = {
  747. { .compatible = "cm,codaj12-jpu-1" },
  748. {}
  749. };
  750. static struct platform_driver jpu_driver = {
  751. .driver = {
  752. .name = JPU_PLATFORM_DEVICE_NAME,
  753. .of_match_table = of_match_ptr(jpu_of_id_table),
  754. },
  755. .probe = jpu_probe,
  756. .remove = jpu_remove,
  757. .suspend = jpu_suspend,
  758. .resume = jpu_resume,
  759. };
  760. #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  761. static int __init jpu_init(void)
  762. {
  763. int res = 0;
  764. u32 i;
  765. DPRINTK("[JPUDRV] begin jpu_init\n");
  766. for (i=0; i<MAX_NUM_INSTANCE; i++) {
  767. init_waitqueue_head(&s_interrupt_wait_q[i]);
  768. }
  769. s_instance_pool.base = 0;
  770. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  771. res = platform_driver_register(&jpu_driver);
  772. #else
  773. res = jpu_probe(NULL);
  774. #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  775. DPRINTK("[JPUDRV] end jpu_init result=0x%x\n", res);
  776. return res;
  777. }
  778. static void __exit jpu_exit(void)
  779. {
  780. DPRINTK("[JPUDRV] [+]jpu_exit\n");
  781. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  782. platform_driver_unregister(&jpu_driver);
  783. #else /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  784. #ifdef JPU_SUPPORT_CLOCK_CONTROL
  785. #else
  786. jpu_clk_disable(s_jpu_clk);
  787. #endif /* JPU_SUPPORT_CLOCK_CONTROL */
  788. jpu_clk_put(s_jpu_clk);
  789. if (s_instance_pool.base) {
  790. vfree((const void *)s_instance_pool.base);
  791. s_instance_pool.base = 0;
  792. }
  793. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  794. if (s_video_memory.base) {
  795. iounmap((void *)s_video_memory.base);
  796. s_video_memory.base = 0;
  797. jmem_exit(&s_jmem);
  798. }
  799. #endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
  800. if (s_jpu_major > 0) {
  801. cdev_del(&s_jpu_cdev);
  802. unregister_chrdev_region(s_jpu_major, 1);
  803. s_jpu_major = 0;
  804. }
  805. #ifdef JPU_SUPPORT_ISR
  806. if (s_jpu_irq)
  807. free_irq(s_jpu_irq, &s_jpu_drv_context);
  808. #endif /* JPU_SUPPORT_ISR */
  809. if (s_jpu_register.virt_addr) {
  810. iounmap((void *)s_jpu_register.virt_addr);
  811. s_jpu_register.virt_addr = 0x00;
  812. }
  813. #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  814. DPRINTK("[JPUDRV] [-]jpu_exit\n");
  815. return;
  816. }
  817. MODULE_AUTHOR("A customer using C&M JPU, Inc.");
  818. MODULE_DESCRIPTION("JPU linux driver");
  819. MODULE_LICENSE("GPL");
  820. module_init(jpu_init);
  821. module_exit(jpu_exit);
  822. static int jpu_hw_reset(void)
  823. {
  824. DPRINTK("[JPUDRV] request jpu reset from application. \n");
  825. return 0;
  826. }
  827. struct clk *jpu_clk_get(struct device *dev)
  828. {
  829. return clk_get(dev, JPU_CLK_NAME);
  830. }
  831. void jpu_clk_put(struct clk *clk)
  832. {
  833. if (!(clk == NULL || IS_ERR(clk)))
  834. clk_put(clk);
  835. }
  836. int jpu_clk_enable(struct clk *clk)
  837. {
  838. if (clk) {
  839. DPRINTK("[JPUDRV] jpu_clk_enable\n");
  840. // You need to implement it
  841. return 1;
  842. }
  843. return 0;
  844. }
  845. void jpu_clk_disable(struct clk *clk)
  846. {
  847. if (!(clk == NULL || IS_ERR(clk))) {
  848. DPRINTK("[JPUDRV] jpu_clk_disable\n");
  849. // You need to implement it
  850. }
  851. }