예제 #1
0
파일: irq.c 프로젝트: ForayJones/iods
static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req)
{
	unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;

	if (irq_nr > AU1000_MAX_INTR)
		return;

	/* Config2[n], Config1[n], Config0[n] */
	if (bit >= 32) {
		switch (type) {
		case INTC_INT_RISE_EDGE: /* 0:0:1 */
			au_writel(1 << (bit - 32), IC1_CFG2CLR);
			au_writel(1 << (bit - 32), IC1_CFG1CLR);
			au_writel(1 << (bit - 32), IC1_CFG0SET);
			set_irq_chip(irq_nr, &rise_edge_irq_type);
			break;
		case INTC_INT_FALL_EDGE: /* 0:1:0 */
			au_writel(1 << (bit - 32), IC1_CFG2CLR);
			au_writel(1 << (bit - 32), IC1_CFG1SET);
			au_writel(1 << (bit - 32), IC1_CFG0CLR);
			set_irq_chip(irq_nr, &fall_edge_irq_type);
			break;
		case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
			au_writel(1 << (bit - 32), IC1_CFG2CLR);
			au_writel(1 << (bit - 32), IC1_CFG1SET);
			au_writel(1 << (bit - 32), IC1_CFG0SET);
			set_irq_chip(irq_nr, &either_edge_irq_type);
			break;
		case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
			au_writel(1 << (bit - 32), IC1_CFG2SET);
			au_writel(1 << (bit - 32), IC1_CFG1CLR);
			au_writel(1 << (bit - 32), IC1_CFG0SET);
			set_irq_chip(irq_nr, &level_irq_type);
			break;
		case INTC_INT_LOW_LEVEL: /* 1:1:0 */
			au_writel(1 << (bit - 32), IC1_CFG2SET);
			au_writel(1 << (bit - 32), IC1_CFG1SET);
			au_writel(1 << (bit - 32), IC1_CFG0CLR);
			set_irq_chip(irq_nr, &level_irq_type);
			break;
		case INTC_INT_DISABLED: /* 0:0:0 */
			au_writel(1 << (bit - 32), IC1_CFG0CLR);
			au_writel(1 << (bit - 32), IC1_CFG1CLR);
			au_writel(1 << (bit - 32), IC1_CFG2CLR);
			break;
		default: /* disable the interrupt */
			printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
			       type, irq_nr);
			au_writel(1 << (bit - 32), IC1_CFG0CLR);
			au_writel(1 << (bit - 32), IC1_CFG1CLR);
			au_writel(1 << (bit - 32), IC1_CFG2CLR);
			return;
		}
		if (int_req) /* assign to interrupt request 1 */
			au_writel(1 << (bit - 32), IC1_ASSIGNCLR);
		else	     /* assign to interrupt request 0 */
			au_writel(1 << (bit - 32), IC1_ASSIGNSET);
		au_writel(1 << (bit - 32), IC1_SRCSET);
		au_writel(1 << (bit - 32), IC1_MASKCLR);
		au_writel(1 << (bit - 32), IC1_WAKECLR);
	} else {
		switch (type) {
		case INTC_INT_RISE_EDGE: /* 0:0:1 */
			au_writel(1 << bit, IC0_CFG2CLR);
			au_writel(1 << bit, IC0_CFG1CLR);
			au_writel(1 << bit, IC0_CFG0SET);
			set_irq_chip(irq_nr, &rise_edge_irq_type);
			break;
		case INTC_INT_FALL_EDGE: /* 0:1:0 */
			au_writel(1 << bit, IC0_CFG2CLR);
			au_writel(1 << bit, IC0_CFG1SET);
			au_writel(1 << bit, IC0_CFG0CLR);
			set_irq_chip(irq_nr, &fall_edge_irq_type);
			break;
		case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
			au_writel(1 << bit, IC0_CFG2CLR);
			au_writel(1 << bit, IC0_CFG1SET);
			au_writel(1 << bit, IC0_CFG0SET);
			set_irq_chip(irq_nr, &either_edge_irq_type);
			break;
		case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
			au_writel(1 << bit, IC0_CFG2SET);
			au_writel(1 << bit, IC0_CFG1CLR);
			au_writel(1 << bit, IC0_CFG0SET);
			set_irq_chip(irq_nr, &level_irq_type);
			break;
		case INTC_INT_LOW_LEVEL: /* 1:1:0 */
			au_writel(1 << bit, IC0_CFG2SET);
			au_writel(1 << bit, IC0_CFG1SET);
			au_writel(1 << bit, IC0_CFG0CLR);
			set_irq_chip(irq_nr, &level_irq_type);
			break;
		case INTC_INT_DISABLED: /* 0:0:0 */
			au_writel(1 << bit, IC0_CFG0CLR);
			au_writel(1 << bit, IC0_CFG1CLR);
			au_writel(1 << bit, IC0_CFG2CLR);
			break;
		default: /* disable the interrupt */
			printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
			       type, irq_nr);
			au_writel(1 << bit, IC0_CFG0CLR);
			au_writel(1 << bit, IC0_CFG1CLR);
			au_writel(1 << bit, IC0_CFG2CLR);
			return;
		}
		if (int_req) /* assign to interrupt request 1 */
			au_writel(1 << bit, IC0_ASSIGNCLR);
		else	     /* assign to interrupt request 0 */
			au_writel(1 << bit, IC0_ASSIGNSET);
		au_writel(1 << bit, IC0_SRCSET);
		au_writel(1 << bit, IC0_MASKCLR);
		au_writel(1 << bit, IC0_WAKECLR);
	}
	au_sync();
}
예제 #2
0
void __init board_setup(void)
{
	volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;

	bcsr_init(DB1000_BCSR_PHYS_ADDR,
		  DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);

	/* Set AUX clock to 12 MHz * 8 = 96 MHz */
	au_writel(8, SYS_AUXPLL);
	alchemy_gpio1_input_enable();
	udelay(100);

#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
	{
		u32 pin_func, sys_freqctrl, sys_clksrc;

		/* Configure pins GPIO[14:9] as GPIO */
		pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;

		/* Zero and disable FREQ2 */
		sys_freqctrl = au_readl(SYS_FREQCTRL0);
		sys_freqctrl &= ~0xFFF00000;
		au_writel(sys_freqctrl, SYS_FREQCTRL0);

		/* Zero and disable USBH/USBD/IrDA clock */
		sys_clksrc = au_readl(SYS_CLKSRC);
		sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);
		au_writel(sys_clksrc, SYS_CLKSRC);

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

		sys_clksrc = au_readl(SYS_CLKSRC);
		sys_clksrc &= ~(SYS_CS_CIR | SYS_CS_DIR | SYS_CS_MIR_MASK);

		/* FREQ2 = aux / 2 = 48 MHz */
		sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) |
				SYS_FC_FE2 | SYS_FC_FS2;
		au_writel(sys_freqctrl, SYS_FREQCTRL0);

		/*
		 * Route 48 MHz FREQ2 into USBH/USBD/IrDA
		 */
		sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MIR_BIT;
		au_writel(sys_clksrc, SYS_CLKSRC);

		/* 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 */

		/*
		 * Get USB Functionality pin state (device vs host drive pins).
		 */
		pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
		/* 2nd USB port is USB host. */
		pin_func |= SYS_PF_USB;
		au_writel(pin_func, SYS_PINFUNC);
	}
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */

	/* Enable sys bus clock divider when IDLE state or no bus activity. */
	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);

	/* Enable the RTC if not already enabled. */
	if (!(readb(base + 0x28) & 0x20)) {
		writeb(readb(base + 0x28) | 0x20, base + 0x28);
		au_sync();
	}
	/* Put the clock in BCD mode. */
	if (readb(base + 0x2C) & 0x4) { /* reg B */
		writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
		au_sync();
	}
}
예제 #3
0
파일: dbdma.c 프로젝트: 1x23/unifi-gpl
/* Allocate a channel and return a non-zero descriptor if successful.
*/
u32
au1xxx_dbdma_chan_alloc(u32 srcid, u32 destid,
       void (*callback)(int, void *, struct pt_regs *), void *callparam)
{
	unsigned long   flags;
	u32		used, chan, rv;
	u32		dcp;
	int		i;
	dbdev_tab_t	*stp, *dtp;
	chan_tab_t	*ctp;
	au1x_dma_chan_t *cp;

	/* We do the intialization on the first channel allocation.
	 * We have to wait because of the interrupt handler initialization
	 * which can't be done successfully during board set up.
	 */
	if (!dbdma_initialized)
		au1xxx_dbdma_init();
	dbdma_initialized = 1;

	if ((stp = find_dbdev_id(srcid)) == NULL) return 0;
	if ((dtp = find_dbdev_id(destid)) == NULL) return 0;

	used = 0;
	rv = 0;

	/* Check to see if we can get both channels.
	*/
	spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
	if (!(stp->dev_flags & DEV_FLAGS_INUSE) ||
	     (stp->dev_flags & DEV_FLAGS_ANYUSE)) {
	     	/* Got source */
		stp->dev_flags |= DEV_FLAGS_INUSE;
		if (!(dtp->dev_flags & DEV_FLAGS_INUSE) ||
		     (dtp->dev_flags & DEV_FLAGS_ANYUSE)) {
			/* Got destination */
			dtp->dev_flags |= DEV_FLAGS_INUSE;
		}
		else {
			/* Can't get dest.  Release src.
			*/
			stp->dev_flags &= ~DEV_FLAGS_INUSE;
			used++;
		}
	}
	else {
		used++;
	}
	spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);

	if (!used) {
		/* Let's see if we can allocate a channel for it.
		*/
		ctp = NULL;
		chan = 0;
		spin_lock_irqsave(&au1xxx_dbdma_spin_lock, flags);
		for (i=0; i<NUM_DBDMA_CHANS; i++) {
			if (chan_tab_ptr[i] == NULL) {
				/* If kmalloc fails, it is caught below same
				 * as a channel not available.
				 */
				ctp = kmalloc(sizeof(chan_tab_t), GFP_KERNEL);
				chan_tab_ptr[i] = ctp;
				break;
			}
		}
		spin_unlock_irqrestore(&au1xxx_dbdma_spin_lock, flags);

		if (ctp != NULL) {
			memset(ctp, 0, sizeof(chan_tab_t));
			ctp->chan_index = chan = i;
			dcp = DDMA_CHANNEL_BASE;
			dcp += (0x0100 * chan);
			ctp->chan_ptr = (au1x_dma_chan_t *)dcp;
			cp = (au1x_dma_chan_t *)dcp;
			ctp->chan_src = stp;
			ctp->chan_dest = dtp;
			ctp->chan_callback = callback;
			ctp->chan_callparam = callparam;

			/* Initialize channel configuration.
			*/
			i = 0;
			if (stp->dev_intlevel)
				i |= DDMA_CFG_SED;
			if (stp->dev_intpolarity)
				i |= DDMA_CFG_SP;
			if (dtp->dev_intlevel)
				i |= DDMA_CFG_DED;
			if (dtp->dev_intpolarity)
				i |= DDMA_CFG_DP;
			if ((stp->dev_flags & DEV_FLAGS_SYNC) ||
				(dtp->dev_flags & DEV_FLAGS_SYNC))
					i |= DDMA_CFG_SYNC;
			cp->ddma_cfg = i;
			au_sync();

			/* Return a non-zero value that can be used to
			 * find the channel information in subsequent
			 * operations.
			 */
			rv = (u32)(&chan_tab_ptr[chan]);
		}
		else {
			/* Release devices */
			stp->dev_flags &= ~DEV_FLAGS_INUSE;
			dtp->dev_flags &= ~DEV_FLAGS_INUSE;
		}
	}
	return rv;
}
예제 #4
0
static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,
				struct mmc_command *cmd, struct mmc_data *data)
{
	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);

	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		break;
	case MMC_RSP_R1:
		mmccmd |= SD_CMD_RT_1;
		break;
	case MMC_RSP_R1B:
		mmccmd |= SD_CMD_RT_1B;
		break;
	case MMC_RSP_R2:
		mmccmd |= SD_CMD_RT_2;
		break;
	case MMC_RSP_R3:
		mmccmd |= SD_CMD_RT_3;
		break;
	default:
		printk(KERN_INFO "au1xmmc: unhandled response type %02x\n",
			mmc_resp_type(cmd));
		return -EINVAL;
	}

	if (data) {
		if (data->flags & MMC_DATA_READ) {
			if (data->blocks > 1)
				mmccmd |= SD_CMD_CT_4;
			else
				mmccmd |= SD_CMD_CT_2;
		} else if (data->flags & MMC_DATA_WRITE) {
			if (data->blocks > 1)
				mmccmd |= SD_CMD_CT_3;
			else
				mmccmd |= SD_CMD_CT_1;
		}
	}

	au_writel(cmd->arg, HOST_CMDARG(host));
	au_sync();

	if (wait)
		IRQ_OFF(host, SD_CONFIG_CR);

	au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
	au_sync();

	
	while (au_readl(HOST_CMD(host)) & SD_CMD_GO)
		;

	
	if (wait) {
		u32 status = au_readl(HOST_STATUS(host));

		while (!(status & SD_STATUS_CR))
			status = au_readl(HOST_STATUS(host));

		
		au_writel(SD_STATUS_CR, HOST_STATUS(host));

		IRQ_ON(host, SD_CONFIG_CR);
	}

	return 0;
}
예제 #5
0
파일: irq.c 프로젝트: 10x-Amin/nAa-kernel
/*
 * For most restore operations, we clear the entire register and
 * then set the bits we found during the save.
 */
