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