示例#1
0
static void reset_mac_unlocked(struct net_device *dev)
{
	struct au1000_private *const aup = netdev_priv(dev);
	int i;

	hard_stop(dev);

	*aup->enable = MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);
	*aup->enable = 0;
	au_sync_delay(2);

	aup->tx_full = 0;
	for (i = 0; i < NUM_RX_DMA; i++) {
		/* reset control bits */
		aup->rx_dma_ring[i]->buff_stat &= ~0xf;
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		/* reset control bits */
		aup->tx_dma_ring[i]->buff_stat &= ~0xf;
	}

	aup->mac_enabled = 0;

}
示例#2
0
static void au1000_timer(unsigned long data)
{
	struct net_device *dev = (struct net_device *)data;
	struct au1000_private *aup = (struct au1000_private *) dev->priv;
	unsigned char if_port;
	u16 link, speed;

	if (!dev) {
		/* fatal error, don't restart the timer */
		printk(KERN_ERR "au1000_timer error: NULL dev\n");
		return;
	}

	if_port = dev->if_port;

#ifdef CLEANUP	
	if (aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed) == 0) {
		if (link) {
			if (!(dev->flags & IFF_RUNNING)) {
				netif_carrier_on(dev);
				dev->flags |= IFF_RUNNING;
				printk(KERN_INFO "%s: link up\n", dev->name);
			}
		}
		else {
			if (dev->flags & IFF_RUNNING) {
				netif_carrier_off(dev);
				dev->flags &= ~IFF_RUNNING;
				dev->if_port = 0;
				printk(KERN_INFO "%s: link down\n", dev->name);
			}
		}
	}
#endif

	if (link && (dev->if_port != if_port) && 
			(dev->if_port != IF_PORT_UNKNOWN)) {
		hard_stop(dev);
		if (dev->if_port == IF_PORT_100BASEFX) {
			printk(KERN_INFO "%s: going to full duplex\n", 
					dev->name);
			aup->mac->control |= MAC_FULL_DUPLEX;
			au_sync_delay(1);
		}
		else {
			aup->mac->control &= ~MAC_FULL_DUPLEX;
			au_sync_delay(1);
		}
		enable_rx_tx(dev);
	}

	aup->timer.expires = RUN_AT((1*HZ)); 
	aup->timer.data = (unsigned long)dev;
	aup->timer.function = &au1000_timer; /* timer handler */
	add_timer(&aup->timer);

}
static int xxs1500_pcmcia_shutdown(void)
{
	/* turn off power */
	au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
			GPIO2_OUTPUT);
	au_sync_delay(100);

	/* assert reset */
	au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20),
			GPIO2_OUTPUT);
	au_sync_delay(100);
	return 0;
}
示例#4
0
/* 
 * Initialize the interface.
 *
 * When the device powers up, the clocks are disabled and the
 * mac is in reset state.  When the interface is closed, we
 * do the same -- reset the device and disable the clocks to
 * conserve power. Thus, whenever au1000_init() is called,
 * the device should already be in reset state.
 */