void restore_au1xxx_intctl(void)
{
	au_writel(0xffffffff, IC0_MASKCLR); au_sync();

	au_writel(0xffffffff, IC0_CFG0CLR); au_sync();
	au_writel(sleep_intctl_config0[0], IC0_CFG0SET); au_sync();
	au_writel(0xffffffff, IC0_CFG1CLR); au_sync();
	au_writel(sleep_intctl_config1[0], IC0_CFG1SET); au_sync();
	au_writel(0xffffffff, IC0_CFG2CLR); au_sync();
	au_writel(sleep_intctl_config2[0], IC0_CFG2SET); au_sync();
	au_writel(0xffffffff, IC0_SRCCLR); au_sync();
	au_writel(sleep_intctl_src[0], IC0_SRCSET); au_sync();
	au_writel(0xffffffff, IC0_ASSIGNCLR); au_sync();
	au_writel(sleep_intctl_assign[0], IC0_ASSIGNSET); au_sync();
	au_writel(0xffffffff, IC0_WAKECLR); au_sync();
	au_writel(sleep_intctl_wake[0], IC0_WAKESET); au_sync();
	au_writel(0xffffffff, IC0_RISINGCLR); au_sync();
	au_writel(0xffffffff, IC0_FALLINGCLR); au_sync();
	au_writel(0x00000000, IC0_TESTBIT); au_sync();

	au_writel(0xffffffff, IC1_MASKCLR); au_sync();

	au_writel(0xffffffff, IC1_CFG0CLR); au_sync();
	au_writel(sleep_intctl_config0[1], IC1_CFG0SET); au_sync();
	au_writel(0xffffffff, IC1_CFG1CLR); au_sync();
	au_writel(sleep_intctl_config1[1], IC1_CFG1SET); au_sync();
	au_writel(0xffffffff, IC1_CFG2CLR); au_sync();
	au_writel(sleep_intctl_config2[1], IC1_CFG2SET); au_sync();
	au_writel(0xffffffff, IC1_SRCCLR); au_sync();
	au_writel(sleep_intctl_src[1], IC1_SRCSET); au_sync();
	au_writel(0xffffffff, IC1_ASSIGNCLR); au_sync();
	au_writel(sleep_intctl_assign[1], IC1_ASSIGNSET); au_sync();
	au_writel(0xffffffff, IC1_WAKECLR); au_sync();
	au_writel(sleep_intctl_wake[1], IC1_WAKESET); au_sync();
	au_writel(0xffffffff, IC1_RISINGCLR); au_sync();
	au_writel(0xffffffff, IC1_FALLINGCLR); au_sync();
	au_writel(0x00000000, IC1_TESTBIT); au_sync();

	au_writel(sleep_intctl_mask[1], IC1_MASKSET); au_sync();

	au_writel(sleep_intctl_mask[0], IC0_MASKSET); au_sync();
}
예제 #6
0
static void
save_core_regs(void)
{
    extern void save_au1xxx_intctl(void);
    extern void pm_eth0_shutdown(void);

    /* Do the serial ports.....these really should be a pm_*
     * registered function by the driver......but of course the
     * standard serial driver doesn't understand our Au1xxx
     * unique registers.
     */
    sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER);
    sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR);
    sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
    sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
    sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);

    /* Shutdown USB host/device.
    */
    sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);

    /* There appears to be some undocumented reset register....
    */
    au_writel(0, 0xb0100004);
    au_sync();
    au_writel(0, USB_HOST_CONFIG);
    au_sync();

    sleep_usbdev_enable = au_readl(USBD_ENABLE);
    au_writel(0, USBD_ENABLE);
    au_sync();

    /* Save interrupt controller state.
    */
    save_au1xxx_intctl();

    /* Clocks and PLLs.
    */
    sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);

    /* We don't really need to do this one, but unless we
     * write it again it won't have a valid value if we
     * happen to read it.
     */
    sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL);

    sleep_pin_function = au_readl(SYS_PINFUNC);

    /* Save the static memory controller configuration.
    */
    sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
    sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
    sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
    sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1);
    sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1);
    sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1);
    sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2);
    sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2);
    sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2);
    sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
    sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
    sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
}
예제 #7
0
void __init board_setup(void)
{
	u32 pin_func = 0;
	char *argptr;

	argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
	argptr = strstr(argptr, "console=");
	if (argptr == NULL) {
		argptr = prom_getcmdline();
		strcat(argptr, " console=ttyS0,115200");
	}
#endif

#ifdef CONFIG_FB_AU1100
	argptr = strstr(argptr, "video=");
	if (argptr == NULL) {
		argptr = prom_getcmdline();
		/* default panel */
		/*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
	}
#endif

#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
	/* au1000 does not support vra, au1500 and au1100 do */
	strcat(argptr, " au1000_audio=vra");
	argptr = prom_getcmdline();
#endif

	/* Not valid for Au1550 */
#if defined(CONFIG_IRDA) && \
   (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
	/* Set IRFIRSEL instead of GPIO15 */
	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_IRF;
	au_writel(pin_func, SYS_PINFUNC);
	/* Power off until the driver is in use */
	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
	bcsr->resets |=  BCSR_RESETS_IRDA_MODE_OFF;
	au_sync();
#endif
	bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */

#ifdef CONFIG_MIPS_MIRAGE
	/* Enable GPIO[31:0] inputs */
	au_writel(0, SYS_PININPUTEN);

	/* GPIO[20] is output, tristate the other input primary GPIOs */
	au_writel(~(1 << 20), SYS_TRIOUTCLR);

	/* Set GPIO[210:208] instead of SSI_0 */
	pin_func = au_readl(SYS_PINFUNC) | SYS_PF_S0;

	/* Set GPIO[215:211] for LEDs */
	pin_func |= 5 << 2;

	/* Set GPIO[214:213] for more LEDs */
	pin_func |= 5 << 12;

	/* Set GPIO[207:200] instead of PCMCIA/LCD */
	pin_func |= SYS_PF_LCD | SYS_PF_PC;
	au_writel(pin_func, SYS_PINFUNC);

	/*
	 * Enable speaker amplifier.  This should
	 * be part of the audio driver.
	 */
	au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
	au_writel(0x02000200, GPIO2_OUTPUT);
#endif

	au_sync();

#ifdef CONFIG_MIPS_DB1000
	printk(KERN_INFO "AMD Alchemy Au1000/Db1000 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1500
	printk(KERN_INFO "AMD Alchemy Au1500/Db1500 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1100
	printk(KERN_INFO "AMD Alchemy Au1100/Db1100 Board\n");
#endif
#ifdef CONFIG_MIPS_BOSPORUS
	printk(KERN_INFO "AMD Alchemy Bosporus Board\n");
#endif
#ifdef CONFIG_MIPS_MIRAGE
	printk(KERN_INFO "AMD Alchemy Mirage Board\n");
#endif
#ifdef CONFIG_MIPS_DB1550
	printk(KERN_INFO "AMD Alchemy Au1550/Db1550 Board\n");
#endif
}
예제 #8
0
파일: mirage_ts.c 프로젝트: 1x23/unifi-gpl
static int ts_thread(void *id)
{
	static int pen_was_down = 0;
	static DOWN_EVENT pen_xy;
	long x, y, z;
	void *ts;	/* handle */
	struct task_struct *tsk = current;
	int timeout = HZ / SAMPLE_RATE;

	ts_task = tsk;

	daemonize();
	tsk->tty = NULL;
	tsk->policy = SCHED_FIFO;
	tsk->rt_priority = 1;
	strcpy(tsk->comm, "touchscreen");

	/* only want to receive SIGKILL */
	spin_lock_irq(&tsk->sigmask_lock);
	siginitsetinv(&tsk->blocked, sigmask(SIGKILL));
	recalc_sigpending(tsk);
	spin_unlock_irq(&tsk->sigmask_lock);

	/* get handle for codec */
	ts = wm97xx_ts_get_handle(0);

	/* proceed only after everybody is ready */
	wait_event_timeout(pendown_wait, wm97xx_ts_ready(ts), HZ/4);

	/* board-specific calibration */
	wm97xx_ts_set_cal(ts,
			mirage_ts_cal.xscale,
			mirage_ts_cal.xtrans,
			mirage_ts_cal.yscale,
			mirage_ts_cal.ytrans);

	/* route Wolfson pendown interrupts to our GPIO */
	au_sync();
	wm97xx_ts_set_ac97(ts, 0x4c, wm97xx_ts_get_ac97(ts, 0x4c) & ~0x0008);
	au_sync();
	wm97xx_ts_set_ac97(ts, 0x56, wm97xx_ts_get_ac97(ts, 0x56) & ~0x0008);
	au_sync();
	wm97xx_ts_set_ac97(ts, 0x52, wm97xx_ts_get_ac97(ts, 0x52) | 0x2008);
	au_sync();

	for (;;) {
		interruptible_sleep_on_timeout(&pendown_wait, timeout);
		disable_irq(PEN_DOWN_IRQ);
		if (signal_pending(tsk)) {
			break;
		}

		/* read codec */
		if (!wm97xx_ts_read_data(ts, &x, &y, &z))
			z = 0;	/* treat no-data and pen-up the same */

		if (signal_pending(tsk)) {
			break;
		}

		if (z >= release_pressure) {
			y = ~y;	/* top to bottom */
			if (pen_was_down > 1 /*&& pen_was_down < PEN_DEBOUNCE*/) {//THXXX
				/* bounce ? */
				x = pen_xy.x;
				y = pen_xy.y;
				--pen_was_down;
			} else if (pen_was_down <= 1) {
				pen_xy.x = x;
				pen_xy.y = y;
				if (pen_was_down)
					wm97xx_ts_send_data(ts, x, y, z);
				pen_was_down = PEN_DEBOUNCE;
			}
			//wm97xx_ts_send_data(ts, x, y, z);
			timeout = HZ / SAMPLE_RATE;
		} else {
			if (pen_was_down) {
				if (--pen_was_down)
					z = release_pressure;
				else //THXXX
				wm97xx_ts_send_data(ts, pen_xy.x, pen_xy.y, z);
			}
			/* The pendown signal takes some time to settle after
			 * reading the pen pressure so wait a little
			 * before enabling the pen.
			 */
			if (! pen_was_down) {
//				interruptible_sleep_on_timeout(&pendown_wait, HZ / PEN_UP_SETTLE);
				timeout = HZ * PEN_UP_TIMEOUT;
			}
		}
		enable_irq(PEN_DOWN_IRQ);
	}
	enable_irq(PEN_DOWN_IRQ);
	ts_task = NULL;
	complete(&ts_complete);
	return 0;
}
예제 #9
0
static void restore_core_regs(void)
{
	/* restore clock configuration.  Writing CPUPLL last will
	 * stall a bit and stabilize other clocks (unless this is
	 * one of those Au1000 with a write-only PLL, where we dont
	 * have a valid value)
	 */
	au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0);
	au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1);
	au_writel(sleep_sys_clocks[2], SYS_CLKSRC);
	au_writel(sleep_sys_clocks[4], SYS_AUXPLL);
	if (!au1xxx_cpu_has_pll_wo())
		au_writel(sleep_sys_clocks[3], SYS_CPUPLL);
	au_sync();

	au_writel(sleep_sys_pinfunc, SYS_PINFUNC);
	au_sync();

#ifndef CONFIG_SOC_AU1200
	au_writel(sleep_usb[0], USB_HOST_CONFIG);
	au_writel(sleep_usb[1], USBD_ENABLE);
	au_sync();
#else
	/* enable accces to OTG memory */
	au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
	au_sync();

	/* restore OTG caps and port mux. */
	au_writel(sleep_usb[0], 0xb4020020 + 0);	/* OTG_CAP */
	au_sync();
	au_writel(sleep_usb[1], 0xb4020020 + 4);	/* OTG_MUX */
	au_sync();
#endif

	/* Restore the static memory controller configuration. */
	au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
	au_writel(sleep_static_memctlr[0][1], MEM_STTIME0);
	au_writel(sleep_static_memctlr[0][2], MEM_STADDR0);
	au_writel(sleep_static_memctlr[1][0], MEM_STCFG1);
	au_writel(sleep_static_memctlr[1][1], MEM_STTIME1);
	au_writel(sleep_static_memctlr[1][2], MEM_STADDR1);
	au_writel(sleep_static_memctlr[2][0], MEM_STCFG2);
	au_writel(sleep_static_memctlr[2][1], MEM_STTIME2);
	au_writel(sleep_static_memctlr[2][2], MEM_STADDR2);
	au_writel(sleep_static_memctlr[3][0], MEM_STCFG3);
	au_writel(sleep_static_memctlr[3][1], MEM_STTIME3);
	au_writel(sleep_static_memctlr[3][2], MEM_STADDR3);

	/*
	 * Enable the UART if it was enabled before sleep.
	 * I guess I should define module control bits........
	 */
	if (sleep_uart0_enable & 0x02) {
		au_writel(0, UART0_ADDR + UART_MOD_CNTRL); au_sync();
		au_writel(1, UART0_ADDR + UART_MOD_CNTRL); au_sync();
		au_writel(3, UART0_ADDR + UART_MOD_CNTRL); au_sync();
		au_writel(sleep_uart0_inten, UART0_ADDR + UART_IER); au_sync();
		au_writel(sleep_uart0_fifoctl, UART0_ADDR + UART_FCR); au_sync();
		au_writel(sleep_uart0_linectl, UART0_ADDR + UART_LCR); au_sync();
		au_writel(sleep_uart0_clkdiv, UART0_ADDR + UART_CLK); au_sync();
	}

	restore_au1xxx_intctl();

#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
	au1xxx_dbdma_resume();
#endif
}
예제 #10
0
파일: setup.c 프로젝트: nhanh0/hah
void __init au1500_setup(void)
{
	char *argptr;
	u32 pin_func, static_cfg0;
	u32 sys_freqctrl, sys_clksrc;
	
	argptr = prom_getcmdline();

	/* NOTE: The memory map is established by YAMON 2.08+ */

	/* Various early Au1500 Errata corrected by this */
	set_cp0_config(1<<19); /* Config[OD] */

#ifdef CONFIG_AU1000_SERIAL_CONSOLE
	if ((argptr = strstr(argptr, "console=")) == NULL) {
		argptr = prom_getcmdline();
		strcat(argptr, " console=ttyS0,115200");
	}
#endif	  

#ifdef CONFIG_SOUND_AU1000
	strcat(argptr, " au1000_audio=vra");
	argptr = prom_getcmdline();
#endif

        __wbflush = au1500_wbflush;
	_machine_restart = au1000_restart;
	_machine_halt = au1000_halt;
	_machine_power_off = au1000_power_off;

	// IO/MEM resources. 
	set_io_port_base(0);
	ioport_resource.start = 0x10000000;
	ioport_resource.end = 0xffffffff;
	iomem_resource.start = 0x10000000;
	iomem_resource.end = 0xffffffff;

#ifdef CONFIG_BLK_DEV_INITRD
	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
	initrd_start = (unsigned long)&__rd_start;
	initrd_end = (unsigned long)&__rd_end;
#endif

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

#if defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)
#ifdef CONFIG_USB_OHCI
	if ((argptr = strstr(argptr, "usb_ohci=")) == NULL) {
	        char usb_args[80];
		argptr = prom_getcmdline();
		memset(usb_args, 0, sizeof(usb_args));
		sprintf(usb_args, " usb_ohci=base:0x%x,len:0x%x,irq:%d",
			USB_OHCI_BASE, USB_OHCI_LEN, AU1000_USB_HOST_INT);
		strcat(argptr, usb_args);
	}
#endif

	/* zero and disable FREQ2 */
	sys_freqctrl = readl(SYS_FREQCTRL0);
	sys_freqctrl &= ~0xFFF00000;
	writel(sys_freqctrl, SYS_FREQCTRL0);

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

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

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

	// FREQ2 = aux/2 = 48 MHz
	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
	writel(sys_freqctrl, SYS_FREQCTRL0);

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


	pin_func = readl(SYS_PINFUNC) & (u32)(~0x8000);
#ifndef CONFIG_AU1000_USB_DEVICE
	// 2nd USB port is USB host
	pin_func |= 0x8000;
#endif
	writel(pin_func, SYS_PINFUNC);
#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1000_USB_DEVICE)


#ifdef CONFIG_USB_OHCI
	// enable host controller and wait for reset done
	writel(0x08, USB_HOST_CONFIG);
	udelay(1000);
	writel(0x0c, USB_HOST_CONFIG);
	udelay(1000);
	readl(USB_HOST_CONFIG);
	while (!(readl(USB_HOST_CONFIG) & 0x10))
	    ;
	readl(USB_HOST_CONFIG);
#endif
	
#ifdef CONFIG_FB
	conswitchp = &dummy_con;
#endif

#ifdef CONFIG_FB_E1356
	if ((argptr = strstr(argptr, "video=")) == NULL) {
		argptr = prom_getcmdline();
		strcat(argptr, " video=e1356fb:system:pb1500,mmunalign:1");
	}
#endif // CONFIG_FB_E1356

#ifndef CONFIG_SERIAL_NONSTANDARD
	/* don't touch the default serial console */
	writel(0, UART0_ADDR + UART_CLK);
#endif
	writel(0, UART3_ADDR + UART_CLK);

#ifdef CONFIG_BLK_DEV_IDE
	ide_ops = &std_ide_ops;
#endif

#ifdef CONFIG_PCI
	// Setup PCI bus controller
	writel(0, Au1500_PCI_CMEM);
	writel(0x00003fff, Au1500_CFG_BASE);
	writel(0xf, Au1500_PCI_CFG);
	writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
	writel(0, Au1500_PCI_MWBASE_REV_CCL);
	writel(0x02a00356, Au1500_PCI_STATCMD);
	writel(0x00003c04, Au1500_PCI_HDRTYPE);	
	writel(0x00000008, Au1500_PCI_MBAR);
	au_sync();
#endif

	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
	writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
	au_sync();
	while (readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
	outl(0, SYS_TOYTRIM);

	/* Enable BCLK switching */
	writel(0x00000060, 0xb190003c);

#ifdef CONFIG_RTC
	rtc_ops = &pb1500_rtc_ops;
	// Enable the RTC if not already enabled 
	if (!(readb(0xac000028) & 0x20)) {
		writeb(readb(0xac000028) | 0x20, 0xac000028);
	}
	// Put the clock in BCD mode
	if (readb(0xac00002C) & 0x4) { /* reg B */
		writeb(readb(0xac00002c) & ~0x4, 0xac00002c);
		au_sync();
	}
#endif
}
예제 #11
0
static int __devinit au1xpsc_i2s_drvprobe(struct platform_device *pdev)
{
    struct resource *r;
    unsigned long sel;
    int ret;
    struct au1xpsc_audio_data *wd;

    if (au1xpsc_i2s_workdata)
        return -EBUSY;

    wd = kzalloc(sizeof(struct au1xpsc_audio_data), GFP_KERNEL);
    if (!wd)
        return -ENOMEM;

    r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    if (!r) {
        ret = -ENODEV;
        goto out0;
    }

    ret = -EBUSY;
    if (!request_mem_region(r->start, resource_size(r), pdev->name))
        goto out0;

    wd->mmio = ioremap(r->start, resource_size(r));
    if (!wd->mmio)
        goto out1;

    /* preserve PSC clock source set up by platform (dev.platform_data
     * is already occupied by soc layer)
     */
    sel = au_readl(PSC_SEL(wd)) & PSC_SEL_CLK_MASK;
    au_writel(PSC_CTRL_DISABLE, PSC_CTRL(wd));
    au_sync();
    au_writel(PSC_SEL_PS_I2SMODE | sel, PSC_SEL(wd));
    au_writel(0, I2S_CFG(wd));
    au_sync();

    /* preconfigure: set max rx/tx fifo depths */
    wd->cfg |= PSC_I2SCFG_RT_FIFO8 | PSC_I2SCFG_TT_FIFO8;

    /* don't wait for I2S core to become ready now; clocks may not
     * be running yet; depending on clock input for PSC a wait might
     * time out.
     */

    ret = snd_soc_register_dai(&au1xpsc_i2s_dai);
    if (ret)
        goto out1;

    /* finally add the DMA device for this PSC */
    wd->dmapd = au1xpsc_pcm_add(pdev);
    if (wd->dmapd) {
        platform_set_drvdata(pdev, wd);
        au1xpsc_i2s_workdata = wd;
        return 0;
    }

    snd_soc_unregister_dai(&au1xpsc_i2s_dai);
out1:
    release_mem_region(r->start, resource_size(r));
out0:
    kfree(wd);
    return ret;
}
예제 #12
0
파일: time.c 프로젝트: cilynx/dd-wrt
void __init plat_timer_setup(struct irqaction *irq)
{
	unsigned int est_freq;

	printk("calculating r4koff... ");
	r4k_offset = cal_r4koff();
	printk("%08lx(%d)\n", r4k_offset, (int) r4k_offset);

	//est_freq = 2*r4k_offset*HZ;
	est_freq = r4k_offset*HZ;
	est_freq += 5000;    /* round */
	est_freq -= est_freq%10000;
	printk("CPU frequency %d.%02d MHz\n", est_freq/1000000,
	       (est_freq%1000000)*100/1000000);
 	set_au1x00_speed(est_freq);
 	set_au1x00_lcd_clock(); // program the LCD clock

	r4k_cur = (read_c0_count() + r4k_offset);
	write_c0_compare(r4k_cur);

#ifdef CONFIG_PM
	/*
	 * setup counter 0, since it keeps ticking after a
	 * 'wait' instruction has been executed. The CP0 timer and
	 * counter 1 do NOT continue running after 'wait'
	 *
	 * It's too early to call request_irq() here, so we handle
	 * counter 0 interrupt as a special irq and it doesn't show
	 * up under /proc/interrupts.
	 *
	 * Check to ensure we really have a 32KHz oscillator before
	 * we do this.
	 */
	if (no_au1xxx_32khz) {
		unsigned int c0_status;

		printk("WARNING: no 32KHz clock found.\n");

		/* Ensure we get CPO_COUNTER interrupts.
		*/
		c0_status = read_c0_status();
		c0_status |= IE_IRQ5;
		write_c0_status(c0_status);
	}
	else {
		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
		au_writel(0, SYS_TOYWRITE);
		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);

		au_writel(au_readl(SYS_WAKEMSK) | (1<<8), SYS_WAKEMSK);
		au_writel(~0, SYS_WAKESRC);
		au_sync();
		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);

		/* setup match20 to interrupt once every HZ */
		last_pc0 = last_match20 = au_readl(SYS_TOYREAD);
		au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
		au_sync();
		while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
		startup_match20_interrupt(counter0_irq);

		/* We can use the real 'wait' instruction.
		*/
		allow_au1k_wait = 1;
	}

#endif
}
예제 #13
0
void __init board_setup(void)
{
	u32 pin_func;
	u32 sys_freqctrl, sys_clksrc;
	char *argptr;

	argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
	argptr = strstr(argptr, "console=");
	if (argptr == NULL) {
		argptr = prom_getcmdline();
		strcat(argptr, " console=ttyS0,115200");
	}
#endif

#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
	/* au1000 does not support vra, au1500 and au1100 do */
	strcat(argptr, " au1000_audio=vra");
	argptr = prom_getcmdline();
#endif

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

#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)

	/* GPIO201 is input for PCMCIA card detect */
	/* GPIO203 is input for PCMCIA interrupt request */
	au_writel(au_readl(GPIO2_DIR) & ~((1 << 1) | (1 << 3)), GPIO2_DIR);

	/* 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 &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
			SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
	au_writel(sys_clksrc, SYS_CLKSRC);

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

	sys_clksrc = au_readl(SYS_CLKSRC);
	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
			SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);

	/* FREQ2 = aux/2 = 48 MHz */
	sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2 | SYS_FC_FS2;
	au_writel(sys_freqctrl, SYS_FREQCTRL0);

	/*
	 * Route 48MHz FREQ2 into USB Host and/or Device
	 */
	sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
	au_writel(sys_clksrc, SYS_CLKSRC);

	pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
	/* 2nd USB port is USB host */
	pin_func |= SYS_PF_USB;
	au_writel(pin_func, SYS_PINFUNC);
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */

#ifdef CONFIG_PCI
	/* Setup PCI bus controller */
	au_writel(0, Au1500_PCI_CMEM);
	au_writel(0x00003fff, Au1500_CFG_BASE);
#if defined(__MIPSEB__)
	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
#else
	au_writel(0xf, Au1500_PCI_CFG);
#endif
	au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
	au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
	au_writel(0x02a00356, Au1500_PCI_STATCMD);
	au_writel(0x00003c04, Au1500_PCI_HDRTYPE);
	au_writel(0x00000008, Au1500_PCI_MBAR);
	au_sync();
#endif

	/* Enable sys bus clock divider when IDLE state or no bus activity. */
	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);

	/* Enable the RTC if not already enabled */
	if (!(au_readl(0xac000028) & 0x20)) {
		printk(KERN_INFO "enabling clock ...\n");
		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
	}
	/* Put the clock in BCD mode */
	if (au_readl(0xac00002c) & 0x4) { /* reg B */
		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
		au_sync();
	}
}
예제 #14
0
void __init board_setup(void)
{
	u32 pin_func;

	pin_func = 0;
	/* not valid for 1550 */
#ifdef CONFIG_AU1X00_USB_DEVICE
	// 2nd USB port is USB device
	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
	au_writel(pin_func, SYS_PINFUNC);
#endif

#if defined(CONFIG_IRDA) && (defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100))
	/* set IRFIRSEL instead of GPIO15 */
	pin_func = au_readl(SYS_PINFUNC) | (u32)((1<<8));
	au_writel(pin_func, SYS_PINFUNC);
	/* power off until the driver is in use */
	bcsr->resets &= ~BCSR_RESETS_IRDA_MODE_MASK;
	bcsr->resets |= BCSR_RESETS_IRDA_MODE_OFF;
	au_sync();
#endif
	bcsr->pcmcia = 0x0000; /* turn off PCMCIA power */

#ifdef CONFIG_MIPS_MIRAGE
	/* enable GPIO[31:0] inputs */
	au_writel(0, SYS_PININPUTEN);

	/* GPIO[20] is output, tristate the other input primary GPIO's */
	au_writel((u32)(~(1<<20)), SYS_TRIOUTCLR);

	/* set GPIO[210:208] instead of SSI_0 */
	pin_func = au_readl(SYS_PINFUNC) | (u32)(1);

	/* set GPIO[215:211] for LED's */
	pin_func |= (u32)((5<<2));

	/* set GPIO[214:213] for more LED's */
	pin_func |= (u32)((5<<12));

	/* set GPIO[207:200] instead of PCMCIA/LCD */
	pin_func |= (u32)((3<<17));
	au_writel(pin_func, SYS_PINFUNC);

	/* Enable speaker amplifier.  This should
	 * be part of the audio driver.
	 */
	au_writel(au_readl(GPIO2_DIR) | 0x200, GPIO2_DIR);
	au_writel(0x02000200, GPIO2_OUTPUT);
#endif

	au_sync();

#ifdef CONFIG_MIPS_DB1000
    printk("AMD Alchemy Au1000/Db1000 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1500
    printk("AMD Alchemy Au1500/Db1500 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1100
    printk("AMD Alchemy Au1100/Db1100 Board\n");
#endif
#ifdef CONFIG_MIPS_BOSPORUS
    printk("AMD Alchemy Bosporus Board\n");
#endif
#ifdef CONFIG_MIPS_MIRAGE
    printk("AMD Alchemy Mirage Board\n");
#endif
#ifdef CONFIG_MIPS_DB1550
    printk("AMD Alchemy Au1550/Db1550 Board\n");
#endif
}
예제 #15
0
파일: irq.c 프로젝트: nhanh0/hah
static void setup_local_irq(unsigned int irq_nr, int type, int int_req)
{
	if (irq_nr > AU1000_MAX_INTR) return;
	/* Config2[n], Config1[n], Config0[n] */
	if (irq_nr > AU1000_LAST_INTC0_INT) {
		switch (type) {
			case INTC_INT_RISE_EDGE: /* 0:0:1 */
				outl(1<<(irq_nr-32), IC1_CFG2CLR);
				outl(1<<(irq_nr-32), IC1_CFG1CLR);
				outl(1<<(irq_nr-32), IC1_CFG0SET);
				break;
			case INTC_INT_FALL_EDGE: /* 0:1:0 */
				outl(1<<(irq_nr-32), IC1_CFG2CLR);
				outl(1<<(irq_nr-32), IC1_CFG1SET);
				outl(1<<(irq_nr-32), IC1_CFG0CLR);
				break;
			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
				outl(1<<(irq_nr-32), IC1_CFG2SET);
				outl(1<<(irq_nr-32), IC1_CFG1CLR);
				outl(1<<(irq_nr-32), IC1_CFG0SET);
				break;
			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
				outl(1<<(irq_nr-32), IC1_CFG2SET);
				outl(1<<(irq_nr-32), IC1_CFG1SET);
				outl(1<<(irq_nr-32), IC1_CFG0CLR);
				break;
			case INTC_INT_DISABLED: /* 0:0:0 */
				outl(1<<(irq_nr-32), IC1_CFG0CLR);
				outl(1<<(irq_nr-32), IC1_CFG1CLR);
				outl(1<<(irq_nr-32), IC1_CFG2CLR);
				break;
			default: /* disable the interrupt */
				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
				outl(1<<(irq_nr-32), IC1_CFG0CLR);
				outl(1<<(irq_nr-32), IC1_CFG1CLR);
				outl(1<<(irq_nr-32), IC1_CFG2CLR);
				return;
		}
		if (int_req) /* assign to interrupt request 1 */
			outl(1<<(irq_nr-32), IC1_ASSIGNCLR);
		else	     /* assign to interrupt request 0 */
			outl(1<<(irq_nr-32), IC1_ASSIGNSET);
		outl(1<<(irq_nr-32), IC1_SRCSET);
		outl(1<<(irq_nr-32), IC1_MASKCLR);
		outl(1<<(irq_nr-32), IC1_WAKECLR);
	}
	else {
		switch (type) {
			case INTC_INT_RISE_EDGE: /* 0:0:1 */
				outl(1<<irq_nr, IC0_CFG2CLR);
				outl(1<<irq_nr, IC0_CFG1CLR);
				outl(1<<irq_nr, IC0_CFG0SET);
				break;
			case INTC_INT_FALL_EDGE: /* 0:1:0 */
				outl(1<<irq_nr, IC0_CFG2CLR);
				outl(1<<irq_nr, IC0_CFG1SET);
				outl(1<<irq_nr, IC0_CFG0CLR);
				break;
			case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
				outl(1<<irq_nr, IC0_CFG2SET);
				outl(1<<irq_nr, IC0_CFG1CLR);
				outl(1<<irq_nr, IC0_CFG0SET);
				break;
			case INTC_INT_LOW_LEVEL: /* 1:1:0 */
				outl(1<<irq_nr, IC0_CFG2SET);
				outl(1<<irq_nr, IC0_CFG1SET);
				outl(1<<irq_nr, IC0_CFG0CLR);
				break;
			case INTC_INT_DISABLED: /* 0:0:0 */
				outl(1<<irq_nr, IC0_CFG0CLR);
				outl(1<<irq_nr, IC0_CFG1CLR);
				outl(1<<irq_nr, IC0_CFG2CLR);
				break;
			default: /* disable the interrupt */
				printk("unexpected int type %d (irq %d)\n", type, irq_nr);
				outl(1<<irq_nr, IC0_CFG0CLR);
				outl(1<<irq_nr, IC0_CFG1CLR);
				outl(1<<irq_nr, IC0_CFG2CLR);
				return;
		}
		if (int_req) /* assign to interrupt request 1 */
			outl(1<<irq_nr, IC0_ASSIGNCLR);
		else	     /* assign to interrupt request 0 */
			outl(1<<irq_nr, IC0_ASSIGNSET);
		outl(1<<irq_nr, IC0_SRCSET);
		outl(1<<irq_nr, IC0_MASKCLR);
		outl(1<<irq_nr, IC0_WAKECLR);
	}
	au_sync();
}
예제 #16
0
static void save_core_regs(void)
{
	extern void save_au1xxx_intctl(void);
	extern void pm_eth0_shutdown(void);

	/*
	 * Do the serial ports.....these really should be a pm_*
	 * registered function by the driver......but of course the
	 * standard serial driver doesn't understand our Au1xxx
	 * unique registers.
	 */
	sleep_uart0_inten = au_readl(UART0_ADDR + UART_IER);
	sleep_uart0_fifoctl = au_readl(UART0_ADDR + UART_FCR);
	sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
	sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
	sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
	au_sync();

#ifndef CONFIG_SOC_AU1200
	/* Shutdown USB host/device. */
	sleep_usb[0] = au_readl(USB_HOST_CONFIG);

	/* There appears to be some undocumented reset register.... */
	au_writel(0, 0xb0100004);
	au_sync();
	au_writel(0, USB_HOST_CONFIG);
	au_sync();

	sleep_usb[1] = au_readl(USBD_ENABLE);
	au_writel(0, USBD_ENABLE);
	au_sync();

#else	/* AU1200 */

	/* enable access to OTG mmio so we can save OTG CAP/MUX.
	 * FIXME: write an OTG driver and move this stuff there!
	 */
	au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
	au_sync();
	sleep_usb[0] = au_readl(0xb4020020);	/* OTG_CAP */
	sleep_usb[1] = au_readl(0xb4020024);	/* OTG_MUX */
#endif

	/* Save interrupt controller state. */
	save_au1xxx_intctl();

	/* Clocks and PLLs. */
	sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0);
	sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1);
	sleep_sys_clocks[2] = au_readl(SYS_CLKSRC);
	sleep_sys_clocks[3] = au_readl(SYS_CPUPLL);
	sleep_sys_clocks[4] = au_readl(SYS_AUXPLL);

	/* pin mux config */
	sleep_sys_pinfunc = au_readl(SYS_PINFUNC);

	/* Save the static memory controller configuration. */
	sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
	sleep_static_memctlr[0][1] = au_readl(MEM_STTIME0);
	sleep_static_memctlr[0][2] = au_readl(MEM_STADDR0);
	sleep_static_memctlr[1][0] = au_readl(MEM_STCFG1);
	sleep_static_memctlr[1][1] = au_readl(MEM_STTIME1);
	sleep_static_memctlr[1][2] = au_readl(MEM_STADDR1);
	sleep_static_memctlr[2][0] = au_readl(MEM_STCFG2);
	sleep_static_memctlr[2][1] = au_readl(MEM_STTIME2);
	sleep_static_memctlr[2][2] = au_readl(MEM_STADDR2);
	sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
	sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
	sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);

