/* ** Function Name : MFC_Open ** ** Function Description : This function open MFC instace and return instance handle. */ DWORD MFC_Open( DWORD InitHandle, DWORD dwAccess, DWORD dwShareMode ) { MFC_HANDLE *handle; // Mutex Lock MFC_Mutex_Lock(); // Allocate & Clear MFC Handle handle = (MFC_HANDLE *) malloc(sizeof(MFC_HANDLE)); if (!handle) { RETAILMSG(1, (L"\n[MFC_Open Error] Momory Allocation Fail.\n")); MFC_Mutex_Release(); return 0; } memset(handle, 0, sizeof(MFC_HANDLE)); // Increment OpenHandle Count InterlockedIncrement(&_openhandle_count); // if (_openhandle_count == 1) // Handle for Power Control { // Save Specific Handle for Power Control gMfcHandlePower = handle; RETAILMSG(1, (L"\n[MFC_Open] Power Manager Handle Opened...\n")); } else if (_openhandle_count >= 2) // Handle for User Application { // Create MFC Instance handle->mfc_inst = MFCInst_Create(); if (!handle->mfc_inst) { RETAILMSG(1, (L"\n[MFC_Open Error] MFC Instance Creattion Fail.\n")); InterlockedDecrement(&_openhandle_count); free(handle); MFC_Mutex_Release(); return 0; } if (_openhandle_count == 2) // First Handle for User Application { // MFC HW Init Mfc_Pwr_On(); Mfc_Clk_On(); if (MFC_HW_Init() == FALSE) { Mfc_Clk_Off(); Mfc_Pwr_Off(); MFCInst_Delete(handle->mfc_inst); InterlockedDecrement(&_openhandle_count); MFC_Mutex_Release(); return 0; } Mfc_Clk_Off(); } } // Mutex Release MFC_Mutex_Release(); return (DWORD) handle; }
static int s3c_mfc_release(struct inode *inode, struct file *file) { MFC_HANDLE *handle = NULL; MFCINST_DEC_INBUF_TYPE inbuf_type; int ret; MFC_Mutex_Lock(); #ifdef CONFIG_MACH_SATURN lcd_gamma_change(LCD_IDLE); // when finishing playing video, AMOLED gamma change to idle mode #endif #if 1 //mfc.error.recovery // If the last issued command is timed out, reset the MFC for error recovery // When MFC doesn't respond with DEC_INIT command (timeout) // It seems that it doesn't operate normally. It doesn't even respond // to swfi command and locks up the cpu when going to sleep. // (SWFI instruction waits for the response from the DOMAIN-V) // if(mfc_critial_error) { printk(KERN_ERR "\x1b[1;31m" "@#@#@# Reset mfc for error recovery" "\x1b[0m \n"); MFC_HW_Init(); } #endif handle = (MFC_HANDLE *)file->private_data; if (handle->mfc_inst == NULL) { ret = -1; goto err_handle; }; //printk("Exit MFC Linux Driver\n"); inbuf_type = handle->mfc_inst->inbuf_type; LOG_MSG(LOG_TRACE, "mfc_release", "delete inst no : %d\n", handle->mfc_inst->inst_no); #if (MFC_LINE_RING_SHARE == 1) // In case of (MFC_LINE_RING_SHARE == 1), all the instances were reserved. // Therefore the instances need to be released. if (inbuf_type == DEC_INBUF_RING_BUF) { MfcInstPool_ReleaseAll(); } #endif MFCInst_Delete(handle->mfc_inst); kfree(handle); #ifdef USE_MFC_DOMAIN_GATING CLOCK_DISABLE; #endif /* USE_MFC_DOMAIN_GATING */ _openhandle_count--; if(_openhandle_count == 0) { #if defined(CONFIG_S3C6400_KDPMD) || defined(CONFIG_S3C6400_KDPMD_MODULE) mfc_pmdev.state = DEV_IDLE; kdpmd_set_event(mfc_pmdev.devid, KDPMD_DRVCLOSE); kdpmd_wakeup(); kdpmd_wait(mfc_pmdev.devid); #endif #ifdef CONFIG_CPU_FREQ set_dvfs_level(1); #endif /* CONFIG_CPU_FREQ */ #ifdef USE_MFC_DOMAIN_GATING DOMAIN_POWER_OFF; #endif /* USE_MFC_DOMAIN_GATING */ } ret = 0; err_handle: MFC_Mutex_Release(); return ret; }
static int s3c_mfc_probe(struct platform_device *pdev) { struct resource *res; int size; int ret; #ifdef USE_MFC_DOMAIN_GATING DOMAIN_POWER_ON; #endif /* USE_MFC_DOMAIN_GATING */ // mfc clock enable #ifdef CONFIG_PLAT_S3C64XX mfc_hclk = clk_get(&pdev->dev, "hclk_mfc"); if (!mfc_hclk || IS_ERR(mfc_hclk)) { #else mfc_hd1clk = clk_get(&pdev->dev, "mfc"); if (!mfc_hd1clk || IS_ERR(mfc_hd1clk)) { #endif /* CONFIG_PLAT_S3C64XX */ printk(KERN_ERR "failed to get mfc clk source\n"); return -ENOENT; } #ifndef CONFIG_PLAT_S5P64XX mfc_sclk = clk_get(&pdev->dev, "sclk_mfc"); if (!mfc_sclk || IS_ERR(mfc_sclk)) { printk(KERN_ERR "failed to get mfc clk source\n"); return -ENOENT; } mfc_pclk = clk_get(&pdev->dev, "pclk_mfc"); if (!mfc_pclk || IS_ERR(mfc_pclk)) { printk(KERN_ERR "failed to get mfc clk source\n"); return -ENOENT; } #endif /* CONFIG_PLAT_S5P64XX */ #ifdef USE_MFC_DOMAIN_GATING CLOCK_ENABLE; #endif /* USE_MFC_DOMAIN_GATING */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { printk(KERN_INFO "failed to get memory region resouce\n"); ret = -ENOENT; goto err_mem; } size = (res->end-res->start)+1; mfc_mem = request_mem_region(res->start, size, pdev->name); if (mfc_mem == NULL) { printk(KERN_INFO "failed to get memory region\n"); ret = -ENOENT; goto err_mem; } mfc_base = ioremap(res->start, size); if (mfc_base == 0) { printk(KERN_INFO "failed to ioremap() region\n"); ret = -EINVAL; goto err_ioremap; } res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (res == NULL) { printk(KERN_INFO "failed to get irq resource\n"); ret = -ENOENT; goto err_irq; } ret = request_irq(res->start, (irq_handler_t) s3c_mfc_irq, 0, pdev->name, pdev); if (ret != 0) { printk(KERN_INFO "failed to install irq (%d)\n", ret); goto err_irq; } if (MFC_Mutex_Create() == FALSE) { ret = -ENOMEM; goto err_mutex; } #ifndef CONFIG_PLAT_S5P64XX { unsigned mfc_clk_val; // mfc clock set 133 Mhz mfc_clk_val = readl(S3C_CLK_DIV0); mfc_clk_val |= (1<<28); __raw_writel(mfc_clk_val, S3C_CLK_DIV0); } #endif /* CONFIG_PLAT_S5P64XX */ ////////////////////////////////// // 2. MFC Memory Setup // ////////////////////////////////// if (MFC_MemorySetup() == FALSE) { ret = -ENOMEM; goto err_MFC_memory_setup; } ////////////////////////////////////// // 3. MFC Hardware Initialization // ////////////////////////////////////// if (MFC_HW_Init() == FALSE) { ret = -ENODEV; goto err_MFC_HW_Init; } ret = misc_register(&s3c_mfc_miscdev); if (ret < 0) goto err_misc_register; ret = 0; goto no_err; err_misc_register: err_MFC_HW_Init: err_MFC_memory_setup: MFC_Mutex_Delete (); err_mutex: free_irq (res->start, pdev); err_irq: iounmap (mfc_base); err_ioremap: release_resource(mfc_mem); kfree(mfc_mem); mfc_mem = NULL; err_mem: no_err: #ifdef USE_MFC_DOMAIN_GATING CLOCK_DISABLE; DOMAIN_POWER_OFF; #endif /* USE_MFC_DOMAIN_GATING */ return ret; } static int s3c_mfc_remove(struct platform_device *pdev) { misc_deregister(&s3c_mfc_miscdev); MFC_Mutex_Delete (); free_irq (IRQ_MFC, pdev); iounmap (mfc_base); if (mfc_mem != NULL) { release_resource(mfc_mem); kfree(mfc_mem); mfc_mem = NULL; } #ifdef USE_MFC_DOMAIN_GATING while (_openhandle_count-- > 0) { CLOCK_DISABLE; } DOMAIN_POWER_OFF; #endif /* USE_MFC_DOMAIN_GATING */ return 0; }
static int s3c_mfc_open(struct inode *inode, struct file *file) { MFC_HANDLE *handle; int ret; ////////////////// // Mutex Lock // ////////////////// MFC_Mutex_Lock(); #ifdef USE_MFC_DOMAIN_GATING if(_openhandle_count == 0) { DOMAIN_POWER_ON; } #endif /* USE_MFC_DOMAIN_GATING */ _openhandle_count++; #ifdef USE_MFC_DOMAIN_GATING CLOCK_ENABLE; #endif /* USE_MFC_DOMAIN_GATING */ if(_openhandle_count == 1) { #if defined(CONFIG_S3C6400_KDPMD) || defined(CONFIG_S3C6400_KDPMD_MODULE) kdpmd_set_event(mfc_pmdev.devid, KDPMD_DRVOPEN); kdpmd_wakeup(); kdpmd_wait(mfc_pmdev.devid); mfc_pmdev.state = DEV_RUNNING; printk("mfc_open woke up\n"); #endif ////////////////////////////////////// // 3. MFC Hardware Initialization // ////////////////////////////////////// if (MFC_HW_Init() == FALSE) { ret = -ENODEV; goto err_MFC_HW_Init; } } handle = (MFC_HANDLE *)kzalloc(sizeof(MFC_HANDLE), GFP_KERNEL); if(!handle) { LOG_MSG(LOG_ERROR, "s3c_mfc_open", "MFC open error\n"); ret = -1; goto err_kzmalloc; } ////////////////////////////// // MFC Instance creation // ////////////////////////////// handle->mfc_inst = MFCInst_Create(); if (handle->mfc_inst == NULL) { LOG_MSG(LOG_ERROR, "s3c_mfc_open", "MFC Instance allocation was failed!\r\n"); ret = -1; goto err_MFCInst_Create; } /* * MFC supports multi-instance. so each instance have own data structure * It saves file->private_data */ file->private_data = (MFC_HANDLE *)handle; #ifdef CONFIG_CPU_FREQ set_dvfs_level(0); #endif /* CONFIG_CPU_FREQ */ LOG_MSG(LOG_TRACE, "mfc_open", "MFC open success! \r\n"); ret = 0; goto no_err; err_MFCInst_Create: kfree (handle); err_kzmalloc: err_MFC_HW_Init: #ifdef USE_MFC_DOMAIN_GATING CLOCK_DISABLE; #endif /* USE_MFC_DOMAIN_GATING */ _openhandle_count --; #ifdef USE_MFC_DOMAIN_GATING if(_openhandle_count == 0) DOMAIN_POWER_OFF; #endif /* USE_MFC_DOMAIN_GATING */ no_err: MFC_Mutex_Release(); return ret; }