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

📄 i82365.c

📁 F:worksip2440a board可启动u-boot-like.tar.gz F:worksip2440a board可启动u-boot-like.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
	case 0:		reg = 0;		break;	case 33:		reg = CB_SC_VCC_3V;		break;	case 50:		reg = CB_SC_VCC_5V;		break;	default:		return -1;	}	switch (state->Vpp) {	case 0:		break;	case 33:		reg |= CB_SC_VPP_3V;		break;	case 50:		reg |= CB_SC_VPP_5V;		break;	case 120:		reg |= CB_SC_VPP_12V;		break;	default:		return -1;	}	if (reg != cb_readl (s, CB_SOCKET_CONTROL))		cb_writel (s, CB_SOCKET_CONTROL, reg);#endif	/* CONFIG_CPC45 */	return 0;}/*======================================================================    Generic routines to get and set controller options======================================================================*/static void get_bridge_state (socket_info_t * s){#ifdef CONFIG_CPC45	cirrus_get_state (s);#else	ti113x_get_state (s);#endif	cb_get_state (s);}static void set_bridge_state (socket_info_t * s){	cb_set_state (s);	i365_set (s, I365_GBLCTL, 0x00);	i365_set (s, I365_GENCTL, 0x00);#ifdef CONFIG_CPC45	cirrus_set_state (s);#else	ti113x_set_state (s);#endif}static void set_bridge_opts (socket_info_t * s){#ifdef CONFIG_CPC45	cirrus_set_opts (s);#else	ti113x_set_opts (s);#endif	cb_set_opts (s);}/*====================================================================*/static int i365_get_status (socket_info_t * s, u_int * value){	u_int status;#ifdef CONFIG_CPC45	u_char val;	u_char power, vcc, vpp;#endif	status = i365_get (s, I365_IDENT);	status = i365_get (s, I365_STATUS);	*value = ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;	if (i365_get (s, I365_INTCTL) & I365_PC_IOCARD) {		*value |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;	} else {		*value |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;		*value |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;	}	*value |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;	*value |= (status & I365_CS_READY) ? SS_READY : 0;	*value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;#ifdef CONFIG_CPC45	/* Check for Cirrus CL-PD67xx chips */	i365_set (s, PD67_CHIP_INFO, 0);	val = i365_get (s, PD67_CHIP_INFO);	s->type = -1;	if ((val & PD67_INFO_CHIP_ID) == PD67_INFO_CHIP_ID) {		val = i365_get (s, PD67_CHIP_INFO);		if ((val & PD67_INFO_CHIP_ID) == 0) {			s->type =				(val & PD67_INFO_SLOTS) ? IS_PD672X :				IS_PD6710;			i365_set (s, PD67_EXT_INDEX, 0xe5);			if (i365_get (s, PD67_EXT_INDEX) != 0xe5)				s->type = IS_VT83C469;		}	} else {		printf ("no Cirrus Chip found\n");		*value = 0;		return -1;	}	i365_bset (s, I365_POWER, I365_VCC_5V);	power = i365_get (s, I365_POWER);	state.flags |= (power & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;	state.flags |= (power & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;	vcc = power & I365_VCC_MASK;	vpp = power & I365_VPP1_MASK;	state.Vcc = state.Vpp = 0;	if (i365_get (s, PD67_MISC_CTL_1) & PD67_MC1_VCC_3V) {		if (power & I365_VCC_5V)			state.Vcc = 33;		if (vpp == I365_VPP1_5V)			state.Vpp = 33;	} else {		if (power & I365_VCC_5V)			state.Vcc = 50;		if (vpp == I365_VPP1_5V)			state.Vpp = 50;	}	if (power == I365_VPP1_12V)		state.Vpp = 120;	/* IO card, RESET flags, IO interrupt */	power = i365_get (s, I365_INTCTL);	state.flags |= (power & I365_PC_RESET) ? 0 : SS_RESET;	if (power & I365_PC_IOCARD)		state.flags |= SS_IOCARD;	state.io_irq = power & I365_IRQ_MASK;	/* Card status change mask */	power = i365_get (s, I365_CSCINT);	state.csc_mask = (power & I365_CSC_DETECT) ? SS_DETECT : 0;	if (state.flags & SS_IOCARD)		state.csc_mask |= (power & I365_CSC_STSCHG) ? SS_STSCHG : 0;	else {		state.csc_mask |= (power & I365_CSC_BVD1) ? SS_BATDEAD : 0;		state.csc_mask |= (power & I365_CSC_BVD2) ? SS_BATWARN : 0;		state.csc_mask |= (power & I365_CSC_READY) ? SS_READY : 0;	}	debug ("i82365: GetStatus(0) = flags %#3.3x, Vcc %d, Vpp %d, "		"io_irq %d, csc_mask %#2.2x\n", state.flags,		state.Vcc, state.Vpp, state.io_irq, state.csc_mask);#else	/* !CONFIG_CPC45 */	status = cb_readl (s, CB_SOCKET_STATE);	*value |= (status & CB_SS_32BIT) ? SS_CARDBUS : 0;	*value |= (status & CB_SS_3VCARD) ? SS_3VCARD : 0;	*value |= (status & CB_SS_XVCARD) ? SS_XVCARD : 0;	*value |= (status & CB_SS_VSENSE) ? 0 : SS_PENDING;	/* For now, ignore cards with unsupported voltage keys */	if (*value & SS_XVCARD)		*value &= ~(SS_DETECT | SS_3VCARD | SS_XVCARD);#endif	/* CONFIG_CPC45 */	return 0;}	/* i365_get_status */static int i365_set_socket (socket_info_t * s, socket_state_t * state){	u_char reg;	set_bridge_state (s);	/* IO card, RESET flag */	reg = 0;	reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;	reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;	i365_set (s, I365_INTCTL, reg);#ifdef CONFIG_CPC45	cb_set_power (s, state);#if 0	/* Card status change interrupt mask */	reg = s->cs_irq << 4;	if (state->csc_mask & SS_DETECT)		reg |= I365_CSC_DETECT;	if (state->flags & SS_IOCARD) {		if (state->csc_mask & SS_STSCHG)			reg |= I365_CSC_STSCHG;	} else {		if (state->csc_mask & SS_BATDEAD)			reg |= I365_CSC_BVD1;		if (state->csc_mask & SS_BATWARN)			reg |= I365_CSC_BVD2;		if (state->csc_mask & SS_READY)			reg |= I365_CSC_READY;	}	i365_set (s, I365_CSCINT, reg);	i365_get (s, I365_CSC);#endif	/* 0 */#else	/* !CONFIG_CPC45 */	reg = I365_PWR_NORESET;	if (state->flags & SS_PWR_AUTO)		reg |= I365_PWR_AUTO;	if (state->flags & SS_OUTPUT_ENA)		reg |= I365_PWR_OUT;	cb_set_power (s, state);	reg |= i365_get (s, I365_POWER) & (I365_VCC_MASK | I365_VPP1_MASK);	if (reg != i365_get (s, I365_POWER))		i365_set (s, I365_POWER, reg);#endif	/* CONFIG_CPC45 */	return 0;}	/* i365_set_socket *//*====================================================================*/static int i365_set_mem_map (socket_info_t * s, struct pccard_mem_map *mem){	u_short base, i;	u_char map;	debug ("i82365: SetMemMap(%d, %#2.2x, %d ns, %#5.5lx-%#5.5lx, %#5.5x)\n",		mem->map, mem->flags, mem->speed,		mem->sys_start, mem->sys_stop, mem->card_start);	map = mem->map;	if ((map > 4) ||	    (mem->card_start > 0x3ffffff) ||	    (mem->sys_start > mem->sys_stop) ||	    (mem->speed > 1000)) {		return -1;	}	/* Turn off the window before changing anything */	if (i365_get (s, I365_ADDRWIN) & I365_ENA_MEM (map))		i365_bclr (s, I365_ADDRWIN, I365_ENA_MEM (map));	/* Take care of high byte, for PCI controllers */	i365_set (s, CB_MEM_PAGE (map), mem->sys_start >> 24);	base = I365_MEM (map);	i = (mem->sys_start >> 12) & 0x0fff;	if (mem->flags & MAP_16BIT)		i |= I365_MEM_16BIT;	if (mem->flags & MAP_0WS)		i |= I365_MEM_0WS;	i365_set_pair (s, base + I365_W_START, i);	i = (mem->sys_stop >> 12) & 0x0fff;	switch (mem->speed / CYCLE_TIME) {	case 0:		break;	case 1:		i |= I365_MEM_WS0;		break;	case 2:		i |= I365_MEM_WS1;		break;	default:		i |= I365_MEM_WS1 | I365_MEM_WS0;		break;	}	i365_set_pair (s, base + I365_W_STOP, i);#ifdef CONFIG_CPC45	i = 0;#else	i = ((mem->card_start - mem->sys_start) >> 12) & 0x3fff;#endif	if (mem->flags & MAP_WRPROT)		i |= I365_MEM_WRPROT;	if (mem->flags & MAP_ATTRIB)		i |= I365_MEM_REG;	i365_set_pair (s, base + I365_W_OFF, i);#ifdef CONFIG_CPC45	/* set System Memory map Upper Adress */	i365_set(s, PD67_EXT_INDEX, PD67_MEM_PAGE(map));	i365_set(s, PD67_EXT_DATA, ((mem->sys_start >> 24) & 0xff));#endif	/* Turn on the window if necessary */	if (mem->flags & MAP_ACTIVE)		i365_bset (s, I365_ADDRWIN, I365_ENA_MEM (map));	return 0;}	/* i365_set_mem_map */static int i365_set_io_map (socket_info_t * s, struct pccard_io_map *io){	u_char map, ioctl;	map = io->map;	/* comment out: comparison is always false due to limited range of data type */	if ((map > 1) || /* (io->start > 0xffff) || (io->stop > 0xffff) || */	    (io->stop < io->start))		return -1;	/* Turn off the window before changing anything */	if (i365_get (s, I365_ADDRWIN) & I365_ENA_IO (map))		i365_bclr (s, I365_ADDRWIN, I365_ENA_IO (map));	i365_set_pair (s, I365_IO (map) + I365_W_START, io->start);	i365_set_pair (s, I365_IO (map) + I365_W_STOP, io->stop);	ioctl = i365_get (s, I365_IOCTL) & ~I365_IOCTL_MASK (map);	if (io->speed)		ioctl |= I365_IOCTL_WAIT (map);	if (io->flags & MAP_0WS)		ioctl |= I365_IOCTL_0WS (map);	if (io->flags & MAP_16BIT)		ioctl |= I365_IOCTL_16BIT (map);	if (io->flags & MAP_AUTOSZ)		ioctl |= I365_IOCTL_IOCS16 (map);	i365_set (s, I365_IOCTL, ioctl);	/* Turn on the window if necessary */	if (io->flags & MAP_ACTIVE)		i365_bset (s, I365_ADDRWIN, I365_ENA_IO (map));	return 0;}	/* i365_set_io_map *//*====================================================================*/int i82365_init (void){	u_int val;	int i;#ifdef CONFIG_CPC45	if (SPD67290Init () != 0)		return 1;#endif	if ((socket.dev = pci_find_devices (supported, 0)) < 0) {		/* Controller not found */		return 1;	}	debug ("i82365 Device Found!\n");	pci_read_config_dword (socket.dev, PCI_BASE_ADDRESS_0, &socket.cb_phys);	socket.cb_phys &= ~0xf;#ifdef CONFIG_CPC45	/* + 0xfe000000 see MPC 8245 Users Manual Adress Map B */	socket.cb_phys += 0xfe000000;#endif	get_bridge_state (&socket);	set_bridge_opts (&socket);	i = i365_get_status (&socket, &val);#ifdef CONFIG_CPC45	if (i > -1) {		puts (pcic[socket.type].name);	} else {		printf ("i82365: Controller not found.\n");		return 1;	}#else	/* !CONFIG_CPC45 */	if (val & SS_DETECT) {		if (val & SS_3VCARD) {			state.Vcc = state.Vpp = 33;			puts (" 3.3V card found: ");		} else if (!(val & SS_XVCARD)) {			state.Vcc = state.Vpp = 50;			puts (" 5.0V card found: ");		} else {			puts ("i82365: unsupported voltage key\n");			state.Vcc = state.Vpp = 0;		}	} else {		/* No card inserted */		puts ("No card\n");		return 1;	}#endif	/* CONFIG_CPC45 */#ifdef CONFIG_CPC45	state.flags |= SS_OUTPUT_ENA;#else	state.flags = SS_IOCARD | SS_OUTPUT_ENA;	state.csc_mask = 0;	state.io_irq = 0;#endif	i365_set_socket (&socket, &state);	for (i = 500; i; i--) {		if ((i365_get (&socket, I365_STATUS) & I365_CS_READY))			break;		udelay (1000);	}	if (i == 0) {		/* PC Card not ready for data transfer */		puts ("i82365 PC Card not ready for data transfer\n");		return 1;	}	debug (" PC Card ready for data transfer: ");	mem.map = 0;	mem.flags = MAP_ATTRIB | MAP_ACTIVE;	mem.speed = 300;	mem.sys_start = CFG_PCMCIA_MEM_ADDR;	mem.sys_stop = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE - 1;	mem.card_start = 0;	i365_set_mem_map (&socket, &mem);#ifdef CONFIG_CPC45	mem.map = 1;	mem.flags = MAP_ACTIVE;	mem.speed = 300;	mem.sys_start = CFG_PCMCIA_MEM_ADDR + CFG_PCMCIA_MEM_SIZE;	mem.sys_stop = CFG_PCMCIA_MEM_ADDR + (2 * CFG_PCMCIA_MEM_SIZE) - 1;	mem.card_start = 0;	i365_set_mem_map (&socket, &mem);#else	/* !CONFIG_CPC45 */	io.map = 0;	io.flags = MAP_AUTOSZ | MAP_ACTIVE;	io.speed = 0;	io.start = 0x0100;	io.stop = 0x010F;	i365_set_io_map (&socket, &io);#endif	/* CONFIG_CPC45 */#ifdef DEBUG	i82365_dump_regions (socket.dev);#endif	return 0;}void i82365_exit (void){	io.map = 0;	io.flags = 0;	io.speed = 0;	io.start = 0;	io.stop = 0x1;	i365_set_io_map (&socket, &io);	mem.map = 0;	mem.flags = 0;	mem.speed = 0;	mem.sys_start = 0;	mem.sys_stop = 0x1000;	mem.card_start = 0;	i365_set_mem_map (&socket, &mem);#ifdef CONFIG_CPC45	mem.map = 1;	mem.flags = 0;	mem.speed = 0;	mem.sys_start = 0;	mem.sys_stop = 0x1000;	mem.card_start = 0;	i365_set_mem_map (&socket, &mem);#else	/* !CONFIG_CPC45 */	socket.state.sysctl &= 0xFFFF00FF;#endif	state.Vcc = state.Vpp = 0;	i365_set_socket (&socket, &state);}/*======================================================================    Debug stuff======================================================================*/#ifdef DEBUGstatic void i82365_dump_regions (pci_dev_t dev){	u_int tmp[2];	u_int *mem = (void *) socket.cb_phys;	u_char *cis = (void *) CFG_PCMCIA_MEM_ADDR;	u_char *ide = (void *) (CFG_ATA_BASE_ADDR + CFG_ATA_REG_OFFSET);	pci_read_config_dword (dev, 0x00, tmp + 0);	pci_read_config_dword (dev, 0x80, tmp + 1);	printf ("PCI CONF: %08X ... %08X\n", tmp[0], tmp[1]);	printf ("PCI MEM:  ... %08X ... %08X\n", mem[0x8 / 4], mem[0x800 / 4]);	printf ("CIS:      ...%c%c%c%c%c%c%c%c...\n",		cis[0x38], cis[0x3a], cis[0x3c], cis[0x3e],		cis[0x40], cis[0x42], cis[0x44], cis[0x48]);	printf ("CIS CONF: %02X %02X %02X ...\n",		cis[0x200], cis[0x202], cis[0x204]);	printf ("IDE:      %02X %02X %02X %02X %02X %02X %02X %02X\n",		ide[0], ide[1], ide[2], ide[3],		ide[4], ide[5], ide[6], ide[7]);}#endif	/* DEBUG */#endif /* CONFIG_I82365 */

⌨️ 快捷键说明

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