#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
	au1xxx_dbdma_suspend();
#endif
}
예제 #17
0
파일: console-io.c 프로젝트: Fyleo/rtems
void console_initialize_hardware(void)
{
    uart0->fifoctrl = 0xf1;   /* enable fifo, max sizes */
    au_sync();
}
예제 #18
0
void __init board_setup(void)
{
	u32 pin_func, pin_val;
	u32 sys_freqctrl, sys_clksrc;


	// 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)

	/* GPIO201 is input for PCMCIA card detect */
	/* GPIO203 is input for PCMCIA interrupt request */
	au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR);

	/* 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;

	// FREQ2 = aux/2 = 48 MHz
	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
	au_writel(sys_freqctrl, SYS_FREQCTRL0);

	/*
	 * 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);


	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
#ifndef CONFIG_AU1X00_USB_DEVICE
	// 2nd USB port is USB host
	pin_func |= 0x8000;
#endif
	au_writel(pin_func, SYS_PINFUNC);
#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)

	/* Configure GPIO2....it's used by PCI among other things.
	*/

	/* Make everything but GP200 (PCI RST) an input until we get
	 * the pins set correctly.
	 */
	au_writel(0x00000001, GPIO2_DIR);

	/* Set the pins used for output.
	 * A zero bit will leave PCI reset, LEDs off, power up USB,
	 * IDSEL disabled.
	 */
	pin_val = ((3 << 30) | (7 << 19) | (1 << 17) | (1 << 16));
	au_writel(pin_val, GPIO2_OUTPUT);

	/* Set the output direction.
	*/
	pin_val = ((3 << 14) | (7 << 3) | (1 << 1) | (1 << 0));
	au_writel(pin_val, GPIO2_DIR);

