示例#1
0
void enable_fio_dma(void)
{
#if ((HOST_MAX_AHB_CLK_EN_BITS == 10) || (I2S_24BITMUX_MODE_REG_BITS == 4))
	u32 val;
#endif

#if (HOST_MAX_AHB_CLK_EN_BITS == 10)
	/* Disable boot-select */
	val = amba_readl(HOST_AHB_CLK_ENABLE_REG);
	val &= ~(HOST_AHB_BOOT_SEL);
	val &= ~(HOST_AHB_FDMA_BURST_DIS);
	amba_writel(HOST_AHB_CLK_ENABLE_REG, val);
#endif

#if (I2S_24BITMUX_MODE_REG_BITS == 4)
	val = amba_readl(I2S_24BITMUX_MODE_REG);
	val &= ~(I2S_24BITMUX_MODE_DMA_BOOTSEL);
	val &= ~(I2S_24BITMUX_MODE_FDMA_BURST_DIS);
	amba_writel(I2S_24BITMUX_MODE_REG, val);
#endif

#if (NAND_DUMMY_XFER == 1)
	nand_dummy_xfer();
#endif
}
示例#2
0
static inline void wait_for_rx(struct uart_port *port)
{
	u32					ls;

	ls = amba_readl(port->membase + UART_LS_OFFSET);
	while ((ls & UART_LS_DR) != UART_LS_DR) {
		cpu_relax();
		ls = amba_readl(port->membase + UART_LS_OFFSET);
	}
}
示例#3
0
static u32 notrace ambarella_read_sched_clock(void)
{
#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
	return (-(u32)amba_readl(AMBARELLA_CS_TIMER_STATUS_REG));
#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (machine_is_hyacinth_0())
		return (-(u32)amba_readl(AMBARELLA_CS_TIMER_AXI0_STATUS_REG));
	if (machine_is_hyacinth_1())
		return (-(u32)amba_readl(AMBARELLA_CS_TIMER_AXI1_STATUS_REG));
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
}
示例#4
0
static cycle_t ambarella_cs_timer_read(struct clocksource *cs)
{
#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
	return (-(u32)amba_readl(AMBARELLA_CS_TIMER_STATUS_REG));
#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (machine_is_hyacinth_0())
		return (-(u32)amba_readl(AMBARELLA_CS_TIMER_AXI0_STATUS_REG));
	else
		return (-(u32)amba_readl(AMBARELLA_CS_TIMER_AXI1_STATUS_REG));
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
}
示例#5
0
int fio_amb_sdio0_is_enable(void)
{
	u32 fio_ctr;
	u32 fio_dmactr;

	fio_ctr = amba_readl(FIO_CTR_REG);
	fio_dmactr = amba_readl(FIO_DMACTR_REG);

	return (((fio_ctr & FIO_CTR_XD) == FIO_CTR_XD) &&
		((fio_dmactr & FIO_DMACTR_SD) == FIO_DMACTR_SD));
}
示例#6
0
static void serial_ambarella_set_mctrl(struct uart_port *port,
	unsigned int mctrl)
{
	struct ambarella_uart_port_info		*port_info;
	u32					mcr;
	u32					mcr_new = 0;

	port_info = (struct ambarella_uart_port_info *)(port->private_data);

	if (port_info->get_ms) {
		mcr = amba_readl(port->membase + UART_MC_OFFSET);

		if (mctrl & TIOCM_DTR)
			mcr_new |= UART_MC_DTR;
		if (mctrl & TIOCM_RTS)
			mcr_new |= UART_MC_RTS;
		if (mctrl & TIOCM_OUT1)
			mcr_new |= UART_MC_OUT1;
		if (mctrl & TIOCM_OUT2)
			mcr_new |= UART_MC_OUT2;
		if (mctrl & TIOCM_LOOP)
			mcr_new |= UART_MC_LB;

		mcr_new |= port_info->mcr;
		if (mcr_new != mcr) {
			if ((mcr & UART_MC_AFCE) == UART_MC_AFCE) {
				mcr &= ~UART_MC_AFCE;
				amba_writel(port->membase + UART_MC_OFFSET,
					mcr);
			}
			amba_writel(port->membase + UART_MC_OFFSET, mcr_new);
		}
	}
}
示例#7
0
static void i2s_channel_select(u32 ch)
{
#if (CHIP_REV == A3)||(CHIP_REV == A5)||(CHIP_REV == A6)|| \
	(CHIP_REV == A5S)||(CHIP_REV == I1)||(CHIP_REV == S2)
	u32 ch_reg_num;

	ch_reg_num = amba_readl(I2S_CHANNEL_SELECT_REG);

	switch (ch) {
	case 2:
		if (ch_reg_num != 0)
			amba_writel(I2S_CHANNEL_SELECT_REG, I2S_2CHANNELS_ENB);
		break;
	case 4:
		if (ch_reg_num != 1)
			amba_writel(I2S_CHANNEL_SELECT_REG, I2S_4CHANNELS_ENB);
		break;
	case 6:
		if (ch_reg_num != 2)
			amba_writel(I2S_CHANNEL_SELECT_REG, I2S_6CHANNELS_ENB);
		break;
	default:
		printk("Don't support %d channels\n", ch);
		break;
	}
#endif
}
示例#8
0
static void ambench_apbread(void)
{
	u64					raw_counter = 0;
	u64					amba_counter = 0;
	unsigned long				flags;

	disable_nonboot_cpus();
	local_irq_save(flags);

	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
	amba_writel(TIMER1_RELOAD_REG, 0x0);
	amba_writel(TIMER1_MATCH1_REG, 0x0);
	amba_writel(TIMER1_MATCH2_REG, 0x0);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);

	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	do {
		raw_counter++;
	} while(__raw_readl((const volatile void *)TIMER1_STATUS_REG));

	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
	amba_writel(TIMER1_RELOAD_REG, 0x0);
	amba_writel(TIMER1_MATCH1_REG, 0x0);
	amba_writel(TIMER1_MATCH2_REG, 0x0);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);

	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	do {
		amba_counter++;
	} while(amba_readl(TIMER1_STATUS_REG));
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);

	local_irq_restore(flags);
	enable_nonboot_cpus();