static int au1000_init(struct net_device *dev)
{
	struct au1000_private *aup = (struct au1000_private *) dev->priv;
	u32 flags;
	int i;
	u32 control;
	u16 link, speed;

	if (au1000_debug > 4) 
		printk("%s: au1000_init\n", dev->name);

	spin_lock_irqsave(&aup->lock, flags);

	/* bring the device out of reset */
	*aup->enable = MAC_EN_CLOCK_ENABLE;
        au_sync_delay(2);
	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
	au_sync_delay(20);

	aup->mac->control = 0;
	aup->tx_head = (aup->tx_dma_ring[0]->buff_stat & 0xC) >> 2;
	aup->tx_tail = aup->tx_head;
	aup->rx_head = (aup->rx_dma_ring[0]->buff_stat & 0xC) >> 2;

	aup->mac->mac_addr_high = dev->dev_addr[5]<<8 | dev->dev_addr[4];
	aup->mac->mac_addr_low = dev->dev_addr[3]<<24 | dev->dev_addr[2]<<16 |
		dev->dev_addr[1]<<8 | dev->dev_addr[0];

	for (i = 0; i < NUM_RX_DMA; i++) {
		aup->rx_dma_ring[i]->buff_stat |= RX_DMA_ENABLE;
	}
	au_sync();

#ifdef CLEANUP
	aup->phy_ops->phy_status(dev, aup->phy_addr, &link, &speed);
#endif
	control = MAC_DISABLE_RX_OWN | MAC_RX_ENABLE | MAC_TX_ENABLE;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
	control |= MAC_BIG_ENDIAN;
#endif
	if (link && (dev->if_port == IF_PORT_100BASEFX)) {
		control |= MAC_FULL_DUPLEX;
	}
	aup->mac->control = control;
	aup->mac->vlan1_tag = 0x8100; /* activate vlan support */
	au_sync();

	spin_unlock_irqrestore(&aup->lock, flags);
	return 0;
}
示例#5
0
int __init au1x_board_init(struct device *dev)
{
	int ret = -ENODEV;
	bcsr->pcmcia = 0; /* turn off power, if it's not already off */
	au_sync_delay(2);
	ret = au1x00_pcmcia_socket_probe(dev, &db1x00_pcmcia_ops, 0, 2);
	return ret;
}
示例#6
0
static void pb1200mmc1_set_power(void *mmc_host, int state)
{
    if (state)
        bcsr->board |= BCSR_BOARD_SD1PWR;
    else
        bcsr->board &= ~BCSR_BOARD_SD1PWR;

    au_sync_delay(1);
}
static int
xxs1500_pcmcia_configure_socket(const struct pcmcia_configure *configure)
{

	if(configure->sock > PCMCIA_MAX_SOCK) return -1;

	DEBUG("Vcc %dV Vpp %dV, reset %d\n",
			configure->vcc, configure->vpp, configure->reset);

	switch(configure->vcc){
		case 33: /* Vcc 3.3V */
			/* turn on power */
			DEBUG("turn on power\n");
			au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<14))|(1<<30),
					GPIO2_OUTPUT);
			au_sync_delay(100);
			break;
		case 50: /* Vcc 5V */
		default: /* what's this ? */
			printk(KERN_ERR "au1x00_cs: unsupported VCC\n");
		case 0:  /* Vcc 0 */
			/* turn off power */
			au_sync_delay(100);
			au_writel(au_readl(GPIO2_PINSTATE) | (1<<14)|(1<<30),
					GPIO2_OUTPUT);
			break;
	}

	if (!configure->reset) {
		DEBUG("deassert reset\n");
		au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<4))|(1<<20),
				GPIO2_OUTPUT);
		au_sync_delay(100);
		au_writel((au_readl(GPIO2_PINSTATE) & ~(1<<5))|(1<<21),
				GPIO2_OUTPUT);
	}
	else {
		DEBUG("assert reset\n");
		au_writel(au_readl(GPIO2_PINSTATE) | (1<<4)|(1<<20),
				GPIO2_OUTPUT);
	}
	au_sync_delay(100);
	return 0;
}
static void enable_rx_tx(struct net_device *dev)
{
	struct au1000_private *aup = (struct au1000_private *) dev->priv;

	if (au1000_debug > 4)
		printk(KERN_INFO "%s: enable_rx_tx\n", dev->name);

	aup->mac->control |= (MAC_RX_ENABLE | MAC_TX_ENABLE);
	au_sync_delay(10);
}
static void hard_stop(struct net_device *dev)
{
	struct au1000_private *aup = (struct au1000_private *) dev->priv;

	if (au1000_debug > 4)
		printk(KERN_INFO "%s: hard stop\n", dev->name);

	aup->mac->control &= ~(MAC_RX_ENABLE | MAC_TX_ENABLE);
	au_sync_delay(10);
}
示例#10
0
static void enable_mac(struct net_device *dev, int force_reset)
{
	unsigned long flags;
	struct au1000_private *aup = netdev_priv(dev);

	spin_lock_irqsave(&aup->lock, flags);

	if(force_reset || (!aup->mac_enabled)) {
		*aup->enable = MAC_EN_CLOCK_ENABLE;
		au_sync_delay(2);
		*aup->enable = (MAC_EN_RESET0 | MAC_EN_RESET1 | MAC_EN_RESET2
				| MAC_EN_CLOCK_ENABLE);
		au_sync_delay(2);

		aup->mac_enabled = 1;
	}

	spin_unlock_irqrestore(&aup->lock, flags);
}
static void reset_mac(struct net_device *dev)
{
	u32 flags;
	struct au1000_private *aup = (struct au1000_private *) dev->priv;

	if (au1000_debug > 4) 
		printk(KERN_INFO "%s: reset mac, aup %x\n", 
				dev->name, (unsigned)aup);

	spin_lock_irqsave(&aup->lock, flags);
	del_timer(&aup->timer);
	hard_stop(dev);
	*aup->enable = MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);
       	*aup->enable = 0;
	au_sync_delay(2);
	aup->tx_full = 0;
	spin_unlock_irqrestore(&aup->lock, flags);
}
示例#12
0
static void au1xmmc_set_power(struct au1xmmc_host *host, int state) 
{

	u32 val = au1xmmc_card_table[host->id].bcsrpwr;

	bcsr->board &= ~val;
	if (state) bcsr->board |= val;
	
	au_sync_delay(1);
}
示例#13
0
static int au1k_init(struct net_device *dev)
{
	struct au1k_private *aup = (struct au1k_private *) dev->priv;
	int i;
	u32 control;
	u32 ring_address;

	/* bring the device out of reset */
	control = 0xe; /* coherent, clock enable, one half system clock */
			  
#ifndef CONFIG_CPU_LITTLE_ENDIAN
	control |= 1;
#endif
	aup->tx_head = 0;
	aup->tx_tail = 0;
	aup->rx_head = 0;

	for (i=0; i<NUM_IR_DESC; i++) {
		aup->rx_ring[i]->flags = AU_OWN;
	}

	writel(control, IR_INTERFACE_CONFIG);
	au_sync_delay(10);

	writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
	au_sync_delay(1);

	writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN);

	ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
	writel(ring_address >> 26, IR_RING_BASE_ADDR_H);
	writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L);

	writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);

	writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
	writel(0, IR_RING_ADDR_CMPR);

	au1k_irda_set_speed(dev, 9600);
	return 0;
}
示例#14
0
static inline void FLUSH_FIFO(struct au1xmmc_host *host)
{
	u32 val = au_readl(HOST_CONFIG2(host));

	au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host));
	au_sync_delay(1);

	
	val &= ~SD_CONFIG2_DF;

	au_writel(val, HOST_CONFIG2(host));
	au_sync();
}
示例#15
0
文件: au1xmmc.c 项目: hajuuk/R7000
static inline void FLUSH_FIFO(struct au1xmmc_host *host)
{
	u32 val = au_readl(HOST_CONFIG2(host));

	au_writel(val | SD_CONFIG2_FF, HOST_CONFIG2(host));
	au_sync_delay(1);

	/* SEND_STOP will turn off clock control - this re-enables it */
	val &= ~SD_CONFIG2_DF;

	au_writel(val, HOST_CONFIG2(host));
	au_sync();
}
示例#16
0
static void reset_mac(struct net_device *dev)
{
	int i;
	u32 flags;
	struct au1000_private *aup = (struct au1000_private *) dev->priv;

	if (au1000_debug > 4) 
		printk(KERN_INFO "%s: reset mac, aup %x\n", 
				dev->name, (unsigned)aup);

	spin_lock_irqsave(&aup->lock, flags);
	del_timer(&aup->timer);
	hard_stop(dev);
	#ifdef CONFIG_BCM5222_DUAL_PHY
	if (aup->mac_id != 0) {
	#endif
		/* If BCM5222, we can't leave MAC0 in reset because then 
		 * we can't access the dual phy for ETH1 */
		*aup->enable = MAC_EN_CLOCK_ENABLE;
		au_sync_delay(2);
		*aup->enable = 0;
		au_sync_delay(2);
	#ifdef CONFIG_BCM5222_DUAL_PHY
	}
	#endif
	aup->tx_full = 0;
	for (i = 0; i < NUM_RX_DMA; i++) {
		/* reset control bits */
		aup->rx_dma_ring[i]->buff_stat &= ~0xf;
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		/* reset control bits */
		aup->tx_dma_ring[i]->buff_stat &= ~0xf;
	}
	spin_unlock_irqrestore(&aup->lock, flags);
}
示例#17
0
void __init pcibios_fixup(void)
{
#ifdef CONFIG_PCI_PB1000_COMPAT
	unsigned long pci_mem_start = (unsigned long) PCI_MEM_START;

	writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
	writel(0, SDRAM_MBAR);        // set mbar to 0
	writel(0x2, SDRAM_CMD);       // enable memory accesses
	au_sync_delay(1);

	// set extend byte to mbar of ext slot
	writel(((pci_mem_start >> 24) & 0xff) |
	       (1 << 8 | 1 << 9 | 1 << 10 | 1 << 27), PCI_BRIDGE_CONFIG);
	DBG("Set bridge config to %x\n", readl(PCI_BRIDGE_CONFIG));
#endif /* CONFIG_PCI_PB1000_COMPAT */
}
示例#18
0
/*
 * Apply power to card slot.
 */