#ifdef CONFIG_PCI
	/* Use FREQ1 for the PCI output clock.  We use the
	 * CPU clock of 384 MHz divided by 12 to get 32 MHz PCI.
	 * If Michael changes the CPU speed, we need to adjust
	 * that here as well :-).
	 */

	/* zero and disable FREQ1
	*/
	sys_freqctrl = au_readl(SYS_FREQCTRL0);
	sys_freqctrl &= ~0x000ffc00;
	au_writel(sys_freqctrl, SYS_FREQCTRL0);

	/* zero and disable PCI clock
	*/
	sys_clksrc = au_readl(SYS_CLKSRC);
	sys_clksrc &= ~0x000f8000;
	au_writel(sys_clksrc, SYS_CLKSRC);

	/* Get current values (which really should match above).
	*/
	sys_freqctrl = au_readl(SYS_FREQCTRL0);
	sys_freqctrl &= ~0x000ffc00;

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

	/* FREQ1 = cpu/12 = 32 MHz
	*/
	sys_freqctrl |= ((5<<12) | (1<<11) | (0<<10));
	au_writel(sys_freqctrl, SYS_FREQCTRL0);

	/* Just connect the clock without further dividing.
	*/
	sys_clksrc |= ((3<<17) | (0<<16) | (0<<15));
	au_writel(sys_clksrc, SYS_CLKSRC);

	udelay(1);

	/* Now that clocks should be running, take PCI out of reset.
	*/
	pin_val = au_readl(GPIO2_OUTPUT);
	pin_val |= ((1 << 16) | 1);
	au_writel(pin_val, GPIO2_OUTPUT);

	// Setup PCI bus controller
	au_writel(0, Au1500_PCI_CMEM);
	au_writel(0x00003fff, Au1500_CFG_BASE);

	/* We run big endian without any of the software byte swapping,
	 * so configure the PCI bridge to help us out.
	 */
	au_writel(0xf | (2<<6) | (1<<5) | (1<<4), Au1500_PCI_CFG);

	au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
	au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
	au_writel(0x02a00356, Au1500_PCI_STATCMD);
	au_writel(0x00003c04, Au1500_PCI_HDRTYPE);	
	au_writel(0x00000008, Au1500_PCI_MBAR);
	au_sync();

	board_pci_idsel = csb250_pci_idsel;
#endif

	/* Enable sys bus clock divider when IDLE state or no bus activity. */
	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);

#ifdef CONFIG_RTC
	rtc_ops = &csb250_rtc_ops;
	// Enable the RTC if not already enabled
	if (!(au_readl(0xac000028) & 0x20)) {
		printk("enabling clock ...\n");
		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
	}
	// Put the clock in BCD mode
	if (readl(0xac00002C) & 0x4) { /* reg B */
		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
		au_sync();
	}
#endif
}
예제 #19
0
void __init board_setup(void)
{
    volatile void __iomem * base = (volatile void __iomem *) 0xac000000UL;

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

#ifdef CONFIG_USB_OHCI
    {
        u32 pin_func, sys_freqctrl, sys_clksrc;

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

        /* zero and disable FREQ2 */
        sys_freqctrl = au_readl(SYS_FREQCTRL0);
        sys_freqctrl &= ~0xFFF00000;
        au_writel(sys_freqctrl, SYS_FREQCTRL0);

        /* zero and disable USBH/USBD/IrDA clock */
        sys_clksrc = au_readl(SYS_CLKSRC);
        sys_clksrc &= ~0x0000001F;
        au_writel(sys_clksrc, SYS_CLKSRC);

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

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

        // FREQ2 = aux/2 = 48 MHz
        sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
        au_writel(sys_freqctrl, SYS_FREQCTRL0);

        /*
         * Route 48MHz FREQ2 into USBH/USBD/IrDA
         */
        sys_clksrc |= ((4<<2) | (0<<1) | 0 );
        au_writel(sys_clksrc, SYS_CLKSRC);

        /* 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 */

        // get USB Functionality pin state (device vs host drive pins)
        pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
        // 2nd USB port is USB host
        pin_func |= 0x8000;
        au_writel(pin_func, SYS_PINFUNC);
    }
#endif // defined (CONFIG_USB_OHCI)

    /* Enable sys bus clock divider when IDLE state or no bus activity. */
    au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);

    // Enable the RTC if not already enabled
    if (!(readb(base + 0x28) & 0x20)) {
        writeb(readb(base + 0x28) | 0x20, base + 0x28);
        au_sync();
    }
    // Put the clock in BCD mode
    if (readb(base + 0x2C) & 0x4) { /* reg B */
        writeb(readb(base + 0x2c) & ~0x4, base + 0x2c);
        au_sync();
    }
}
예제 #20
0
static unsigned long do_fast_gettimeoffset(void)
{
#ifdef CONFIG_PM
	unsigned long pc0;
	unsigned long offset;

	pc0 = au_readl(SYS_TOYREAD);
	if (pc0 < last_pc0) {
		offset = 0xffffffff - last_pc0 + pc0;
		printk("offset over: %x\n", (unsigned)offset);
	}
	else {
		offset = (unsigned long)(((pc0 - last_pc0) * 305) / 10);
	}
	if ((pc0-last_pc0) > 2*MATCH20_INC) {
		printk("huge offset %x, last_pc0 %x last_match20 %x pc0 %x\n",
				(unsigned)offset, (unsigned)last_pc0,
				(unsigned)last_match20, (unsigned)pc0);
	}
	au_sync();
	return offset;
#else
	u32 count;
	unsigned long res, tmp;
	unsigned long r0;

	/* Last jiffy when do_fast_gettimeoffset() was called. */
	static unsigned long last_jiffies=0;
	unsigned long quotient;

	/*
	 * Cached "1/(clocks per usec)*2^32" value.
	 * It has to be recalculated once each jiffy.
	 */
	static unsigned long cached_quotient=0;

	tmp = jiffies;

	quotient = cached_quotient;

	if (tmp && last_jiffies != tmp) {
		last_jiffies = tmp;
		if (last_jiffies != 0) {
			r0 = div64_32(timerhi, timerlo, tmp);
			quotient = div64_32(USECS_PER_JIFFY, USECS_PER_JIFFY_FRAC, r0);
			cached_quotient = quotient;
		}
	}

	/* Get last timer tick in absolute kernel time */
	count = read_c0_count();

	/* .. relative to previous jiffy (32 bits is enough) */
	count -= timerlo;

	__asm__("multu\t%1,%2\n\t"
		"mfhi\t%0"
		:"=r" (res)
		:"r" (count),
		 "r" (quotient));

	/*
 	 * Due to possible jiffies inconsistencies, we need to check
	 * the result so that we'll get a timer that is monotonic.
	 */
	if (res >= USECS_PER_JIFFY)
		res = USECS_PER_JIFFY-1;

	return res;
#endif
}
예제 #21
0
void __init board_setup(void)
{
	char *argptr = NULL;
	u32 pin_func;

#if 0
	/* Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
	 * but it is board specific code, so put it here.
	 */
	pin_func = au_readl(SYS_PINFUNC);
	au_sync();
	pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
	au_writel(pin_func, SYS_PINFUNC);

	au_writel(0, (u32)bcsr|0x10); /* turn off pcmcia power */
	au_sync();
#endif

#if defined(CONFIG_I2C_AU1550)
	{
	u32 freq0, clksrc;

	/* Select SMBUS in CPLD */
	bcsr->resets &= ~(BCSR_RESETS_PCS0MUX);

	pin_func = au_readl(SYS_PINFUNC);
	au_sync();
	pin_func &= ~(3<<17 | 1<<4);
	/* Set GPIOs correctly */
	pin_func |= 2<<17;
	au_writel(pin_func, SYS_PINFUNC);
	au_sync();

	/* The i2c driver depends on 50Mhz clock */
	freq0 = au_readl(SYS_FREQCTRL0);
	au_sync();
	freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
	freq0 |= (3<<SYS_FC_FRDIV1_BIT);
	/* 396Mhz / (3+1)*2 == 49.5Mhz */
	au_writel(freq0, SYS_FREQCTRL0);
	au_sync();
	freq0 |= SYS_FC_FE1;
	au_writel(freq0, SYS_FREQCTRL0);
	au_sync();

	clksrc = au_readl(SYS_CLKSRC);
	au_sync();
	clksrc &= ~0x01f00000;
	/* bit 22 is EXTCLK0 for PSC0 */
	clksrc |= (0x3 << 22);
	au_writel(clksrc, SYS_CLKSRC);
	au_sync();
	}
#endif

#ifdef CONFIG_FB_AU1200
	argptr = prom_getcmdline();
#ifdef CONFIG_MIPS_PB1200
	strcat(argptr, " video=au1200fb:panel:bs");
#endif
#ifdef CONFIG_MIPS_DB1200
	strcat(argptr, " video=au1200fb:panel:bs");
#endif
#endif

	/* The Pb1200 development board uses external MUX for PSC0 to
	support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
	*/
#if defined(CONFIG_AU1XXX_PSC_SPI) && defined(CONFIG_I2C_AU1550)
	#error I2C and SPI are mutually exclusive. Both are physically connected to PSC0.\
			Refer to Pb1200/Db1200 documentation.
#elif defined( CONFIG_AU1XXX_PSC_SPI )
	bcsr->resets |= BCSR_RESETS_PCS0MUX;
	/*Hard Coding Value to enable Temp Sensors [bit 14] Value for SOC Au1200. Pls refer documentation*/
	  bcsr->resets =0x900f;
#elif defined( CONFIG_I2C_AU1550 )
	bcsr->resets &= (~BCSR_RESETS_PCS0MUX);
#endif
	au_sync();

#ifdef CONFIG_MIPS_PB1200
	printk("AMD Alchemy Pb1200 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1200
	printk("AMD Alchemy Db1200 Board\n");
#endif

	/* Setup Pb1200 External Interrupt Controller */
	{
		extern void (*board_init_irq)(void);
		extern void _board_init_irq(void);
		board_init_irq = _board_init_irq;
	}
}
예제 #22
0
void __init board_setup(void)
{
	char *argptr;

	argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_8250_CONSOLE
	argptr = strstr(argptr, "console=");
	if (argptr == NULL) {
		argptr = prom_getcmdline();
		strcat(argptr, " console=ttyS0,115200");
	}
#endif
#ifdef CONFIG_FB_AU1200
	strcat(argptr, " video=au1200fb:panel:bs");
#endif

#if 0
	{
		u32 pin_func;

		/*
		 * Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
		 * but it is board specific code, so put it here.
		 */
		pin_func = au_readl(SYS_PINFUNC);
		au_sync();
		pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
		au_writel(pin_func, SYS_PINFUNC);

		au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
		au_sync();
	}
#endif

#if defined(CONFIG_I2C_AU1550)
	{
		u32 freq0, clksrc;
		u32 pin_func;

		/* Select SMBus in CPLD */
		bcsr->resets &= ~BCSR_RESETS_PCS0MUX;

		pin_func = au_readl(SYS_PINFUNC);
		au_sync();
		pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
		/* Set GPIOs correctly */
		pin_func |= 2 << 17;
		au_writel(pin_func, SYS_PINFUNC);
		au_sync();

		/* The I2C driver depends on 50 MHz clock */
		freq0 = au_readl(SYS_FREQCTRL0);
		au_sync();
		freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
		freq0 |= 3 << SYS_FC_FRDIV1_BIT;
		/* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
		au_writel(freq0, SYS_FREQCTRL0);
		au_sync();
		freq0 |= SYS_FC_FE1;
		au_writel(freq0, SYS_FREQCTRL0);
		au_sync();

		clksrc = au_readl(SYS_CLKSRC);
		au_sync();
		clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
		/* Bit 22 is EXTCLK0 for PSC0 */
		clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
		au_writel(clksrc, SYS_CLKSRC);
		au_sync();
	}
#endif

	/*
	 * The Pb1200 development board uses external MUX for PSC0 to
	 * support SMB/SPI. bcsr->resets bit 12: 0=SMB 1=SPI
	 */
#ifdef CONFIG_I2C_AU1550
	bcsr->resets &= ~BCSR_RESETS_PCS0MUX;
#endif
	au_sync();

#ifdef CONFIG_MIPS_PB1200
	printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
#endif
#ifdef CONFIG_MIPS_DB1200
	printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
#endif
}
예제 #23
0
파일: pm.c 프로젝트: 03199618/linux
static int db1x_pm_enter(suspend_state_t state)
{
	unsigned short bcsrs[16];
	int i, j, hasint;

	/* save CPLD regs */
	hasint = bcsr_read(BCSR_WHOAMI);
	hasint = BCSR_WHOAMI_BOARD(hasint) >= BCSR_WHOAMI_DB1200;
	j = (hasint) ? BCSR_MASKSET : BCSR_SYSTEM;

	for (i = BCSR_STATUS; i <= j; i++)
		bcsrs[i] = bcsr_read(i);

	/* shut off hexleds */
	bcsr_write(BCSR_HEXCLEAR, 3);

	/* enable GPIO based wakeup */
	alchemy_gpio1_input_enable();

	/* clear and setup wake cause and source */
	au_writel(0, SYS_WAKEMSK);
	au_sync();
	au_writel(0, SYS_WAKESRC);
	au_sync();

	au_writel(db1x_pm_wakemsk, SYS_WAKEMSK);
	au_sync();

	/* setup 1Hz-timer-based wakeup: wait for reg access */
	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
		asm volatile ("nop");

	au_writel(au_readl(SYS_TOYREAD) + db1x_pm_sleep_secs, SYS_TOYMATCH2);
	au_sync();

	/* wait for value to really hit the register */
	while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
		asm volatile ("nop");

	/* ...and now the sandman can come! */
	au_sleep();


	/* restore CPLD regs */
	for (i = BCSR_STATUS; i <= BCSR_SYSTEM; i++)
		bcsr_write(i, bcsrs[i]);

	/* restore CPLD int registers */
	if (hasint) {
		bcsr_write(BCSR_INTCLR, 0xffff);
		bcsr_write(BCSR_MASKCLR, 0xffff);
		bcsr_write(BCSR_INTSTAT, 0xffff);
		bcsr_write(BCSR_INTSET, bcsrs[BCSR_INTSET]);
		bcsr_write(BCSR_MASKSET, bcsrs[BCSR_MASKSET]);
	}

	/* light up hexleds */
	bcsr_write(BCSR_HEXCLEAR, 0);

	return 0;
}
예제 #24
0
void __init board_setup(void)
{
	u32 pin_func;
	u32 sys_freqctrl, sys_clksrc;

	bcsr_init(DB1000_BCSR_PHYS_ADDR,
		  DB1000_BCSR_PHYS_ADDR + DB1000_BCSR_HEXLED_OFS);

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

	/* GPIO201 is input for PCMCIA card detect */
	/* GPIO203 is input for PCMCIA interrupt request */
	alchemy_gpio_direction_input(201);
	alchemy_gpio_direction_input(203);

#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)

	/* 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 &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
			SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);
	au_writel(sys_clksrc, SYS_CLKSRC);

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

	sys_clksrc = au_readl(SYS_CLKSRC);
	sys_clksrc &= ~(SYS_CS_CUD | SYS_CS_DUD | SYS_CS_MUD_MASK |
			SYS_CS_CUH | SYS_CS_DUH | SYS_CS_MUH_MASK);

	/* FREQ2 = aux/2 = 48 MHz */
	sys_freqctrl |= (0 << SYS_FC_FRDIV2_BIT) | SYS_FC_FE2 | SYS_FC_FS2;
	au_writel(sys_freqctrl, SYS_FREQCTRL0);

	/*
	 * Route 48MHz FREQ2 into USB Host and/or Device
	 */
	sys_clksrc |= SYS_CS_MUX_FQ2 << SYS_CS_MUH_BIT;
	au_writel(sys_clksrc, SYS_CLKSRC);

	pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_USB;
	/* 2nd USB port is USB host */
	pin_func |= SYS_PF_USB;
	au_writel(pin_func, SYS_PINFUNC);
#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */

#ifdef CONFIG_PCI
	/* Setup PCI bus controller */
	au_writel(0, Au1500_PCI_CMEM);
	au_writel(0x00003fff, Au1500_CFG_BASE);
#if defined(__MIPSEB__)
	au_writel(0xf | (2 << 6) | (1 << 4), Au1500_PCI_CFG);
#else
	au_writel(0xf, Au1500_PCI_CFG);
#endif
	au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
	au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
	au_writel(0x02a00356, Au1500_PCI_STATCMD);
	au_writel(0x00003c04, Au1500_PCI_HDRTYPE);
	au_writel(0x00000008, Au1500_PCI_MBAR);
	au_sync();
#endif

	/* Enable sys bus clock divider when IDLE state or no bus activity. */
	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);

	/* Enable the RTC if not already enabled */
	if (!(au_readl(0xac000028) & 0x20)) {
		printk(KERN_INFO "enabling clock ...\n");
		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
	}
	/* Put the clock in BCD mode */
	if (au_readl(0xac00002c) & 0x4) { /* reg B */
		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
		au_sync();
	}
}
예제 #25
0
파일: irq.c 프로젝트: 10x-Amin/nAa-kernel
static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
{
	struct irq_chip *chip;
	unsigned long icr[6];
	unsigned int bit, ic;
	int ret;

	if (irq >= AU1000_INTC1_INT_BASE) {
		bit = irq - AU1000_INTC1_INT_BASE;
		chip = &au1x_ic1_chip;
		ic = 1;
	} else {
		bit = irq - AU1000_INTC0_INT_BASE;
		chip = &au1x_ic0_chip;
		ic = 0;
	}

	if (bit > 31)
		return -EINVAL;

	icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET;
	icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET;
	icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET;
	icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR;
	icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR;
	icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR;

	ret = 0;

	switch (flow_type) {	/* cfgregs 2:1:0 */
	case IRQ_TYPE_EDGE_RISING:	/* 0:0:1 */
		au_writel(1 << bit, icr[5]);
		au_writel(1 << bit, icr[4]);
		au_writel(1 << bit, icr[0]);
		set_irq_chip_and_handler_name(irq, chip,
				handle_edge_irq, "riseedge");
		break;
	case IRQ_TYPE_EDGE_FALLING:	/* 0:1:0 */
		au_writel(1 << bit, icr[5]);
		au_writel(1 << bit, icr[1]);
		au_writel(1 << bit, icr[3]);
		set_irq_chip_and_handler_name(irq, chip,
				handle_edge_irq, "falledge");
		break;
	case IRQ_TYPE_EDGE_BOTH:	/* 0:1:1 */
		au_writel(1 << bit, icr[5]);
		au_writel(1 << bit, icr[1]);
		au_writel(1 << bit, icr[0]);
		set_irq_chip_and_handler_name(irq, chip,
				handle_edge_irq, "bothedge");
		break;
	case IRQ_TYPE_LEVEL_HIGH:	/* 1:0:1 */
		au_writel(1 << bit, icr[2]);
		au_writel(1 << bit, icr[4]);
		au_writel(1 << bit, icr[0]);
		set_irq_chip_and_handler_name(irq, chip,
				handle_level_irq, "hilevel");
		break;
	case IRQ_TYPE_LEVEL_LOW:	/* 1:1:0 */
		au_writel(1 << bit, icr[2]);
		au_writel(1 << bit, icr[1]);
		au_writel(1 << bit, icr[3]);
		set_irq_chip_and_handler_name(irq, chip,
				handle_level_irq, "lowlevel");
		break;
	case IRQ_TYPE_NONE:		/* 0:0:0 */
		au_writel(1 << bit, icr[5]);
		au_writel(1 << bit, icr[4]);
		au_writel(1 << bit, icr[3]);
		/* set at least chip so we can call set_irq_type() on it */
		set_irq_chip(irq, chip);
		break;
	default:
		ret = -EINVAL;
	}
	au_sync();

	return ret;
}
예제 #26
0
void __init board_setup(void)
{
	printk(KERN_INFO "AMD Alchemy Pb1200 Board\n");
	bcsr_init(PB1200_BCSR_PHYS_ADDR,
		  PB1200_BCSR_PHYS_ADDR + PB1200_BCSR_HEXLED_OFS);

#if 0
	{
		u32 pin_func;

		/*
		 * Enable PSC1 SYNC for AC97.  Normaly done in audio driver,
		 * but it is board specific code, so put it here.
		 */
		pin_func = au_readl(SYS_PINFUNC);
		au_sync();
		pin_func |= SYS_PF_MUST_BE_SET | SYS_PF_PSC1_S1;
		au_writel(pin_func, SYS_PINFUNC);

		au_writel(0, (u32)bcsr | 0x10); /* turn off PCMCIA power */
		au_sync();
	}
#endif

#if defined(CONFIG_I2C_AU1550)
	{
		u32 freq0, clksrc;
		u32 pin_func;

		/* Select SMBus in CPLD */
		bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);

		pin_func = au_readl(SYS_PINFUNC);
		au_sync();
		pin_func &= ~(SYS_PINFUNC_P0A | SYS_PINFUNC_P0B);
		/* Set GPIOs correctly */
		pin_func |= 2 << 17;
		au_writel(pin_func, SYS_PINFUNC);
		au_sync();

		/* The I2C driver depends on 50 MHz clock */
		freq0 = au_readl(SYS_FREQCTRL0);
		au_sync();
		freq0 &= ~(SYS_FC_FRDIV1_MASK | SYS_FC_FS1 | SYS_FC_FE1);
		freq0 |= 3 << SYS_FC_FRDIV1_BIT;
		/* 396 MHz / (3 + 1) * 2 == 49.5 MHz */
		au_writel(freq0, SYS_FREQCTRL0);
		au_sync();
		freq0 |= SYS_FC_FE1;
		au_writel(freq0, SYS_FREQCTRL0);
		au_sync();

		clksrc = au_readl(SYS_CLKSRC);
		au_sync();
		clksrc &= ~(SYS_CS_CE0 | SYS_CS_DE0 | SYS_CS_ME0_MASK);
		/* Bit 22 is EXTCLK0 for PSC0 */
		clksrc |= SYS_CS_MUX_FQ1 << SYS_CS_ME0_BIT;
		au_writel(clksrc, SYS_CLKSRC);
		au_sync();
	}
