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

📄 mv64x60.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
#ifdef CONFIG_MV643XX_ETH	&mv64x60_eth_shared_device,#endif#ifdef CONFIG_MV643XX_ETH_0	&eth0_device,#endif#ifdef CONFIG_MV643XX_ETH_1	&eth1_device,#endif#ifdef CONFIG_MV643XX_ETH_2	&eth2_device,#endif#ifdef	CONFIG_I2C_MV64XXX	&i2c_device,#endif#if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)	&mv64xxx_device,#endif};/* ***************************************************************************** * *	Bridge Initialization Routines * ***************************************************************************** *//* * mv64x60_init() * * Initialze the bridge based on setting passed in via 'si'.  The bridge * handle, 'bh', will be set so that it can be used to make subsequent * calls to routines in this file. */int __initmv64x60_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si){	u32	mem_windows[MV64x60_CPU2MEM_WINDOWS][2];	if (ppc_md.progress)		ppc_md.progress("mv64x60 initialization", 0x0);	spin_lock_init(&mv64x60_lock);	mv64x60_early_init(bh, si);	if (mv64x60_get_type(bh) || mv64x60_setup_for_chip(bh)) {		iounmap(bh->v_base);		bh->v_base = 0;		if (ppc_md.progress)			ppc_md.progress("mv64x60_init: Can't determine chip",0);		return -1;	}	bh->ci->disable_all_windows(bh, si);	mv64x60_get_mem_windows(bh, mem_windows);	mv64x60_config_cpu2mem_windows(bh, si, mem_windows);	if (bh->ci->config_io2mem_windows)		bh->ci->config_io2mem_windows(bh, si, mem_windows);	if (bh->ci->set_mpsc2regs_window)		bh->ci->set_mpsc2regs_window(bh, si->phys_reg_base);	if (si->pci_1.enable_bus) {		bh->io_base_b = (u32)ioremap(si->pci_1.pci_io.cpu_base,			si->pci_1.pci_io.size);		isa_io_base = bh->io_base_b;	}	if (si->pci_0.enable_bus) {		bh->io_base_a = (u32)ioremap(si->pci_0.pci_io.cpu_base,			si->pci_0.pci_io.size);		isa_io_base = bh->io_base_a;		mv64x60_alloc_hose(bh, MV64x60_PCI0_CONFIG_ADDR,			MV64x60_PCI0_CONFIG_DATA, &bh->hose_a);		mv64x60_config_resources(bh->hose_a, &si->pci_0, bh->io_base_a);		mv64x60_config_pci_params(bh->hose_a, &si->pci_0);		mv64x60_config_cpu2pci_windows(bh, &si->pci_0, 0);		mv64x60_config_pci2mem_windows(bh, bh->hose_a, &si->pci_0, 0,			mem_windows);		bh->ci->set_pci2regs_window(bh, bh->hose_a, 0,			si->phys_reg_base);	}	if (si->pci_1.enable_bus) {		mv64x60_alloc_hose(bh, MV64x60_PCI1_CONFIG_ADDR,			MV64x60_PCI1_CONFIG_DATA, &bh->hose_b);		mv64x60_config_resources(bh->hose_b, &si->pci_1, bh->io_base_b);		mv64x60_config_pci_params(bh->hose_b, &si->pci_1);		mv64x60_config_cpu2pci_windows(bh, &si->pci_1, 1);		mv64x60_config_pci2mem_windows(bh, bh->hose_b, &si->pci_1, 1,			mem_windows);		bh->ci->set_pci2regs_window(bh, bh->hose_b, 1,			si->phys_reg_base);	}	bh->ci->chip_specific_init(bh, si);	mv64x60_pd_fixup(bh, mv64x60_pd_devs, ARRAY_SIZE(mv64x60_pd_devs));	return 0;}/* * mv64x60_early_init() * * Do some bridge work that must take place before we start messing with * the bridge for real. */void __initmv64x60_early_init(struct mv64x60_handle *bh, struct mv64x60_setup_info *si){	struct pci_controller	hose_a, hose_b;	memset(bh, 0, sizeof(*bh));	bh->p_base = si->phys_reg_base;	bh->v_base = ioremap(bh->p_base, MV64x60_INTERNAL_SPACE_SIZE);	mv64x60_bridge_pbase = bh->p_base;	mv64x60_bridge_vbase = bh->v_base;	/* Assuming pci mode [reserved] bits 4:5 on 64260 are 0 */	bh->pci_mode_a = mv64x60_read(bh, MV64x60_PCI0_MODE) &		MV64x60_PCIMODE_MASK;	bh->pci_mode_b = mv64x60_read(bh, MV64x60_PCI1_MODE) &		MV64x60_PCIMODE_MASK;	/* Need temporary hose structs to call mv64x60_set_bus() */	memset(&hose_a, 0, sizeof(hose_a));	memset(&hose_b, 0, sizeof(hose_b));	setup_indirect_pci_nomap(&hose_a, bh->v_base + MV64x60_PCI0_CONFIG_ADDR,		bh->v_base + MV64x60_PCI0_CONFIG_DATA);	setup_indirect_pci_nomap(&hose_b, bh->v_base + MV64x60_PCI1_CONFIG_ADDR,		bh->v_base + MV64x60_PCI1_CONFIG_DATA);	bh->hose_a = &hose_a;	bh->hose_b = &hose_b;#if defined(CONFIG_SYSFS) && !defined(CONFIG_GT64260)	/* Save a copy of hose_a for sysfs functions -- hack */	memcpy(&sysfs_hose_a, &hose_a, sizeof(hose_a));#endif	mv64x60_set_bus(bh, 0, 0);	mv64x60_set_bus(bh, 1, 0);	bh->hose_a = NULL;	bh->hose_b = NULL;	/* Clear bit 0 of PCI addr decode control so PCI->CPU remap 1:1 */	mv64x60_clr_bits(bh, MV64x60_PCI0_PCI_DECODE_CNTL, 0x00000001);	mv64x60_clr_bits(bh, MV64x60_PCI1_PCI_DECODE_CNTL, 0x00000001);	/* Bit 12 MUST be 0; set bit 27--don't auto-update cpu remap regs */	mv64x60_clr_bits(bh, MV64x60_CPU_CONFIG, (1<<12));	mv64x60_set_bits(bh, MV64x60_CPU_CONFIG, (1<<27));	mv64x60_set_bits(bh, MV64x60_PCI0_TO_RETRY, 0xffff);	mv64x60_set_bits(bh, MV64x60_PCI1_TO_RETRY, 0xffff);}/* ***************************************************************************** * *	Window Config Routines * ***************************************************************************** *//* * mv64x60_get_32bit_window() * * Determine the base address and size of a 32-bit window on the bridge. */void __initmv64x60_get_32bit_window(struct mv64x60_handle *bh, u32 window,	u32 *base, u32 *size){	u32	val, base_reg, size_reg, base_bits, size_bits;	u32	(*get_from_field)(u32 val, u32 num_bits);	base_reg = bh->ci->window_tab_32bit[window].base_reg;	if (base_reg != 0) {		size_reg  = bh->ci->window_tab_32bit[window].size_reg;		base_bits = bh->ci->window_tab_32bit[window].base_bits;		size_bits = bh->ci->window_tab_32bit[window].size_bits;		get_from_field= bh->ci->window_tab_32bit[window].get_from_field;		val = mv64x60_read(bh, base_reg);		*base = get_from_field(val, base_bits);		if (size_reg != 0) {			val = mv64x60_read(bh, size_reg);			val = get_from_field(val, size_bits);			*size = bh->ci->untranslate_size(*base, val, size_bits);		} else			*size = 0;	} else {		*base = 0;		*size = 0;	}	pr_debug("get 32bit window: %d, base: 0x%x, size: 0x%x\n",		window, *base, *size);}/* * mv64x60_set_32bit_window() * * Set the base address and size of a 32-bit window on the bridge. */void __initmv64x60_set_32bit_window(struct mv64x60_handle *bh, u32 window,	u32 base, u32 size, u32 other_bits){	u32	val, base_reg, size_reg, base_bits, size_bits;	u32	(*map_to_field)(u32 val, u32 num_bits);	pr_debug("set 32bit window: %d, base: 0x%x, size: 0x%x, other: 0x%x\n",		window, base, size, other_bits);	base_reg = bh->ci->window_tab_32bit[window].base_reg;	if (base_reg != 0) {		size_reg  = bh->ci->window_tab_32bit[window].size_reg;		base_bits = bh->ci->window_tab_32bit[window].base_bits;		size_bits = bh->ci->window_tab_32bit[window].size_bits;		map_to_field = bh->ci->window_tab_32bit[window].map_to_field;		val = map_to_field(base, base_bits) | other_bits;		mv64x60_write(bh, base_reg, val);		if (size_reg != 0) {			val = bh->ci->translate_size(base, size, size_bits);			val = map_to_field(val, size_bits);			mv64x60_write(bh, size_reg, val);		}		(void)mv64x60_read(bh, base_reg); /* Flush FIFO */	}}/* * mv64x60_get_64bit_window() * * Determine the base address and size of a 64-bit window on the bridge. */void __initmv64x60_get_64bit_window(struct mv64x60_handle *bh, u32 window,	u32 *base_hi, u32 *base_lo, u32 *size){	u32	val, base_lo_reg, size_reg, base_lo_bits, size_bits;	u32	(*get_from_field)(u32 val, u32 num_bits);	base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;	if (base_lo_reg != 0) {		size_reg = bh->ci->window_tab_64bit[window].size_reg;		base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;		size_bits = bh->ci->window_tab_64bit[window].size_bits;		get_from_field= bh->ci->window_tab_64bit[window].get_from_field;		*base_hi = mv64x60_read(bh,			bh->ci->window_tab_64bit[window].base_hi_reg);		val = mv64x60_read(bh, base_lo_reg);		*base_lo = get_from_field(val, base_lo_bits);		if (size_reg != 0) {			val = mv64x60_read(bh, size_reg);			val = get_from_field(val, size_bits);			*size = bh->ci->untranslate_size(*base_lo, val,								size_bits);		} else			*size = 0;	} else {		*base_hi = 0;		*base_lo = 0;		*size = 0;	}	pr_debug("get 64bit window: %d, base hi: 0x%x, base lo: 0x%x, "		"size: 0x%x\n", window, *base_hi, *base_lo, *size);}/* * mv64x60_set_64bit_window() * * Set the base address and size of a 64-bit window on the bridge. */void __initmv64x60_set_64bit_window(struct mv64x60_handle *bh, u32 window,	u32 base_hi, u32 base_lo, u32 size, u32 other_bits){	u32	val, base_lo_reg, size_reg, base_lo_bits, size_bits;	u32	(*map_to_field)(u32 val, u32 num_bits);	pr_debug("set 64bit window: %d, base hi: 0x%x, base lo: 0x%x, "		"size: 0x%x, other: 0x%x\n",		window, base_hi, base_lo, size, other_bits);	base_lo_reg = bh->ci->window_tab_64bit[window].base_lo_reg;	if (base_lo_reg != 0) {		size_reg = bh->ci->window_tab_64bit[window].size_reg;		base_lo_bits = bh->ci->window_tab_64bit[window].base_lo_bits;		size_bits = bh->ci->window_tab_64bit[window].size_bits;		map_to_field = bh->ci->window_tab_64bit[window].map_to_field;		mv64x60_write(bh, bh->ci->window_tab_64bit[window].base_hi_reg,			base_hi);		val = map_to_field(base_lo, base_lo_bits) | other_bits;		mv64x60_write(bh, base_lo_reg, val);		if (size_reg != 0) {			val = bh->ci->translate_size(base_lo, size, size_bits);			val = map_to_field(val, size_bits);			mv64x60_write(bh, size_reg, val);		}		(void)mv64x60_read(bh, base_lo_reg); /* Flush FIFO */	}}/* * mv64x60_mask() * * Take the high-order 'num_bits' of 'val' & mask off low bits. */u32 __initmv64x60_mask(u32 val, u32 num_bits){	return val & (0xffffffff << (32 - num_bits));}/* * mv64x60_shift_left() * * Take the low-order 'num_bits' of 'val', shift left to align at bit 31 (MSB). */u32 __initmv64x60_shift_left(u32 val, u32 num_bits){	return val << (32 - num_bits);}/* * mv64x60_shift_right() * * Take the high-order 'num_bits' of 'val', shift right to align at bit 0 (LSB). */u32 __initmv64x60_shift_right(u32 val, u32 num_bits){	return val >> (32 - num_bits);}/* ***************************************************************************** * *	Chip Identification Routines * ***************************************************************************** *//* * mv64x60_get_type() * * Determine the type of bridge chip we have. */int __initmv64x60_get_type(struct mv64x60_handle *bh){	struct pci_controller hose;	u16	val;	u8	save_exclude;	memset(&hose, 0, sizeof(hose));	setup_indirect_pci_nomap(&hose, bh->v_base + MV64x60_PCI0_CONFIG_ADDR,		bh->v_base + MV64x60_PCI0_CONFIG_DATA);	save_exclude = mv64x60_pci_exclude_bridge;	mv64x60_pci_exclude_bridge = 0;	/* Sanity check of bridge's Vendor ID */	early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_VENDOR_ID, &val);	if (val != PCI_VENDOR_ID_MARVELL) {		mv64x60_pci_exclude_bridge = save_exclude;		return -1;	}	/* Get the revision of the chip */	early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_CLASS_REVISION,		&val);	bh->rev = (u32)(val & 0xff);	/* Figure out the type of Marvell bridge it is */	early_read_config_word(&hose, 0, PCI_DEVFN(0, 0), PCI_DEVICE_ID, &val);	mv64x60_pci_exclude_bridge = save_exclude;	switch (val) {	case PCI_DEVICE_ID_MARVELL_GT64260:		switch (bh->rev) {		case GT64260_REV_A:			bh->type = MV64x60_TYPE_GT64260A;			break;		default:			printk(KERN_WARNING "Unsupported GT64260 rev %04x\n",				bh->rev);			/* Assume its similar to a 'B' rev and fallthru */		case GT64260_REV_B:			bh->type = MV64x60_TYPE_GT64260B;			break;		}		break;	case PCI_DEVICE_ID_MARVELL_MV64360:		/* Marvell won't tell me how to distinguish a 64361 & 64362 */		bh->type = MV64x60_TYPE_MV64360;		break;	case PCI_DEVICE_ID_MARVELL_MV64460:		bh->type = MV64x60_TYPE_MV64460;		break;	default:		printk(KERN_ERR "Unknown Marvell bridge type %04x\n", val);		return -1;	}	/* Hang onto bridge type & rev for PIC code */	mv64x60_bridge_type = bh->type;	mv64x60_bridge_rev = bh->rev;	return 0;}/* * mv64x60_setup_for_chip() * * Set 'bh' to use the proper set of routine for the bridge chip that we have. */int __initmv64x60_setup_for_chip(struct mv64x60_handle *bh){	int	rc = 0;	/* Set up chip-specific info based on the chip/bridge type */	switch(bh->type) {	case MV64x60_TYPE_GT64260A:		bh->ci = &gt64260a_ci;		break;	case MV64x60_TYPE_GT64260B:		bh->ci = &gt64260b_ci;		break;

⌨️ 快捷键说明

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