void mmc_power_on(int _n_)
{
	BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
	unsigned long mmc_pwr, board_specific;

	if (_n_) {
		mmc_pwr = BCSR_BOARD_SD1_PWR;
	} else {
		mmc_pwr = BCSR_BOARD_SD0_PWR;
	}

	board_specific = au_readl((unsigned long)(&bcsr->specific));
	board_specific |= mmc_pwr;

	au_writel(board_specific, (int)(&bcsr->specific));
	au_sync_delay(1);
}
示例#19
0
static void db1x00_pcmcia_shutdown(struct au1000_pcmcia_socket *skt)
{
	bcsr->pcmcia = 0; /* turn off power */
	au_sync_delay(2);
}
示例#20
0
static int
db1x00_pcmcia_configure_socket(struct au1000_pcmcia_socket *skt, struct socket_state_t *state)
{
	u16 pwr;
	int sock = skt->nr;

	debug("config_skt %d Vcc %dV Vpp %dV, reset %d\n",
			sock, state->Vcc, state->Vpp,
			state->flags & SS_RESET);

	/* pcmcia reg was set to zero at init time. Be careful when
	 * initializing a socket not to wipe out the settings of the
	 * other socket.
	 */
	pwr = bcsr->pcmcia;
	pwr &= ~(0xf << sock*8); /* clear voltage settings */

	state->Vpp = 0;
	switch(state->Vcc){
		case 0:  /* Vcc 0 */
			pwr |= SET_VCC_VPP(0,0,sock);
			break;
		case 50: /* Vcc 5V */
			switch(state->Vpp) {
				case 0:
					pwr |= SET_VCC_VPP(2,0,sock);
					break;
				case 50:
					pwr |= SET_VCC_VPP(2,1,sock);
					break;
				case 12:
					pwr |= SET_VCC_VPP(2,2,sock);
					break;
				case 33:
				default:
					pwr |= SET_VCC_VPP(0,0,sock);
					printk("%s: bad Vcc/Vpp (%d:%d)\n",
							__FUNCTION__,
							state->Vcc,
							state->Vpp);
					break;
			}
			break;
		case 33: /* Vcc 3.3V */
			switch(state->Vpp) {
				case 0:
					pwr |= SET_VCC_VPP(1,0,sock);
					break;
				case 12:
					pwr |= SET_VCC_VPP(1,2,sock);
					break;
				case 33:
					pwr |= SET_VCC_VPP(1,1,sock);
					break;
				case 50:
				default:
					pwr |= SET_VCC_VPP(0,0,sock);
					printk("%s: bad Vcc/Vpp (%d:%d)\n",
							__FUNCTION__,
							state->Vcc,
							state->Vpp);
					break;
			}
			break;
		default: /* what's this ? */
			pwr |= SET_VCC_VPP(0,0,sock);
			printk(KERN_ERR "%s: bad Vcc %d\n",
					__FUNCTION__, state->Vcc);
			break;
	}

	bcsr->pcmcia = pwr;
	au_sync_delay(300);

	if (sock == 0) {
		if (!(state->flags & SS_RESET)) {
			pwr |= BCSR_PCMCIA_PC0DRVEN;
			bcsr->pcmcia = pwr;
			au_sync_delay(300);
			pwr |= BCSR_PCMCIA_PC0RST;
			bcsr->pcmcia = pwr;
			au_sync_delay(100);
		}
		else {
			pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
			bcsr->pcmcia = pwr;
			au_sync_delay(100);
		}
	}
	else {
		if (!(state->flags & SS_RESET)) {
			pwr |= BCSR_PCMCIA_PC1DRVEN;
			bcsr->pcmcia = pwr;
			au_sync_delay(300);
			pwr |= BCSR_PCMCIA_PC1RST;
			bcsr->pcmcia = pwr;
			au_sync_delay(100);
		}
		else {
			pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
			bcsr->pcmcia = pwr;
			au_sync_delay(100);
		}
	}
	return 0;
}
示例#21
0
static int __init au1000_pcmcia_driver_init(void)
{
	servinfo_t info;
	struct pcmcia_init pcmcia_init;
	struct pcmcia_state state;
	unsigned int i;
	unsigned long timing3;

	printk("\nAu1x00 PCMCIA (CS release %s)\n", CS_RELEASE);

	CardServices(GetCardServicesInfo, &info);

	if(info.Revision!=CS_RELEASE_CODE){
		printk(KERN_ERR "Card Services release codes do not match\n");
		return -1;
	}

#ifdef CONFIG_MIPS_PB1000
	pcmcia_low_level=&pb1000_pcmcia_ops;
#elif defined(CONFIG_MIPS_PB1500)
	pcmcia_low_level=&pb1500_pcmcia_ops;
#else
#error Unsupported AU1000 board.
#endif

	pcmcia_init.handler=au1000_pcmcia_interrupt;
	if((socket_count=pcmcia_low_level->init(&pcmcia_init))<0) {
		printk(KERN_ERR "Unable to initialize PCMCIA service.\n");
		return -EIO;
	}

	/* setup the static bus controller */
	timing3 = 0x100e3a07;
	writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
	writel(timing3, MEM_STTIME3); 
	writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */
	au_sync_delay(1);

	pcmcia_socket = 
		kmalloc(sizeof(struct au1000_pcmcia_socket) * socket_count, 
				GFP_KERNEL);
	if (!pcmcia_socket) {
		printk(KERN_ERR "Card Services can't get memory \n");
		return -1;
	}
	memset(pcmcia_socket, 0,
			sizeof(struct au1000_pcmcia_socket) * socket_count);
			
	for(i=0; i < socket_count; i++) {

		if(pcmcia_low_level->socket_state(i, &state)<0){
			printk(KERN_ERR "Unable to get PCMCIA status\n");
			return -EIO;
		}
		pcmcia_socket[i].k_state=state;
		pcmcia_socket[i].cs_state.csc_mask=SS_DETECT;
		
		if (i == 0) {
			pcmcia_socket[i].virt_io = 
				(u32)ioremap(0xC0000000, 0x1000);
			pcmcia_socket[i].phys_attr = 0xC4000000;
			pcmcia_socket[i].phys_mem = 0xC8000000;
		}
		else  {
			printk(KERN_ERR "au1000: socket 1 not supported\n");
			return 1;
		}
	}

	/* Only advertise as many sockets as we can detect: */
	if(register_ss_entry(socket_count, &au1000_pcmcia_operations)<0){
		printk(KERN_ERR "Unable to register socket service routine\n");
		return -ENXIO;
	}

	/* Start the event poll timer.  
	 * It will reschedule by itself afterwards. 
	 */
	au1000_pcmcia_poll_event(0);

	DEBUG(1, "au1000: initialization complete\n");
	return 0;

}  /* au1000_pcmcia_driver_init() */
static int __init
au1000_probe1(struct net_device *dev, long ioaddr, int irq, int port_num)
{
	static unsigned version_printed = 0;
	struct au1000_private *aup = NULL;
	int i, retval = 0;
	db_dest_t *pDB, *pDBfree;
	char *pmac, *argptr;
	char ethaddr[6];

	if (!request_region(ioaddr, MAC_IOSIZE, "Au1000 ENET")) {
		 return -ENODEV;
	}

	if (version_printed++ == 0) printk(version);

	if (!dev) {
		dev = init_etherdev(0, sizeof(struct au1000_private));
	}
	if (!dev) {
		 printk (KERN_ERR "au1000 eth: init_etherdev failed\n");  
		 return -ENODEV;
	}

	printk("%s: Au1xxx ethernet found at 0x%lx, irq %d\n", 
			dev->name, ioaddr, irq);

	/* Initialize our private structure */
	if (dev->priv == NULL) {
		aup = (struct au1000_private *) 
			kmalloc(sizeof(*aup), GFP_KERNEL);
		if (aup == NULL) {
			retval = -ENOMEM;
			goto free_region;
		}
		dev->priv = aup;
	}

	aup = dev->priv;
	memset(aup, 0, sizeof(*aup));


	/* Allocate the data buffers */
	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
			(NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
	if (!aup->vaddr) {
		retval = -ENOMEM;
		goto free_region;
	}

	/* aup->mac is the base address of the MAC's registers */
	aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
	/* Setup some variables for quick register address access */
	switch (ioaddr) {
	case AU1000_ETH0_BASE:
	case AU1500_ETH0_BASE:
		/* check env variables first */
		if (!get_ethernet_addr(ethaddr)) { 
			memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
		} else {
			/* Check command line */
			argptr = prom_getcmdline();
			if ((pmac = strstr(argptr, "ethaddr=")) == NULL) {
				printk(KERN_INFO "%s: No mac address found\n", 
						dev->name);
				/* use the hard coded mac addresses */
			} else {
				str2eaddr(ethaddr, pmac + strlen("ethaddr="));
				memcpy(au1000_mac_addr, ethaddr, 
						sizeof(dev->dev_addr));
			}
		}
		if (ioaddr == AU1000_ETH0_BASE)
			aup->enable = (volatile u32 *) 
				((unsigned long)AU1000_MAC0_ENABLE);
		else
			aup->enable = (volatile u32 *) 
				((unsigned long)AU1500_MAC0_ENABLE);
		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
			break;
	case AU1000_ETH1_BASE:
	case AU1500_ETH1_BASE:
		if (ioaddr == AU1000_ETH1_BASE)
			aup->enable = (volatile u32 *) 
				((unsigned long)AU1000_MAC1_ENABLE);
		else
			aup->enable = (volatile u32 *) 
				((unsigned long)AU1500_MAC1_ENABLE);
		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
		dev->dev_addr[4] += 0x10;
		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
			break;
	default:
		printk(KERN_ERR "%s: bad ioaddr\n", dev->name);
		break;

	}

	aup->phy_addr = PHY_ADDRESS;

	/* bring the device out of reset, otherwise probing the mii
	 * will hang */
	*aup->enable = MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);
	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);

	if (mii_probe(dev) != 0) {
		 goto free_region;
	}

	pDBfree = NULL;
	/* setup the data buffer descriptors and attach a buffer to each one */
	pDB = aup->db;
	for (i=0; i<(NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	for (i=0; i<NUM_RX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto free_region;
		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->rx_db_inuse[i] = pDB;
	}
	for (i=0; i<NUM_TX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) goto free_region;
		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->tx_dma_ring[i]->len = 0;
		aup->tx_db_inuse[i] = pDB;
	}

	spin_lock_init(&aup->lock);
	dev->base_addr = ioaddr;
	dev->irq = irq;
	dev->open = au1000_open;
	dev->hard_start_xmit = au1000_tx;
	dev->stop = au1000_close;
	dev->get_stats = au1000_get_stats;
	dev->set_multicast_list = &set_rx_mode;
	dev->do_ioctl = &au1000_ioctl;
	dev->set_config = &au1000_set_config;
	dev->tx_timeout = au1000_tx_timeout;
	dev->watchdog_timeo = ETH_TX_TIMEOUT;


	/* Fill in the fields of the device structure with ethernet values. */
	ether_setup(dev);

	/* 
	 * The boot code uses the ethernet controller, so reset it to start 
	 * fresh.  au1000_init() expects that the device is in reset state.
	 */
	reset_mac(dev);
	return 0;

free_region:
	release_region(ioaddr, MAC_IOSIZE);
	unregister_netdev(dev);
	if (aup->vaddr) 
		dma_free((void *)aup->vaddr, 
				MAX_BUF_SIZE * (NUM_TX_BUFFS+NUM_RX_BUFFS));
	if (dev->priv != NULL)
		kfree(dev->priv);
	printk(KERN_ERR "%s: au1000_probe1 failed.  Returns %d\n",
	       dev->name, retval);
	kfree(dev);
	return retval;
}
示例#23
0
static int pm_do_freq(ctl_table * ctl, int write, struct file *file,
		      void *buffer, size_t * len)
{
	int retval = 0, i;
	unsigned long val, pll;
#define TMPBUFLEN 64
#define MAX_CPU_FREQ 396
	char buf[TMPBUFLEN], *p;
	unsigned long flags, intc0_mask, intc1_mask;
	unsigned long old_baud_base, old_cpu_freq, baud_rate, old_clk,
	    old_refresh;
	unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;

	spin_lock_irqsave(&pm_lock, flags);
	if (!write) {
		*len = 0;
	} else {
		/* Parse the new frequency */
		if (*len > TMPBUFLEN - 1) {
			spin_unlock_irqrestore(&pm_lock, flags);
			return -EFAULT;
		}
		if (copy_from_user(buf, buffer, *len)) {
			spin_unlock_irqrestore(&pm_lock, flags);
			return -EFAULT;
		}
		buf[*len] = 0;
		p = buf;
		val = simple_strtoul(p, &p, 0);
		if (val > MAX_CPU_FREQ) {
			spin_unlock_irqrestore(&pm_lock, flags);
			return -EFAULT;
		}

		pll = val / 12;
		if ((pll > 33) || (pll < 7)) {	/* 396 MHz max, 84 MHz min */
			/* revisit this for higher speed cpus */
			spin_unlock_irqrestore(&pm_lock, flags);
			return -EFAULT;
		}

		old_baud_base = get_au1x00_uart_baud_base();
		old_cpu_freq = get_au1x00_speed();

		new_cpu_freq = pll * 12 * 1000000;
	        new_baud_base =  (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)&0x03) + 2) * 16));
		set_au1x00_speed(new_cpu_freq);
		set_au1x00_uart_baud_base(new_baud_base);

		old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
		new_refresh =
		    ((old_refresh * new_cpu_freq) /
		     old_cpu_freq) | (au_readl(MEM_SDREFCFG) & ~0x1ffffff);

		au_writel(pll, SYS_CPUPLL);
		au_sync_delay(1);
		au_writel(new_refresh, MEM_SDREFCFG);
		au_sync_delay(1);

		for (i = 0; i < 4; i++) {
			if (au_readl
			    (UART_BASE + UART_MOD_CNTRL +
			     i * 0x00100000) == 3) {
				old_clk =
				    au_readl(UART_BASE + UART_CLK +
					  i * 0x00100000);
				// baud_rate = baud_base/clk
				baud_rate = old_baud_base / old_clk;
				/* we won't get an exact baud rate and the error
				 * could be significant enough that our new
				 * calculation will result in a clock that will
				 * give us a baud rate that's too far off from
				 * what we really want.
				 */
				if (baud_rate > 100000)
					baud_rate = 115200;
				else if (baud_rate > 50000)
					baud_rate = 57600;
				else if (baud_rate > 30000)
					baud_rate = 38400;
				else if (baud_rate > 17000)
					baud_rate = 19200;
				else
					(baud_rate = 9600);
				// new_clk = new_baud_base/baud_rate
				new_clk = new_baud_base / baud_rate;
				au_writel(new_clk,
				       UART_BASE + UART_CLK +
				       i * 0x00100000);
				au_sync_delay(10);
			}
		}
	}


	/* We don't want _any_ interrupts other than
	 * match20. Otherwise our calibrate_delay()
	 * calculation will be off, potentially a lot.
	 */
	intc0_mask = save_local_and_disable(0);
	intc1_mask = save_local_and_disable(1);
	local_enable_irq(AU1000_TOY_MATCH2_INT);
	spin_unlock_irqrestore(&pm_lock, flags);
	calibrate_delay();
	restore_local_and_enable(0, intc0_mask);
	restore_local_and_enable(1, intc1_mask);
	return retval;
}
示例#24
0
static void
au1000_adjust_link(struct net_device *dev)
{
	struct au1000_private *aup = netdev_priv(dev);
	struct phy_device *phydev = aup->phy_dev;
	unsigned long flags;

	int status_change = 0;

	BUG_ON(!aup->phy_dev);

	spin_lock_irqsave(&aup->lock, flags);

	if (phydev->link && (aup->old_speed != phydev->speed)) {
		// speed changed

		switch(phydev->speed) {
		case SPEED_10:
		case SPEED_100:
			break;
		default:
			printk(KERN_WARNING
			       "%s: Speed (%d) is not 10/100 ???\n",
			       dev->name, phydev->speed);
			break;
		}

		aup->old_speed = phydev->speed;

		status_change = 1;
	}

	if (phydev->link && (aup->old_duplex != phydev->duplex)) {
		// duplex mode changed

		/* switching duplex mode requires to disable rx and tx! */
		hard_stop(dev);

		if (DUPLEX_FULL == phydev->duplex)
			aup->mac->control = ((aup->mac->control
					     | MAC_FULL_DUPLEX)
					     & ~MAC_DISABLE_RX_OWN);
		else
			aup->mac->control = ((aup->mac->control
					      & ~MAC_FULL_DUPLEX)
					     | MAC_DISABLE_RX_OWN);
		au_sync_delay(1);

		enable_rx_tx(dev);
		aup->old_duplex = phydev->duplex;

		status_change = 1;
	}

	if(phydev->link != aup->old_link) {
		// link state changed

		if (!phydev->link) {
			/* link went down */
			aup->old_speed = 0;
			aup->old_duplex = -1;
		}

		aup->old_link = phydev->link;
		status_change = 1;
	}

	spin_unlock_irqrestore(&aup->lock, flags);

	if (status_change) {
		if (phydev->link)
			printk(KERN_INFO "%s: link up (%d/%s)\n",
			       dev->name, phydev->speed,
			       DUPLEX_FULL == phydev->duplex ? "Full" : "Half");
		else
			printk(KERN_INFO "%s: link down\n", dev->name);
	}
}
示例#25
0
static void
db1x00_pcmcia_socket_state(struct au1000_pcmcia_socket *skt, struct pcmcia_state *state)
{
	u32 inserted;
	unsigned char vs;

	state->ready = 0;
	state->vs_Xv = 0;
	state->vs_3v = 0;
	state->detect = 0;

	switch (skt->nr) {
	case 0:
		vs = bcsr->status & 0x3;
#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200)
		inserted = BOARD_CARD_INSERTED(0);
#else
		inserted = !(bcsr->status & (1<<4));
#endif
		break;
	case 1:
		vs = (bcsr->status & 0xC)>>2;
#if defined(CONFIG_MIPS_DB1200) || defined(CONFIG_MIPS_PB1200) 
		inserted = BOARD_CARD_INSERTED(1);
#else
		inserted = !(bcsr->status & (1<<5));
#endif
		break;
	default:/* should never happen */
		return;
	}

	if (inserted)
		debug("db1x00 socket %d: inserted %d, vs %d pcmcia %x\n",
				skt->nr, inserted, vs, bcsr->pcmcia);

	if (inserted) {
		switch (vs) {
			case 0:
			case 2:
				state->vs_3v=1;
				break;
			case 3: /* 5V */
				break;
			default:
				/* return without setting 'detect' */
				printk(KERN_ERR "db1x00 bad VS (%d)\n",
						vs);
		}
		state->detect = 1;
		state->ready = 1;
	}
	else {
		/* if the card was previously inserted and then ejected,
		 * we should turn off power to it
		 */
		if ((skt->nr == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST |
					BCSR_PCMCIA_PC0DRVEN |
					BCSR_PCMCIA_PC0VPP |
					BCSR_PCMCIA_PC0VCC);
			au_sync_delay(10);
		}
		else if ((skt->nr == 1) && bcsr->pcmcia & BCSR_PCMCIA_PC1RST) {
			bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST |
					BCSR_PCMCIA_PC1DRVEN |
					BCSR_PCMCIA_PC1VPP |
					BCSR_PCMCIA_PC1VCC);
			au_sync_delay(10);
		}
	}

	state->bvd1=1;
	state->bvd2=1;
	state->wrprot=0;
}
示例#26
0
void __init board_setup(void)
{
	u32 pin_func, static_cfg0;
	u32 sys_freqctrl, sys_clksrc;
	u32 prid = read_c0_prid();

	rtc_ops = &no_rtc_ops;

	// set AUX clock to 12MHz * 8 = 96 MHz
	au_writel(8, SYS_AUXPLL);
	au_writel(0, SYS_PINSTATERD);
	udelay(100);

#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)
	/* zero and disable FREQ2 */
	sys_freqctrl = au_readl(SYS_FREQCTRL0);
	sys_freqctrl &= ~0xFFF00000;
	au_writel(sys_freqctrl, SYS_FREQCTRL0);

	/* zero and disable USBH/USBD clocks */
	sys_clksrc = au_readl(SYS_CLKSRC);
	sys_clksrc &= ~0x00007FE0;
	au_writel(sys_clksrc, SYS_CLKSRC);

	sys_freqctrl = au_readl(SYS_FREQCTRL0);
	sys_freqctrl &= ~0xFFF00000;

	sys_clksrc = au_readl(SYS_CLKSRC);
	sys_clksrc &= ~0x00007FE0;

	switch (prid & 0x000000FF)
	{
	case 0x00: /* DA */
	case 0x01: /* HA */
	case 0x02: /* HB */
	/* CPU core freq to 48MHz to slow it way down... */
	au_writel(4, SYS_CPUPLL);

	/*
	 * Setup 48MHz FREQ2 from CPUPLL for USB Host
	 */
	/* FRDIV2=3 -> div by 8 of 384MHz -> 48MHz */
	sys_freqctrl |= ((3<<22) | (1<<21) | (0<<20));
	au_writel(sys_freqctrl, SYS_FREQCTRL0);

	/* CPU core freq to 384MHz */
	au_writel(0x20, SYS_CPUPLL);

	printk("Au1000: 48MHz OHCI workaround enabled\n");
		break;

	default:  /* HC and newer */
	// FREQ2 = aux/2 = 48 MHz
	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
	au_writel(sys_freqctrl, SYS_FREQCTRL0);
		break;
	}

	/*
	 * Route 48MHz FREQ2 into USB Host and/or Device
	 */
#ifdef CONFIG_USB_OHCI
	sys_clksrc |= ((4<<12) | (0<<11) | (0<<10));
#endif
#ifdef CONFIG_AU1X00_USB_DEVICE
	sys_clksrc |= ((4<<7) | (0<<6) | (0<<5));
#endif
	au_writel(sys_clksrc, SYS_CLKSRC);

	// configure pins GPIO[14:9] as GPIO
	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8080);