#endif

	/*
	 * The Pb1200 development board uses external MUX for PSC0 to
	 * support SMB/SPI. bcsr_resets bit 12: 0=SMB 1=SPI
	 */
#ifdef CONFIG_I2C_AU1550
	bcsr_mod(BCSR_RESETS, BCSR_RESETS_PSC0MUX, 0);
#endif
	au_sync();
}
예제 #27
0
void __init board_setup(void)
{
	u32 pin_func;
	u32 sys_freqctrl, sys_clksrc;


	// 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)

	/* GPIO201 is input for PCMCIA card detect */
	/* GPIO203 is input for PCMCIA interrupt request */
	au_writel(au_readl(GPIO2_DIR) & (u32)(~((1<<1)|(1<<3))), GPIO2_DIR);

	/* 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;

	// FREQ2 = aux/2 = 48 MHz
	sys_freqctrl |= ((0<<22) | (1<<21) | (1<<20));
	au_writel(sys_freqctrl, SYS_FREQCTRL0);

	/*
	 * 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);


	pin_func = au_readl(SYS_PINFUNC) & (u32)(~0x8000);
#ifndef CONFIG_AU1X00_USB_DEVICE
	// 2nd USB port is USB host
	pin_func |= 0x8000;
#endif
	au_writel(pin_func, SYS_PINFUNC);
#endif // defined (CONFIG_USB_OHCI) || defined (CONFIG_AU1X00_USB_DEVICE)



#ifdef CONFIG_PCI
	// Setup PCI bus controller
	au_writel(0, Au1500_PCI_CMEM);
	au_writel(0x00003fff, Au1500_CFG_BASE);
#if defined(__MIPSEB__)
	au_writel(0xf | (2<<6) | (1<<4), Au1500_PCI_CFG);
#else
	au_writel(0xf, Au1500_PCI_CFG);
#endif
	au_writel(0xf0000000, Au1500_PCI_MWMASK_DEV);
	au_writel(0, Au1500_PCI_MWBASE_REV_CCL);
	au_writel(0x02a00356, Au1500_PCI_STATCMD);
	au_writel(0x00003c04, Au1500_PCI_HDRTYPE);
	au_writel(0x00000008, Au1500_PCI_MBAR);
	au_sync();
#endif

	/* Enable sys bus clock divider when IDLE state or no bus activity. */
	au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);

