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

📄 mv64x60.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	case MV64x60_TYPE_MV64360:		bh->ci = &mv64360_ci;		break;	case MV64x60_TYPE_MV64460:		bh->ci = &mv64460_ci;		break;	case MV64x60_TYPE_INVALID:	default:		if (ppc_md.progress)			ppc_md.progress("mv64x60: Unsupported bridge", 0x0);		printk(KERN_ERR "mv64x60: Unsupported bridge\n");		rc = -1;	}	return rc;}/* * mv64x60_get_bridge_vbase() * * Return the virtual address of the bridge's registers. */void __iomem *mv64x60_get_bridge_vbase(void){	return mv64x60_bridge_vbase;}/* * mv64x60_get_bridge_type() * * Return the type of bridge on the platform. */u32mv64x60_get_bridge_type(void){	return mv64x60_bridge_type;}/* * mv64x60_get_bridge_rev() * * Return the revision of the bridge on the platform. */u32mv64x60_get_bridge_rev(void){	return mv64x60_bridge_rev;}/* ***************************************************************************** * *	System Memory Window Related Routines * ***************************************************************************** *//* * mv64x60_get_mem_size() * * Calculate the amount of memory that the memory controller is set up for. * This should only be used by board-specific code if there is no other * way to determine the amount of memory in the system. */u32 __initmv64x60_get_mem_size(u32 bridge_base, u32 chip_type){	struct mv64x60_handle	bh;	u32	mem_windows[MV64x60_CPU2MEM_WINDOWS][2];	u32	rc = 0;	memset(&bh, 0, sizeof(bh));	bh.type = chip_type;	bh.v_base = (void *)bridge_base;	if (!mv64x60_setup_for_chip(&bh)) {		mv64x60_get_mem_windows(&bh, mem_windows);		rc = mv64x60_calc_mem_size(&bh, mem_windows);	}	return rc;}/* * mv64x60_get_mem_windows() * * Get the values in the memory controller & return in the 'mem_windows' array. */void __initmv64x60_get_mem_windows(struct mv64x60_handle *bh,	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]){	u32	i, win;	for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)		if (bh->ci->is_enabled_32bit(bh, win))			mv64x60_get_32bit_window(bh, win,				&mem_windows[i][0], &mem_windows[i][1]);		else {			mem_windows[i][0] = 0;			mem_windows[i][1] = 0;		}}/* * mv64x60_calc_mem_size() * * Using the memory controller register values in 'mem_windows', determine * how much memory it is set up for. */u32 __initmv64x60_calc_mem_size(struct mv64x60_handle *bh,	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]){	u32	i, total = 0;	for (i=0; i<MV64x60_CPU2MEM_WINDOWS; i++)		total += mem_windows[i][1];	return total;}/* ***************************************************************************** * *	CPU->System MEM, PCI Config Routines * ***************************************************************************** *//* * mv64x60_config_cpu2mem_windows() * * Configure CPU->Memory windows on the bridge. */static u32 prot_tab[] __initdata = {	MV64x60_CPU_PROT_0_WIN, MV64x60_CPU_PROT_1_WIN,	MV64x60_CPU_PROT_2_WIN, MV64x60_CPU_PROT_3_WIN};static u32 cpu_snoop_tab[] __initdata = {	MV64x60_CPU_SNOOP_0_WIN, MV64x60_CPU_SNOOP_1_WIN,	MV64x60_CPU_SNOOP_2_WIN, MV64x60_CPU_SNOOP_3_WIN};void __initmv64x60_config_cpu2mem_windows(struct mv64x60_handle *bh,	struct mv64x60_setup_info *si,	u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]){	u32	i, win;	/* Set CPU protection & snoop windows */	for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)		if (bh->ci->is_enabled_32bit(bh, win)) {			mv64x60_set_32bit_window(bh, prot_tab[i],				mem_windows[i][0], mem_windows[i][1],				si->cpu_prot_options[i]);			bh->ci->enable_window_32bit(bh, prot_tab[i]);			if (bh->ci->window_tab_32bit[cpu_snoop_tab[i]].								base_reg != 0) {				mv64x60_set_32bit_window(bh, cpu_snoop_tab[i],					mem_windows[i][0], mem_windows[i][1],					si->cpu_snoop_options[i]);				bh->ci->enable_window_32bit(bh,					cpu_snoop_tab[i]);			}		}}/* * mv64x60_config_cpu2pci_windows() * * Configure the CPU->PCI windows for one of the PCI buses. */static u32 win_tab[2][4] __initdata = {	{ MV64x60_CPU2PCI0_IO_WIN, MV64x60_CPU2PCI0_MEM_0_WIN,	  MV64x60_CPU2PCI0_MEM_1_WIN, MV64x60_CPU2PCI0_MEM_2_WIN },	{ MV64x60_CPU2PCI1_IO_WIN, MV64x60_CPU2PCI1_MEM_0_WIN,	  MV64x60_CPU2PCI1_MEM_1_WIN, MV64x60_CPU2PCI1_MEM_2_WIN },};static u32 remap_tab[2][4] __initdata = {	{ MV64x60_CPU2PCI0_IO_REMAP_WIN, MV64x60_CPU2PCI0_MEM_0_REMAP_WIN,	  MV64x60_CPU2PCI0_MEM_1_REMAP_WIN, MV64x60_CPU2PCI0_MEM_2_REMAP_WIN },	{ MV64x60_CPU2PCI1_IO_REMAP_WIN, MV64x60_CPU2PCI1_MEM_0_REMAP_WIN,	  MV64x60_CPU2PCI1_MEM_1_REMAP_WIN, MV64x60_CPU2PCI1_MEM_2_REMAP_WIN }};void __initmv64x60_config_cpu2pci_windows(struct mv64x60_handle *bh,	struct mv64x60_pci_info *pi, u32 bus){	int	i;	if (pi->pci_io.size > 0) {		mv64x60_set_32bit_window(bh, win_tab[bus][0],			pi->pci_io.cpu_base, pi->pci_io.size, pi->pci_io.swap);		mv64x60_set_32bit_window(bh, remap_tab[bus][0],			pi->pci_io.pci_base_lo, 0, 0);		bh->ci->enable_window_32bit(bh, win_tab[bus][0]);	} else /* Actually, the window should already be disabled */		bh->ci->disable_window_32bit(bh, win_tab[bus][0]);	for (i=0; i<3; i++)		if (pi->pci_mem[i].size > 0) {			mv64x60_set_32bit_window(bh, win_tab[bus][i+1],				pi->pci_mem[i].cpu_base, pi->pci_mem[i].size,				pi->pci_mem[i].swap);			mv64x60_set_64bit_window(bh, remap_tab[bus][i+1],				pi->pci_mem[i].pci_base_hi,				pi->pci_mem[i].pci_base_lo, 0, 0);			bh->ci->enable_window_32bit(bh, win_tab[bus][i+1]);		} else /* Actually, the window should already be disabled */			bh->ci->disable_window_32bit(bh, win_tab[bus][i+1]);}/* ***************************************************************************** * *	PCI->System MEM Config Routines * ***************************************************************************** *//* * mv64x60_config_pci2mem_windows() * * Configure the PCI->Memory windows on the bridge. */static u32 pci_acc_tab[2][4] __initdata = {	{ MV64x60_PCI02MEM_ACC_CNTL_0_WIN, MV64x60_PCI02MEM_ACC_CNTL_1_WIN,	  MV64x60_PCI02MEM_ACC_CNTL_2_WIN, MV64x60_PCI02MEM_ACC_CNTL_3_WIN },	{ MV64x60_PCI12MEM_ACC_CNTL_0_WIN, MV64x60_PCI12MEM_ACC_CNTL_1_WIN,	  MV64x60_PCI12MEM_ACC_CNTL_2_WIN, MV64x60_PCI12MEM_ACC_CNTL_3_WIN }};static u32 pci_snoop_tab[2][4] __initdata = {	{ MV64x60_PCI02MEM_SNOOP_0_WIN, MV64x60_PCI02MEM_SNOOP_1_WIN,	  MV64x60_PCI02MEM_SNOOP_2_WIN, MV64x60_PCI02MEM_SNOOP_3_WIN },	{ MV64x60_PCI12MEM_SNOOP_0_WIN, MV64x60_PCI12MEM_SNOOP_1_WIN,	  MV64x60_PCI12MEM_SNOOP_2_WIN, MV64x60_PCI12MEM_SNOOP_3_WIN }};static u32 pci_size_tab[2][4] __initdata = {	{ MV64x60_PCI0_MEM_0_SIZE, MV64x60_PCI0_MEM_1_SIZE,	  MV64x60_PCI0_MEM_2_SIZE, MV64x60_PCI0_MEM_3_SIZE },	{ MV64x60_PCI1_MEM_0_SIZE, MV64x60_PCI1_MEM_1_SIZE,	  MV64x60_PCI1_MEM_2_SIZE, MV64x60_PCI1_MEM_3_SIZE }};void __initmv64x60_config_pci2mem_windows(struct mv64x60_handle *bh,	struct pci_controller *hose, struct mv64x60_pci_info *pi,	u32 bus, u32 mem_windows[MV64x60_CPU2MEM_WINDOWS][2]){	u32	i, win;	/*	 * Set the access control, snoop, BAR size, and window base addresses.	 * PCI->MEM windows base addresses will match exactly what the	 * CPU->MEM windows are.	 */	for (win=MV64x60_CPU2MEM_0_WIN,i=0;win<=MV64x60_CPU2MEM_3_WIN;win++,i++)		if (bh->ci->is_enabled_32bit(bh, win)) {			mv64x60_set_64bit_window(bh,				pci_acc_tab[bus][i], 0,				mem_windows[i][0], mem_windows[i][1],				pi->acc_cntl_options[i]);			bh->ci->enable_window_64bit(bh, pci_acc_tab[bus][i]);			if (bh->ci->window_tab_64bit[				pci_snoop_tab[bus][i]].base_lo_reg != 0) {				mv64x60_set_64bit_window(bh,					pci_snoop_tab[bus][i], 0,					mem_windows[i][0], mem_windows[i][1],					pi->snoop_options[i]);				bh->ci->enable_window_64bit(bh,					pci_snoop_tab[bus][i]);			}			bh->ci->set_pci2mem_window(hose, bus, i,				mem_windows[i][0]);			mv64x60_write(bh, pci_size_tab[bus][i],				mv64x60_mask(mem_windows[i][1] - 1, 20));			/* Enable the window */			mv64x60_clr_bits(bh, ((bus == 0) ?				MV64x60_PCI0_BAR_ENABLE :				MV64x60_PCI1_BAR_ENABLE), (1 << i));		}}/* ***************************************************************************** * *	Hose & Resource Alloc/Init Routines * ***************************************************************************** *//* * mv64x60_alloc_hoses() * * Allocate the PCI hose structures for the bridge's PCI buses. */void __initmv64x60_alloc_hose(struct mv64x60_handle *bh, u32 cfg_addr, u32 cfg_data,	struct pci_controller **hose){	*hose = pcibios_alloc_controller();	setup_indirect_pci_nomap(*hose, bh->v_base + cfg_addr,		bh->v_base + cfg_data);}/* * mv64x60_config_resources() * * Calculate the offsets, etc. for the hose structures to reflect all of * the address remapping that happens as you go from CPU->PCI and PCI->MEM. */void __initmv64x60_config_resources(struct pci_controller *hose,	struct mv64x60_pci_info *pi, u32 io_base){	int		i;	/* 2 hoses; 4 resources/hose; string <= 64 bytes */	static char	s[2][4][64];	if (pi->pci_io.size != 0) {		sprintf(s[hose->index][0], "PCI hose %d I/O Space",			hose->index);		pci_init_resource(&hose->io_resource, io_base - isa_io_base,			io_base - isa_io_base + pi->pci_io.size - 1,			IORESOURCE_IO, s[hose->index][0]);		hose->io_space.start = pi->pci_io.pci_base_lo;		hose->io_space.end = pi->pci_io.pci_base_lo + pi->pci_io.size-1;		hose->io_base_phys = pi->pci_io.cpu_base;		hose->io_base_virt = (void *)isa_io_base;	}	for (i=0; i<3; i++)		if (pi->pci_mem[i].size != 0) {			sprintf(s[hose->index][i+1], "PCI hose %d MEM Space %d",				hose->index, i);			pci_init_resource(&hose->mem_resources[i],				pi->pci_mem[i].cpu_base,				pi->pci_mem[i].cpu_base + pi->pci_mem[i].size-1,				IORESOURCE_MEM, s[hose->index][i+1]);		}	hose->mem_space.end = pi->pci_mem[0].pci_base_lo +						pi->pci_mem[0].size - 1;	hose->pci_mem_offset = pi->pci_mem[0].cpu_base -						pi->pci_mem[0].pci_base_lo;}/* * mv64x60_config_pci_params() * * Configure a hose's PCI config space parameters. */void __initmv64x60_config_pci_params(struct pci_controller *hose,	struct mv64x60_pci_info *pi){	u32	devfn;	u16	u16_val;	u8	save_exclude;	devfn = PCI_DEVFN(0,0);	save_exclude = mv64x60_pci_exclude_bridge;	mv64x60_pci_exclude_bridge = 0;	/* Set class code to indicate host bridge */	u16_val = PCI_CLASS_BRIDGE_HOST; /* 0x0600 (host bridge) */	early_write_config_word(hose, 0, devfn, PCI_CLASS_DEVICE, u16_val);	/* Enable bridge to be PCI master & respond to PCI MEM cycles */	early_read_config_word(hose, 0, devfn, PCI_COMMAND, &u16_val);	u16_val &= ~(PCI_COMMAND_IO | PCI_COMMAND_INVALIDATE |		PCI_COMMAND_PARITY | PCI_COMMAND_SERR | PCI_COMMAND_FAST_BACK);	u16_val |= pi->pci_cmd_bits | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;	early_write_config_word(hose, 0, devfn, PCI_COMMAND, u16_val);	/* Set latency timer, cache line size, clear BIST */	u16_val = (pi->latency_timer << 8) | (L1_CACHE_BYTES >> 2);	early_write_config_word(hose, 0, devfn, PCI_CACHE_LINE_SIZE, u16_val);	mv64x60_pci_exclude_bridge = save_exclude;}/* ***************************************************************************** * *	PCI Related Routine * ***************************************************************************** *//* * mv64x60_set_bus() * * Set the bus number for the hose directly under the bridge. */void __initmv64x60_set_bus(struct mv64x60_handle *bh, u32 bus, u32 child_bus){	struct pci_controller	*hose;	u32	pci_mode, p2p_cfg, pci_cfg_offset, val;	u8	save_exclude;	if (bus == 0) {		pci_mode = bh->pci_mode_a;		p2p_cfg = MV64x60_PCI0_P2P_CONFIG;		pci_cfg_offset = 0x64;		hose = bh->hose_a;	} else {		pci_mode = bh->pci_mode_b;		p2p_cfg = MV64x60_PCI1_P2P_CONFIG;		pci_cfg_offset = 0xe4;		hose = bh->hose_b;	}	child_bus &= 0xff;	val = mv64x60_read(bh, p2p_cfg);	if (pci_mode == MV64x60_PCIMODE_CONVENTIONAL) {		val &= 0xe0000000; /* Force dev num to 0, turn off P2P bridge */		val |= (child_bus << 16) | 0xff;		mv64x60_write(bh, p2p_cfg, val);		(void)mv64x60_read(bh, p2p_cfg); /* Flush FIFO */	} else { /* PCI-X */		/*		 * Need to use the current bus/dev number (that's in the		 * P2P CONFIG reg) to access the bridge's pci config space.		 */		save_exclude = mv64x60_pci_exclude_bridge;		mv64x60_pci_exclude_bridge = 0;		early_write_config_dword(hose, (val & 0x00ff0000) >> 16,			PCI_DEVFN(((val & 0x1f000000) >> 24), 0),			pci_cfg_offset, child_bus << 8);		mv64x60_pci_exclude_bridge = save_exclude;	}}/* * mv64x60_pci_exclude_device() * * This routine is used to make the bridge not appear when the * PCI subsystem is accessing PCI devices (in PCI config space). */intmv64x60_pci_exclude_device(u8 bus, u8 devfn)

⌨️ 快捷键说明

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