core.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 874 行 · 第 1/2 页

C
874
字号
	}	return &vga;}/* * Disable all display connectors on the interface module. */static void versatile_clcd_disable(struct clcd_fb *fb){	unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;	u32 val;	val = readl(sys_clcd);	val &= ~SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;	writel(val, sys_clcd);}/* * Enable the relevant connector on the interface module. */static void versatile_clcd_enable(struct clcd_fb *fb){	unsigned long sys_clcd = IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_CLCD_OFFSET;	u32 val;	val = readl(sys_clcd);	val &= ~SYS_CLCD_MODE_MASK;	switch (fb->fb.var.green.length) {	case 5:#if 0		/*		 * For some undocumented reason, we need to select 565 mode		 * even when using 555 with VGA.  Maybe this is only true		 * for the VGA output and needs to be done for LCD panels?		 * I can't get an explaination from the people who should		 * know.		 */		val |= SYS_CLCD_MODE_5551;		break;#endif	case 6:		val |= SYS_CLCD_MODE_565;		break;	case 8:		val |= SYS_CLCD_MODE_888;		break;	}	/*	 * Set the MUX	 */	writel(val, sys_clcd);	/*	 * And now enable the PSUs	 */	val |= SYS_CLCD_NLCDIOON | SYS_CLCD_PWR3V5SWITCH;	writel(val, sys_clcd);}static unsigned long framesize = SZ_1M;static int versatile_clcd_setup(struct clcd_fb *fb){	dma_addr_t dma;	fb->panel		= versatile_clcd_panel();	fb->fb.screen_base = dma_alloc_writecombine(&fb->dev->dev, framesize,						    &dma, GFP_KERNEL);	if (!fb->fb.screen_base) {		printk(KERN_ERR "CLCD: unable to map framebuffer\n");		return -ENOMEM;	}	fb->fb.fix.smem_start	= dma;	fb->fb.fix.smem_len	= framesize;	return 0;}static void versatile_clcd_remove(struct clcd_fb *fb){	dma_free_writecombine(&fb->dev->dev, fb->fb.fix.smem_len,			      fb->fb.screen_base, fb->fb.fix.smem_start);}static struct clcd_board clcd_plat_data = {	.name		= "Versatile PB",	.check		= clcdfb_check,	.decode		= clcdfb_decode,	.disable	= versatile_clcd_disable,	.enable		= versatile_clcd_enable,	.setup		= versatile_clcd_setup,	.remove		= versatile_clcd_remove,};#define AMBA_DEVICE(name,busid,base,plat)			\static struct amba_device name##_device = {			\	.dev		= {					\		.coherent_dma_mask = ~0,			\		.bus_id	= busid,				\		.platform_data = plat,				\	},							\	.res		= {					\		.start	= VERSATILE_##base##_BASE,		\		.end	= (VERSATILE_##base##_BASE) + SZ_4K - 1,\		.flags	= IORESOURCE_MEM,			\	},							\	.dma_mask	= ~0,					\	.irq		= base##_IRQ,				\	/* .dma		= base##_DMA,*/				\}#define AACI_IRQ	{ IRQ_AACI, NO_IRQ }#define AACI_DMA	{ 0x80, 0x81 }#define MMCI0_IRQ	{ IRQ_MMCI0A,IRQ_SIC_MMCI0B }#define MMCI0_DMA	{ 0x84, 0 }#define KMI0_IRQ	{ IRQ_SIC_KMI0, NO_IRQ }#define KMI0_DMA	{ 0, 0 }#define KMI1_IRQ	{ IRQ_SIC_KMI1, NO_IRQ }#define KMI1_DMA	{ 0, 0 }#define UART3_IRQ	{ IRQ_SIC_UART3, NO_IRQ }#define UART3_DMA	{ 0x86, 0x87 }#define SCI1_IRQ	{ IRQ_SIC_SCI3, NO_IRQ }#define SCI1_DMA	{ 0x88, 0x89 }#define MMCI1_IRQ	{ IRQ_MMCI1A, IRQ_SIC_MMCI1B }#define MMCI1_DMA	{ 0x85, 0 }/* * These devices are connected directly to the multi-layer AHB switch */#define SMC_IRQ		{ NO_IRQ, NO_IRQ }#define SMC_DMA		{ 0, 0 }#define MPMC_IRQ	{ NO_IRQ, NO_IRQ }#define MPMC_DMA	{ 0, 0 }#define CLCD_IRQ	{ IRQ_CLCDINT, NO_IRQ }#define CLCD_DMA	{ 0, 0 }#define DMAC_IRQ	{ IRQ_DMAINT, NO_IRQ }#define DMAC_DMA	{ 0, 0 }/* * These devices are connected via the core APB bridge */#define SCTL_IRQ	{ NO_IRQ, NO_IRQ }#define SCTL_DMA	{ 0, 0 }#define WATCHDOG_IRQ	{ IRQ_WDOGINT, NO_IRQ }#define WATCHDOG_DMA	{ 0, 0 }#define GPIO0_IRQ	{ IRQ_GPIOINT0, NO_IRQ }#define GPIO0_DMA	{ 0, 0 }#define GPIO1_IRQ	{ IRQ_GPIOINT1, NO_IRQ }#define GPIO1_DMA	{ 0, 0 }#define GPIO2_IRQ	{ IRQ_GPIOINT2, NO_IRQ }#define GPIO2_DMA	{ 0, 0 }#define GPIO3_IRQ	{ IRQ_GPIOINT3, NO_IRQ }#define GPIO3_DMA	{ 0, 0 }#define RTC_IRQ		{ IRQ_RTCINT, NO_IRQ }#define RTC_DMA		{ 0, 0 }/* * These devices are connected via the DMA APB bridge */#define SCI_IRQ		{ IRQ_SCIINT, NO_IRQ }#define SCI_DMA		{ 7, 6 }#define UART0_IRQ	{ IRQ_UARTINT0, NO_IRQ }#define UART0_DMA	{ 15, 14 }#define UART1_IRQ	{ IRQ_UARTINT1, NO_IRQ }#define UART1_DMA	{ 13, 12 }#define UART2_IRQ	{ IRQ_UARTINT2, NO_IRQ }#define UART2_DMA	{ 11, 10 }#define SSP_IRQ		{ IRQ_SSPINT, NO_IRQ }#define SSP_DMA		{ 9, 8 }/* FPGA Primecells */AMBA_DEVICE(aaci,  "fpga:04", AACI,     NULL);#ifdef CONFIG_MMCAMBA_DEVICE(mmc0,  "fpga:05", MMCI0,    &mmc0_plat_data);#endifAMBA_DEVICE(kmi0,  "fpga:06", KMI0,     NULL);AMBA_DEVICE(kmi1,  "fpga:07", KMI1,     NULL);AMBA_DEVICE(uart3, "fpga:09", UART3,    NULL);AMBA_DEVICE(sci1,  "fpga:0a", SCI1,     NULL);#ifdef CONFIG_MMCAMBA_DEVICE(mmc1,  "fpga:0b", MMCI1,    &mmc1_plat_data);#endif/* DevChip Primecells */AMBA_DEVICE(smc,   "dev:00",  SMC,      NULL);AMBA_DEVICE(mpmc,  "dev:10",  MPMC,     NULL);AMBA_DEVICE(clcd,  "dev:20",  CLCD,     &clcd_plat_data);AMBA_DEVICE(dmac,  "dev:30",  DMAC,     NULL);AMBA_DEVICE(sctl,  "dev:e0",  SCTL,     NULL);AMBA_DEVICE(wdog,  "dev:e1",  WATCHDOG, NULL);AMBA_DEVICE(gpio0, "dev:e4",  GPIO0,    NULL);AMBA_DEVICE(gpio1, "dev:e5",  GPIO1,    NULL);AMBA_DEVICE(gpio2, "dev:e6",  GPIO2,    NULL);AMBA_DEVICE(gpio3, "dev:e7",  GPIO3,    NULL);AMBA_DEVICE(rtc,   "dev:e8",  RTC,      NULL);AMBA_DEVICE(sci0,  "dev:f0",  SCI,      NULL);AMBA_DEVICE(uart0, "dev:f1",  UART0,    NULL);AMBA_DEVICE(uart1, "dev:f2",  UART1,    NULL);AMBA_DEVICE(uart2, "dev:f3",  UART2,    NULL);AMBA_DEVICE(ssp0,  "dev:f4",  SSP,      NULL);static struct amba_device *amba_devs[] __initdata = {	&dmac_device,	&uart0_device,	&uart1_device,	&uart2_device,	&uart3_device,	&smc_device,	&mpmc_device,	&clcd_device,	&sctl_device,	&wdog_device,	&gpio0_device,	&gpio1_device,	&gpio2_device,	&gpio3_device,	&rtc_device,	&sci0_device,	&ssp0_device,	&aaci_device,#ifdef CONFIG_MMC	&mmc0_device,#endif	&kmi0_device,	&kmi1_device,	&sci1_device,#ifdef CONFIG_MMC	&mmc1_device,#endif};#define VA_LEDS_BASE (IO_ADDRESS(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)static void versatile_leds_event(led_event_t ledevt){	unsigned long flags;	u32 val;	local_irq_save(flags);	val = readl(VA_LEDS_BASE);	switch (ledevt) {	case led_idle_start:		val = val & ~VERSATILE_SYS_LED0;		break;	case led_idle_end:		val = val | VERSATILE_SYS_LED0;		break;	case led_timer:		val = val ^ VERSATILE_SYS_LED1;		break;	case led_halted:		val = 0;		break;	default:		break;	}	writel(val, VA_LEDS_BASE);	local_irq_restore(flags);}static void __init versatile_init(void){	int i;	platform_device_register(&versatile_flash_device);	platform_device_register(&smc91x_device);	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {		struct amba_device *d = amba_devs[i];		amba_device_register(d, &iomem_resource);	}	leds_event = versatile_leds_event;}/* * Where is the timer (VA)? */#define TIMER0_VA_BASE		 IO_ADDRESS(VERSATILE_TIMER0_1_BASE)#define TIMER1_VA_BASE		(IO_ADDRESS(VERSATILE_TIMER0_1_BASE) + 0x20)#define TIMER2_VA_BASE		 IO_ADDRESS(VERSATILE_TIMER2_3_BASE)#define TIMER3_VA_BASE		(IO_ADDRESS(VERSATILE_TIMER2_3_BASE) + 0x20)#define VA_IC_BASE		 IO_ADDRESS(VERSATILE_VIC_BASE) /* * How long is the timer interval? */#define TIMER_INTERVAL	(TICKS_PER_uSEC * mSEC_10)#if TIMER_INTERVAL >= 0x100000#define TIMER_RELOAD	(TIMER_INTERVAL >> 8)		/* Divide by 256 */#define TIMER_CTRL	0x88				/* Enable, Clock / 256 */#define TICKS2USECS(x)	(256 * (x) / TICKS_PER_uSEC)#elif TIMER_INTERVAL >= 0x10000#define TIMER_RELOAD	(TIMER_INTERVAL >> 4)		/* Divide by 16 */#define TIMER_CTRL	0x84				/* Enable, Clock / 16 */#define TICKS2USECS(x)	(16 * (x) / TICKS_PER_uSEC)#else#define TIMER_RELOAD	(TIMER_INTERVAL)#define TIMER_CTRL	0x80				/* Enable */#define TICKS2USECS(x)	((x) / TICKS_PER_uSEC)#endif#define TIMER_CTRL_IE	(1 << 5)	/* Interrupt Enable *//* * What does it look like? */typedef struct TimerStruct {	unsigned long TimerLoad;	unsigned long TimerValue;	unsigned long TimerControl;	unsigned long TimerClear;} TimerStruct_t;extern unsigned long (*gettimeoffset)(void);/* * Returns number of ms since last clock interrupt.  Note that interrupts * will have been disabled by do_gettimeoffset() */static unsigned long versatile_gettimeoffset(void){	volatile TimerStruct_t *timer0 = (TimerStruct_t *)TIMER0_VA_BASE;	unsigned long ticks1, ticks2, status;	/*	 * Get the current number of ticks.  Note that there is a race	 * condition between us reading the timer and checking for	 * an interrupt.  We get around this by ensuring that the	 * counter has not reloaded between our two reads.	 */	ticks2 = timer0->TimerValue & 0xffff;	do {		ticks1 = ticks2;		status = __raw_readl(VA_IC_BASE + VIC_IRQ_RAW_STATUS);		ticks2 = timer0->TimerValue & 0xffff;	} while (ticks2 > ticks1);	/*	 * Number of ticks since last interrupt.	 */	ticks1 = TIMER_RELOAD - ticks2;	/*	 * Interrupt pending?  If so, we've reloaded once already.	 *	 * FIXME: Need to check this is effectively timer 0 that expires	 */	if (status & IRQMASK_TIMERINT0_1)		ticks1 += TIMER_RELOAD;	/*	 * Convert the ticks to usecs	 */	return TICKS2USECS(ticks1);}/* * IRQ handler for the timer */static irqreturn_t versatile_timer_interrupt(int irq, void *dev_id, struct pt_regs *regs){	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;	// ...clear the interrupt	timer0->TimerClear = 1;	timer_tick(regs);	return IRQ_HANDLED;}static struct irqaction versatile_timer_irq = {	.name		= "Versatile Timer Tick",	.flags		= SA_INTERRUPT,	.handler	= versatile_timer_interrupt};/* * Set up timer interrupt, and return the current time in seconds. */void __init versatile_init_time(void){	volatile TimerStruct_t *timer0 = (volatile TimerStruct_t *)TIMER0_VA_BASE;	volatile TimerStruct_t *timer1 = (volatile TimerStruct_t *)TIMER1_VA_BASE;	volatile TimerStruct_t *timer2 = (volatile TimerStruct_t *)TIMER2_VA_BASE;	volatile TimerStruct_t *timer3 = (volatile TimerStruct_t *)TIMER3_VA_BASE;	/* 	 * set clock frequency: 	 *	VERSATILE_REFCLK is 32KHz	 *	VERSATILE_TIMCLK is 1MHz	 */	*(volatile unsigned int *)IO_ADDRESS(VERSATILE_SCTL_BASE) |= 	  ((VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER2_EnSel) | 	   (VERSATILE_TIMCLK << VERSATILE_TIMER3_EnSel) | (VERSATILE_TIMCLK << VERSATILE_TIMER4_EnSel));	/*	 * Initialise to a known state (all timers off)	 */	timer0->TimerControl = 0;	timer1->TimerControl = 0;	timer2->TimerControl = 0;	timer3->TimerControl = 0;	timer0->TimerLoad    = TIMER_RELOAD;	timer0->TimerValue   = TIMER_RELOAD;	timer0->TimerControl = TIMER_CTRL | 0x40 | TIMER_CTRL_IE;  /* periodic + IE */	/* 	 * Make irqs happen for the system timer	 */	setup_irq(IRQ_TIMERINT0_1, &versatile_timer_irq);	gettimeoffset = versatile_gettimeoffset;}MACHINE_START(VERSATILE_PB, "ARM-Versatile PB")	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")	BOOT_MEM(0x00000000, 0x101f1000, 0xf11f1000)	BOOT_PARAMS(0x00000100)	MAPIO(versatile_map_io)	INITIRQ(versatile_init_irq)	INITTIME(versatile_init_time)	INIT_MACHINE(versatile_init)MACHINE_END

⌨️ 快捷键说明

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