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

📄 core.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/arch/arm/mach-versatile/core.c * *  Copyright (C) 1999 - 2003 ARM Limited *  Copyright (C) 2000 Deep Blue Solutions Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <linux/init.h>#include <linux/device.h>#include <linux/dma-mapping.h>#include <linux/platform_device.h>#include <linux/sysdev.h>#include <linux/interrupt.h>#include <linux/amba/bus.h>#include <linux/amba/clcd.h>#include <linux/clocksource.h>#include <linux/clockchips.h>#include <asm/cnt32_to_63.h>#include <asm/system.h>#include <asm/hardware.h>#include <asm/io.h>#include <asm/irq.h>#include <asm/leds.h>#include <asm/hardware/arm_timer.h>#include <asm/hardware/icst307.h>#include <asm/hardware/vic.h>#include <asm/mach-types.h>#include <asm/mach/arch.h>#include <asm/mach/flash.h>#include <asm/mach/irq.h>#include <asm/mach/time.h>#include <asm/mach/map.h>#include <asm/mach/mmc.h>#include "core.h"#include "clock.h"/* * All IO addresses are mapped onto VA 0xFFFx.xxxx, where x.xxxx * is the (PA >> 12). * * Setup a VA for the Versatile Vectored Interrupt Controller. */#define __io_address(n)		__io(IO_ADDRESS(n))#define VA_VIC_BASE		__io_address(VERSATILE_VIC_BASE)#define VA_SIC_BASE		__io_address(VERSATILE_SIC_BASE)static void sic_mask_irq(unsigned int irq){	irq -= IRQ_SIC_START;	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);}static void sic_unmask_irq(unsigned int irq){	irq -= IRQ_SIC_START;	writel(1 << irq, VA_SIC_BASE + SIC_IRQ_ENABLE_SET);}static struct irq_chip sic_chip = {	.name	= "SIC",	.ack	= sic_mask_irq,	.mask	= sic_mask_irq,	.unmask	= sic_unmask_irq,};static voidsic_handle_irq(unsigned int irq, struct irq_desc *desc){	unsigned long status = readl(VA_SIC_BASE + SIC_IRQ_STATUS);	if (status == 0) {		do_bad_IRQ(irq, desc);		return;	}	do {		irq = ffs(status) - 1;		status &= ~(1 << irq);		irq += IRQ_SIC_START;		desc = irq_desc + irq;		desc_handle_irq(irq, desc);	} while (status);}#if 1#define IRQ_MMCI0A	IRQ_VICSOURCE22#define IRQ_AACI	IRQ_VICSOURCE24#define IRQ_ETH		IRQ_VICSOURCE25#define PIC_MASK	0xFFD00000#else#define IRQ_MMCI0A	IRQ_SIC_MMCI0A#define IRQ_AACI	IRQ_SIC_AACI#define IRQ_ETH		IRQ_SIC_ETH#define PIC_MASK	0#endifvoid __init versatile_init_irq(void){	unsigned int i;	vic_init(VA_VIC_BASE, IRQ_VIC_START, ~0);	set_irq_chained_handler(IRQ_VICSOURCE31, sic_handle_irq);	/* Do second interrupt controller */	writel(~0, VA_SIC_BASE + SIC_IRQ_ENABLE_CLEAR);	for (i = IRQ_SIC_START; i <= IRQ_SIC_END; i++) {		if ((PIC_MASK & (1 << (i - IRQ_SIC_START))) == 0) {			set_irq_chip(i, &sic_chip);			set_irq_handler(i, handle_level_irq);			set_irq_flags(i, IRQF_VALID | IRQF_PROBE);		}	}	/*	 * Interrupts on secondary controller from 0 to 8 are routed to	 * source 31 on PIC.	 * Interrupts from 21 to 31 are routed directly to the VIC on	 * the corresponding number on primary controller. This is controlled	 * by setting PIC_ENABLEx.	 */	writel(PIC_MASK, VA_SIC_BASE + SIC_INT_PIC_ENABLE);}static struct map_desc versatile_io_desc[] __initdata = {	{		.virtual	=  IO_ADDRESS(VERSATILE_SYS_BASE),		.pfn		= __phys_to_pfn(VERSATILE_SYS_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  IO_ADDRESS(VERSATILE_SIC_BASE),		.pfn		= __phys_to_pfn(VERSATILE_SIC_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  IO_ADDRESS(VERSATILE_VIC_BASE),		.pfn		= __phys_to_pfn(VERSATILE_VIC_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  IO_ADDRESS(VERSATILE_SCTL_BASE),		.pfn		= __phys_to_pfn(VERSATILE_SCTL_BASE),		.length		= SZ_4K * 9,		.type		= MT_DEVICE	},#ifdef CONFIG_MACH_VERSATILE_AB 	{		.virtual	=  IO_ADDRESS(VERSATILE_GPIO0_BASE),		.pfn		= __phys_to_pfn(VERSATILE_GPIO0_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  IO_ADDRESS(VERSATILE_IB2_BASE),		.pfn		= __phys_to_pfn(VERSATILE_IB2_BASE),		.length		= SZ_64M,		.type		= MT_DEVICE	},#endif#ifdef CONFIG_DEBUG_LL 	{		.virtual	=  IO_ADDRESS(VERSATILE_UART0_BASE),		.pfn		= __phys_to_pfn(VERSATILE_UART0_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	},#endif#ifdef CONFIG_PCI 	{		.virtual	=  IO_ADDRESS(VERSATILE_PCI_CORE_BASE),		.pfn		= __phys_to_pfn(VERSATILE_PCI_CORE_BASE),		.length		= SZ_4K,		.type		= MT_DEVICE	}, {		.virtual	=  (unsigned long)VERSATILE_PCI_VIRT_BASE,		.pfn		= __phys_to_pfn(VERSATILE_PCI_BASE),		.length		= VERSATILE_PCI_BASE_SIZE,		.type		= MT_DEVICE	}, {		.virtual	=  (unsigned long)VERSATILE_PCI_CFG_VIRT_BASE,		.pfn		= __phys_to_pfn(VERSATILE_PCI_CFG_BASE),		.length		= VERSATILE_PCI_CFG_BASE_SIZE,		.type		= MT_DEVICE	},#if 0 	{		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE0,		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE0),		.length		= SZ_16M,		.type		= MT_DEVICE	}, {		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE1,		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE1),		.length		= SZ_16M,		.type		= MT_DEVICE	}, {		.virtual	=  VERSATILE_PCI_VIRT_MEM_BASE2,		.pfn		= __phys_to_pfn(VERSATILE_PCI_MEM_BASE2),		.length		= SZ_16M,		.type		= MT_DEVICE	},#endif#endif};void __init versatile_map_io(void){	iotable_init(versatile_io_desc, ARRAY_SIZE(versatile_io_desc));}#define VERSATILE_REFCOUNTER	(__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_24MHz_OFFSET)/* * This is the Versatile sched_clock implementation.  This has * a resolution of 41.7ns, and a maximum value of about 35583 days. * * The return value is guaranteed to be monotonic in that range as * long as there is always less than 89 seconds between successive * calls to this function. */unsigned long long sched_clock(void){	unsigned long long v = cnt32_to_63(readl(VERSATILE_REFCOUNTER));	/* the <<1 gets rid of the cnt_32_to_63 top bit saving on a bic insn */	v *= 125<<1;	do_div(v, 3<<1);	return v;}#define VERSATILE_FLASHCTRL    (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_FLASH_OFFSET)static int versatile_flash_init(void){	u32 val;	val = __raw_readl(VERSATILE_FLASHCTRL);	val &= ~VERSATILE_FLASHPROG_FLVPPEN;	__raw_writel(val, VERSATILE_FLASHCTRL);	return 0;}static void versatile_flash_exit(void){	u32 val;	val = __raw_readl(VERSATILE_FLASHCTRL);	val &= ~VERSATILE_FLASHPROG_FLVPPEN;	__raw_writel(val, VERSATILE_FLASHCTRL);}static void versatile_flash_set_vpp(int on){	u32 val;	val = __raw_readl(VERSATILE_FLASHCTRL);	if (on)		val |= VERSATILE_FLASHPROG_FLVPPEN;	else		val &= ~VERSATILE_FLASHPROG_FLVPPEN;	__raw_writel(val, VERSATILE_FLASHCTRL);}static struct flash_platform_data versatile_flash_data = {	.map_name		= "cfi_probe",	.width			= 4,	.init			= versatile_flash_init,	.exit			= versatile_flash_exit,	.set_vpp		= versatile_flash_set_vpp,};static struct resource versatile_flash_resource = {	.start			= VERSATILE_FLASH_BASE,	.end			= VERSATILE_FLASH_BASE + VERSATILE_FLASH_SIZE - 1,	.flags			= IORESOURCE_MEM,};static struct platform_device versatile_flash_device = {	.name			= "armflash",	.id			= 0,	.dev			= {		.platform_data	= &versatile_flash_data,	},	.num_resources		= 1,	.resource		= &versatile_flash_resource,};static struct resource smc91x_resources[] = {	[0] = {		.start		= VERSATILE_ETH_BASE,		.end		= VERSATILE_ETH_BASE + SZ_64K - 1,		.flags		= IORESOURCE_MEM,	},	[1] = {		.start		= IRQ_ETH,		.end		= IRQ_ETH,		.flags		= IORESOURCE_IRQ,	},};static struct platform_device smc91x_device = {	.name		= "smc91x",	.id		= 0,	.num_resources	= ARRAY_SIZE(smc91x_resources),	.resource	= smc91x_resources,};static struct resource versatile_i2c_resource = {	.start			= VERSATILE_I2C_BASE,	.end			= VERSATILE_I2C_BASE + SZ_4K - 1,	.flags			= IORESOURCE_MEM,};static struct platform_device versatile_i2c_device = {	.name			= "versatile-i2c",	.id			= -1,	.num_resources		= 1,	.resource		= &versatile_i2c_resource,};#define VERSATILE_SYSMCI	(__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_MCI_OFFSET)unsigned int mmc_status(struct device *dev){	struct amba_device *adev = container_of(dev, struct amba_device, dev);	u32 mask;	if (adev->res.start == VERSATILE_MMCI0_BASE)		mask = 1;	else		mask = 2;	return readl(VERSATILE_SYSMCI) & mask;}static struct mmc_platform_data mmc0_plat_data = {	.ocr_mask	= MMC_VDD_32_33|MMC_VDD_33_34,	.status		= mmc_status,};/* * Clock handling */static const struct icst307_params versatile_oscvco_params = {	.ref		= 24000,	.vco_max	= 200000,	.vd_min		= 4 + 8,	.vd_max		= 511 + 8,	.rd_min		= 1 + 2,	.rd_max		= 127 + 2,};static void versatile_oscvco_set(struct clk *clk, struct icst307_vco vco){	void __iomem *sys_lock = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LOCK_OFFSET;	void __iomem *sys_osc = __io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_OSCCLCD_OFFSET;	u32 val;	val = readl(sys_osc) & ~0x7ffff;	val |= vco.v | (vco.r << 9) | (vco.s << 16);	writel(0xa05f, sys_lock);	writel(val, sys_osc);	writel(0, sys_lock);}static struct clk versatile_clcd_clk = {	.name	= "CLCDCLK",	.params	= &versatile_oscvco_params,	.setvco = versatile_oscvco_set,};/* * CLCD support. */#define SYS_CLCD_MODE_MASK	(3 << 0)#define SYS_CLCD_MODE_888	(0 << 0)#define SYS_CLCD_MODE_5551	(1 << 0)#define SYS_CLCD_MODE_565_RLSB	(2 << 0)#define SYS_CLCD_MODE_565_BLSB	(3 << 0)#define SYS_CLCD_NLCDIOON	(1 << 2)#define SYS_CLCD_VDDPOSSWITCH	(1 << 3)#define SYS_CLCD_PWR3V5SWITCH	(1 << 4)#define SYS_CLCD_ID_MASK	(0x1f << 8)#define SYS_CLCD_ID_SANYO_3_8	(0x00 << 8)#define SYS_CLCD_ID_UNKNOWN_8_4	(0x01 << 8)#define SYS_CLCD_ID_EPSON_2_2	(0x02 << 8)#define SYS_CLCD_ID_SANYO_2_5	(0x07 << 8)#define SYS_CLCD_ID_VGA		(0x1f << 8)static struct clcd_panel vga = {	.mode		= {		.name		= "VGA",		.refresh	= 60,		.xres		= 640,		.yres		= 480,		.pixclock	= 39721,		.left_margin	= 40,		.right_margin	= 24,		.upper_margin	= 32,		.lower_margin	= 11,		.hsync_len	= 96,		.vsync_len	= 2,		.sync		= 0,		.vmode		= FB_VMODE_NONINTERLACED,	},	.width		= -1,	.height		= -1,	.tim2		= TIM2_BCD | TIM2_IPC,	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),	.bpp		= 16,};static struct clcd_panel sanyo_3_8_in = {	.mode		= {		.name		= "Sanyo QVGA",		.refresh	= 116,		.xres		= 320,		.yres		= 240,		.pixclock	= 100000,		.left_margin	= 6,		.right_margin	= 6,		.upper_margin	= 5,		.lower_margin	= 5,		.hsync_len	= 6,		.vsync_len	= 6,		.sync		= 0,		.vmode		= FB_VMODE_NONINTERLACED,	},	.width		= -1,	.height		= -1,	.tim2		= TIM2_BCD,	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),	.bpp		= 16,};static struct clcd_panel sanyo_2_5_in = {	.mode		= {		.name		= "Sanyo QVGA Portrait",		.refresh	= 116,		.xres		= 240,		.yres		= 320,		.pixclock	= 100000,		.left_margin	= 20,		.right_margin	= 10,		.upper_margin	= 2,		.lower_margin	= 2,		.hsync_len	= 10,		.vsync_len	= 2,		.sync		= FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,		.vmode		= FB_VMODE_NONINTERLACED,	},	.width		= -1,	.height		= -1,	.tim2		= TIM2_IVS | TIM2_IHS | TIM2_IPC,	.cntl		= CNTL_LCDTFT | CNTL_LCDVCOMP(1),	.bpp		= 16,};static struct clcd_panel epson_2_2_in = {	.mode		= {		.name		= "Epson QCIF",		.refresh	= 390,		.xres		= 176,		.yres		= 220,		.pixclock	= 62500,		.left_margin	= 3,

⌨️ 快捷键说明

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