⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sh7722gfx.c

📁 DirectFB1.1.1 技术研究类型软件
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *	SH7722 Graphics Device * *	Copyright (C) 2006-2007  IGEL Co.,Ltd * *      Written by Denis Oliver Kropp <dok@directfb.org> * * *	This program is free software; you can redistribute it and/or *	modify it under the terms of the GNU General Public License v2 *	as published by the Free Software Foundation. */#include <linux/module.h>#include <linux/version.h>#include <linux/interrupt.h>#include <linux/miscdevice.h>#include <linux/mm.h>#include <linux/sched.h>#include <asm/io.h>#include <asm/uaccess.h>#include <sh7722gfx.h>//#define SH7722GFX_DEBUG//#define SH7722GFX_IRQ_POLLER/**********************************************************************************************************************/#define	ENGINE_REG_TOP   0xfd000000#define SH7722_BEU_BASE  0xFE930000#define BEM_REG(x)       (*(volatile u32*)((x)+ENGINE_REG_TOP))#define BEU_REG(x)       (*(volatile u32*)((x)+SH7722_BEU_BASE))#define	BEM_HC_STATUS			BEM_REG(0x00000)#define	BEM_HC_RESET			BEM_REG(0x00004)#define	BEM_HC_CLOCK			BEM_REG(0x00008)#define	BEM_HC_INT_STATUS		BEM_REG(0x00020)#define	BEM_HC_INT_MASK			BEM_REG(0x00024)#define	BEM_HC_INT_CLEAR		BEM_REG(0x00028)#define	BEM_HC_CACHE_FLUSH		BEM_REG(0x0002C)#define	BEM_HC_DMA_ADR			BEM_REG(0x00040)#define	BEM_HC_DMA_START		BEM_REG(0x00044)#define	BEM_HC_DMA_STOP			BEM_REG(0x00048)#define	BEM_PE_CACHE			BEM_REG(0x010B0)#define BEVTR                   BEU_REG(0x018C)/**********************************************************************************************************************/#ifdef SH7722GFX_DEBUG#define QPRINT(x...)     do {                                                        \     char buf[128];                                                                  \     struct timeval tv;                                                              \     do_gettimeofday( &tv );                                                         \     snprintf( buf, sizeof(buf), x );                                                \     printk( KERN_DEBUG "%ld.%03ld.%03ld - %-17s: %s\n",                             \             tv.tv_sec - base_time.tv_sec,                                           \             tv.tv_usec / 1000, tv.tv_usec % 1000, __FUNCTION__, buf );              \} while (0)#else#define QPRINT(x...)     do {} while (0)#endif#define QDUMP(msg)       QPRINT( "%-12s (%s, hw %5d-%5d, next %5d-%5d, %svalid, "    \                                 "HC %07x, INT %06x)", msg,                          \                                 shared->hw_running ? "running" : "   idle",         \                                 shared->hw_start,                                   \                                 shared->hw_end,                                     \                                 shared->next_start,                                 \                                 shared->next_end,                                   \                                 shared->next_valid ? "  " : "in",                   \                                 BEM_HC_STATUS, BEM_HC_INT_STATUS );/**********************************************************************************************************************/static DECLARE_WAIT_QUEUE_HEAD( wait_idle );static DECLARE_WAIT_QUEUE_HEAD( wait_next );static SH7722GfxSharedArea *shared;static struct timeval       base_time;#ifndef SHARED_AREA_PHYSstatic struct page         *shared_page;static unsigned int         shared_order;#endif#ifdef SH7722GFX_IRQ_POLLERstatic int                  stop_poller;#endif/**********************************************************************************************************************/static intsh7722_reset( SH7722GfxSharedArea *shared ){     int i;     do_gettimeofday( &base_time );     QPRINT( "Resetting hardware..." );     BEM_HC_CLOCK = 0;     for (i=0; i<30000; i++);     BEM_HC_CLOCK = 0x1111;     BEM_HC_RESET = 0x1111;     for (i=0; i<30000; i++);     BEM_HC_RESET = 0;     QPRINT( "Initializing shared area..." );     memset( (void*) shared, 0, sizeof(SH7722GfxSharedArea) );     shared->buffer_phys = virt_to_phys(&shared->buffer[0]);     shared->magic       = SH7722GFX_SHARED_MAGIC;     QPRINT( "Clearing interrupts..." );     BEM_HC_INT_CLEAR = 0x111111;     BEM_HC_INT_MASK  = 0x110011;     BEM_HC_CACHE_FLUSH = 0;     QDUMP( "Ready" );     return 0;}static intsh7722_wait_idle( SH7722GfxSharedArea *shared ){     int ret;     QDUMP( "Waiting....." );     /* Does not need to be atomic. There's a lock in user space,      * but anyhow, this is just for statistics. */     shared->num_wait_idle++;     ret = wait_event_interruptible_timeout( wait_idle, !shared->hw_running, 42*HZ );     if (!ret) {          printk( KERN_ERR "%s: TIMEOUT! (%srunning, hw %d-%d, next %d-%d - %svalid, "                           "STATUS 0x%08x, INT_STATUS 0x%08x)\n",                  __FUNCTION__,                  shared->hw_running ? "" : "not ",                  shared->hw_start,                  shared->hw_end,                  shared->next_start,                  shared->next_end,                  shared->next_valid ? "" : "not ",                  BEM_HC_STATUS, BEM_HC_INT_STATUS );     }     QDUMP( "........done" );     return (ret > 0) ? 0 : (ret < 0) ? ret : -ETIMEDOUT;}static intsh7722_wait_next( SH7722GfxSharedArea *shared ){     int ret;     QDUMP( "Waiting....." );     /* Does not need to be atomic. There's a lock in user space,      * but anyhow, this is just for statistics. */     shared->num_wait_next++;     ret = wait_event_interruptible_timeout( wait_next, !shared->hw_running ||                                             shared->next_start == shared->next_end, 42*HZ );     if (!ret) {          printk( KERN_ERR "%s: TIMEOUT! (%srunning, hw %d-%d, next %d-%d - %svalid, "                           "STATUS 0x%08x, INT_STATUS 0x%08x)\n",                  __FUNCTION__,                  shared->hw_running ? "" : "not ",                  shared->hw_start,                  shared->hw_end,                  shared->next_start,                  shared->next_end,                  shared->next_valid ? "" : "not ",                  BEM_HC_STATUS, BEM_HC_INT_STATUS );     }     QDUMP( "........done" );     return (ret > 0) ? 0 : (ret < 0) ? ret : -ETIMEDOUT;}/**********************************************************************************************************************/static irqreturn_tsh7722_beu_irq( int irq, void *ctx ){     BEVTR = 0;     /* Nothing here so far. But Vsync could be added. */     return IRQ_HANDLED;}static irqreturn_tsh7722_tdg_irq( int irq, void *ctx ){     SH7722GfxSharedArea *shared = ctx;     u32                  status = BEM_HC_INT_STATUS;     if (! (status & 0x111111)) {#ifndef SH7722GFX_IRQ_POLLER          printk( KERN_WARNING "%s: bogus interrupt, INT_STATUS 0x%08x!\n", __FUNCTION__, status );#endif          return IRQ_NONE;     }     if (status & ~0x100)          QDUMP( "-Interrupt" );     if (status & ~0x101100)          printk( KERN_ERR "%s: error! INT_STATUS 0x%08x!\n", __FUNCTION__, status );     shared->num_interrupts++;     /* Clear the interrupt. */     BEM_HC_INT_CLEAR = status;     if (status & 0x100010) {          if (!shared->hw_running)               printk( KERN_WARNING "%s: hw not running? INT_STATUS 0x%08x!\n", __FUNCTION__, status );          if (status & 0x10) {               printk( KERN_ERR "%s: RUNAWAY! (%srunning, hw %d-%d, next %d-%d - %svalid, "                                "STATUS 0x%08x, INT_STATUS 0x%08x)\n",                       __FUNCTION__,                       shared->hw_running ? "" : "not ",                       shared->hw_start,                       shared->hw_end,                       shared->next_start,                       shared->next_end,                       shared->next_valid ? "" : "not ",                       BEM_HC_STATUS, status );               BEM_HC_RESET = 0x1111;          }          /* Next valid means user space is not in the process of extending the buffer. */          if (shared->next_valid && shared->next_start != shared->next_end) {               shared->hw_start = shared->next_start;               shared->hw_end   = shared->next_end;               shared->next_start = shared->next_end = (shared->hw_end + 1 + 3) & ~3;               shared->next_valid = 0;               shared->num_words += shared->hw_end - shared->hw_start;               shared->num_starts++;               QDUMP( " '-> Start!" );               BEM_HC_DMA_ADR   = shared->buffer_phys + shared->hw_start*4;               BEM_HC_DMA_START = 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -