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

📄 pmc440.c

📁 U-boot latest tarball
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * pci_pre_init * * This routine is called just prior to registering the hose and gives * the board the opportunity to check things. Returning a value of zero * indicates that things are bad & PCI initialization should be aborted. * * Different boards may wish to customize the pci controller structure * (add regions, override default access routines, etc) or perform * certain pre-initialization actions. */#if defined(CONFIG_PCI)int pci_pre_init(struct pci_controller *hose){	unsigned long addr;	/*	 * Set priority for all PLB3 devices to 0.	 * Set PLB3 arbiter to fair mode.	 */	mfsdr(sdr_amp1, addr);	mtsdr(sdr_amp1, (addr & 0x000000FF) | 0x0000FF00);	addr = mfdcr(plb3_acr);	mtdcr(plb3_acr, addr | 0x80000000);	/*	 * Set priority for all PLB4 devices to 0.	 */	mfsdr(sdr_amp0, addr);	mtsdr(sdr_amp0, (addr & 0x000000FF) | 0x0000FF00);	addr = mfdcr(plb4_acr) | 0xa0000000;	/* Was 0x8---- */	mtdcr(plb4_acr, addr);	/*	 * Set Nebula PLB4 arbiter to fair mode.	 */	/* Segment0 */	addr = (mfdcr(plb0_acr) & ~plb0_acr_ppm_mask) | plb0_acr_ppm_fair;	addr = (addr & ~plb0_acr_hbu_mask) | plb0_acr_hbu_enabled;	addr = (addr & ~plb0_acr_rdp_mask) | plb0_acr_rdp_4deep;	addr = (addr & ~plb0_acr_wrp_mask) | plb0_acr_wrp_2deep;	mtdcr(plb0_acr, addr);	/* Segment1 */	addr = (mfdcr(plb1_acr) & ~plb1_acr_ppm_mask) | plb1_acr_ppm_fair;	addr = (addr & ~plb1_acr_hbu_mask) | plb1_acr_hbu_enabled;	addr = (addr & ~plb1_acr_rdp_mask) | plb1_acr_rdp_4deep;	addr = (addr & ~plb1_acr_wrp_mask) | plb1_acr_wrp_2deep;	mtdcr(plb1_acr, addr);#ifdef CONFIG_PCI_PNP	hose->fixup_irq = pmc440_pci_fixup_irq;#endif	return 1;}#endif /* defined(CONFIG_PCI) *//* * pci_target_init * * The bootstrap configuration provides default settings for the pci * inbound map (PIM). But the bootstrap config choices are limited and * may not be sufficient for a given board. */#if defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_TARGET_INIT)void pci_target_init(struct pci_controller *hose){	char *ptmla_str, *ptmms_str;	/*	 * Set up Direct MMIO registers	 */	/*	 * PowerPC440EPX PCI Master configuration.	 * Map one 1Gig range of PLB/processor addresses to PCI memory space.	 * PLB address 0x80000000-0xBFFFFFFF	 *     ==> PCI address 0x80000000-0xBFFFFFFF	 * Use byte reversed out routines to handle endianess.	 * Make this region non-prefetchable.	 */	out32r(PCIX0_PMM0MA, 0x00000000);	/* PMM0 Mask/Attribute */						/* - disabled b4 setting */	out32r(PCIX0_PMM0LA, CONFIG_SYS_PCI_MEMBASE);	/* PMM0 Local Address */	out32r(PCIX0_PMM0PCILA, CONFIG_SYS_PCI_MEMBASE); /* PMM0 PCI Low Address */	out32r(PCIX0_PMM0PCIHA, 0x00000000);	/* PMM0 PCI High Address */	out32r(PCIX0_PMM0MA, 0xc0000001);	/* 1G + No prefetching, */						/* and enable region */	if (!is_monarch()) {		ptmla_str = getenv("ptm1la");		ptmms_str = getenv("ptm1ms");		if(NULL != ptmla_str && NULL != ptmms_str ) {			out32r(PCIX0_PTM1MS,			       simple_strtoul(ptmms_str, NULL, 16));			out32r(PCIX0_PTM1LA,			       simple_strtoul(ptmla_str, NULL, 16));		} else {			/* BAR1: default top 64MB of RAM */			out32r(PCIX0_PTM1MS, 0xfc000001);			out32r(PCIX0_PTM1LA, 0x0c000000);		}	} else {		/* BAR1: default: complete 256MB RAM */		out32r(PCIX0_PTM1MS, 0xf0000001);		out32r(PCIX0_PTM1LA, 0x00000000);	}	ptmla_str = getenv("ptm2la");		/* Local Addr. Reg */	ptmms_str = getenv("ptm2ms");		/* Memory Size/Attribute */	if(NULL != ptmla_str && NULL != ptmms_str ) {		out32r(PCIX0_PTM2MS, simple_strtoul(ptmms_str, NULL, 16));		out32r(PCIX0_PTM2LA, simple_strtoul(ptmla_str, NULL, 16));	} else {		/* BAR2: default: 4MB FPGA */		out32r(PCIX0_PTM2MS, 0xffc00001); /* Memory Size/Attribute */		out32r(PCIX0_PTM2LA, 0xef000000); /* Local Addr. Reg */	}	if (is_monarch()) {		/* BAR2: map FPGA registers behind system memory at 1GB */		pci_hose_write_config_dword(hose, 0, PCI_BASE_ADDRESS_2, 0x40000008);	}	/*	 * Set up Configuration registers	 */	/* Program the board's vendor id */	pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_VENDOR_ID,				   CONFIG_SYS_PCI_SUBSYS_VENDORID);	/* disabled for PMC405 backward compatibility */	/* Configure command register as bus master */	/* pci_write_config_word(0, PCI_COMMAND, PCI_COMMAND_MASTER); */	/* 240nS PCI clock */	pci_hose_write_config_word(hose, 0, PCI_LATENCY_TIMER, 1);	/* No error reporting */	pci_hose_write_config_word(hose, 0, PCI_ERREN, 0);	pci_write_config_dword(0, PCI_BRDGOPT2, 0x00000101);	if (!is_monarch()) {		/* Program the board's subsystem id/classcode */		pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_ID,					   CONFIG_SYS_PCI_SUBSYS_ID_NONMONARCH);		pci_hose_write_config_word(hose, 0, PCI_CLASS_SUB_CODE,					   CONFIG_SYS_PCI_CLASSCODE_NONMONARCH);		/* PCI configuration done: release ERREADY */		out_be32((void*)GPIO1_OR,			 in_be32((void*)GPIO1_OR) | GPIO1_PPC_EREADY);		out_be32((void*)GPIO1_TCR,			 in_be32((void*)GPIO1_TCR) | GPIO1_PPC_EREADY);	} else {		/* Program the board's subsystem id/classcode */		pci_hose_write_config_word(hose, 0, PCI_SUBSYSTEM_ID,					   CONFIG_SYS_PCI_SUBSYS_ID_MONARCH);		pci_hose_write_config_word(hose, 0, PCI_CLASS_SUB_CODE,					   CONFIG_SYS_PCI_CLASSCODE_MONARCH);	}	/* enable host configuration */	pci_hose_write_config_dword(hose, 0, PCI_BRDGOPT2, 0x00000101);}#endif /* defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_TARGET_INIT) *//* * pci_master_init */#if defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_MASTER_INIT)void pci_master_init(struct pci_controller *hose){	unsigned short temp_short;	/*	 * Write the PowerPC440 EP PCI Configuration regs.	 * Enable PowerPC440 EP to be a master on the PCI bus (PMM).	 * Enable PowerPC440 EP to act as a PCI memory target (PTM).	 */	if (is_monarch()) {		pci_read_config_word(0, PCI_COMMAND, &temp_short);		pci_write_config_word(0, PCI_COMMAND,				      temp_short | PCI_COMMAND_MASTER |				      PCI_COMMAND_MEMORY);	}}#endif /* defined(CONFIG_PCI) && defined(CONFIG_SYS_PCI_MASTER_INIT) */static void wait_for_pci_ready(void){	int i;	char *s = getenv("pcidelay");	/*	 * We have our own handling of the pcidelay variable.	 * Using CONFIG_PCI_BOOTDELAY enables pausing for host	 * and adapter devices. For adapter devices we do not	 * want this.	 */	if (s) {		int ms = simple_strtoul(s, NULL, 10);		printf("PCI:   Waiting for %d ms\n", ms);		for (i=0; i<ms; i++)			udelay(1000);	}	if (!(in_be32((void*)GPIO1_IR) & GPIO1_PPC_EREADY)) {		printf("PCI:   Waiting for EREADY (CTRL-C to skip) ... ");		while (1) {			if (ctrlc()) {				puts("abort\n");				break;			}			if (in_be32((void*)GPIO1_IR) & GPIO1_PPC_EREADY) {				printf("done\n");				break;			}		}	}}/* * is_pci_host * * This routine is called to determine if a pci scan should be * performed. With various hardware environments (especially cPCI and * PPMC) it's insufficient to depend on the state of the arbiter enable * bit in the strap register, or generic host/adapter assumptions. * * Rather than hard-code a bad assumption in the general 440 code, the * 440 pci code requires the board to decide at runtime. * * Return 0 for adapter mode, non-zero for host (monarch) mode. */#if defined(CONFIG_PCI)int is_pci_host(struct pci_controller *hose){	char *s = getenv("pciscan");	if (s == NULL)		if (is_monarch()) {			wait_for_pci_ready();			return 1;		} else			return 0;	else if (!strcmp(s, "yes"))		return 1;	return 0;}#endif /* defined(CONFIG_PCI) */#if defined(CONFIG_POST)/* * Returns 1 if keys pressed to start the power-on long-running tests * Called from board_init_f(). */int post_hotkeys_pressed(void){	return 0;	/* No hotkeys supported */}#endif /* CONFIG_POST */#ifdef CONFIG_RESET_PHY_Rvoid reset_phy(void){	char *s;	unsigned short val_method, val_behavior;	/* special LED setup for NGCC/CANDES */	if ((s = getenv("bd_type")) &&	    ((!strcmp(s, "ngcc")) || (!strcmp(s, "candes")))) {		val_method   = 0x0e0a;		val_behavior = 0x0cf2;	} else {		/* PMC440 standard type */		val_method   = 0x0e10;		val_behavior = 0x0cf0;	}	if (miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0001) == 0) {		miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, 0x0010);		miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x11, val_behavior);		miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x10, val_method);		miiphy_write("ppc_4xx_eth0", CONFIG_PHY_ADDR, 0x1f, 0x0000);	}	if (miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0001) == 0) {		miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, 0x0010);		miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x11, val_behavior);		miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x10, val_method);		miiphy_write("ppc_4xx_eth1", CONFIG_PHY1_ADDR, 0x1f, 0x0000);	}}#endif#if defined(CONFIG_SYS_EEPROM_WREN)/* *  Input: <dev_addr> I2C address of EEPROM device to enable. *         <state>    -1: deliver current state *	               0: disable write *		       1: enable write *  Returns:          -1: wrong device address *                     0: dis-/en- able done *		     0/1: current state if <state> was -1. */int eeprom_write_enable(unsigned dev_addr, int state){	if ((CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) &&	    (CONFIG_SYS_I2C_BOOT_EEPROM_ADDR != dev_addr)) {		return -1;	} else {		switch (state) {		case 1:			/* Enable write access, clear bit GPIO_SINT2. */			out32(GPIO0_OR, in32(GPIO0_OR) & ~GPIO0_EP_EEP);			state = 0;			break;		case 0:			/* Disable write access, set bit GPIO_SINT2. */			out32(GPIO0_OR, in32(GPIO0_OR) | GPIO0_EP_EEP);			state = 0;			break;		default:			/* Read current status back. */			state = (0 == (in32(GPIO0_OR) & GPIO0_EP_EEP));			break;		}	}	return state;}#endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */#define CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS 3int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset,			   uchar *buffer, unsigned cnt){	unsigned end = offset + cnt;	unsigned blk_off;	int rcode = 0;#if defined(CONFIG_SYS_EEPROM_WREN)	eeprom_write_enable(dev_addr, 1);#endif	/*	 * Write data until done or would cross a write page boundary.	 * We must write the address again when changing pages	 * because the address counter only increments within a page.	 */	while (offset < end) {		unsigned alen, len;		unsigned maxlen;		uchar addr[2];		blk_off = offset & 0xFF;	/* block offset */		addr[0] = offset >> 8;		/* block number */		addr[1] = blk_off;		/* block offset */		alen	= 2;		addr[0] |= dev_addr;		/* insert device address */		len = end - offset;#define	BOOT_EEPROM_PAGE_SIZE	   (1 << CONFIG_SYS_BOOT_EEPROM_PAGE_WRITE_BITS)#define	BOOT_EEPROM_PAGE_OFFSET(x) ((x) & (BOOT_EEPROM_PAGE_SIZE - 1))		maxlen = BOOT_EEPROM_PAGE_SIZE -			BOOT_EEPROM_PAGE_OFFSET(blk_off);		if (maxlen > I2C_RXTX_LEN)			maxlen = I2C_RXTX_LEN;		if (len > maxlen)			len = maxlen;		if (i2c_write (addr[0], offset, alen-1, buffer, len) != 0)			rcode = 1;		buffer += len;		offset += len;#if defined(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS)		udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);#endif	}#if defined(CONFIG_SYS_EEPROM_WREN)	eeprom_write_enable(dev_addr, 0);#endif	return rcode;}int bootstrap_eeprom_read (unsigned dev_addr, unsigned offset,			   uchar *buffer, unsigned cnt){	unsigned end = offset + cnt;	unsigned blk_off;	int rcode = 0;	/*	 * Read data until done or would cross a page boundary.	 * We must write the address again when changing pages	 * because the next page may be in a different device.	 */	while (offset < end) {		unsigned alen, len;		unsigned maxlen;		uchar addr[2];		blk_off = offset & 0xFF;	/* block offset */		addr[0] = offset >> 8;		/* block number */		addr[1] = blk_off;		/* block offset */		alen	= 2;		addr[0] |= dev_addr;		/* insert device address */		len = end - offset;		maxlen = 0x100 - blk_off;		if (maxlen > I2C_RXTX_LEN)			maxlen = I2C_RXTX_LEN;		if (len > maxlen)			len = maxlen;		if (i2c_read (addr[0], offset, alen-1, buffer, len) != 0)			rcode = 1;		buffer += len;		offset += len;	}	return rcode;}#if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT)int usb_board_init(void){	char *act = getenv("usbact");	int i;	if ((act == NULL || strcmp(act, "host") == 0) &&	    !(in_be32((void*)GPIO0_IR) & GPIO0_USB_PRSNT))		/* enable power on USB socket */		out_be32((void*)GPIO1_OR,			 in_be32((void*)GPIO1_OR) & ~GPIO1_USB_PWR_N);	for (i=0; i<1000; i++)		udelay(1000);	return 0;}int usb_board_stop(void){	/* disable power on USB socket */	out_be32((void*)GPIO1_OR, in_be32((void*)GPIO1_OR) | GPIO1_USB_PWR_N);	return 0;}int usb_board_init_fail(void){	usb_board_stop();	return 0;}#endif /* defined(CONFIG_USB_OHCI) && defined(CONFIG_SYS_USB_OHCI_BOARD_INIT) */#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)void ft_board_setup(void *blob, bd_t *bd){	int rc;	__ft_board_setup(blob, bd);	/*	 * Disable PCI in non-monarch mode.	 */	if (!is_monarch()) {		rc = fdt_find_and_setprop(blob, "/plb/pci@1ec000000", "status",					  "disabled", sizeof("disabled"), 1);		if (rc) {			printf("Unable to update property status in PCI node, err=%s\n",			       fdt_strerror(rc));		}	}}#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */

⌨️ 快捷键说明

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