drivers/video/fbdev/i810/i810_accel.c

Source file repositories/reference/linux-study-clean/drivers/video/fbdev/i810/i810_accel.c

File Facts

System
Linux kernel
Corpus path
drivers/video/fbdev/i810/i810_accel.c
Extension
.c
Size
12190 bytes
Lines
457
Domain
Driver Families
Bucket
drivers/video
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/fb.h>

#include "i810_regs.h"
#include "i810.h"
#include "i810_main.h"

static u32 i810fb_rop[] = {
	COLOR_COPY_ROP, /* ROP_COPY */
	XOR_ROP         /* ROP_XOR  */
};

/* Macros */
#define PUT_RING(n) {                                        \
	i810_writel(par->cur_tail, par->iring.virtual, n);   \
        par->cur_tail += 4;                                  \
        par->cur_tail &= RING_SIZE_MASK;                     \
}                                                                      

extern void flush_cache(void);

/************************************************************/

/* BLT Engine Routines */
static inline void i810_report_error(u8 __iomem *mmio)
{
	printk("IIR     : 0x%04x\n"
	       "EIR     : 0x%04x\n"
	       "PGTBL_ER: 0x%04x\n"
	       "IPEIR   : 0x%04x\n"
	       "IPEHR   : 0x%04x\n",
	       i810_readw(IIR, mmio),
	       i810_readb(EIR, mmio),
	       i810_readl(PGTBL_ER, mmio),
	       i810_readl(IPEIR, mmio), 
	       i810_readl(IPEHR, mmio));
}

/**
 * wait_for_space - check ring buffer free space
 * @space: amount of ringbuffer space needed in bytes
 * @par: pointer to i810fb_par structure
 *
 * DESCRIPTION:
 * The function waits until a free space from the ringbuffer
 * is available 
 */	
static inline int wait_for_space(struct fb_info *info, u32 space)
{
	struct i810fb_par *par = info->par;
	u32 head, count = WAIT_COUNT, tail;
	u8 __iomem *mmio = par->mmio_start_virtual;

	tail = par->cur_tail;
	while (count--) {
		head = i810_readl(IRING + 4, mmio) & RBUFFER_HEAD_MASK;	
		if ((tail == head) || 
		    (tail > head && 
		     (par->iring.size - tail + head) >= space) || 
		    (tail < head && (head - tail) >= space)) {
			return 0;	
		}
	}
	printk("ringbuffer lockup!!!\n");
	i810_report_error(mmio); 
	par->dev_flags |= LOCKUP;
	info->pixmap.scan_align = 1;
	return 1;
}

/** 
 * wait_for_engine_idle - waits for all hardware engines to finish
 * @par: pointer to i810fb_par structure
 *
 * DESCRIPTION:
 * This waits for lring(0), iring(1), and batch(3), etc to finish and
 * waits until ringbuffer is empty.
 */
static inline int wait_for_engine_idle(struct fb_info *info)
{
	struct i810fb_par *par = info->par;
	u8 __iomem *mmio = par->mmio_start_virtual;
	int count = WAIT_COUNT;

	if (wait_for_space(info, par->iring.size)) /* flush */
		return 1;

	while((i810_readw(INSTDONE, mmio) & 0x7B) != 0x7B && --count); 
	if (count) return 0;

Annotation

Implementation Notes