Exemplo n.º 1
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);
		}
	}
}
Exemplo n.º 2
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
}
Exemplo n.º 3
0
static void serial_ambarella_transmit_chars(struct uart_port *port)
{
	struct circ_buf				*xmit = &port->state->xmit;
	int					count;
	struct ambarella_uart_port_info		*port_info;

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

	if (port->x_char) {
		amba_writel(port->membase + UART_TH_OFFSET, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}

	if (uart_tx_stopped(port) || uart_circ_empty(xmit)) {
		port_info->stop_tx(port->membase);
		return;
	}

	count = port->fifosize;
	while (count-- > 0) {
		amba_writel(port->membase + UART_TH_OFFSET,
			xmit->buf[xmit->tail]);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
		if (uart_circ_empty(xmit))
			break;
	}
	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);
	if (uart_circ_empty(xmit))
		port_info->stop_tx(port->membase);
}
Exemplo n.º 4
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
}
Exemplo n.º 5
0
int __init ambarella_init_fio(void)
{
#ifndef CONFIG_AMBARELLA_QUICK_INIT
	/* Following should be handled by the bootloader... */
#if (HOST_MAX_AHB_CLK_EN_BITS == 10)
	amba_clrbitsl(HOST_AHB_CLK_ENABLE_REG,
		(HOST_AHB_BOOT_SEL | HOST_AHB_FDMA_BURST_DIS));
#endif
	rct_reset_fio();
	fio_amb_exit_random_mode();
	enable_fio_dma();
	amba_writel(FLASH_INT_REG, 0x0);
	amba_writel(XD_INT_REG, 0x0);
	amba_writel(CF_STA_REG, CF_STA_CW | CF_STA_DW);
#endif

	//SMIO_38 ~ SMIO_43
	amba_setbitsl(GPIO2_MASK_REG, 0x000007e0);
	amba_clrbitsl(GPIO2_DIR_REG, 0x00000780);
	amba_setbitsl(GPIO2_DIR_REG, 0x00000060);
	amba_setbitsl(GPIO2_DATA_REG, 0x00000040);
	amba_clrbitsl(GPIO2_DATA_REG, 0x00000020);

	return 0;
}
Exemplo n.º 6
0
static int serial_ambarella_startup(struct uart_port *port)
{
	int					retval = 0;
	struct ambarella_uart_port_info		*port_info;
	unsigned long				flags;

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

	spin_lock_irqsave(&port->lock, flags);
	amba_setbitsl(port->membase + UART_SRR_OFFSET, 0x00);
	amba_writel(port->membase + UART_IE_OFFSET, port_info->ier |
		UART_IE_PTIME);
	amba_writel(port->membase + UART_FC_OFFSET, (port_info->fcr |
		UART_FC_XMITR | UART_FC_RCVRR));
#if defined(CONFIG_PLAT_AMBARELLA_BOSS)
	boss_set_irq_owner(port->irq, BOSS_IRQ_OWNER_LINUX, 0);	
#endif
	/*retval = request_irq(port->irq, serial_ambarella_irq,
		IRQF_TRIGGER_HIGH, dev_name(port->dev), port); */
	amba_writel(port->membase + UART_IE_OFFSET, port_info->ier);
	spin_unlock_irqrestore(&port->lock, flags);
	retval = request_irq(port->irq, serial_ambarella_irq,
		IRQF_TRIGGER_HIGH, dev_name(port->dev), port);

	return retval;
}
Exemplo n.º 7
0
static int ambarella_ce_timer_set_next_event(unsigned long delta,
	struct clock_event_device *dev)
{
#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
	amba_writel(AMBARELLA_CE_TIMER_STATUS_REG, delta);
#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (machine_is_hyacinth_0())
		amba_writel(AMBARELLA_CE_TIMER_AXI0_STATUS_REG, delta);
	else if (machine_is_hyacinth_1())
		amba_writel(AMBARELLA_CE_TIMER_AXI1_STATUS_REG, delta);
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */

	return 0;
}
Exemplo n.º 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);
}
Exemplo n.º 9
0
int __init ambarella_init_fio(void)
{
#if defined(CONFIG_AMBARELLA_FIO_FORCE_SDIO_GPIO)
	unsigned long				flags;

	//SMIO_38 ~ SMIO_43
	ambarella_gpio_raw_lock(2, &flags);
	amba_clrbitsl(GPIO2_AFSEL_REG, 0x000007e0);
	amba_clrbitsl(GPIO2_DIR_REG, 0x00000780);
	amba_setbitsl(GPIO2_DIR_REG, 0x00000060);
	amba_writel(GPIO2_MASK_REG, 0x00000060);
	amba_writel(GPIO2_DATA_REG, 0x00000040);
	ambarella_gpio_raw_unlock(2, &flags);
#endif

	return 0;
}
Exemplo n.º 10
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);
}
Exemplo n.º 11
0
static void serial_ambarella_poll_put_char(struct uart_port *port,
	unsigned char chr)
{
	struct ambarella_uart_port_info		*port_info;

	port_info = (struct ambarella_uart_port_info *)(port->private_data);
	if (!port->suspended) {
		wait_for_tx(port);
		amba_writel(port->membase + UART_TH_OFFSET, chr);
	}
}
Exemplo n.º 12
0
static irqreturn_t ambarella_wdt_irq(int irq, void *devid)
{
	struct ambarella_wdt_info		*pinfo;

	pinfo = (struct ambarella_wdt_info *)devid;

	amba_writel(pinfo->regbase + WDOG_CLR_TMO_OFFSET, 0x01);

	dev_info(pinfo->dev, "Watchdog timer expired!\n");

	return IRQ_HANDLED;
}
Exemplo n.º 13
0
static void ambarella_wdt0_start(u32 mode)
{
	if ((mode & WDOG_CTR_RST_EN) == WDOG_CTR_RST_EN) {
	
		/* Allow the change of WDT_RST_L_REG via APB */  
#if (RCT_SUPPORT_UNL_WDT_RST_ANAPWR == 1)
		amba_writel(ANA_PWR_REG, readl(ANA_PWR_REG) | 0x80);
#endif	

		/* Clear the WDT_RST_L_REG to zero */
#if (RCT_WDT_RESET_VAL == 0)
		amba_writel(WDT_RST_L_REG, RCT_WDT_RESET_VAL);
#else
		amba_writel(WDT_RST_L_REG, 0x1);		
#endif

		/* Not allow the change of WDT_RST_L_REG via APB */
#if (RCT_SUPPORT_UNL_WDT_RST_ANAPWR == 1)
		amba_writel(ANA_PWR_REG, readl(ANA_PWR_REG) & (~0x80));
#endif

		/* Clear software reset bit. */
		amba_writel(SOFT_RESET_REG, 0x2);
	}
	amba_writel(WDOG_CONTROL_REG, mode);
	while(amba_tstbitsl(WDOG_CONTROL_REG, mode) != mode);
}
Exemplo n.º 14
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);
}
Exemplo n.º 15
0
int __init ambarella_init_fio(void)
{

	fio_amb_exit_random_mode();
	enable_fio_dma();
	amba_writel(FLASH_INT_REG, 0x0);
	amba_writel(XD_INT_REG, 0x0);
	amba_writel(CF_STA_REG, CF_STA_CW | CF_STA_DW);
//#if defined(CONFIG_AMBARELLA_FIO_FORCE_SDIO_GPIO)
	unsigned long				flags;

	//SMIO_38 ~ SMIO_43
	ambarella_gpio_raw_lock(2, &flags);
	amba_clrbitsl(GPIO2_AFSEL_REG, 0x000007e0);
	amba_clrbitsl(GPIO2_DIR_REG, 0x00000780);
	amba_setbitsl(GPIO2_DIR_REG, 0x00000060);
	amba_writel(GPIO2_MASK_REG, 0x00000060);
	amba_writel(GPIO2_DATA_REG, 0x00000040);
	ambarella_gpio_raw_unlock(2, &flags);
//#endif

	return 0;
}
Exemplo n.º 16
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);
	}
}
Exemplo n.º 17
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
}
Exemplo n.º 18
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
}
Exemplo n.º 19
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
}
Exemplo n.º 20
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);
}
Exemplo n.º 21
0
static inline void ambarella_ce_timer_set_oneshot(void)
{
#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
	amba_writel(AMBARELLA_CE_TIMER_STATUS_REG, 0x0);
	amba_writel(AMBARELLA_CE_TIMER_RELOAD_REG, 0xffffffff);
	amba_writel(AMBARELLA_CE_TIMER_MATCH1_REG, 0x0);
	amba_writel(AMBARELLA_CE_TIMER_MATCH2_REG, 0x0);
#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (machine_is_hyacinth_0()) {
		amba_writel(AMBARELLA_CE_TIMER_AXI0_STATUS_REG, 0x0);
		amba_writel(AMBARELLA_CE_TIMER_AXI0_RELOAD_REG, 0xffffffff);
		amba_writel(AMBARELLA_CE_TIMER_AXI0_MATCH1_REG, 0x0);
		amba_writel(AMBARELLA_CE_TIMER_AXI0_MATCH2_REG, 0x0);
	}
	else if (machine_is_hyacinth_1()) {
		amba_writel(AMBARELLA_CE_TIMER_AXI1_STATUS_REG, 0x0);
		amba_writel(AMBARELLA_CE_TIMER_AXI1_RELOAD_REG, 0xffffffff);
		amba_writel(AMBARELLA_CE_TIMER_AXI1_MATCH1_REG, 0x0);
		amba_writel(AMBARELLA_CE_TIMER_AXI1_MATCH2_REG, 0x0);
	}
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	ambarella_ce_timer_misc();
}
Exemplo n.º 22
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 */
}
Exemplo n.º 23
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);
}
Exemplo n.º 24
0
static void ambarella_wdt_keepalive(struct ambarella_wdt_info *pinfo)
{
	amba_writel(pinfo->regbase + WDOG_RELOAD_OFFSET, pinfo->tmo);
	amba_writel(pinfo->regbase + WDOG_RESTART_OFFSET, WDT_RESTART_VAL);
}
Exemplo n.º 25
0
static inline void ambarella_cs_timer_init(void)
{
#if defined(CONFIG_PLAT_AMBARELLA_SUPPORT_HAL)
#else
	ambarella_register_clk(&pll_out_core);
	ambarella_register_clk(&pll_out_idsp);
	ambarella_register_clk(&gclk_core);
	ambarella_register_clk(&gclk_ahb);
	ambarella_register_clk(&gclk_apb);
#endif
#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
	amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_CTR_EN);
	amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_CTR_OF);
	amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_CTR_CSL);
	amba_writel(AMBARELLA_CS_TIMER_STATUS_REG, 0xffffffff);
	amba_writel(AMBARELLA_CS_TIMER_RELOAD_REG, 0xffffffff);
	amba_writel(AMBARELLA_CS_TIMER_MATCH1_REG, 0x0);
	amba_writel(AMBARELLA_CS_TIMER_MATCH2_REG, 0x0);
	amba_setbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_CTR_EN);
#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (machine_is_hyacinth_0()) {
		amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_AXI0_CTR_EN);
		amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_AXI0_CTR_OF);
		amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_AXI0_CTR_CSL);
		amba_writel(AMBARELLA_CS_TIMER_AXI0_STATUS_REG, 0xffffffff);
		amba_writel(AMBARELLA_CS_TIMER_AXI0_RELOAD_REG, 0xffffffff);
		amba_writel(AMBARELLA_CS_TIMER_AXI0_MATCH1_REG, 0x0);
		amba_writel(AMBARELLA_CS_TIMER_AXI0_MATCH2_REG, 0x0);
		amba_setbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_AXI0_CTR_EN);
	}
	else if (machine_is_hyacinth_1()) {
		amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_AXI1_CTR_EN);
		amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_AXI1_CTR_OF);
		amba_clrbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_AXI1_CTR_CSL);
		amba_writel(AMBARELLA_CS_TIMER_AXI1_STATUS_REG, 0xffffffff);
		amba_writel(AMBARELLA_CS_TIMER_AXI1_RELOAD_REG, 0xffffffff);
		amba_writel(AMBARELLA_CS_TIMER_AXI1_MATCH1_REG, 0x0);
		amba_writel(AMBARELLA_CS_TIMER_AXI1_MATCH2_REG, 0x0);
		amba_setbitsl(TIMER_CTR_REG, AMBARELLA_CS_TIMER_AXI1_CTR_EN);
	}
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
}
Exemplo n.º 26
0
static void serial_ambarella_console_putchar(struct uart_port *port, int ch)
{
	wait_for_tx(port);
	amba_writel(port->membase + UART_TH_OFFSET, ch);
}
Exemplo n.º 27
0
u32 ambarella_timer_resume(u32 level)
{
	u32					timer_ctr_mask;

#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
		timer_ctr_mask = AMBARELLA_CE_TIMER_CTR_MASK;
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		timer_ctr_mask |= AMBARELLA_CS_TIMER_CTR_MASK;
#endif
		amba_clrbitsl(TIMER_CTR_REG, timer_ctr_mask);
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		amba_writel(AMBARELLA_CS_TIMER_STATUS_REG,
				ambarella_timer_pm.timer_cs_status_reg);
		amba_writel(AMBARELLA_CS_TIMER_RELOAD_REG,
				ambarella_timer_pm.timer_cs_reload_reg);
		amba_writel(AMBARELLA_CS_TIMER_MATCH1_REG,
				ambarella_timer_pm.timer_cs_match1_reg);
		amba_writel(AMBARELLA_CS_TIMER_MATCH2_REG,
				ambarella_timer_pm.timer_cs_match2_reg);
#endif
		if ((ambarella_timer_pm.timer_ce_status_reg == 0) &&
			(ambarella_timer_pm.timer_ce_reload_reg == 0)){
			amba_writel(AMBARELLA_CE_TIMER_STATUS_REG,
					AMBARELLA_TIMER_FREQ / HZ);
		} else {
			amba_writel(AMBARELLA_CE_TIMER_STATUS_REG,
					ambarella_timer_pm.timer_ce_status_reg);
		}
		amba_writel(AMBARELLA_CE_TIMER_RELOAD_REG,
				ambarella_timer_pm.timer_ce_reload_reg);
		amba_writel(AMBARELLA_CE_TIMER_MATCH1_REG,
				ambarella_timer_pm.timer_ce_match1_reg);
		amba_writel(AMBARELLA_CE_TIMER_MATCH2_REG,
				ambarella_timer_pm.timer_ce_match2_reg);
#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (machine_is_hyacinth_0()) {
		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
		amba_clrbitsl(TIMER_CTR_REG, timer_ctr_mask);
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		amba_writel(AMBARELLA_CS_TIMER_AXI0_STATUS_REG,
				ambarella_timer_pm.timer_cs_status_reg);
		amba_writel(AMBARELLA_CS_TIMER_AXI0_RELOAD_REG,
				ambarella_timer_pm.timer_cs_reload_reg);
		amba_writel(AMBARELLA_CS_TIMER_AXI0_MATCH1_REG,
				ambarella_timer_pm.timer_cs_match1_reg);
		amba_writel(AMBARELLA_CS_TIMER_AXI0_MATCH2_REG,
				ambarella_timer_pm.timer_cs_match2_reg);
#endif
		if ((ambarella_timer_pm.timer_ce_status_reg == 0) &&
			(ambarella_timer_pm.timer_ce_reload_reg == 0)){
			amba_writel(AMBARELLA_CE_TIMER_AXI0_STATUS_REG,
					AMBARELLA_TIMER_FREQ / HZ);
		} else {
			amba_writel(AMBARELLA_CE_TIMER_AXI0_STATUS_REG,
					ambarella_timer_pm.timer_ce_status_reg);
		}
		amba_writel(AMBARELLA_CE_TIMER_AXI0_RELOAD_REG,
				ambarella_timer_pm.timer_ce_reload_reg);
		amba_writel(AMBARELLA_CE_TIMER_AXI0_MATCH1_REG,
				ambarella_timer_pm.timer_ce_match1_reg);
		amba_writel(AMBARELLA_CE_TIMER_AXI0_MATCH2_REG,
				ambarella_timer_pm.timer_ce_match2_reg);
	}
	else if (machine_is_hyacinth_1()) {
		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
		amba_clrbitsl(TIMER_CTR_REG, timer_ctr_mask);
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		amba_writel(AMBARELLA_CS_TIMER_AXI1_STATUS_REG,
				ambarella_timer_pm.timer_cs_status_reg);
		amba_writel(AMBARELLA_CS_TIMER_AXI1_RELOAD_REG,
				ambarella_timer_pm.timer_cs_reload_reg);
		amba_writel(AMBARELLA_CS_TIMER_AXI1_MATCH1_REG,
				ambarella_timer_pm.timer_cs_match1_reg);
		amba_writel(AMBARELLA_CS_TIMER_AXI1_MATCH2_REG,
				ambarella_timer_pm.timer_cs_match2_reg);
#endif
		if ((ambarella_timer_pm.timer_ce_status_reg == 0) &&
			(ambarella_timer_pm.timer_ce_reload_reg == 0)){
			amba_writel(AMBARELLA_CE_TIMER_AXI1_STATUS_REG,
					AMBARELLA_TIMER_FREQ / HZ);
		} else {
			amba_writel(AMBARELLA_CE_TIMER_AXI1_STATUS_REG,
					ambarella_timer_pm.timer_ce_status_reg);
		}
		amba_writel(AMBARELLA_CE_TIMER_AXI1_RELOAD_REG,
				ambarella_timer_pm.timer_ce_reload_reg);
		amba_writel(AMBARELLA_CE_TIMER_AXI1_MATCH1_REG,
				ambarella_timer_pm.timer_ce_match1_reg);
		amba_writel(AMBARELLA_CE_TIMER_AXI1_MATCH2_REG,
				ambarella_timer_pm.timer_ce_match2_reg);
	}
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */

	if (ambarella_timer_pm.timer_clk != AMBARELLA_TIMER_FREQ) {
		clockevents_calc_mult_shift(&ambarella_clkevt,
				AMBARELLA_TIMER_FREQ, 5);
		ambarella_clkevt.max_delta_ns =
			clockevent_delta2ns(0xffffffff, &ambarella_clkevt);
		ambarella_clkevt.min_delta_ns =
			clockevent_delta2ns(1, &ambarella_clkevt);
		switch (ambarella_clkevt.mode) {
		case CLOCK_EVT_MODE_PERIODIC:
			ambarella_ce_timer_set_periodic();
			break;
		case CLOCK_EVT_MODE_ONESHOT:
		case CLOCK_EVT_MODE_UNUSED:
		case CLOCK_EVT_MODE_SHUTDOWN:
		case CLOCK_EVT_MODE_RESUME:
			break;
		}

#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		clocksource_change_rating(&ambarella_cs_timer_clksrc, 0);
		ambarella_cs_timer_clksrc.mult = clocksource_hz2mult(
			AMBARELLA_TIMER_FREQ, ambarella_cs_timer_clksrc.shift);
		pr_debug("%s: mult = %u, shift = %u\n",
			ambarella_cs_timer_clksrc.name,
			ambarella_cs_timer_clksrc.mult,
			ambarella_cs_timer_clksrc.shift);
		clocksource_change_rating(&ambarella_cs_timer_clksrc,
			AMBARELLA_TIMER_RATING);
#if defined(CONFIG_HAVE_SCHED_CLOCK)
		setup_sched_clock(ambarella_read_sched_clock,
			32, AMBARELLA_TIMER_FREQ);
#endif
#endif
	}

#if !defined(CONFIG_MACH_HYACINTH_0) && !defined(CONFIG_MACH_HYACINTH_1)
		timer_ctr_mask = AMBARELLA_CE_TIMER_CTR_MASK;
#if defined(CONFIG_AMBARELLA_SUPPORT_CLOCKSOURCE)
		timer_ctr_mask |= AMBARELLA_CS_TIMER_CTR_MASK;
#endif
		amba_setbitsl(TIMER_CTR_REG,
				(ambarella_timer_pm.timer_ctr_reg & timer_ctr_mask));
		if (level)
			enable_irq(AMBARELLA_CE_TIMER_IRQ);
#else /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */
	if (machine_is_hyacinth_0()) {
		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
		amba_setbitsl(TIMER_CTR_REG,
				(ambarella_timer_pm.timer_ctr_reg & timer_ctr_mask));
		if (level)
			enable_irq(AMBARELLA_CE_TIMER_AXI0_IRQ);
	}
	else if (machine_is_hyacinth_1()) {
		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
		amba_setbitsl(TIMER_CTR_REG,
				(ambarella_timer_pm.timer_ctr_reg & timer_ctr_mask));
		if (level)
			enable_irq(AMBARELLA_CE_TIMER_AXI1_IRQ);
	}
#endif /* defined(CONFIG_MACH_HYACINTH_0) || defined(CONFIG_MACH_HYACINTH_1) */

#if defined(CONFIG_SMP)
	//percpu_timer_update_rate(amb_get_axi_clock_frequency(HAL_BASE_VP));
#endif

	return 0;
}
Exemplo n.º 28
0
static void serial_ambarella_set_termios(struct uart_port *port,
	struct ktermios *termios, struct ktermios *old)
{
	struct ambarella_uart_port_info		*port_info;
	unsigned int				baud, quot;
	u32					lc = 0x0;

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

	port->uartclk = port_info->get_pll();
	switch (termios->c_cflag & CSIZE) {
	case CS5:
		lc |= UART_LC_CLS_5_BITS;
		break;
	case CS6:
		lc |= UART_LC_CLS_6_BITS;
		break;
	case CS7:
		lc |= UART_LC_CLS_7_BITS;
		break;
	case CS8:
	default:
		lc |= UART_LC_CLS_8_BITS;
		break;
	}

	if (termios->c_cflag & CSTOPB)
		lc |= UART_LC_STOP_2BIT;
	else
		lc |= UART_LC_STOP_1BIT;

	if (termios->c_cflag & PARENB) {
		if (termios->c_cflag & PARODD)
			lc |= (UART_LC_EPS | UART_LC_ODD_PARITY);
		else
			lc |= (UART_LC_EPS | UART_LC_EVEN_PARITY);
	}

	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
	quot = uart_get_divisor(port, baud);

