void _g2d_command_handler(g2d_command_t *cmd) { G2D_DBG("start to handle command (0x%04x)\n", cmd->ctx.flag); switch (cmd->ctx.flag) { case G2D_FLAG_END_OF_FRAME: g2d_drv_fb_queue_buffer(cmd->ctx.fb_id); break; case G2D_FLAG_FLUSH: break; case G2D_FLAG_MIRROR_FRONT_FB: if (g2d_drv_fb_fill_mirror_cmd(&cmd->ctx) != 0) break; default: { #ifdef G2D_PROFILE struct timeval t1, t2; do_gettimeofday(&t1); #endif g2d_drv_power_on(); g2d_drv_run(&cmd->ctx); while (g2d_drv_get_status()) { wait_event_interruptible_timeout(isr_wait_queue, !g2d_drv_get_status(), (30 * HZ / 1000)); if (g2d_drv_get_status()) G2D_ERR("TIMEOUT: G2D is still busy"); } #ifdef G2D_PROFILE do_gettimeofday(&t2); G2D_INF("process time (%u)\n", (t2.tv_sec - t1.tv_sec) * 1000000 + (t2.tv_usec - t1.tv_usec)); #endif #ifdef G2D_DEBUG _g2d_reg_dump(); #endif g2d_drv_reset(); g2d_drv_power_off(); } break; } G2D_DBG("handle command (0x%04x) W2M(0x%08x) L0(0x%08x) L1(0x%08x) L2(0x%08x) L3(0x%08x) done\n", cmd->ctx.flag, ioread32(0xF20C5044), ioread32(0xF20C5084), ioread32(0xF20C50C4), ioread32(0xF20C5104), ioread32(0xF20C5144)); memset(&cmd->ctx, 0, sizeof(g2d_context_t)); #ifdef G2D_QUEUE if (cmd->sync_cmd) { cmd->sync_cmd = false; up(&cmd->sync); } up(&cmd->lock); #endif }
void _g2d_command_handler(g2d_command_t *cmd) { G2D_DBG("start to handle command\n"); #ifdef G2D_QUEUE if (cmd->ctx.end_of_frame) { g2d_drv_fb_queue_buffer(cmd->ctx.fb_id); up(&cmd->lock); return; } #endif g2d_drv_power_on(); g2d_drv_run(&cmd->ctx); wait_event_interruptible(isr_wait_queue, !g2d_drv_get_status()); #ifdef G2D_DEBUG _g2d_reg_dump(); #endif g2d_drv_power_off(); G2D_DBG("handle command done\n"); #ifdef G2D_QUEUE up(&cmd->lock); #endif }
int g2d_allocate_mva(unsigned int va, unsigned int *mva, unsigned int size) { int err = 0; if (!_m4u_g2d_func.isInit) { G2D_ERR("m4u is not initialized\n"); return -1; } G2D_DBG("try to allocate mva with 0x%x (%d)\n", va, size); err = _m4u_g2d_func.m4u_alloc_mva(M4U_CLNTMOD_G2D, va, size, mva); if (err != 0) { G2D_ERR("failed to allocate mva\n"); return -1; } err = _m4u_g2d_func.m4u_insert_tlb_range(M4U_CLNTMOD_G2D, *mva, *mva + size - 1, RT_RANGE_HIGH_PRIORITY, 1); if (err != 0) { G2D_ERR("failed to insert m4u tlb\n"); _m4u_g2d_func.m4u_dealloc_mva(M4U_CLNTMOD_G2D, va, size, *mva); return -1; } return 0; }
void g2d_drv_run(g2d_context_t *g2d_ctx) { #ifdef G2D_PROFILE struct timeval t1, t2; do_gettimeofday(&t1); #endif HARD_RESET_G2D_ENGINE; REG_G2D_MODE_CON = 0; REG_G2D_ROI_CON = 0; REG_G2D_SLOW_DOWN = 0x00400000; REG_G2D_IRQ |= G2D_IRQ_ENABLE_BIT; _g2d_drv_set_dst_info(g2d_ctx); if (g2d_ctx->flag & G2D_FLAG_MIRROR_FRONT_FB) _g2d_drv_set_mirror_fb(g2d_ctx); else if (g2d_ctx->flag & G2D_FLAG_AFFINE_TRANSFORM) _g2d_drv_set_affine_info(g2d_ctx); else _g2d_drv_set_bitblt_info(g2d_ctx); _g2d_drv_set_roi_info(g2d_ctx); #ifdef G2D_PROFILE do_gettimeofday(&t2); G2D_DBG("register config time (%u)\n", (t2.tv_sec - t1.tv_sec) * 1000000 + (t2.tv_usec - t1.tv_usec)); #endif START_G2D_ENGINE; }
int g2d_deallocate_mva(unsigned int va, unsigned int mva, unsigned int size) { G2D_DBG("try to deallocate mva with 0x%x (%d)\n", va, size); m4u_invalid_tlb_range(M4U_CLNTMOD_G2D, mva, mva + size - 1); m4u_dealloc_mva(M4U_CLNTMOD_G2D, va, size, mva); return 0; }
static irqreturn_t g2d_drv_isr(int irq, void *dev_id) { for(;;) { if (!g2d_drv_get_status()) break; G2D_DBG("handle interrupt, status : %d\n", g2d_drv_get_status()); } wake_up_interruptible(&isr_wait_queue); return IRQ_HANDLED; }
int g2d_deallocate_mva(unsigned int va, unsigned int mva, unsigned int size) { if (!_m4u_g2d_func.isInit) { G2D_ERR("m4u is not initialized\n"); return -1; } G2D_DBG("try to deallocate mva with 0x%x (%d)\n", va, size); _m4u_g2d_func.m4u_invalid_tlb_range(M4U_CLNTMOD_G2D, mva, mva + size - 1); _m4u_g2d_func.m4u_dealloc_mva(M4U_CLNTMOD_G2D, va, size, mva); return 0; }
void g2d_drv_run(g2d_context_t *g2d_ctx) { #ifdef G2D_PROFILE struct timeval t1, t2; do_gettimeofday(&t1); #endif HARD_RESET_G2D_ENGINE; REG_G2D_MODE_CON = 0; REG_G2D_ROI_CON = 0; REG_G2D_SLOW_DOWN = 0x00400000; REG_G2D_IRQ |= G2D_IRQ_ENABLE_BIT; _g2d_drv_set_dst_info(g2d_ctx); if (g2d_ctx->flag & G2D_FLAG_MIRROR_FRONT_FB) _g2d_drv_set_mirror_fb(g2d_ctx); else if (g2d_ctx->flag & G2D_FLAG_AFFINE_TRANSFORM) _g2d_drv_set_affine_info(g2d_ctx); else _g2d_drv_set_bitblt_info(g2d_ctx); _g2d_drv_set_roi_info(g2d_ctx); #ifdef G2D_PROFILE do_gettimeofday(&t2); G2D_DBG("register config time (%u)\n", (t2.tv_sec - t1.tv_sec) * 1000000 + (t2.tv_usec - t1.tv_usec)); #endif if (g2d_ctx->cache_clean) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,27)) on_each_cpu(per_cpu_cache_flush, NULL, 1); #else on_each_cpu(per_cpu_cache_flush, NULL, 0, 1); #endif #ifdef CONFIG_OUTER_CACHE outer_clean_all(); #endif } START_G2D_ENGINE; }
static int g2d_release(struct inode *inode, struct file *file) { G2D_DBG("G2D Driver release\n"); return 0; }
static ssize_t g2d_read(struct file *file, char __user *data, size_t len, loff_t *ppos) { G2D_DBG("driver read\n"); return 0; }
static int g2d_open(struct inode *inode, struct file *file) { G2D_DBG("driver open\n"); return 0; }
static long g2d_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { int ret = 0; switch (cmd) { #ifdef G2D_QUEUE case G2D_IOCTL_ASYNCCMD: ret = _g2d_queue_command(arg, false); G2D_DBG("insert async command successfully\n"); break; case G2D_IOCTL_SYNCCMD: ret = _g2d_queue_command(arg, true); G2D_DBG("insert sync command successfully\n"); break; #else case G2D_IOCTL_SYNCCMD: spin_lock(&g2d_cmd_spinlock); if (copy_from_user(&g2d_cmd_buffer->ctx, (void *)arg, sizeof(g2d_context_t))) { G2D_ERR("copy from user is failed\n"); return -EFAULT; } _g2d_command_handler(g2d_cmd_buffer); spin_unlock(&g2d_cmd_spinlock); break; #endif case G2D_IOCTL_CONNECTFB: if (g2d_drv_fb_init() != 0) { G2D_ERR("failed to connect fb driver\n"); return -EFAULT; } break; case G2D_IOCTL_DISCONNECTFB: g2d_drv_fb_deinit(); break; case G2D_IOCTL_DEQUEUEFB: { fb_buffer_t *buffer = g2d_drv_fb_dequeue_buffer(); if (buffer == NULL) { G2D_ERR("failed to get framebuffer\n"); return -EFAULT; } if (copy_to_user((void *)arg, &buffer->info, sizeof(g2d_buffer_t))) { G2D_ERR("copy to user is failed\n"); return -EFAULT; } } break; case G2D_IOCTL_ENQUEUEFB: #ifdef G2D_QUEUE { g2d_context_t ctx; memset(&ctx, 0, sizeof(g2d_context_t)); ctx.flag = G2D_FLAG_END_OF_FRAME; if (copy_from_user(&ctx.fb_id, (void *)arg, sizeof(int))) { G2D_ERR("copy from user is failed\n"); return -EFAULT; } _g2d_queue_command2(&ctx, false); } #else { spin_lock(&g2d_cmd_spinlock); g2d_cmd_buffer->ctx.flag = G2D_FLAG_END_OF_FRAME; if (copy_from_user(&g2d_cmd_buffer->ctx.fb_id, (void *)arg, sizeof(int))) { G2D_ERR("copy from user is failed\n"); return -EFAULT; } _g2d_command_handler(g2d_cmd_buffer); spin_unlock(&g2d_cmd_spinlock); } #endif break; } return ret; }