#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_HAL)
	raw_counter *= get_apb_bus_freq_hz();
#else
	raw_counter *= clk_get_rate(clk_get(NULL, "gclk_apb"));
#endif
	do_div(raw_counter, APBREAD_RELOAD_NUM);
#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_HAL)
	amba_counter *= get_apb_bus_freq_hz();
#else
	amba_counter *= clk_get_rate(clk_get(NULL, "gclk_apb"));
#endif
	do_div(amba_counter, APBREAD_RELOAD_NUM);
	pr_info("CPU[0x%x] APBRead: raw speed %llu/s!\n",
		cpu_architecture(), raw_counter);
	pr_info("CPU[0x%x] APBRead: amba speed %llu/s!\n",
		cpu_architecture(), amba_counter);
}
示例#9
0
static int serial_ambarella_poll_get_char(struct uart_port *port)
{
	struct ambarella_uart_port_info		*port_info;

	port_info = (struct ambarella_uart_port_info *)(port->private_data);
	if (!port->suspended) {
		wait_for_rx(port);
		return amba_readl(port->membase + UART_RB_OFFSET);
	}
	return 0;
}
示例#10
0
static unsigned int serial_ambarella_tx_empty(struct uart_port *port)
{
	unsigned long				flags;
	unsigned int				lsr;

	spin_lock_irqsave(&port->lock, flags);
	lsr = amba_readl(port->membase + UART_LS_OFFSET);
	spin_unlock_irqrestore(&port->lock, flags);

	return ((lsr & (UART_LS_TEMT | UART_LS_THRE)) ==
		(UART_LS_TEMT | UART_LS_THRE)) ? TIOCSER_TEMT : 0;
}
示例#11
0
static int flush_rxfifo(void)
{
	int retry_count = 1000;
	int rval = 0;

#if (CHIP_REV == A2) || (CHIP_REV == A3)
	retry_count = retry_count * 10;
	if (!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)){
		/* Switch to slave mode */
		amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_DMA_MD);

		while (!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)) {
			if (retry_count-- < 0) {
				printk (KERN_ERR "%s: failed", __func__);
				rval = -1;
				break;
			}
			amba_readl(USB_RXFIFO_BASE);
			udelay(5);
		}
		/* Switch to DMA mode */
		amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_DMA_MD);
	}
#else
	amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_NAK);
	amba_setbitsl(USB_DEV_CTRL_REG, USB_DEV_FLUSH_RXFIFO);
	while(!(amba_readl(USB_DEV_STS_REG) & USB_DEV_RXFIFO_EMPTY_STS)) {
		if (retry_count-- < 0) {
			printk (KERN_ERR "%s: failed", __func__);
			rval = -1;
			break;
		}
		udelay(5);
	}
	amba_clrbitsl(USB_DEV_CTRL_REG, USB_DEV_NAK);