	disable_irq(port->irq);
	uart_update_timeout(port, termios->c_cflag, baud);

	port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
	if (termios->c_iflag & (BRKINT | PARMRK))
		port->read_status_mask |= UART_LSR_BI;

	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
	if (termios->c_iflag & IGNBRK) {
		port->ignore_status_mask |= UART_LSR_BI;
		if (termios->c_iflag & IGNPAR)
			port->ignore_status_mask |= UART_LSR_OE;
	}
	if ((termios->c_cflag & CREAD) == 0)
		port->ignore_status_mask |= UART_LSR_DR;

	if ((termios->c_cflag & CRTSCTS) == 0)
		port_info->mcr &= ~UART_MC_AFCE;
	else
		port_info->mcr |= UART_MC_AFCE;

	amba_writel(port->membase + UART_LC_OFFSET, UART_LC_DLAB);
	amba_writel(port->membase + UART_DLL_OFFSET, quot & 0xff);
	amba_writel(port->membase + UART_DLH_OFFSET, (quot >> 8) & 0xff);
	amba_writel(port->membase + UART_LC_OFFSET, lc);
	if (UART_ENABLE_MS(port, termios->c_cflag))
		__serial_ambarella_enable_ms(port);
	else
		__serial_ambarella_disable_ms(port);
	serial_ambarella_set_mctrl(port, port->mctrl);

	enable_irq(port->irq);
}