#ifdef CONFIG_RTC
	rtc_ops = &pb1500_rtc_ops;
	// Enable the RTC if not already enabled
	if (!(au_readl(0xac000028) & 0x20)) {
		printk("enabling clock ...\n");
		au_writel((au_readl(0xac000028) | 0x20), 0xac000028);
	}
	// Put the clock in BCD mode
	if (readl(0xac00002C) & 0x4) { /* reg B */
		au_writel(au_readl(0xac00002c) & ~0x4, 0xac00002c);
		au_sync();
	}
#endif
}
예제 #28
0
/*
 * registering functions to load algorithms at runtime
 * Prior to calling us, the 50MHz clock frequency and routing
 * must have been set up for the PSC indicated by the adapter.
 */
static int __devinit
i2c_au1550_probe(struct platform_device *pdev)
{
	struct i2c_au1550_data *priv;
	volatile psc_smb_t *sp;
	struct resource *r;
	u32 stat;
	int ret;

	r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!r) {
		ret = -ENODEV;
		goto out;
	}

	priv = kzalloc(sizeof(struct i2c_au1550_data), GFP_KERNEL);
	if (!priv) {
		ret = -ENOMEM;
		goto out;
	}

	priv->ioarea = request_mem_region(r->start, r->end - r->start + 1,
					  pdev->name);
	if (!priv->ioarea) {
		ret = -EBUSY;
		goto out_mem;
	}

	priv->psc_base = r->start;
	priv->xfer_timeout = 200;
	priv->ack_timeout = 200;

	priv->adap.id = I2C_HW_AU1550_PSC;
	priv->adap.nr = pdev->id;
	priv->adap.algo = &au1550_algo;
	priv->adap.algo_data = priv;
	priv->adap.dev.parent = &pdev->dev;
	strlcpy(priv->adap.name, "Au1xxx PSC I2C", sizeof(priv->adap.name));

	/* Now, set up the PSC for SMBus PIO mode.
	*/
	sp = (volatile psc_smb_t *)priv->psc_base;
	sp->psc_ctrl = PSC_CTRL_DISABLE;
	au_sync();
	sp->psc_sel = PSC_SEL_PS_SMBUSMODE;
	sp->psc_smbcfg = 0;
	au_sync();
	sp->psc_ctrl = PSC_CTRL_ENABLE;
	au_sync();
	do {
		stat = sp->psc_smbstat;
		au_sync();
	} while ((stat & PSC_SMBSTAT_SR) == 0);

	sp->psc_smbcfg = (PSC_SMBCFG_RT_FIFO8 | PSC_SMBCFG_TT_FIFO8 |
				PSC_SMBCFG_DD_DISABLE);

	/* Divide by 8 to get a 6.25 MHz clock.  The later protocol
	 * timings are based on this clock.
	 */
	sp->psc_smbcfg |= PSC_SMBCFG_SET_DIV(PSC_SMBCFG_DIV8);
	sp->psc_smbmsk = PSC_SMBMSK_ALLMASK;
	au_sync();

	/* Set the protocol timer values.  See Table 71 in the
	 * Au1550 Data Book for standard timing values.
	 */
	sp->psc_smbtmr = PSC_SMBTMR_SET_TH(0) | PSC_SMBTMR_SET_PS(15) | \
		PSC_SMBTMR_SET_PU(15) | PSC_SMBTMR_SET_SH(15) | \
		PSC_SMBTMR_SET_SU(15) | PSC_SMBTMR_SET_CL(15) | \
		PSC_SMBTMR_SET_CH(15);
	au_sync();

	sp->psc_smbcfg |= PSC_SMBCFG_DE_ENABLE;
	do {
		stat = sp->psc_smbstat;
		au_sync();
	} while ((stat & PSC_SMBSTAT_DR) == 0);

	ret = i2c_add_numbered_adapter(&priv->adap);
	if (ret == 0) {
		platform_set_drvdata(pdev, priv);
		return 0;
	}

	/* disable the PSC */
	sp->psc_smbcfg = 0;
	sp->psc_ctrl = PSC_CTRL_DISABLE;
	au_sync();

	release_resource(priv->ioarea);
	kfree(priv->ioarea);