#ifndef CONFIG_AU1X00_USB_DEVICE
	// 2nd USB port is USB host
	pin_func |= 0x8000;
#endif
	au_writel(pin_func, SYS_PINFUNC);
	au_writel(0x2800, SYS_TRIOUTCLR);
	au_writel(0x0030, SYS_OUTPUTCLR);
#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)

	// make gpio 15 an input (for interrupt line)
	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x100);
	// we don't need I2S, so make it available for GPIO[31:29]
	pin_func |= (1<<5);
	au_writel(pin_func, SYS_PINFUNC);

	au_writel(0x8000, SYS_TRIOUTCLR);

	static_cfg0 = au_readl(MEM_STCFG0) & (u32)(~0xc00);
	au_writel(static_cfg0, MEM_STCFG0);

	// configure RCE2* for LCD
	au_writel(0x00000004, MEM_STCFG2);

	// MEM_STTIME2
	au_writel(0x09000000, MEM_STTIME2);

	// Set 32-bit base address decoding for RCE2*
	au_writel(0x10003ff0, MEM_STADDR2);

	// PCI CPLD setup
	// expand CE0 to cover PCI
	au_writel(0x11803e40, MEM_STADDR1);

	// burst visibility on
	au_writel(au_readl(MEM_STCFG0) | 0x1000, MEM_STCFG0);

	au_writel(0x83, MEM_STCFG1);         // ewait enabled, flash timing
	au_writel(0x33030a10, MEM_STTIME1);   // slower timing for FPGA

	/* setup the static bus controller */
	au_writel(0x00000002, MEM_STCFG3);  /* type = PCMCIA */
	au_writel(0x280E3D07, MEM_STTIME3); /* 250ns cycle time */
	au_writel(0x10000000, MEM_STADDR3); /* any PCMCIA select */

