jpu.c 39 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346
  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 clktree is work,try this...*/
  51. //#define STARFIVE_JPU_SUPPORT_CLOCK_CONTROL
  52. /* if the platform driver knows the name of this driver */
  53. /* JPU_PLATFORM_DEVICE_NAME */
  54. #define JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  55. /* if this driver knows the dedicated video memory address */
  56. //#define JPU_SUPPORT_RESERVED_VIDEO_MEMORY //if this driver knows the dedicated video memory address
  57. #define JPU_PLATFORM_DEVICE_NAME "cnm_jpu"
  58. #define JPU_CLK_NAME "jpege"
  59. #define JPU_DEV_NAME "jpu"
  60. #define JPU_REG_BASE_ADDR 0x11900000
  61. #define JPU_REG_SIZE 0x300
  62. #ifdef JPU_SUPPORT_ISR
  63. #define JPU_IRQ_NUM 24
  64. /* if the driver want to disable and enable IRQ whenever interrupt asserted. */
  65. /*#define JPU_IRQ_CONTROL*/
  66. #endif
  67. #ifndef VM_RESERVED /*for kernel up to 3.7.0 version*/
  68. #define VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
  69. #endif
  70. struct device *jpu_dev;
  71. typedef struct jpu_drv_context_t {
  72. struct fasync_struct *async_queue;
  73. u32 open_count; /*!<< device reference count. Not instance count */
  74. u32 interrupt_reason[MAX_NUM_INSTANCE];
  75. } jpu_drv_context_t;
  76. /* To track the allocated memory buffer */
  77. typedef struct jpudrv_buffer_pool_t {
  78. struct list_head list;
  79. struct jpudrv_buffer_t jb;
  80. struct file* filp;
  81. } jpudrv_buffer_pool_t;
  82. /* To track the instance index and buffer in instance pool */
  83. typedef struct jpudrv_instance_list_t {
  84. struct list_head list;
  85. unsigned long inst_idx;
  86. struct file* filp;
  87. } jpudrv_instance_list_t;
  88. typedef struct jpudrv_instance_pool_t {
  89. unsigned char codecInstPool[MAX_NUM_INSTANCE][MAX_INST_HANDLE_SIZE];
  90. } jpudrv_instance_pool_t;
  91. #ifndef STARFIVE_JPU_SUPPORT_CLOCK_CONTROL
  92. typedef struct jpu_clkgen_t {
  93. void __iomem *en_ctrl;
  94. uint32_t rst_mask;
  95. } jpu_clkgen_t;
  96. #endif
  97. typedef struct jpu_clk_t {
  98. #ifndef STARFIVE_JPU_SUPPORT_CLOCK_CONTROL
  99. void __iomem *rst_ctrl;
  100. void __iomem *rst_status;
  101. uint32_t en_shift;
  102. uint32_t en_mask;
  103. jpu_clkgen_t apb_clk;
  104. jpu_clkgen_t axi_clk;
  105. jpu_clkgen_t core_clk;
  106. #else
  107. struct clk *apb_clk;
  108. struct clk *axi_clk;
  109. struct clk *core_clk;
  110. #endif
  111. void __iomem *clkgen;
  112. phys_addr_t pmu_base;
  113. } jpu_clk_t;
  114. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  115. #include "jmm.h"
  116. static jpu_mm_t s_jmem;
  117. static jpudrv_buffer_t s_video_memory = {0};
  118. #endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
  119. static int jpu_hw_reset(void);
  120. static void jpu_clk_disable(jpu_clk_t *clk);
  121. static void jpu_clk_enable(jpu_clk_t *clk);
  122. static jpu_clk_t *jpu_clk_get(struct platform_device *pdev);
  123. static void jpu_clk_put(jpu_clk_t *clk);
  124. // end customer definition
  125. static jpudrv_buffer_t s_instance_pool = {0};
  126. static jpu_drv_context_t s_jpu_drv_context;
  127. static int s_jpu_major;
  128. static struct cdev s_jpu_cdev;
  129. static jpu_clk_t *s_jpu_clk;
  130. static int s_jpu_open_ref_count;
  131. #ifdef JPU_SUPPORT_ISR
  132. static int s_jpu_irq = JPU_IRQ_NUM;
  133. #endif
  134. static jpudrv_buffer_t s_jpu_register = {0};
  135. static int s_interrupt_flag[MAX_NUM_INSTANCE];
  136. static wait_queue_head_t s_interrupt_wait_q[MAX_NUM_INSTANCE];
  137. static spinlock_t s_jpu_lock = __SPIN_LOCK_UNLOCKED(s_jpu_lock);
  138. #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,36)
  139. static DECLARE_MUTEX(s_jpu_sem);
  140. #else
  141. static DEFINE_SEMAPHORE(s_jpu_sem);
  142. #endif
  143. static struct list_head s_jbp_head = LIST_HEAD_INIT(s_jbp_head);
  144. static struct list_head s_inst_list_head = LIST_HEAD_INIT(s_inst_list_head);
  145. #ifdef CONFIG_PM
  146. /* implement to power management functions */
  147. #endif
  148. #define NPT_BASE 0x0000
  149. #define NPT_REG_SIZE 0x300
  150. #define MJPEG_PIC_STATUS_REG(_inst_no) (NPT_BASE + (_inst_no*NPT_REG_SIZE) + 0x004)
  151. #define ReadJpuRegister(addr) *(volatile unsigned int *)(s_jpu_register.virt_addr + addr)
  152. #define WriteJpuRegister(addr, val) *(volatile unsigned int *)(s_jpu_register.virt_addr + addr) = (unsigned int)val
  153. #define WriteJpu(addr, val) *(volatile unsigned int *)(addr) = (unsigned int)val;
  154. static int jpu_alloc_dma_buffer(jpudrv_buffer_t *jb)
  155. {
  156. if (!jb)
  157. return -1;
  158. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  159. jb->phys_addr = (unsigned long long)jmem_alloc(&s_jmem, jb->size, 0);
  160. if ((unsigned long)jb->phys_addr == (unsigned long)-1) {
  161. printk(KERN_ERR "[JPUDRV] Physical memory allocation error size=%d\n", jb->size);
  162. return -1;
  163. }
  164. jb->base = (unsigned long)(s_video_memory.base + (jb->phys_addr - s_video_memory.phys_addr));
  165. #else
  166. jb->base = (unsigned long)dma_alloc_coherent(jpu_dev, PAGE_ALIGN(jb->size), (dma_addr_t *) (&jb->phys_addr), GFP_DMA | GFP_KERNEL);
  167. if ((void *)(jb->base) == NULL) {
  168. printk(KERN_ERR "[JPUDRV] Physical memory allocation error size=%d\n", jb->size);
  169. return -1;
  170. }
  171. starfive_flush_dcache(jb->phys_addr,PAGE_ALIGN(jb->size));
  172. #endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
  173. return 0;
  174. }
  175. static void jpu_free_dma_buffer(jpudrv_buffer_t *jb)
  176. {
  177. if (!jb) {
  178. return;
  179. }
  180. if (jb->base)
  181. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  182. jmem_free(&s_jmem, jb->phys_addr, 0);
  183. #else
  184. dma_free_coherent(jpu_dev, PAGE_ALIGN(jb->size), (void *)jb->base, jb->phys_addr);
  185. #endif /* JPUR_SUPPORT_RESERVED_VIDEO_MEMORY */
  186. }
  187. static int jpu_free_instances(struct file *filp)
  188. {
  189. jpudrv_instance_list_t *vil, *n;
  190. jpudrv_instance_pool_t *vip;
  191. void *vip_base;
  192. int instance_pool_size_per_core;
  193. void *jdi_mutexes_base;
  194. const int PTHREAD_MUTEX_T_DESTROY_VALUE = 0xdead10cc;
  195. DPRINTK("[JPUDRV] jpu_free_instances\n");
  196. 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. */
  197. list_for_each_entry_safe(vil, n, &s_inst_list_head, list)
  198. {
  199. if (vil->filp == filp) {
  200. vip_base = (void *)(s_instance_pool.base + instance_pool_size_per_core);
  201. 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);
  202. vip = (jpudrv_instance_pool_t *)vip_base;
  203. if (vip) {
  204. 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. */
  205. #define PTHREAD_MUTEX_T_HANDLE_SIZE 4
  206. jdi_mutexes_base = (vip_base + (instance_pool_size_per_core - PTHREAD_MUTEX_T_HANDLE_SIZE*4));
  207. DPRINTK("[JPUDRV] jpu_free_instances : force to destroy jdi_mutexes_base=%p in userspace \n", jdi_mutexes_base);
  208. if (jdi_mutexes_base) {
  209. int i;
  210. for (i = 0; i < 4; i++) {
  211. memcpy(jdi_mutexes_base, &PTHREAD_MUTEX_T_DESTROY_VALUE, PTHREAD_MUTEX_T_HANDLE_SIZE);
  212. jdi_mutexes_base += PTHREAD_MUTEX_T_HANDLE_SIZE;
  213. }
  214. }
  215. }
  216. s_jpu_open_ref_count--;
  217. list_del(&vil->list);
  218. kfree(vil);
  219. }
  220. }
  221. return 1;
  222. }
  223. static int jpu_free_buffers(struct file *filp)
  224. {
  225. jpudrv_buffer_pool_t *pool, *n;
  226. jpudrv_buffer_t jb;
  227. DPRINTK("[JPUDRV] jpu_free_buffers\n");
  228. list_for_each_entry_safe(pool, n, &s_jbp_head, list)
  229. {
  230. if (pool->filp == filp) {
  231. jb = pool->jb;
  232. if (jb.base) {
  233. jpu_free_dma_buffer(&jb);
  234. list_del(&pool->list);
  235. kfree(pool);
  236. }
  237. }
  238. }
  239. return 0;
  240. }
  241. static irqreturn_t jpu_irq_handler(int irq, void *dev_id)
  242. {
  243. jpu_drv_context_t* dev = (jpu_drv_context_t *)dev_id;
  244. int i;
  245. u32 flag;
  246. DPRINTK("[JPUDRV][+]%s\n", __func__);
  247. #ifdef JPU_IRQ_CONTROL
  248. disable_irq_nosync(s_jpu_irq);
  249. #endif
  250. for (i=0; i<MAX_NUM_INSTANCE; i++) {
  251. flag = ReadJpuRegister(MJPEG_PIC_STATUS_REG(i));
  252. if (flag != 0) {
  253. break;
  254. }
  255. }
  256. dev->interrupt_reason[i] = flag;
  257. s_interrupt_flag[i] = 1;
  258. DPRINTK("[JPUDRV][%d] INTERRUPT FLAG: %08x, %08x\n", i, dev->interrupt_reason[i], MJPEG_PIC_STATUS_REG(i));
  259. if (dev->async_queue)
  260. kill_fasync(&dev->async_queue, SIGIO, POLL_IN); // notify the interrupt to userspace
  261. #ifndef JPU_IRQ_CONTROL
  262. WriteJpuRegister(MJPEG_PIC_STATUS_REG(i),flag); //clear interrut
  263. #endif
  264. wake_up_interruptible(&s_interrupt_wait_q[i]);
  265. DPRINTK("[JPUDRV][-]%s\n", __func__);
  266. return IRQ_HANDLED;
  267. }
  268. static int jpu_open(struct inode *inode, struct file *filp)
  269. {
  270. DPRINTK("[JPUDRV][+] %s\n", __func__);
  271. spin_lock(&s_jpu_lock);
  272. s_jpu_drv_context.open_count++;
  273. filp->private_data = (void *)(&s_jpu_drv_context);
  274. spin_unlock(&s_jpu_lock);
  275. DPRINTK("[JPUDRV][-] %s\n", __func__);
  276. return 0;
  277. }
  278. static long jpu_ioctl(struct file *filp, u_int cmd, u_long arg)
  279. {
  280. int ret = 0;
  281. switch (cmd)
  282. {
  283. case JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY:
  284. {
  285. jpudrv_buffer_pool_t *jbp;
  286. DPRINTK("[JPUDRV][+]JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
  287. if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
  288. jbp = kzalloc(sizeof(jpudrv_buffer_pool_t), GFP_KERNEL);
  289. if (!jbp) {
  290. up(&s_jpu_sem);
  291. return -ENOMEM;
  292. }
  293. ret = copy_from_user(&(jbp->jb), (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
  294. if (ret)
  295. {
  296. kfree(jbp);
  297. up(&s_jpu_sem);
  298. return -EFAULT;
  299. }
  300. ret = jpu_alloc_dma_buffer(&(jbp->jb));
  301. if (ret == -1)
  302. {
  303. ret = -ENOMEM;
  304. kfree(jbp);
  305. up(&s_jpu_sem);
  306. break;
  307. }
  308. ret = copy_to_user((void __user *)arg, &(jbp->jb), sizeof(jpudrv_buffer_t));
  309. if (ret)
  310. {
  311. kfree(jbp);
  312. ret = -EFAULT;
  313. up(&s_jpu_sem);
  314. break;
  315. }
  316. jbp->filp = filp;
  317. spin_lock(&s_jpu_lock);
  318. list_add(&jbp->list, &s_jbp_head);
  319. spin_unlock(&s_jpu_lock);
  320. up(&s_jpu_sem);
  321. }
  322. DPRINTK("[JPUDRV][-]JDI_IOCTL_ALLOCATE_PHYSICAL_MEMORY\n");
  323. }
  324. break;
  325. case JDI_IOCTL_FREE_PHYSICALMEMORY:
  326. {
  327. jpudrv_buffer_pool_t *jbp, *n;
  328. jpudrv_buffer_t jb;
  329. DPRINTK("[JPUDRV][+]VDI_IOCTL_FREE_PHYSICALMEMORY\n");
  330. if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
  331. ret = copy_from_user(&jb, (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
  332. if (ret) {
  333. up(&s_jpu_sem);
  334. return -EACCES;
  335. }
  336. if (jb.base)
  337. jpu_free_dma_buffer(&jb);
  338. spin_lock(&s_jpu_lock);
  339. list_for_each_entry_safe(jbp, n, &s_jbp_head, list) {
  340. if (jbp->jb.base == jb.base) {
  341. list_del(&jbp->list);
  342. kfree(jbp);
  343. break;
  344. }
  345. }
  346. spin_unlock(&s_jpu_lock);
  347. up(&s_jpu_sem);
  348. }
  349. DPRINTK("[JPUDRV][-]VDI_IOCTL_FREE_PHYSICALMEMORY\n");
  350. }
  351. break;
  352. case JDI_IOCTL_GET_RESERVED_VIDEO_MEMORY_INFO:
  353. {
  354. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  355. if (s_video_memory.base != 0) {
  356. ret = copy_to_user((void __user *)arg, &s_video_memory, sizeof(jpudrv_buffer_t));
  357. if (ret != 0)
  358. ret = -EFAULT;
  359. } else {
  360. ret = -EFAULT;
  361. }
  362. #endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
  363. }
  364. break;
  365. case JDI_IOCTL_WAIT_INTERRUPT:
  366. {
  367. jpudrv_intr_info_t info;
  368. struct jpu_drv_context_t *dev = (struct jpu_drv_context_t *)filp->private_data;
  369. u32 instance_no;
  370. DPRINTK("[JPUDRV][+]JDI_IOCTL_WAIT_INTERRUPT\n");
  371. ret = copy_from_user(&info, (jpudrv_intr_info_t *)arg, sizeof(jpudrv_intr_info_t));
  372. if (ret != 0)
  373. return -EFAULT;
  374. instance_no = info.inst_idx;
  375. DPRINTK("[JPUDRV] INSTANCE NO: %d\n", instance_no);
  376. ret = wait_event_interruptible_timeout(s_interrupt_wait_q[instance_no], s_interrupt_flag[instance_no] != 0, msecs_to_jiffies(info.timeout));
  377. if (!ret) {
  378. DPRINTK("[JPUDRV] INSTANCE NO: %d ETIME\n", instance_no);
  379. ret = -ETIME;
  380. break;
  381. }
  382. if (signal_pending(current)) {
  383. ret = -ERESTARTSYS;
  384. DPRINTK("[JPUDRV] INSTANCE NO: %d ERESTARTSYS\n", instance_no);
  385. break;
  386. }
  387. DPRINTK("[JPUDRV] INST(%d) s_interrupt_flag(%d), reason(0x%08x)\n", instance_no, s_interrupt_flag[instance_no], dev->interrupt_reason[instance_no]);
  388. info.intr_reason = dev->interrupt_reason[instance_no];
  389. s_interrupt_flag[instance_no] = 0;
  390. dev->interrupt_reason[instance_no] = 0;
  391. ret = copy_to_user((void __user *)arg, &info, sizeof(jpudrv_intr_info_t));
  392. #ifdef JPU_IRQ_CONTROL
  393. enable_irq(s_jpu_irq);
  394. #endif
  395. DPRINTK("[VPUDRV][-]VDI_IOCTL_WAIT_INTERRUPT\n");
  396. if (ret != 0)
  397. return -EFAULT;
  398. }
  399. break;
  400. case JDI_IOCTL_SET_CLOCK_GATE:
  401. {
  402. u32 clkgate;
  403. if (get_user(clkgate, (u32 __user *) arg))
  404. return -EFAULT;
  405. #ifdef JPU_SUPPORT_CLOCK_CONTROL
  406. if (clkgate)
  407. jpu_clk_enable(s_jpu_clk);
  408. else
  409. jpu_clk_disable(s_jpu_clk);
  410. #endif /* JPU_SUPPORT_CLOCK_CONTROL */
  411. }
  412. break;
  413. case JDI_IOCTL_GET_INSTANCE_POOL:
  414. DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_INSTANCE_POOL\n");
  415. if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
  416. if (s_instance_pool.base != 0) {
  417. ret = copy_to_user((void __user *)arg, &s_instance_pool, sizeof(jpudrv_buffer_t));
  418. } else {
  419. ret = copy_from_user(&s_instance_pool, (jpudrv_buffer_t *)arg, sizeof(jpudrv_buffer_t));
  420. if (ret == 0) {
  421. s_instance_pool.size = PAGE_ALIGN(s_instance_pool.size);
  422. s_instance_pool.base = (unsigned long)vmalloc(s_instance_pool.size);
  423. s_instance_pool.phys_addr = s_instance_pool.base;
  424. if (s_instance_pool.base != 0) {
  425. memset((void *)s_instance_pool.base, 0x0, s_instance_pool.size); /*clearing memory*/
  426. ret = copy_to_user((void __user *)arg, &s_instance_pool, sizeof(jpudrv_buffer_t));
  427. if (ret == 0) {
  428. /* success to get memory for instance pool */
  429. up(&s_jpu_sem);
  430. break;
  431. }
  432. }
  433. ret = -EFAULT;
  434. }
  435. }
  436. up(&s_jpu_sem);
  437. }
  438. DPRINTK("[JPUDRV][-]JDI_IOCTL_GET_INSTANCE_POOL: %s base: %lx, size: %d\n",
  439. (ret==0 ? "OK" : "NG"), s_instance_pool.base, s_instance_pool.size);
  440. break;
  441. case JDI_IOCTL_OPEN_INSTANCE:
  442. {
  443. jpudrv_inst_info_t inst_info;
  444. if (copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t)))
  445. return -EFAULT;
  446. spin_lock(&s_jpu_lock);
  447. s_jpu_open_ref_count++; /* flag just for that jpu is in opened or closed */
  448. inst_info.inst_open_count = s_jpu_open_ref_count;
  449. spin_unlock(&s_jpu_lock);
  450. if (copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t))) {
  451. return -EFAULT;
  452. }
  453. DPRINTK("[JPUDRV] JDI_IOCTL_OPEN_INSTANCE inst_idx=%d, s_jpu_open_ref_count=%d, inst_open_count=%d\n",
  454. (int)inst_info.inst_idx, s_jpu_open_ref_count, inst_info.inst_open_count);
  455. }
  456. break;
  457. case JDI_IOCTL_CLOSE_INSTANCE:
  458. {
  459. jpudrv_inst_info_t inst_info;
  460. DPRINTK("[JPUDRV][+]JDI_IOCTL_CLOSE_INSTANCE\n");
  461. if (copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t)))
  462. return -EFAULT;
  463. spin_lock(&s_jpu_lock);
  464. s_jpu_open_ref_count--; /* flag just for that jpu is in opened or closed */
  465. inst_info.inst_open_count = s_jpu_open_ref_count;
  466. spin_unlock(&s_jpu_lock);
  467. if (copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t)))
  468. return -EFAULT;
  469. DPRINTK("[JPUDRV] JDI_IOCTL_CLOSE_INSTANCE inst_idx=%d, s_jpu_open_ref_count=%d, inst_open_count=%d\n",
  470. (int)inst_info.inst_idx, s_jpu_open_ref_count, inst_info.inst_open_count);
  471. }
  472. break;
  473. case JDI_IOCTL_GET_INSTANCE_NUM:
  474. {
  475. jpudrv_inst_info_t inst_info;
  476. DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_INSTANCE_NUM\n");
  477. ret = copy_from_user(&inst_info, (jpudrv_inst_info_t *)arg, sizeof(jpudrv_inst_info_t));
  478. if (ret != 0)
  479. break;
  480. spin_lock(&s_jpu_lock);
  481. inst_info.inst_open_count = s_jpu_open_ref_count;
  482. spin_unlock(&s_jpu_lock);
  483. ret = copy_to_user((void __user *)arg, &inst_info, sizeof(jpudrv_inst_info_t));
  484. DPRINTK("[JPUDRV] JDI_IOCTL_GET_INSTANCE_NUM inst_idx=%d, open_count=%d\n", (int)inst_info.inst_idx, inst_info.inst_open_count);
  485. }
  486. break;
  487. case JDI_IOCTL_RESET:
  488. jpu_hw_reset();
  489. break;
  490. case JDI_IOCTL_GET_REGISTER_INFO:
  491. DPRINTK("[JPUDRV][+]JDI_IOCTL_GET_REGISTER_INFO\n");
  492. ret = copy_to_user((void __user *)arg, &s_jpu_register, sizeof(jpudrv_buffer_t));
  493. if (ret != 0)
  494. ret = -EFAULT;
  495. 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",
  496. s_jpu_register.phys_addr , s_jpu_register.virt_addr, s_jpu_register.size);
  497. break;
  498. case JDI_IOCTL_FLUSH_DCACHE:
  499. {
  500. jpudrv_flush_cache_t cache_info;
  501. //DPRINTK("[JPUDRV][+]JDI_IOCTL_FLUSH_DCACHE\n");
  502. ret = copy_from_user(&cache_info, (jpudrv_flush_cache_t *)arg, sizeof(jpudrv_flush_cache_t));
  503. if (ret != 0)
  504. ret = -EFAULT;
  505. if(cache_info.flag)
  506. starfive_flush_dcache(cache_info.start,cache_info.size);
  507. //DPRINTK("[JPUDRV][-]JDI_IOCTL_FLUSH_DCACHE\n");
  508. break;
  509. }
  510. default:
  511. {
  512. printk(KERN_ERR "No such IOCTL, cmd is %d\n", cmd);
  513. }
  514. break;
  515. }
  516. return ret;
  517. }
  518. static ssize_t jpu_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos)
  519. {
  520. return -1;
  521. }
  522. static ssize_t jpu_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos)
  523. {
  524. /* DPRINTK("[VPUDRV] vpu_write len=%d\n", (int)len); */
  525. if (!buf) {
  526. printk(KERN_ERR "[VPUDRV] vpu_write buf = NULL error \n");
  527. return -EFAULT;
  528. }
  529. return -1;
  530. }
  531. static int jpu_release(struct inode *inode, struct file *filp)
  532. {
  533. int ret = 0;
  534. u32 open_count;
  535. DPRINTK("[JPUDRV][+] jpu_release\n");
  536. if ((ret = down_interruptible(&s_jpu_sem)) == 0) {
  537. /* found and free the not handled buffer by user applications */
  538. jpu_free_buffers(filp);
  539. /* found and free the not closed instance by user applications */
  540. jpu_free_instances(filp);
  541. DPRINTK("[JPUDRV] open_count: %d\n", s_jpu_drv_context.open_count);
  542. spin_lock(&s_jpu_lock);
  543. s_jpu_drv_context.open_count--;
  544. open_count = s_jpu_drv_context.open_count;
  545. spin_unlock(&s_jpu_lock);
  546. if (open_count == 0) {
  547. if (s_instance_pool.base) {
  548. DPRINTK("[JPUDRV] free instance pool\n");
  549. vfree((const void *)s_instance_pool.base);
  550. s_instance_pool.base = 0;
  551. }
  552. }
  553. }
  554. up(&s_jpu_sem);
  555. DPRINTK("[JPUDRV][-] jpu_release\n");
  556. return 0;
  557. }
  558. static int jpu_fasync(int fd, struct file *filp, int mode)
  559. {
  560. struct jpu_drv_context_t *dev = (struct jpu_drv_context_t *)filp->private_data;
  561. return fasync_helper(fd, filp, mode, &dev->async_queue);
  562. }
  563. static int jpu_map_to_register(struct file *fp, struct vm_area_struct *vm)
  564. {
  565. unsigned long pfn;
  566. vm->vm_flags |= VM_IO | VM_RESERVED;
  567. vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
  568. pfn = s_jpu_register.phys_addr >> PAGE_SHIFT;
  569. return remap_pfn_range(vm, vm->vm_start, pfn, vm->vm_end-vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0;
  570. }
  571. static int jpu_map_to_physical_memory(struct file *fp, struct vm_area_struct *vm)
  572. {
  573. vm->vm_flags |= VM_IO | VM_RESERVED;
  574. vm->vm_page_prot = pgprot_noncached(vm->vm_page_prot);
  575. return remap_pfn_range(vm, vm->vm_start, vm->vm_pgoff, vm->vm_end-vm->vm_start, vm->vm_page_prot) ? -EAGAIN : 0;
  576. }
  577. static int jpu_map_to_instance_pool_memory(struct file *fp, struct vm_area_struct *vm)
  578. {
  579. int ret;
  580. long length = vm->vm_end - vm->vm_start;
  581. unsigned long start = vm->vm_start;
  582. char *vmalloc_area_ptr = (char *)s_instance_pool.base;
  583. unsigned long pfn;
  584. vm->vm_flags |= VM_RESERVED;
  585. /* loop over all pages, map it page individually */
  586. while (length > 0) {
  587. pfn = vmalloc_to_pfn(vmalloc_area_ptr);
  588. if ((ret = remap_pfn_range(vm, start, pfn, PAGE_SIZE, PAGE_SHARED)) < 0) {
  589. return ret;
  590. }
  591. start += PAGE_SIZE;
  592. vmalloc_area_ptr += PAGE_SIZE;
  593. length -= PAGE_SIZE;
  594. }
  595. return 0;
  596. }
  597. /*!
  598. * @brief memory map interface for jpu file operation
  599. * @return 0 on success or negative error code on error
  600. */
  601. static int jpu_mmap(struct file *fp, struct vm_area_struct *vm)
  602. {
  603. if (vm->vm_pgoff == 0)
  604. return jpu_map_to_instance_pool_memory(fp, vm);
  605. if (vm->vm_pgoff == (s_jpu_register.phys_addr>>PAGE_SHIFT))
  606. return jpu_map_to_register(fp, vm);
  607. return jpu_map_to_physical_memory(fp, vm);
  608. }
  609. struct file_operations jpu_fops = {
  610. .owner = THIS_MODULE,
  611. .open = jpu_open,
  612. .read = jpu_read,
  613. .write = jpu_write,
  614. .unlocked_ioctl = jpu_ioctl,
  615. .release = jpu_release,
  616. .fasync = jpu_fasync,
  617. .mmap = jpu_mmap,
  618. };
  619. static int jpu_probe(struct platform_device *pdev)
  620. {
  621. int err = 0;
  622. struct resource *res = NULL;
  623. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  624. struct resource res_cma;
  625. struct device_node *node;
  626. #endif
  627. DPRINTK("[JPUDRV] jpu_probe\n");
  628. if (pdev) {
  629. res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  630. }
  631. if (res) {/* if platform driver is implemented */
  632. s_jpu_register.phys_addr = res->start;
  633. s_jpu_register.virt_addr = (unsigned long)ioremap(res->start, res->end - res->start);
  634. s_jpu_register.size = res->end - res->start;
  635. 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);
  636. } else {
  637. s_jpu_register.phys_addr = JPU_REG_BASE_ADDR;
  638. s_jpu_register.virt_addr = (unsigned long)ioremap(s_jpu_register.phys_addr, JPU_REG_SIZE);
  639. s_jpu_register.size = JPU_REG_SIZE;
  640. 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);
  641. }
  642. if (pdev) {
  643. jpu_dev = &pdev->dev;
  644. //jpu_dev->dma_ops = NULL;
  645. dev_info(jpu_dev,"init device.\n");
  646. }
  647. /* get the major number of the character device */
  648. if ((alloc_chrdev_region(&s_jpu_major, 0, 1, JPU_DEV_NAME)) < 0) {
  649. err = -EBUSY;
  650. printk(KERN_ERR "could not allocate major number\n");
  651. goto ERROR_PROVE_DEVICE;
  652. }
  653. /* initialize the device structure and register the device with the kernel */
  654. cdev_init(&s_jpu_cdev, &jpu_fops);
  655. if ((cdev_add(&s_jpu_cdev, s_jpu_major, 1)) < 0) {
  656. err = -EBUSY;
  657. printk(KERN_ERR "could not allocate chrdev\n");
  658. goto ERROR_PROVE_DEVICE;
  659. }
  660. if (pdev)
  661. s_jpu_clk = jpu_clk_get(pdev);
  662. else
  663. s_jpu_clk = jpu_clk_get(NULL);
  664. if (!s_jpu_clk) {
  665. printk(KERN_ERR "[JPUDRV] : not support clock controller.\n");
  666. }
  667. else {
  668. DPRINTK("[JPUDRV] : get clock controller s_jpu_clk=%p\n", s_jpu_clk);
  669. }
  670. #ifdef JPU_SUPPORT_CLOCK_CONTROL
  671. #else
  672. jpu_clk_enable(s_jpu_clk);
  673. #endif
  674. #ifdef JPU_SUPPORT_ISR
  675. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  676. if(pdev)
  677. res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
  678. if (res) {/* if platform driver is implemented */
  679. s_jpu_irq = res->start;
  680. DPRINTK("[JPUDRV] : jpu irq number get from platform driver irq=0x%x\n", s_jpu_irq );
  681. } else {
  682. DPRINTK("[JPUDRV] : jpu irq number get from defined value irq=0x%x\n", s_jpu_irq );
  683. }
  684. #else
  685. DPRINTK("[JPUDRV] : jpu irq number get from defined value irq=0x%x\n", s_jpu_irq);
  686. #endif
  687. err = request_irq(s_jpu_irq, jpu_irq_handler, 0, "JPU_CODEC_IRQ", (void *)(&s_jpu_drv_context));
  688. if (err) {
  689. printk(KERN_ERR "[JPUDRV] : fail to register interrupt handler\n");
  690. goto ERROR_PROVE_DEVICE;
  691. }
  692. #endif
  693. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  694. node = of_parse_phandle(jpu_dev->of_node, "memory-region", 0);
  695. if(node){
  696. dev_info(jpu_dev, "Get mem form memory-region\n");
  697. of_address_to_resource(node, 0, &res_cma);
  698. s_video_memory.size = resource_size(&res_cma);
  699. s_video_memory.phys_addr = res_cma.start;
  700. }else{
  701. dev_info(jpu_dev, "Get mem form reserved memory failed.please check the dts file.\n");
  702. return 0;
  703. }
  704. s_video_memory.base = (unsigned long)ioremap(MEM2SYS(s_video_memory.phys_addr), PAGE_ALIGN(s_video_memory.size));
  705. if (!s_video_memory.base) {
  706. 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);
  707. goto ERROR_PROVE_DEVICE;
  708. }
  709. if (jmem_init(&s_jmem, s_video_memory.phys_addr, s_video_memory.size) < 0) {
  710. printk(KERN_ERR "[JPUDRV] : fail to init vmem system\n");
  711. goto ERROR_PROVE_DEVICE;
  712. }
  713. 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);
  714. #else
  715. DPRINTK("[JPUDRV] success to probe jpu device with non reserved video memory\n");
  716. #endif
  717. return 0;
  718. ERROR_PROVE_DEVICE:
  719. if (s_jpu_major)
  720. unregister_chrdev_region(s_jpu_major, 1);
  721. if (s_jpu_register.virt_addr)
  722. iounmap((void *)s_jpu_register.virt_addr);
  723. return err;
  724. }
  725. static int jpu_remove(struct platform_device *pdev)
  726. {
  727. DPRINTK("[JPUDRV] jpu_remove\n");
  728. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  729. if (s_instance_pool.base) {
  730. vfree((const void *)s_instance_pool.base);
  731. s_instance_pool.base = 0;
  732. }
  733. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  734. if (s_video_memory.base) {
  735. iounmap((void *)s_video_memory.base);
  736. s_video_memory.base = 0;
  737. jmem_exit(&s_jmem);
  738. }
  739. #endif
  740. if (s_jpu_major > 0) {
  741. cdev_del(&s_jpu_cdev);
  742. unregister_chrdev_region(s_jpu_major, 1);
  743. s_jpu_major = 0;
  744. }
  745. #ifdef JPU_SUPPORT_ISR
  746. if (s_jpu_irq)
  747. free_irq(s_jpu_irq, &s_jpu_drv_context);
  748. #endif
  749. if (s_jpu_register.virt_addr)
  750. iounmap((void*)s_jpu_register.virt_addr);
  751. jpu_clk_put(s_jpu_clk);
  752. #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  753. return 0;
  754. }
  755. //#ifdef CONFIG_PM
  756. #if 1
  757. static int jpu_suspend(struct platform_device *pdev, pm_message_t state)
  758. {
  759. jpu_clk_disable(s_jpu_clk);
  760. return 0;
  761. }
  762. static int jpu_resume(struct platform_device *pdev)
  763. {
  764. jpu_clk_enable(s_jpu_clk);
  765. return 0;
  766. }
  767. #else
  768. #define jpu_suspend NULL
  769. #define jpu_resume NULL
  770. #endif /* !CONFIG_PM */
  771. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  772. static const struct of_device_id jpu_of_id_table[] = {
  773. { .compatible = "cm,codaj12-jpu-1" },
  774. { .compatible = "starfive,jpu" },
  775. {}
  776. };
  777. static struct platform_driver jpu_driver = {
  778. .driver = {
  779. .name = JPU_PLATFORM_DEVICE_NAME,
  780. .of_match_table = of_match_ptr(jpu_of_id_table),
  781. },
  782. .probe = jpu_probe,
  783. .remove = jpu_remove,
  784. .suspend = jpu_suspend,
  785. .resume = jpu_resume,
  786. };
  787. #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  788. static int __init jpu_init(void)
  789. {
  790. int res = 0;
  791. u32 i;
  792. DPRINTK("[JPUDRV] begin jpu_init\n");
  793. for (i=0; i<MAX_NUM_INSTANCE; i++) {
  794. init_waitqueue_head(&s_interrupt_wait_q[i]);
  795. }
  796. s_instance_pool.base = 0;
  797. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  798. res = platform_driver_register(&jpu_driver);
  799. #else
  800. res = jpu_probe(NULL);
  801. #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  802. DPRINTK("[JPUDRV] end jpu_init result=0x%x\n", res);
  803. return res;
  804. }
  805. static void __exit jpu_exit(void)
  806. {
  807. DPRINTK("[JPUDRV] [+]jpu_exit\n");
  808. #ifdef JPU_SUPPORT_PLATFORM_DRIVER_REGISTER
  809. platform_driver_unregister(&jpu_driver);
  810. #else /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  811. #ifdef JPU_SUPPORT_CLOCK_CONTROL
  812. #else
  813. jpu_clk_disable(s_jpu_clk);
  814. #endif /* JPU_SUPPORT_CLOCK_CONTROL */
  815. jpu_clk_put(s_jpu_clk);
  816. if (s_instance_pool.base) {
  817. vfree((const void *)s_instance_pool.base);
  818. s_instance_pool.base = 0;
  819. }
  820. #ifdef JPU_SUPPORT_RESERVED_VIDEO_MEMORY
  821. if (s_video_memory.base) {
  822. iounmap((void *)s_video_memory.base);
  823. s_video_memory.base = 0;
  824. jmem_exit(&s_jmem);
  825. }
  826. #endif /* JPU_SUPPORT_RESERVED_VIDEO_MEMORY */
  827. if (s_jpu_major > 0) {
  828. cdev_del(&s_jpu_cdev);
  829. unregister_chrdev_region(s_jpu_major, 1);
  830. s_jpu_major = 0;
  831. }
  832. #ifdef JPU_SUPPORT_ISR
  833. if (s_jpu_irq)
  834. free_irq(s_jpu_irq, &s_jpu_drv_context);
  835. #endif /* JPU_SUPPORT_ISR */
  836. if (s_jpu_register.virt_addr) {
  837. iounmap((void *)s_jpu_register.virt_addr);
  838. s_jpu_register.virt_addr = 0x00;
  839. }
  840. #endif /* JPU_SUPPORT_PLATFORM_DRIVER_REGISTER */
  841. DPRINTK("[JPUDRV] [-]jpu_exit\n");
  842. return;
  843. }
  844. MODULE_AUTHOR("A customer using C&M JPU, Inc.");
  845. MODULE_DESCRIPTION("JPU linux driver");
  846. MODULE_LICENSE("GPL");
  847. module_init(jpu_init);
  848. module_exit(jpu_exit);
  849. /*pmu define*/
  850. #define PMU_BASE_ADDR 0x17030000
  851. #define PMU_JPU_MASK (0x1 << 3)
  852. static void pmu_pd_set(jpu_clk_t *clk, int on_off, uint32_t pd_flag)
  853. {
  854. const uint32_t flag_off = 0x0c;
  855. const uint32_t sw_off = 0x44;
  856. void __iomem *base = ioremap(clk->pmu_base, 0x100);
  857. writel(pd_flag, base + flag_off);
  858. writel(0xff, base + sw_off);
  859. if (on_off) {
  860. writel(0x05, base + sw_off);
  861. writel(0x50, base + sw_off);
  862. } else {
  863. writel(0x0a, base + sw_off);
  864. writel(0xa0, base + sw_off);
  865. }
  866. iounmap(base);
  867. }
  868. #ifndef STARFIVE_JPU_SUPPORT_CLOCK_CONTROL
  869. #define CLK_ENABLE_DATA 1
  870. #define CLK_DISABLE_DATA 0
  871. #define CLK_EN_SHIFT 31
  872. #define CLK_EN_MASK 0x80000000U
  873. #define SAIF_BD_APBS_BASE 0x13020000
  874. #define CODAJ12_CLK_AXI_CTRL 0x108U
  875. #define CODAJ12_CLK_APB_CTRL 0x110U
  876. #define CODAJ12_CLK_CORE_CTRL 0x10cU
  877. #define RSTGEN_SOFTWARE_RESET_ASSERT1 0x2FCU
  878. #define RSTGEN_SOFTWARE_RESET_STATUS1 0x30CU
  879. #define RSTN_AXI_MASK (0x1 << 12)
  880. #define RSTN_CORE_MASK (0x1 << 13)
  881. #define RSTN_APB_MASK (0x1 << 14)
  882. static __maybe_unused uint32_t saif_get_reg(
  883. const volatile void __iomem *addr,
  884. uint32_t shift, uint32_t mask)
  885. {
  886. u32 tmp;
  887. tmp = readl(addr);
  888. tmp = (tmp & mask) >> shift;
  889. return tmp;
  890. }
  891. static void saif_set_reg(volatile void __iomem *addr, uint32_t data,
  892. uint32_t shift, uint32_t mask)
  893. {
  894. uint32_t tmp;
  895. tmp = readl(addr);
  896. tmp &= ~mask;
  897. tmp |= (data << shift) & mask;
  898. writel(tmp, addr);
  899. }
  900. static void saif_assert_rst(volatile void __iomem *addr,
  901. const volatile void __iomem *addr_status, uint32_t mask)
  902. {
  903. uint32_t tmp;
  904. tmp = readl(addr);
  905. tmp |= mask;
  906. writel(tmp, addr);
  907. do {
  908. tmp = readl(addr_status);
  909. } while ((tmp & mask) != 0);
  910. }
  911. static void saif_clear_rst(volatile void __iomem *addr,
  912. const volatile void __iomem *addr_status, uint32_t mask)
  913. {
  914. uint32_t tmp;
  915. tmp = readl(addr);
  916. tmp &= ~mask;
  917. writel(tmp, addr);
  918. do {
  919. tmp = readl(addr_status);
  920. } while ((tmp & mask) != mask);
  921. }
  922. static void jpu_clk_control(jpu_clk_t *clk, bool enable)
  923. {
  924. if (enable) {
  925. /*enable*/
  926. saif_set_reg(clk->apb_clk.en_ctrl, CLK_ENABLE_DATA, clk->en_shift, clk->en_mask);
  927. saif_set_reg(clk->axi_clk.en_ctrl, CLK_ENABLE_DATA, clk->en_shift, clk->en_mask);
  928. saif_set_reg(clk->core_clk.en_ctrl, CLK_ENABLE_DATA, clk->en_shift, clk->en_mask);
  929. /*clr-reset*/
  930. saif_clear_rst(clk->rst_ctrl, clk->rst_status, clk->apb_clk.rst_mask);
  931. saif_clear_rst(clk->rst_ctrl, clk->rst_status, clk->axi_clk.rst_mask);
  932. saif_clear_rst(clk->rst_ctrl, clk->rst_status, clk->core_clk.rst_mask);
  933. } else {
  934. /*assert-reset*/
  935. saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->apb_clk.rst_mask);
  936. saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->axi_clk.rst_mask);
  937. saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->core_clk.rst_mask);
  938. /*disable*/
  939. saif_set_reg(clk->apb_clk.en_ctrl, CLK_DISABLE_DATA, clk->en_shift, clk->en_mask);
  940. saif_set_reg(clk->axi_clk.en_ctrl, CLK_DISABLE_DATA, clk->en_shift, clk->en_mask);
  941. saif_set_reg(clk->core_clk.en_ctrl, CLK_DISABLE_DATA, clk->en_shift, clk->en_mask);
  942. }
  943. }
  944. static void jpu_clk_reset(jpu_clk_t *clk)
  945. {
  946. /*assert-reset*/
  947. saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->apb_clk.rst_mask);
  948. saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->axi_clk.rst_mask);
  949. saif_assert_rst(clk->rst_ctrl, clk->rst_status, clk->core_clk.rst_mask);
  950. /*clr-reset*/
  951. saif_clear_rst(clk->rst_ctrl, clk->rst_status, clk->apb_clk.rst_mask);
  952. saif_clear_rst(clk->rst_ctrl, clk->rst_status, clk->axi_clk.rst_mask);
  953. saif_clear_rst(clk->rst_ctrl, clk->rst_status, clk->core_clk.rst_mask);
  954. }
  955. int jpu_hw_reset(void)
  956. {
  957. if (!s_jpu_clk)
  958. return -1;
  959. jpu_clk_reset(s_jpu_clk);
  960. DPRINTK("[VPUDRV] reset vpu hardware. \n");
  961. return 0;
  962. }
  963. static int jpu_of_clk_get(struct platform_device *pdev, jpu_clk_t *jpu_clk)
  964. {
  965. if (!pdev)
  966. return -ENXIO;
  967. jpu_clk->pmu_base = PMU_BASE_ADDR;
  968. jpu_clk->clkgen = ioremap(SAIF_BD_APBS_BASE, 0x400);
  969. if (IS_ERR(jpu_clk->clkgen)) {
  970. dev_err(&pdev->dev, "ioremap clkgen failed.\n");
  971. return PTR_ERR(jpu_clk->clkgen);
  972. }
  973. /* clkgen define */
  974. jpu_clk->axi_clk.en_ctrl = jpu_clk->clkgen + CODAJ12_CLK_AXI_CTRL;
  975. jpu_clk->apb_clk.en_ctrl = jpu_clk->clkgen + CODAJ12_CLK_APB_CTRL;
  976. jpu_clk->core_clk.en_ctrl = jpu_clk->clkgen + CODAJ12_CLK_CORE_CTRL;
  977. jpu_clk->en_mask = CLK_EN_MASK;
  978. jpu_clk->en_shift = CLK_EN_SHIFT;
  979. /* rstgen define */
  980. jpu_clk->rst_ctrl = jpu_clk->clkgen + RSTGEN_SOFTWARE_RESET_ASSERT1;
  981. jpu_clk->rst_status = jpu_clk->clkgen + RSTGEN_SOFTWARE_RESET_STATUS1;
  982. jpu_clk->axi_clk.rst_mask = RSTN_AXI_MASK;
  983. jpu_clk->apb_clk.rst_mask = RSTN_APB_MASK;
  984. jpu_clk->core_clk.rst_mask = RSTN_CORE_MASK;
  985. return 0;
  986. }
  987. static jpu_clk_t *jpu_clk_get(struct platform_device *pdev)
  988. {
  989. jpu_clk_t *jpu_clk;
  990. jpu_clk = devm_kzalloc(&pdev->dev, sizeof(*jpu_clk), GFP_KERNEL);
  991. if (!jpu_clk)
  992. return NULL;
  993. if (jpu_of_clk_get(pdev, jpu_clk))
  994. goto err_get_clk;
  995. return jpu_clk;
  996. err_get_clk:
  997. kfree(jpu_clk);
  998. return NULL;
  999. }
  1000. static void jpu_clk_put(jpu_clk_t *clk)
  1001. {
  1002. iounmap(clk->clkgen);
  1003. }
  1004. static void jpu_clk_enable(jpu_clk_t *clk)
  1005. {
  1006. if (clk == NULL || IS_ERR(clk))
  1007. return;
  1008. pmu_pd_set(clk, true, PMU_JPU_MASK);
  1009. jpu_clk_control(clk, true);
  1010. DPRINTK("[VPUDRV] vpu_clk_enable\n");
  1011. }
  1012. static void jpu_clk_disable(jpu_clk_t *clk)
  1013. {
  1014. if (clk == NULL || IS_ERR(clk))
  1015. return;
  1016. jpu_clk_control(clk, false);
  1017. pmu_pd_set(clk, false, PMU_JPU_MASK);
  1018. DPRINTK("[VPUDRV] vpu_clk_disable\n");
  1019. }
  1020. #else /* STARFIVE_JPU_SUPPORT_CLOCK_CONTROL */
  1021. static int jpu_hw_reset(void)
  1022. {
  1023. DPRINTK("[JPUDRV] request jpu reset from application. \n");
  1024. return 0;
  1025. }
  1026. static int clk_check_err(struct clk *clk)
  1027. {
  1028. return !!(clk == NULL || IS_ERR(clk));
  1029. }
  1030. static int jpu_of_clk_get(struct platform_device *pdev, jpu_clk_t *jpu_clk)
  1031. {
  1032. struct resource *pmu;
  1033. struct device *dev = &pdev->dev;
  1034. pmu = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pmu");
  1035. if (IS_ERR(pmu))
  1036. dev_warn(dev, "get pmu failed.\n");
  1037. jpu_clk->pmu_base = pmu->start;
  1038. jpu_clk->apb_clk = devm_clk_get(dev, "apb_clk");
  1039. if (clk_check_err(jpu_clk->apb_clk)) {
  1040. dev_err(dev, "apb_clk get failed.\n");
  1041. return PTR_ERR(jpu_clk->apb_clk);
  1042. }
  1043. jpu_clk->axi_clk = devm_clk_get(dev, "axi_clk");
  1044. if (clk_check_err(jpu_clk->axi_clk)) {
  1045. dev_err(dev, "axi_clk get failed.\n");
  1046. return PTR_ERR(jpu_clk->axi_clk);
  1047. }
  1048. jpu_clk->core_clk = devm_clk_get(dev, "core_clk");
  1049. if (clk_check_err(jpu_clk->core_clk)) {
  1050. dev_err(dev, "core_clk get failed.\n");
  1051. return PTR_ERR(jpu_clk->core_clk);
  1052. }
  1053. return 0;
  1054. }
  1055. static jpu_clk_t *jpu_clk_get(struct platform_device *pdev)
  1056. {
  1057. jpu_clk_t *jpu_clk;
  1058. if (!pdev)
  1059. return NULL;
  1060. jpu_clk = devm_kzalloc(&pdev->dev, sizeof(*jpu_clk), GFP_KERNEL);
  1061. if (!jpu_clk)
  1062. return NULL;
  1063. if (jpu_of_clk_get(pdev, jpu_clk))
  1064. goto err_of_clk_get;
  1065. return jpu_clk;
  1066. err_of_clk_get:
  1067. kfree(jpu_clk);
  1068. return NULL;
  1069. }
  1070. static void jpu_clk_put(jpu_clk_t *clk)
  1071. {
  1072. if (!(clk_check_err(clk->apb_clk)))
  1073. clk_put(clk->apb_clk);
  1074. if (!(clk_check_err(clk->axi_clk)))
  1075. clk_put(clk->axi_clk);
  1076. if (!(clk_check_err(clk->core_clk)))
  1077. clk_put(clk->core_clk);
  1078. }
  1079. static void jpu_clk_enable(jpu_clk_t *clk)
  1080. {
  1081. pmu_pd_set(clk, true, PMU_JPU_MASK);
  1082. if (!(clk_check_err(clk->apb_clk)))
  1083. clk_prepare_enable(clk->apb_clk);
  1084. if (!(clk_check_err(clk->axi_clk)))
  1085. clk_prepare_enable(clk->axi_clk);
  1086. if (!(clk_check_err(clk->core_clk)))
  1087. clk_prepare_enable(clk->core_clk);
  1088. DPRINTK("[VPUDRV] vpu_clk_enable\n");
  1089. }
  1090. static void jpu_clk_disable(jpu_clk_t *clk)
  1091. {
  1092. if (!(clk_check_err(clk->apb_clk)))
  1093. clk_disable_unprepare(clk->apb_clk);
  1094. if (!(clk_check_err(clk->axi_clk)))
  1095. clk_disable_unprepare(clk->axi_clk);
  1096. if (!(clk_check_err(clk->core_clk)))
  1097. clk_disable_unprepare(clk->core_clk);
  1098. pmu_pd_set(clk, false, PMU_JPU_MASK);
  1099. }
  1100. #endif /* STARFIVE_JPU_SUPPORT_CLOCK_CONTROL */