out_mem:
	kfree(priv);
out:
	return ret;
}
예제 #29
0
/*
 * Au1000 receive routine.
 */
static int au1000_rx(struct net_device *dev)
{
	struct au1000_private *aup = netdev_priv(dev);
	struct sk_buff *skb;
	volatile rx_dma_t *prxd;
	u32 buff_stat, status;
	db_dest_t *pDB;
	u32	frmlen;

	if (au1000_debug > 5)
		printk("%s: au1000_rx head %d\n", dev->name, aup->rx_head);

	prxd = aup->rx_dma_ring[aup->rx_head];
	buff_stat = prxd->buff_stat;
	while (buff_stat & RX_T_DONE)  {
		status = prxd->status;
		pDB = aup->rx_db_inuse[aup->rx_head];
		update_rx_stats(dev, status);
		if (!(status & RX_ERROR))  {

			/* good frame */
			frmlen = (status & RX_FRAME_LEN_MASK);
			frmlen -= 4; /* Remove FCS */
			skb = dev_alloc_skb(frmlen + 2);
			if (skb == NULL) {
				printk(KERN_ERR
				       "%s: Memory squeeze, dropping packet.\n",
				       dev->name);
				dev->stats.rx_dropped++;
				continue;
			}
			skb_reserve(skb, 2);	/* 16 byte IP header align */
			skb_copy_to_linear_data(skb,
				(unsigned char *)pDB->vaddr, frmlen);
			skb_put(skb, frmlen);
			skb->protocol = eth_type_trans(skb, dev);
			netif_rx(skb);	/* pass the packet to upper layers */
		}
		else {
			if (au1000_debug > 4) {
				if (status & RX_MISSED_FRAME)
					printk("rx miss\n");
				if (status & RX_WDOG_TIMER)
					printk("rx wdog\n");
				if (status & RX_RUNT)
					printk("rx runt\n");
				if (status & RX_OVERLEN)
					printk("rx overlen\n");
				if (status & RX_COLL)
					printk("rx coll\n");
				if (status & RX_MII_ERROR)
					printk("rx mii error\n");
				if (status & RX_CRC_ERROR)
					printk("rx crc error\n");
				if (status & RX_LEN_ERROR)
					printk("rx len error\n");
				if (status & RX_U_CNTRL_FRAME)
					printk("rx u control frame\n");
			}
		}
		prxd->buff_stat = (u32)(pDB->dma_addr | RX_DMA_ENABLE);
		aup->rx_head = (aup->rx_head + 1) & (NUM_RX_DMA - 1);
		au_sync();

		/* next descriptor */
		prxd = aup->rx_dma_ring[aup->rx_head];
		buff_stat = prxd->buff_stat;
	}
	return 0;
}
예제 #30
0
static int au1xmmc_send_command(struct au1xmmc_host *host, int wait,  
				struct mmc_command *cmd) 
{

	u32 mmccmd = (cmd->opcode << SD_CMD_CI_SHIFT);

	switch(cmd->flags) {
	case MMC_RSP_R1:
		mmccmd |= SD_CMD_RT_1;
		break;
	case MMC_RSP_R1B:
		mmccmd |= SD_CMD_RT_1B;
		break;
	case MMC_RSP_R2:
		mmccmd |= SD_CMD_RT_2;
		break;
	case MMC_RSP_R3:
		mmccmd |= SD_CMD_RT_3;
		break;
	}

	switch(cmd->opcode) {
	case MMC_READ_SINGLE_BLOCK:
	case 51:
		mmccmd |= SD_CMD_CT_2;
		break;
	case MMC_READ_MULTIPLE_BLOCK:
		mmccmd |= SD_CMD_CT_4;
		break;
	case MMC_WRITE_BLOCK:
		mmccmd |= SD_CMD_CT_1;
		break;
	
	case MMC_WRITE_MULTIPLE_BLOCK:
		mmccmd |= SD_CMD_CT_3;
		break;
	case MMC_STOP_TRANSMISSION:
		mmccmd |= SD_CMD_CT_7;
		break;
	}
	
	au_writel(cmd->arg, HOST_CMDARG(host));
	au_sync();

	if (wait) 
		IRQ_OFF(host, SD_CONFIG_CR);
	
	au_writel((mmccmd | SD_CMD_GO), HOST_CMD(host));
	au_sync();

	/* Wait for the command to go on the line */

	while(1) {
		if (!(au_readl(HOST_CMD(host)) & SD_CMD_GO))
			break;
	}

	/* Wait for the command to come back */

	if (wait) {
		u32 status = au_readl(HOST_STATUS(host));

		while(!(status & SD_STATUS_CR)) 
			status = au_readl(HOST_STATUS(host));
		
		/* Clear the CR status */
		au_writel(SD_STATUS_CR, HOST_STATUS(host));

		IRQ_ON(host, SD_CONFIG_CR);
	}

	return MMC_ERR_NONE;
}