#ifdef CONFIG_PCI
	au_writel(0, PCI_BRIDGE_CONFIG); // set extend byte to 0
	au_writel(0, SDRAM_MBAR);        // set mbar to 0
	au_writel(0x2, SDRAM_CMD);       // enable memory accesses
	au_sync_delay(1);
#endif

	/* Enable Au1000 BCLK switching - note: sed1356 must not use
	 * its BCLK (Au1000 LCLK) for any timings */
	switch (prid & 0x000000FF)
	{
	case 0x00: /* DA */
	case 0x01: /* HA */
	case 0x02: /* HB */
		break;
	default:  /* HC and newer */
		/* Enable sys bus clock divider when IDLE state or no bus 
		   activity. */
		au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
		break;
	}
}
示例#27
0
static struct net_device *
au1000_probe(u32 ioaddr, int irq, int port_num)
{
	static unsigned version_printed = 0;
	struct au1000_private *aup = NULL;
	struct net_device *dev = NULL;
	db_dest_t *pDB, *pDBfree;
	char *pmac, *argptr;
	char ethaddr[6];
	int i, err;

	if (!request_region(ioaddr, MAC_IOSIZE, "Au1x00 ENET"))
		return NULL;

	if (version_printed++ == 0) 
		printk(version);

	dev = alloc_etherdev(sizeof(struct au1000_private));
	if (!dev) {
		printk (KERN_ERR "au1000 eth: alloc_etherdev failed\n");  
		return NULL;
	}

	if ((err = register_netdev(dev))) {
		printk(KERN_ERR "Au1x_eth Cannot register net device err %d\n",
				err);
		kfree(dev);
		return NULL;
	}

	printk("%s: Au1x Ethernet found at 0x%x, irq %d\n", 
			dev->name, ioaddr, irq);

	aup = dev->priv;

	/* Allocate the data buffers */
	aup->vaddr = (u32)dma_alloc(MAX_BUF_SIZE * 
			(NUM_TX_BUFFS+NUM_RX_BUFFS), &aup->dma_addr);
	if (!aup->vaddr) {
		kfree(dev);
		release_region(ioaddr, MAC_IOSIZE);
		return NULL;
	}

	/* aup->mac is the base address of the MAC's registers */
	aup->mac = (volatile mac_reg_t *)((unsigned long)ioaddr);
	/* Setup some variables for quick register address access */
	if (ioaddr == iflist[0].base_addr)
	{
		/* check env variables first */
		if (!get_ethernet_addr(ethaddr)) { 
			memcpy(au1000_mac_addr, ethaddr, sizeof(dev->dev_addr));
		} else {
			/* Check command line */
			argptr = prom_getcmdline();
			if ((pmac = strstr(argptr, "ethaddr=")) == NULL) {
				printk(KERN_INFO "%s: No mac address found\n", 
						dev->name);
				/* use the hard coded mac addresses */
			} else {
				str2eaddr(ethaddr, pmac + strlen("ethaddr="));
				memcpy(au1000_mac_addr, ethaddr, 
						sizeof(dev->dev_addr));
			}
		}
			aup->enable = (volatile u32 *) 
				((unsigned long)iflist[0].macen_addr);
		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
		setup_hw_rings(aup, MAC0_RX_DMA_ADDR, MAC0_TX_DMA_ADDR);
		aup->mac_id = 0;
		au_macs[0] = aup;
	}
		else
	if (ioaddr == iflist[1].base_addr)
	{
			aup->enable = (volatile u32 *) 
				((unsigned long)iflist[1].macen_addr);
		memcpy(dev->dev_addr, au1000_mac_addr, sizeof(dev->dev_addr));
		dev->dev_addr[4] += 0x10;
		setup_hw_rings(aup, MAC1_RX_DMA_ADDR, MAC1_TX_DMA_ADDR);
		aup->mac_id = 1;
		au_macs[1] = aup;
	}
	else
	{
		printk(KERN_ERR "%s: bad ioaddr\n", dev->name);
	}

	/* bring the device out of reset, otherwise probing the mii
	 * will hang */
	*aup->enable = MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);
	*aup->enable = MAC_EN_RESET0 | MAC_EN_RESET1 | 
		MAC_EN_RESET2 | MAC_EN_CLOCK_ENABLE;
	au_sync_delay(2);

	aup->mii = kmalloc(sizeof(struct mii_phy), GFP_KERNEL);
	if (!aup->mii) {
		printk(KERN_ERR "%s: out of memory\n", dev->name);
		goto err_out;
	}
	aup->mii->mii_control_reg = 0;
	aup->mii->mii_data_reg = 0;

	if (mii_probe(dev) != 0) {
		goto err_out;
	}

	pDBfree = NULL;
	/* setup the data buffer descriptors and attach a buffer to each one */
	pDB = aup->db;
	for (i = 0; i < (NUM_TX_BUFFS+NUM_RX_BUFFS); i++) {
		pDB->pnext = pDBfree;
		pDBfree = pDB;
		pDB->vaddr = (u32 *)((unsigned)aup->vaddr + MAX_BUF_SIZE*i);
		pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
		pDB++;
	}
	aup->pDBfree = pDBfree;

	for (i = 0; i < NUM_RX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) {
			goto err_out;
		}
		aup->rx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->rx_db_inuse[i] = pDB;
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		pDB = GetFreeDB(aup);
		if (!pDB) {
			goto err_out;
		}
		aup->tx_dma_ring[i]->buff_stat = (unsigned)pDB->dma_addr;
		aup->tx_dma_ring[i]->len = 0;
		aup->tx_db_inuse[i] = pDB;
	}

	spin_lock_init(&aup->lock);
	dev->base_addr = ioaddr;
	dev->irq = irq;
	dev->open = au1000_open;
	dev->hard_start_xmit = au1000_tx;
	dev->stop = au1000_close;
	dev->get_stats = au1000_get_stats;
	dev->set_multicast_list = &set_rx_mode;
	dev->do_ioctl = &au1000_ioctl;
	dev->set_config = &au1000_set_config;
	dev->tx_timeout = au1000_tx_timeout;
	dev->watchdog_timeo = ETH_TX_TIMEOUT;

	/* 
	 * The boot code uses the ethernet controller, so reset it to start 
	 * fresh.  au1000_init() expects that the device is in reset state.
	 */
	reset_mac(dev);

	return dev;

err_out:
	/* here we should have a valid dev plus aup-> register addresses
	 * so we can reset the mac properly.*/
	reset_mac(dev);
	if (aup->mii)
		kfree(aup->mii);
	for (i = 0; i < NUM_RX_DMA; i++) {
		if (aup->rx_db_inuse[i])
			ReleaseDB(aup, aup->rx_db_inuse[i]);
	}
	for (i = 0; i < NUM_TX_DMA; i++) {
		if (aup->tx_db_inuse[i])
			ReleaseDB(aup, aup->tx_db_inuse[i]);
	}
	dma_free((void *)aup->vaddr, MAX_BUF_SIZE * 
			(NUM_TX_BUFFS+NUM_RX_BUFFS));
	unregister_netdev(dev);
	kfree(dev);
	release_region(ioaddr, MAC_IOSIZE);
	return NULL;
}