#endif
	return rval;
}
示例#12
0
void nand_dummy_xfer(void)
{
	amba_writel(FIO_CTR_REG, 0x15);
	amba_writel(NAND_CTR_REG, 0x4080110);

	amba_writel(DMA_FIOS_CHAN0_STA_REG, 0x0);
	amba_writel(DMA_FIOS_CHAN0_SRC_REG, 0x60000000);
	amba_writel(DMA_FIOS_CHAN0_DST_REG, 0xc0000000);
	amba_writel(DMA_FIOS_CHAN0_CTR_REG, 0xae800020);

	amba_writel(FIO_DMAADR_REG, 0x0);
	amba_writel(FIO_DMACTR_REG, 0x86800020);

	while ((amba_readl(DMA_FIOS_INT_REG) & 0x1) != 0x1);
	amba_writel(DMA_FIOS_CHAN0_STA_REG, 0x0);

	while ((amba_readl(FIO_STA_REG) & 0x1) != 0x1);
	amba_writel(FIO_CTR_REG, 0x1);
	amba_writel(NAND_INT_REG, 0x0);

	while ((amba_readl(FIO_DMASTA_REG) & 0x1000000) != 0x1000000);
	amba_writel(FIO_DMASTA_REG, 0x0);
}
示例#13
0
static void ambench_apbread(void)
{
	u64					raw_counter = 0;
	u64					amba_counter = 0;
	unsigned long				flags;

	disable_nonboot_cpus();
	local_irq_save(flags);

	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
	amba_writel(TIMER1_RELOAD_REG, 0x0);
	amba_writel(TIMER1_MATCH1_REG, 0x0);
	amba_writel(TIMER1_MATCH2_REG, 0x0);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);

	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	do {
		raw_counter++;
	} while(__raw_readl(TIMER1_STATUS_REG));

	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	amba_writel(TIMER1_STATUS_REG, APBREAD_RELOAD_NUM);
	amba_writel(TIMER1_RELOAD_REG, 0x0);
	amba_writel(TIMER1_MATCH1_REG, 0x0);
	amba_writel(TIMER1_MATCH2_REG, 0x0);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_OF1);
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_CSL1);

	amba_setbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);
	do {
		amba_counter++;
	} while(amba_readl(TIMER1_STATUS_REG));
	amba_clrbitsl(TIMER_CTR_REG, TIMER_CTR_EN1);

	local_irq_restore(flags);
	enable_nonboot_cpus();

	raw_counter *= get_apb_bus_freq_hz();
	do_div(raw_counter, APBREAD_RELOAD_NUM);
	amba_counter *= get_apb_bus_freq_hz();
	do_div(amba_counter, APBREAD_RELOAD_NUM);
	pr_info("CPU[0x%x] APBRead: raw speed %llu/s!\n",
		cpu_architecture(), raw_counter);
	pr_info("CPU[0x%x] APBRead: amba speed %llu/s!\n",
		cpu_architecture(), amba_counter);
}
示例#14
0
static void ambarella_enable_usb_host(struct ambarella_uhc_controller *pdata)
{
	u32 sys_config;
	amb_usb_port_state_t state;

	sys_config = amba_readl(SYS_CONFIG_REG);

	if (sys_config & USB1_IS_HOST)
		pdata->usb1_is_host = 1;

	if (usb_host_initialized == 1)
		return;

	usb_host_initialized = 1;

	/* GPIO8 and GPIO10 are programmed as hardware mode */
	if (sys_config & USB1_IS_HOST)
		amba_setbitsl(GPIO0_AFSEL_REG, 0x00000500);
	/* GPIO7 and GPIO9 are programmed as hardware mode */
	amba_setbitsl(GPIO0_AFSEL_REG, 0x00000280);

	/* Reset usb host controller */
	if (amb_usb_host_soft_reset(HAL_BASE_VP) != AMB_HAL_SUCCESS)
		pr_info("%s: amb_set_usb_port0_state fail!\n", __func__);

	/*
	 * We must enable both of the usb ports first, then we can disable
	 * usb port1 if it is configured as device port.
	 */
	state = amb_get_usb_port1_state(HAL_BASE_VP);
	if (state != AMB_USB_ON && amb_set_usb_port1_state(HAL_BASE_VP, AMB_USB_ON)
			!= AMB_HAL_SUCCESS) {
		pr_info("%s: amb_set_usb_port1_state fail!\n", __func__);
	}

	if (amb_set_usb_port0_state(HAL_BASE_VP, AMB_USB_ON)
			!= AMB_HAL_SUCCESS) {
		pr_info("%s: amb_set_usb_port0_state fail!\n", __func__);
	}

	if (!(sys_config & USB1_IS_HOST) && state != AMB_USB_ON) {
		if (amb_set_usb_port1_state(HAL_BASE_VP, state)
				!= AMB_HAL_SUCCESS) {
			pr_info("%s: amb_set_usb_port1_state fail!\n", __func__);
		}
	}
}
示例#15
0
void fio_amb_sdio0_set_int(u32 mask, u32 on)
{
	unsigned long				flags;
	u32					int_flag;

	spin_lock_irqsave(&fio_sd0_int_lock, flags);
	int_flag = amba_readl(SD_NISEN_REG);
	if (on)
		int_flag |= mask;
	else
		int_flag &= ~mask;
	fio_sdio_int = int_flag;
	if (fio_amb_sdio0_is_enable()) {
		amba_writel(SD_NISEN_REG, int_flag);
		amba_writel(SD_NIXEN_REG, int_flag);
	}
	spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
}
示例#16
0
static irqreturn_t serial_ambarella_irq(int irq, void *dev_id)
{
	struct uart_port			*port = dev_id;
	struct ambarella_uart_port_info		*port_info;
	int					rval = IRQ_HANDLED;
	u32					ii;
	unsigned long				flags;

	port_info = (struct ambarella_uart_port_info *)(port->private_data);

	spin_lock_irqsave(&port->lock, flags);

	ii = amba_readl(port->membase + UART_II_OFFSET);
	switch (ii & 0x0F) {
	case UART_II_MODEM_STATUS_CHANGED:
		serial_ambarella_check_modem_status(port);
		break;

	case UART_II_THR_EMPTY:
		serial_ambarella_transmit_chars(port);
		break;

	case UART_II_RCV_STATUS:
	case UART_II_RCV_DATA_AVAIL:
		serial_ambarella_receive_chars(port, 0);
		break;
	case UART_II_CHAR_TIMEOUT:
		serial_ambarella_receive_chars(port, 1);
		break;

	case UART_II_NO_INT_PENDING:
	default:
		printk(KERN_DEBUG "%s: 0x%x\n", __func__, ii);
		rval = IRQ_NONE;
		break;
	}

	spin_unlock_irqrestore(&port->lock, flags);

	return rval;
}
示例#17
0
static int ambarella_wdt_suspend(struct platform_device *pdev,
	pm_message_t state)
{
	struct ambarella_wdt_info		*pinfo;
	int					errorCode = 0;

	pinfo = platform_get_drvdata(pdev);

	if (pinfo) {
		disable_irq(pinfo->irq);
		pinfo->ctl_reg = amba_readl(pinfo->regbase +
			WDOG_CONTROL_OFFSET);
		ambarella_wdt_stop(pinfo);
	} else {
		dev_err(&pdev->dev, "Cannot find valid pinfo\n");
		errorCode = -ENXIO;
	}

	dev_dbg(&pdev->dev, "%s exit with %d @ %d\n",
		__func__, errorCode, state.event);

	return errorCode;
}
示例#18
0
static void ambarella_disable_usb_host(void)
{
	u32 sys_config;

	if (usb_host_initialized == 0)
		return;

	usb_host_initialized = 0;

	sys_config = amba_readl(SYS_CONFIG_REG);

	if (amb_set_usb_port0_state(HAL_BASE_VP, AMB_USB_OFF)
			!= AMB_HAL_SUCCESS) {
		pr_info("%s: amb_set_usb_port0_state fail!\n", __func__);
	}

	if (sys_config & USB1_IS_HOST) {
		if (amb_set_usb_port1_state(HAL_BASE_VP, AMB_USB_OFF)
				!= AMB_HAL_SUCCESS) {
			pr_info("%s: amb_set_usb_port1_state fail!\n", __func__);
		}
	}
}
示例#19
0
static void serial_ambarella_console_write(struct console *co,
	const char *s, unsigned int count)
{
	u32					ie;
	struct uart_port			*port;
	unsigned long				flags;
	int					locked = 1;

	port = (struct uart_port *)(
		ambarella_uart_ports.amba_port[co->index].port);

	if (!port->suspended) {
		local_irq_save(flags);
		if (port->sysrq) {
			locked = 0;
		} else if (oops_in_progress) {
			locked = spin_trylock(&port->lock);
		} else {
			spin_lock(&port->lock);
			locked = 1;
		}

		ie = amba_readl(port->membase + UART_IE_OFFSET);
		amba_writel(port->membase + UART_IE_OFFSET,
			ie & ~UART_IE_ETBEI);

		uart_console_write(port, s, count,
			serial_ambarella_console_putchar);

		wait_for_tx(port);
		amba_writel(port->membase + UART_IE_OFFSET, ie);

		if (locked)
			spin_unlock(&port->lock);
		local_irq_restore(flags);
	}
}
示例#20
0
/* ==========================================================================*/
void __fio_select_lock(int module)
{
	u32					fio_ctr;
	u32					fio_dmactr;
#if (SD_HAS_INTERNAL_MUXER == 1)
	unsigned long				flags;
#endif

	fio_ctr = amba_readl(FIO_CTR_REG);
	fio_dmactr = amba_readl(FIO_DMACTR_REG);

	switch (module) {
	case SELECT_FIO_FL:
		fio_ctr &= ~FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_FL;
		break;

	case SELECT_FIO_XD:
		fio_ctr |= FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_XD;
		break;

	case SELECT_FIO_CF:
		fio_ctr &= ~FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_CF;
#if (FIO_SUPPORT_AHB_CLK_ENA == 1)
		fio_amb_sd2_disable();
		fio_amb_cf_enable();
#endif
		break;

	case SELECT_FIO_SD:
		fio_ctr &= ~FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
		break;

	case SELECT_FIO_SDIO:
		fio_ctr |= FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
		break;

	case SELECT_FIO_SD2:
#if (FIO_SUPPORT_AHB_CLK_ENA == 1)
		fio_amb_cf_disable();
		fio_amb_sd2_enable();
#endif
#if (SD_HOST1_HOST2_HAS_MUX == 1)
		fio_ctr &= ~FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
#endif
		break;

	default:
		break;
	}

#if (SD_HAS_INTERNAL_MUXER == 1)
	spin_lock_irqsave(&fio_sd0_int_lock, flags);
	amba_clrbitsl(SD_NISEN_REG, SD_NISEN_CARD);
	spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
#if defined(CONFIG_AMBARELLA_FIO_FORCE_SDIO_GPIO)
	if (module != SELECT_FIO_SDIO) {
		ambarella_gpio_raw_lock(2, &flags);
		amba_clrbitsl(GPIO2_AFSEL_REG, 0x000007e0);
		ambarella_gpio_raw_unlock(2, &flags);
	}
#endif
#endif
	amba_writel(FIO_CTR_REG, fio_ctr);
	amba_writel(FIO_DMACTR_REG, fio_dmactr);
#if (SD_HAS_INTERNAL_MUXER == 1)
	if (module == SELECT_FIO_SD) {
		spin_lock_irqsave(&fio_sd0_int_lock, flags);
		amba_writel(SD_NISEN_REG, fio_sd_int);
		amba_writel(SD_NIXEN_REG, fio_sd_int);
		spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
	} else
	if (module == SELECT_FIO_SDIO) {
#if defined(CONFIG_AMBARELLA_FIO_FORCE_SDIO_GPIO)
		ambarella_gpio_raw_lock(2, &flags);
		amba_setbitsl(GPIO2_AFSEL_REG, 0x000007e0);
		ambarella_gpio_raw_unlock(2, &flags);
#endif
		spin_lock_irqsave(&fio_sd0_int_lock, flags);
		amba_writel(SD_NISEN_REG, fio_sdio_int);
		amba_writel(SD_NIXEN_REG, fio_sdio_int);
		spin_unlock_irqrestore(&fio_sd0_int_lock, flags);
	}
#endif
}
示例#21
0
void fio_unlock(int module)
{
	if (atomic_read(&fio_owner) == module) {
#if (SD_HAS_INTERNAL_MUXER == 1)
		if (fio_select_sdio_as_default && (module != SELECT_FIO_SDIO)) {
			u32 fio_dmactr;

#if (HANDLE_SDIO_FAKE_IRQ == 1)
			/* When swtich back to SDIO, SMIO38 ~ 43 connected to */
			/* SD controller internally and a detection of low of */
			/* SMIO41 cause fake SDIO irq. */
			unsigned long flags;

			flags = arm_irq_save();
			/* SMIO_38 ~ 43 HW */
			amba_setbitsl(GPIO2_AFSEL_REG, 0x000007e0);

			fio_dmactr = amba_readl(FIO_DMACTR_REG);
			fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;

			amba_writel(FIO_DMACTR_REG, fio_dmactr);
			amba_setbitsl(FIO_CTR_REG, FIO_CTR_XD);

			fio_reactive_sdio_irq();
			arm_irq_restore(flags);
#else
			fio_dmactr = amba_readl(FIO_DMACTR_REG);
			fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
			amba_writel(FIO_DMACTR_REG, fio_dmactr);
			amba_setbitsl(FIO_CTR_REG, FIO_CTR_XD);
#endif
		}
#endif
#if (FIO_SUPPORT_AHB_CLK_ENA == 1)
		if (fio_select_sdio_as_default && (module == SELECT_FIO_CF)) {
			fio_amb_cf_disable();
			fio_amb_sd2_enable();
		}
#endif
	}

	if ((atomic_read(&fio_owner) == module) &&
		(fio_default_owner != SELECT_FIO_FREE) &&
		(fio_default_owner != module)) {
		__fio_select_lock(fio_default_owner);
	}

#if	defined(CONFIG_AMBARELLA_IPC)
	atomic_set(&fio_owner, SELECT_FIO_FREE);
#if (SD_HOST1_HOST2_HAS_MUX == 1)
	switch (module) {
	case SELECT_FIO_SD:
	case SELECT_FIO_SDIO:
		ipc_mutex_unlock(IPC_MUTEX_ID_SD);
		return;
	case SELECT_FIO_SD2:
		ipc_mutex_unlock(IPC_MUTEX_ID_SD2);
		return;
	default:
		ipc_mutex_unlock(IPC_MUTEX_ID_SD);
		ipc_mutex_unlock(IPC_MUTEX_ID_SD2);
		return;
	}
#else
	ipc_mutex_unlock(IPC_MUTEX_ID_FIO);
#endif	/* SD_HOST1_HOST2_HAS_MUX */
#else
	if (atomic_cmpxchg(&fio_owner, module, SELECT_FIO_FREE) == module) {
		wake_up(&fio_lock);
	} else {
		pr_err("%s: fio_owner[%d] != module[%d]!.\n",
			__func__, atomic_read(&fio_owner), module);
	}
#endif
}
示例#22
0
/* ==========================================================================*/
void __fio_select_lock(int module)
{
	u32 fio_ctr;
	u32 fio_dmactr;

	fio_ctr = amba_readl(FIO_CTR_REG);
	fio_dmactr = amba_readl(FIO_DMACTR_REG);

	switch (module) {
	case SELECT_FIO_FL:
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_FL;
		break;

	case SELECT_FIO_XD:
		fio_ctr |= FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_XD;
		break;

	case SELECT_FIO_CF:
		fio_ctr &= ~FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_CF;
#if (FIO_SUPPORT_AHB_CLK_ENA == 1)
		fio_amb_sd2_disable();
		fio_amb_cf_enable();
#endif
		break;

	case SELECT_FIO_SD:
		fio_ctr &= ~FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
		break;

	case SELECT_FIO_SDIO:
		fio_ctr |= FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
		break;

	case SELECT_FIO_SD2:
#if (FIO_SUPPORT_AHB_CLK_ENA == 1)
		fio_amb_cf_disable();
		fio_amb_sd2_enable();
#endif
#if (CHIP_REV == A7L)
		fio_ctr &= ~FIO_CTR_XD;
		fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
#endif
		break;

	default:
		break;
	}

#if (SD_HAS_INTERNAL_MUXER == 1)
	if (module != SELECT_FIO_SDIO) {
#if (HANDLE_SDIO_FAKE_IRQ == 1)
		amba_clrbitsw(SD_NISEN_REG, SD_NISEN_CARD);
#endif
		//SMIO_38 ~ SMIO_43
		amba_clrbitsl(GPIO2_AFSEL_REG, 0x000007e0);
	}
#endif

	amba_writel(FIO_DMACTR_REG, fio_dmactr);
	amba_writel(FIO_CTR_REG, fio_ctr);

#if (SD_HAS_INTERNAL_MUXER == 1)
	if (module == SELECT_FIO_SDIO) {
		//SMIO_38 ~ SMIO_43
		amba_setbitsl(GPIO2_AFSEL_REG, 0x000007e0);
	}
#endif
}
示例#23
0
void fio_unlock(int module)
{
	unsigned long flags;

	if (fio_owner == module) {
#if (SD_HAS_INTERNAL_MUXER == 1)
		if (fio_select_sdio_as_default && (module != SELECT_FIO_SDIO)) {
			u32 fio_dmactr;

#if (HANDLE_SDIO_FAKE_IRQ == 1)
			/* When swtich back to SDIO, SMIO38 ~ 43 connected to */
			/* SD controller internally and a detection of low of */
			/* SMIO41 cause fake SDIO irq. */
			unsigned long flags;

			flags = arm_irq_save();
			/* SMIO_38 ~ 43 HW */
			amba_setbitsl(GPIO2_AFSEL_REG, 0x000007e0);

			fio_dmactr = amba_readl(FIO_DMACTR_REG);
			fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;

			amba_writel(FIO_DMACTR_REG, fio_dmactr);
			amba_setbitsl(FIO_CTR_REG, FIO_CTR_XD);

			fio_reactive_sdio_irq();
			arm_irq_restore(flags);
#else
			fio_dmactr = amba_readl(FIO_DMACTR_REG);
			fio_dmactr = (fio_dmactr & 0xcfffffff) | FIO_DMACTR_SD;
			amba_writel(FIO_DMACTR_REG, fio_dmactr);
			amba_setbitsl(FIO_CTR_REG, FIO_CTR_XD);
#endif
		}
#endif
	}

	if (!(fio_owner & (~module)) &&
	    (fio_default_owner != SELECT_FIO_FREE) &&
	    (fio_default_owner != module)) {
		__fio_select_lock(fio_default_owner);
	}

	spin_lock_irqsave(&fio_lock, flags);

#if (SD_HOST1_HOST2_HAS_MUX == 1)
	if (module & (SELECT_FIO_SD | SELECT_FIO_SD2)) {
		if (fio_owner & module) {
			fio_owner &= (~module);
			wake_up(&fio_wait);
		} else {
			pr_err("%s: fio_owner(0x%x) != module(0x%x)!.\n",
			       __func__, fio_owner, module);
		}
	} else
#endif
		if (fio_owner == module) {
			fio_owner = SELECT_FIO_FREE;
			wake_up(&fio_wait);
		} else {
			pr_err("%s: fio_owner(%d) != module(%d)!.\n",
			       __func__, fio_owner, module);
		}

	spin_unlock_irqrestore(&fio_lock, flags);

#if defined(CONFIG_AMBALINK_LOCK)
#if (SD_HOST1_HOST2_HAS_MUX == 1)
	switch (module) {
	case SELECT_FIO_SD:
	case SELECT_FIO_SDIO:
		aipc_mutex_unlock(AMBA_IPC_MUTEX_SD0);
		return;
	case SELECT_FIO_SD2:
		aipc_mutex_unlock(AMBA_IPC_MUTEX_SD1);
		return;
	default:
		aipc_mutex_unlock(AMBA_IPC_MUTEX_SD0);
		aipc_mutex_unlock(AMBA_IPC_MUTEX_SD1);
		return;
	}
#else
	aipc_mutex_unlock(AMBA_IPC_MUTEX_FIO);
#endif	/* SD_HOST1_HOST2_HAS_MUX */
#endif	/* CONFIG_AMBALINK_LOCK */
}
示例#24
0
static void ambarella_wdt_stop(struct ambarella_wdt_info *pinfo)
{
	amba_writel(pinfo->regbase + WDOG_CONTROL_OFFSET, 0);
	while(amba_readl(pinfo->regbase + WDOG_CONTROL_OFFSET) != 0);
}
示例#25
0
static int __devinit ambarella_wdt_probe(struct platform_device *pdev)
{
	int					errorCode = 0;
	struct resource 			*irq;
	struct resource 			*mem;
	struct resource 			*ioarea;
	struct ambarella_wdt_info		*pinfo;

	mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (mem == NULL) {
		dev_err(&pdev->dev, "Get WDT mem resource failed!\n");
		errorCode = -ENXIO;
		goto ambarella_wdt_na;
	}

	irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
	if (irq == NULL) {
		dev_err(&pdev->dev, "Get WDT irq resource failed!\n");
		errorCode = -ENXIO;
		goto ambarella_wdt_na;
	}

	ioarea = request_mem_region(mem->start,
			(mem->end - mem->start) + 1, pdev->name);
	if (ioarea == NULL) {
		dev_err(&pdev->dev, "Request WDT ioarea failed!\n");
		errorCode = -EBUSY;
		goto ambarella_wdt_na;
	}

	pinfo = kzalloc(sizeof(struct ambarella_wdt_info),
		GFP_KERNEL);
	if (pinfo == NULL) {
		dev_err(&pdev->dev, "Out of memory!\n");
		errorCode = -ENOMEM;
		goto ambarella_wdt_ioarea;
	}

	pinfo->pcontroller =
		(struct ambarella_wdt_controller *)pdev->dev.platform_data;
	if ((pinfo->pcontroller == NULL) ||
		(pinfo->pcontroller->get_pll == NULL) ||
		(pinfo->pcontroller->start == NULL)) {
		dev_err(&pdev->dev, "Need WDT controller info!\n");
		errorCode = -EPERM;
		goto ambarella_wdt_free_pinfo;
	}

	pinfo->regbase = (unsigned char __iomem *)mem->start;
	pinfo->mem = mem;
	pinfo->dev = &pdev->dev;
	pinfo->irq = irq->start;
	sema_init(&pinfo->wdt_mutex, 1);
	pinfo->state = AMBA_WDT_CLOSE_STATE_DISABLE;
	pinfo->wdt_dev.minor = WATCHDOG_MINOR,
	pinfo->wdt_dev.name = "watchdog",
	pinfo->wdt_dev.fops = &ambarella_wdt_fops,
	pinfo->boot_tmo = amba_readl(pinfo->regbase + WDOG_TIMEOUT_OFFSET);
	pinfo->init_mode = (init_mode & (WDOG_CTR_INT_EN | WDOG_CTR_RST_EN));
	platform_set_drvdata(pdev, pinfo);
	pwdtinfo = pinfo;

	errorCode = ambarella_wdt_set_heartbeat(pinfo, init_tmo);
	if (errorCode)
		ambarella_wdt_set_heartbeat(pinfo,
			CONFIG_WDT_AMBARELLA_TIMEOUT);

	errorCode = misc_register(&pinfo->wdt_dev);
	if (errorCode) {
		dev_err(&pdev->dev, "cannot register miscdev minor=%d (%d)\n",
			WATCHDOG_MINOR, errorCode);
		goto ambarella_wdt_free_pinfo;
	}

	ambarella_wdt_stop(pinfo);

	errorCode = request_irq(pinfo->irq, ambarella_wdt_irq,
		IRQF_TRIGGER_RISING, dev_name(&pdev->dev), pinfo);
	if (errorCode) {
		dev_err(&pdev->dev, "Request IRQ failed!\n");
		goto ambarella_wdt_deregister;
	}

	dev_notice(&pdev->dev,
		"Ambarella Media Processor Watch Dog Timer[%s].\n",
		dev_name(&pdev->dev));

	goto ambarella_wdt_na;

ambarella_wdt_deregister:
	errorCode = misc_deregister(&pinfo->wdt_dev);

ambarella_wdt_free_pinfo:
	kfree(pinfo);

ambarella_wdt_ioarea:
	release_mem_region(mem->start, (mem->end - mem->start) + 1);

ambarella_wdt_na:
	return errorCode;
}
示例#26
0
/* ==========================================================================*/
static inline void serial_ambarella_receive_chars(struct uart_port *port,
	u32 tmo)
{
	struct tty_struct			*tty = port->state->port.tty;
	u32					ch;
	u32					flag;
	int					max_count;
	u32					ls;

	ls = amba_readl(port->membase + UART_LS_OFFSET);
	max_count = port->fifosize;

	do {
		flag = TTY_NORMAL;
		if (unlikely(ls & (UART_LS_BI | UART_LS_PE |
					UART_LS_FE | UART_LS_OE))) {
			if (ls & UART_LS_BI) {
				ls &= ~(UART_LS_FE | UART_LS_PE);
				port->icount.brk++;

				if (uart_handle_break(port))
					goto ignore_char;
			}
			if (ls & UART_LS_FE)
				port->icount.frame++;
			if (ls & UART_LS_PE)
				port->icount.parity++;
			if (ls & UART_LS_OE)
				port->icount.overrun++;

			ls &= port->read_status_mask;

			if (ls & UART_LS_BI)
				flag = TTY_BREAK;
			else if (ls & UART_LS_FE)
				flag = TTY_FRAME;
			else if (ls & UART_LS_PE)
				flag = TTY_PARITY;
			else if (ls & UART_LS_OE)
				flag = TTY_OVERRUN;

			if (ls & UART_LS_OE) {
				printk(KERN_DEBUG "%s: OVERFLOW\n", __func__);
			}
		}

		if (likely(ls & UART_LS_DR)) {
			ch = amba_readl(port->membase + UART_RB_OFFSET);
			port->icount.rx++;
			tmo = 0;

			if (uart_handle_sysrq_char(port, ch))
				goto ignore_char;

			uart_insert_char(port, ls, UART_LS_OE, ch, flag);
		} else {
			if (tmo) {
				ch = amba_readl(port->membase + UART_RB_OFFSET);
				printk(KERN_DEBUG "False TMO get %d\n", ch);
			}
		}

ignore_char:
		ls = amba_readl(port->membase + UART_LS_OFFSET);
	} while ((ls & UART_LS_DR) && (max_count-- > 0));

	spin_unlock(&port->lock);
	tty_flip_buffer_push(tty);
	spin_lock(&port->lock);
}
示例#27
0
u32 ambarella_timer_suspend(u32 level)
{
	u32					timer_ctr_mask;

	ambarella_timer_pm.timer_ctr_reg = amba_readl(TIMER_CTR_REG);
	ambarella_timer_pm.timer_clk = AMBARELLA_TIMER_FREQ;

#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
		ambarella_timer_pm.timer_ce_status_reg =
			amba_readl(AMBARELLA_CE_TIMER_STATUS_REG);
		ambarella_timer_pm.timer_ce_reload_reg =
			amba_readl(AMBARELLA_CE_TIMER_RELOAD_REG);
		ambarella_timer_pm.timer_ce_match1_reg =
			amba_readl(AMBARELLA_CE_TIMER_MATCH1_REG);
		ambarella_timer_pm.timer_ce_match2_reg =
			amba_readl(AMBARELLA_CE_TIMER_MATCH2_REG);
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		ambarella_timer_pm.timer_cs_status_reg =
			amba_readl(AMBARELLA_CS_TIMER_STATUS_REG);
		ambarella_timer_pm.timer_cs_reload_reg =
			amba_readl(AMBARELLA_CS_TIMER_RELOAD_REG);
		ambarella_timer_pm.timer_cs_match1_reg =
			amba_readl(AMBARELLA_CS_TIMER_MATCH1_REG);
		ambarella_timer_pm.timer_cs_match2_reg =
			amba_readl(AMBARELLA_CS_TIMER_MATCH2_REG);
#endif

#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (machine_is_hyacinth_0()) {
		ambarella_timer_pm.timer_ce_status_reg =
			amba_readl(AMBARELLA_CE_TIMER_AXI0_STATUS_REG);
		ambarella_timer_pm.timer_ce_reload_reg =
			amba_readl(AMBARELLA_CE_TIMER_AXI0_RELOAD_REG);
		ambarella_timer_pm.timer_ce_match1_reg =
			amba_readl(AMBARELLA_CE_TIMER_AXI0_MATCH1_REG);
		ambarella_timer_pm.timer_ce_match2_reg =
			amba_readl(AMBARELLA_CE_TIMER_AXI0_MATCH2_REG);
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		ambarella_timer_pm.timer_cs_status_reg =
			amba_readl(AMBARELLA_CS_TIMER_AXI0_STATUS_REG);
		ambarella_timer_pm.timer_cs_reload_reg =
			amba_readl(AMBARELLA_CS_TIMER_AXI0_RELOAD_REG);
		ambarella_timer_pm.timer_cs_match1_reg =
			amba_readl(AMBARELLA_CS_TIMER_AXI0_MATCH1_REG);
		ambarella_timer_pm.timer_cs_match2_reg =
			amba_readl(AMBARELLA_CS_TIMER_AXI0_MATCH2_REG);
#endif
	}
	else if (machine_is_hyacinth_1()) {
		ambarella_timer_pm.timer_ce_status_reg =
			amba_readl(AMBARELLA_CE_TIMER_AXI1_STATUS_REG);
		ambarella_timer_pm.timer_ce_reload_reg =
			amba_readl(AMBARELLA_CE_TIMER_AXI1_RELOAD_REG);
		ambarella_timer_pm.timer_ce_match1_reg =
			amba_readl(AMBARELLA_CE_TIMER_AXI1_MATCH1_REG);
		ambarella_timer_pm.timer_ce_match2_reg =
			amba_readl(AMBARELLA_CE_TIMER_AXI1_MATCH2_REG);
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		ambarella_timer_pm.timer_cs_status_reg =
			amba_readl(AMBARELLA_CS_TIMER_AXI1_STATUS_REG);
		ambarella_timer_pm.timer_cs_reload_reg =
			amba_readl(AMBARELLA_CS_TIMER_AXI1_RELOAD_REG);
		ambarella_timer_pm.timer_cs_match1_reg =
			amba_readl(AMBARELLA_CS_TIMER_AXI1_MATCH1_REG);
		ambarella_timer_pm.timer_cs_match2_reg =
			amba_readl(AMBARELLA_CS_TIMER_AXI1_MATCH2_REG);
#endif
	}
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (level) {
#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
			disable_irq(AMBARELLA_CE_TIMER_IRQ);
			timer_ctr_mask = AMBARELLA_CE_TIMER_CTR_MASK;
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
			timer_ctr_mask |= AMBARELLA_CS_TIMER_CTR_MASK;
#endif
#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
		if (machine_is_hyacinth_0()) {
			disable_irq(AMBARELLA_CE_TIMER_AXI0_IRQ);
			timer_ctr_mask = AMBARELLA_CE_TIMER_AXI0_CTR_MASK;
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
			timer_ctr_mask |= AMBARELLA_CS_TIMER_AXI0_CTR_MASK;
#endif
		}
		else if (machine_is_hyacinth_1()) {
			disable_irq(AMBARELLA_CE_TIMER_AXI1_IRQ);
			timer_ctr_mask = AMBARELLA_CE_TIMER_AXI1_CTR_MASK;
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
			timer_ctr_mask |= AMBARELLA_CS_TIMER_AXI1_CTR_MASK;
#endif
		}
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
		amba_clrbitsl(TIMER_CTR_REG, timer_ctr_mask);
	}

	return 0;
}