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); } } }
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 }
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); }
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 }
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; }
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; }
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; }
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); }
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; }
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); }
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); } }
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; }
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); }
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); }
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; }
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); } }
/* ==========================================================================*/ 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 }
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 }
/* ==========================================================================*/ 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 }
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); }
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(); }
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 */ }
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); }
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); }
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) */ }
static void serial_ambarella_console_putchar(struct uart_port *port, int ch) { wait_for_tx(port); amba_writel(port->membase + UART_TH_OFFSET, ch); }
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; }
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); }