static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; dma_addr_t ptr; snd_pcm_uframes_t offset; if (cpu_is_omap1510()) { offset = prtd->period_index * runtime->period_size; } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { ptr = omap_get_dma_dst_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); } else { ptr = omap_get_dma_src_pos(prtd->dma_ch); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); } if (offset >= runtime->buffer_size) offset = 0; return offset; }
static void __init _omap_map_io(void) { initialized = 1; /* We have to initialize the IO space mapping before we can run * cpu_is_omapxxx() macros. */ iotable_init(omap_io_desc, ARRAY_SIZE(omap_io_desc)); omap_check_revision(); #ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730()) { iotable_init(omap730_io_desc, ARRAY_SIZE(omap730_io_desc)); } #endif #ifdef CONFIG_ARCH_OMAP1510 if (cpu_is_omap1510()) { iotable_init(omap1510_io_desc, ARRAY_SIZE(omap1510_io_desc)); } #endif #if defined(CONFIG_ARCH_OMAP16XX) if (cpu_is_omap1610() || cpu_is_omap1710()) { iotable_init(omap1610_io_desc, ARRAY_SIZE(omap1610_io_desc)); } if (cpu_is_omap5912()) { iotable_init(omap5912_io_desc, ARRAY_SIZE(omap5912_io_desc)); } #endif /* REVISIT: Refer to OMAP5910 Errata, Advisory SYS_1: "Timeout Abort * on a Posted Write in the TIPB Bridge". */ omap_writew(0x0, MPU_PUBLIC_TIPB_CNTL); omap_writew(0x0, MPU_PRIVATE_TIPB_CNTL); /* Must init clocks early to assure that timer interrupt works */ clk_init(); }
/* * Main dma routine, requests dma according where you are in main alsa buffer */ static void audio_process_dma(struct audio_stream *s) { struct snd_pcm_substream *substream = s->stream; struct snd_pcm_runtime *runtime; unsigned int dma_size; unsigned int offset; int ret; ADEBUG(); runtime = substream->runtime; if (s->active) { dma_size = frames_to_bytes(runtime, runtime->period_size); offset = dma_size * s->period; snd_assert(dma_size <= DMA_BUF_SIZE,); /* * On omap1510 based devices, we need to call the stop_dma * before calling the start_dma or we will not receive the * irq from DMA after the first transfered/played buffer. * (invocation of callback_omap_alsa_sound_dma() method). */ if (cpu_is_omap1510()) { omap_stop_alsa_sound_dma(s); } ret = omap_start_alsa_sound_dma(s, (dma_addr_t)runtime->dma_area + offset, dma_size); if (ret) { printk(KERN_ERR "audio_process_dma: cannot queue DMA buffer (%i)\n", ret); return; } s->period++; s->period %= runtime->periods; s->periods++; s->offset = offset; }
static void omap_pcm_dma_irq(int ch, u16 stat, void *data) { struct snd_pcm_substream *substream = data; struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; unsigned long flags; if ((cpu_is_omap1510())) { /* * OMAP1510 doesn't fully support DMA progress counter * and there is no software emulation implemented yet, * so have to maintain our own progress counters * that can be used by omap_pcm_pointer() instead. */ spin_lock_irqsave(&prtd->lock, flags); if ((stat == OMAP_DMA_LAST_IRQ) && (prtd->period_index == runtime->periods - 1)) { /* we are in sync, do nothing */ spin_unlock_irqrestore(&prtd->lock, flags); return; } if (prtd->period_index >= 0) { if (stat & OMAP_DMA_BLOCK_IRQ) { /* end of buffer reached, loop back */ prtd->period_index = 0; } else if (stat & OMAP_DMA_LAST_IRQ) { /* update the counter for the last period */ prtd->period_index = runtime->periods - 1; } else if (++prtd->period_index >= runtime->periods) { /* end of buffer missed? loop back */ prtd->period_index = 0; } } spin_unlock_irqrestore(&prtd->lock, flags); } snd_pcm_period_elapsed(substream); }
static void omap_pcm_dma_irq(int ch, u16 stat, void *data) { struct snd_pcm_substream *substream = data; struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; unsigned long flags; if (cpu_is_omap1510()) { /* * OMAP1510 doesn't support DMA chaining so have to restart * the transfer after all periods are transferred */ spin_lock_irqsave(&prtd->lock, flags); if (prtd->period_index >= 0) { if (++prtd->period_index == runtime->periods) { prtd->period_index = 0; omap_start_dma(prtd->dma_ch); } } spin_unlock_irqrestore(&prtd->lock, flags); } snd_pcm_period_elapsed(substream); }
static int omap_pcm_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; struct omap_pcm_dma_data *dma_data = prtd->dma_data; struct omap_dma_channel_params dma_params; int bytes; /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!prtd->dma_data) return 0; memset(&dma_params, 0, sizeof(dma_params)); dma_params.data_type = dma_data->data_type; dma_params.trigger = dma_data->dma_req; dma_params.sync_mode = dma_data->sync_mode; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dma_params.src_amode = OMAP_DMA_AMODE_POST_INC; dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT; dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC; dma_params.src_start = runtime->dma_addr; dma_params.dst_start = dma_data->port_addr; dma_params.dst_port = OMAP_DMA_PORT_MPUI; dma_params.dst_fi = dma_data->packet_size; } else { dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC; dma_params.src_start = dma_data->port_addr; dma_params.dst_start = runtime->dma_addr; dma_params.src_port = OMAP_DMA_PORT_MPUI; dma_params.src_fi = dma_data->packet_size; } /* * Set DMA transfer frame size equal to ALSA period size and frame * count as no. of ALSA periods. Then with DMA frame interrupt enabled, * we can transfer the whole ALSA buffer with single DMA transfer but * still can get an interrupt at each period bounary */ bytes = snd_pcm_lib_period_bytes(substream); dma_params.elem_count = bytes >> dma_data->data_type; dma_params.frame_count = runtime->periods; omap_set_dma_params(prtd->dma_ch, &dma_params); if ((cpu_is_omap1510())) omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); else if (!substream->runtime->no_period_wakeup) omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); else { /* * No period wakeup: * we need to disable BLOCK_IRQ, which is enabled by the omap * dma core at request dma time. */ omap_disable_dma_irq(prtd->dma_ch, OMAP_DMA_BLOCK_IRQ); } if (!(cpu_class_is_omap1())) { omap_set_dma_src_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16); omap_set_dma_dest_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16); } return 0; }
/* * Note that on Innovator-1510 UART2 pins conflict with USB2. * By default UART2 does not work on Innovator-1510 if you have * USB OHCI enabled. To use UART2, you must disable USB2 first. */ void __init omap_serial_init(void) { int i; const struct omap_uart_config *info; if (cpu_is_omap730()) { serial_platform_data[0].regshift = 0; serial_platform_data[1].regshift = 0; serial_platform_data[0].irq = INT_730_UART_MODEM_1; serial_platform_data[1].irq = INT_730_UART_MODEM_IRDA_2; } if (cpu_is_omap1510()) { serial_platform_data[0].uartclk = OMAP1510_BASE_BAUD * 16; serial_platform_data[1].uartclk = OMAP1510_BASE_BAUD * 16; serial_platform_data[2].uartclk = OMAP1510_BASE_BAUD * 16; } info = omap_get_config(OMAP_TAG_UART, struct omap_uart_config); if (info == NULL) return; for (i = 0; i < OMAP_MAX_NR_PORTS; i++) { unsigned char reg; if (!((1 << i) & info->enabled_uarts)) { serial_platform_data[i].membase = NULL; serial_platform_data[i].mapbase = 0; continue; } switch (i) { case 0: uart1_ck = clk_get(NULL, "uart1_ck"); if (IS_ERR(uart1_ck)) printk("Could not get uart1_ck\n"); else { clk_use(uart1_ck); if (cpu_is_omap1510()) clk_set_rate(uart1_ck, 12000000); } if (cpu_is_omap1510()) { omap_cfg_reg(UART1_TX); omap_cfg_reg(UART1_RTS); if (machine_is_omap_innovator()) { reg = fpga_read(OMAP1510_FPGA_POWER); reg |= OMAP1510_FPGA_PCR_COM1_EN; fpga_write(reg, OMAP1510_FPGA_POWER); udelay(10); } } break; case 1: uart2_ck = clk_get(NULL, "uart2_ck"); if (IS_ERR(uart2_ck)) printk("Could not get uart2_ck\n"); else { clk_use(uart2_ck); if (cpu_is_omap1510()) clk_set_rate(uart2_ck, 12000000); else clk_set_rate(uart2_ck, 48000000); } if (cpu_is_omap1510()) { omap_cfg_reg(UART2_TX); omap_cfg_reg(UART2_RTS); if (machine_is_omap_innovator()) { reg = fpga_read(OMAP1510_FPGA_POWER); reg |= OMAP1510_FPGA_PCR_COM2_EN; fpga_write(reg, OMAP1510_FPGA_POWER); udelay(10); } } break; case 2: uart3_ck = clk_get(NULL, "uart3_ck"); if (IS_ERR(uart3_ck)) printk("Could not get uart3_ck\n"); else { clk_use(uart3_ck); if (cpu_is_omap1510()) clk_set_rate(uart3_ck, 12000000); } if (cpu_is_omap1510()) { omap_cfg_reg(UART3_TX); omap_cfg_reg(UART3_RX); } break; } omap_serial_reset(&serial_platform_data[i]); } }
int __init omap1_clk_init(void) { struct omap_clk *c; int crystal_type = 0; /* Default 12 MHz */ u32 reg; #ifdef CONFIG_DEBUG_LL /* * Resets some clocks that may be left on from bootloader, * but leaves serial clocks on. */ omap_writel(0x3 << 29, MOD_CONF_CTRL_0); #endif /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ reg = omap_readw(SOFT_REQ_REG) & (1 << 4); omap_writew(reg, SOFT_REQ_REG); if (!cpu_is_omap15xx()) omap_writew(0, SOFT_REQ_REG2); /* By default all idlect1 clocks are allowed to idle */ arm_idlect1_mask = ~0; for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) clk_preinit(c->lk.clk); cpu_mask = 0; if (cpu_is_omap1710()) cpu_mask |= CK_1710; if (cpu_is_omap16xx()) cpu_mask |= CK_16XX; if (cpu_is_omap1510()) cpu_mask |= CK_1510; if (cpu_is_omap7xx()) cpu_mask |= CK_7XX; if (cpu_is_omap310()) cpu_mask |= CK_310; for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) if (c->cpu & cpu_mask) { clkdev_add(&c->lk); clk_register(c->lk.clk); } /* Pointers to these clocks are needed by code in clock.c */ api_ck_p = clk_get(NULL, "api_ck"); ck_dpll1_p = clk_get(NULL, "ck_dpll1"); ck_ref_p = clk_get(NULL, "ck_ref"); if (cpu_is_omap7xx()) ck_ref.rate = 13000000; if (cpu_is_omap16xx() && crystal_type == 2) ck_ref.rate = 19200000; pr_info("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: 0x%04x\n", omap_readw(ARM_SYSST), omap_readw(DPLL_CTL), omap_readw(ARM_CKCTL)); /* We want to be in syncronous scalable mode */ omap_writew(0x1000, ARM_SYSST); /* * Initially use the values set by bootloader. Determine PLL rate and * recalculate dependent clocks as if kernel had changed PLL or * divisors. See also omap1_clk_late_init() that can reprogram dpll1 * after the SRAM is initialized. */ { unsigned pll_ctl_val = omap_readw(DPLL_CTL); ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */ if (pll_ctl_val & 0x10) { /* PLL enabled, apply multiplier and divisor */ if (pll_ctl_val & 0xf80) ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7; ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1; } else { /* PLL disabled, apply bypass divisor */ switch (pll_ctl_val & 0xc) { case 0: break; case 0x4: ck_dpll1.rate /= 2; break; default: ck_dpll1.rate /= 4; break; } } }
/*************************************************************************************** * * Sync up the buffers before we shutdown, else under-run errors will happen * **************************************************************************************/ int audio_sync(struct file *file) { audio_state_t *state = file->private_data; audio_stream_t *s = state->output_stream; audio_buf_t *b; u_int shiftval = 0; unsigned long flags; DECLARE_WAITQUEUE(wait, current); FN_IN; if (!(file->f_mode & FMODE_WRITE) || !s->buffers || s->mapped) { FN_OUT(1); return 0; } /* * Send current buffer if it contains data. Be sure to send * a full sample count. */ b = &s->buffers[s->usr_head]; if (b->offset &= ~3) { /* Wait for a buffer to become free */ if (wait_for_completion_interruptible(&s->wfc)) return 0; /* * HACK ALERT ! * To avoid increased complexity in the rest of the code * where full fragment sizes are assumed, we cheat a little * with the start pointer here and don't forget to restore * it later. */ /* As this is a last frag we need only one dma channel * to complete. So it's need to unlink dma channels * to avoid empty dma work. */ if (!cpu_is_omap1510() && AUDIO_QUEUE_EMPTY(s)) omap_sound_dma_unlink_lch(s); shiftval = s->fragsize - b->offset; b->offset = shiftval; b->dma_addr -= shiftval; b->data -= shiftval; local_irq_save(flags); s->bytecount -= shiftval; if (++s->usr_head >= s->nbfrags) s->usr_head = 0; s->pending_frags++; audio_process_dma(s); local_irq_restore(flags); } /* Let's wait for all buffers to complete */ set_current_state(TASK_INTERRUPTIBLE); add_wait_queue(&s->wq, &wait); while ((s->pending_frags || (s->wfc.done < s->nbfrags)) && !signal_pending(current)) { schedule(); set_current_state(TASK_INTERRUPTIBLE); } set_current_state(TASK_RUNNING); remove_wait_queue(&s->wq, &wait); /* undo the pointer hack above */ if (shiftval) { local_irq_save(flags); b->dma_addr += shiftval; b->data += shiftval; /* ensure sane DMA code behavior if not yet processed */ if (b->offset != 0) b->offset = s->fragsize; local_irq_restore(flags); } FN_OUT(0); return 0; }
/** * usb_hcd_omap_probe - initialize OMAP-based HCDs * Context: !in_interrupt() * * Allocates basic resources for this USB host controller, and * then invokes the start() method for the HCD associated with it * through the hotplug entry's driver_data. */ static int usb_hcd_omap_probe (const struct hc_driver *driver, struct platform_device *pdev) { int retval, irq; struct usb_hcd *hcd = 0; struct ohci_hcd *ohci; if (pdev->num_resources != 2) { printk(KERN_ERR "hcd probe: invalid num_resources: %i\n", pdev->num_resources); return -ENODEV; } if (pdev->resource[0].flags != IORESOURCE_MEM || pdev->resource[1].flags != IORESOURCE_IRQ) { printk(KERN_ERR "hcd probe: invalid resource type\n"); return -ENODEV; } usb_host_ck = clk_get(0, "usb_hhc_ck"); if (IS_ERR(usb_host_ck)) return PTR_ERR(usb_host_ck); if (!cpu_is_omap1510()) usb_dc_ck = clk_get(0, "usb_dc_ck"); else usb_dc_ck = clk_get(0, "lb_ck"); if (IS_ERR(usb_dc_ck)) { clk_put(usb_host_ck); return PTR_ERR(usb_dc_ck); } hcd = usb_create_hcd (driver, &pdev->dev, pdev->dev.bus_id); if (!hcd) { retval = -ENOMEM; goto err0; } hcd->rsrc_start = pdev->resource[0].start; hcd->rsrc_len = pdev->resource[0].end - pdev->resource[0].start + 1; if (!request_mem_region(hcd->rsrc_start, hcd->rsrc_len, hcd_name)) { dev_dbg(&pdev->dev, "request_mem_region failed\n"); retval = -EBUSY; goto err1; } hcd->regs = (void __iomem *) (int) IO_ADDRESS(hcd->rsrc_start); ohci = hcd_to_ohci(hcd); ohci_hcd_init(ohci); host_initialized = 0; host_enabled = 1; irq = platform_get_irq(pdev, 0); if (irq < 0) { retval = -ENXIO; goto err2; } retval = usb_add_hcd(hcd, irq, IRQF_DISABLED); if (retval) goto err2; host_initialized = 1; if (!host_enabled) omap_ohci_clock_power(0); return 0; err2: release_mem_region(hcd->rsrc_start, hcd->rsrc_len); err1: usb_put_hcd(hcd); err0: clk_put(usb_dc_ck); clk_put(usb_host_ck); return retval; }
static int ohci_omap_init(struct usb_hcd *hcd) { struct ohci_hcd *ohci = hcd_to_ohci(hcd); struct omap_usb_config *config = hcd->self.controller->platform_data; int need_transceiver = (config->otg != 0); int ret; dev_dbg(hcd->self.controller, "starting USB Controller\n"); if (config->otg) { ohci_to_hcd(ohci)->self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ ohci_to_hcd(ohci)->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_ARCH_OMAP_OTG if (need_transceiver) { ohci->transceiver = otg_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver, &ohci_to_hcd(ohci)->self); dev_dbg(hcd->self.controller, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(hcd->self.controller, "can't find transceiver\n"); return -ENODEV; } } #endif omap_ohci_clock_power(1); if (cpu_is_omap1510()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } if ((ret = ohci_init(ohci)) < 0) return ret; /* board-specific power switching and overcurrent support */ if (machine_is_omap_osk() || machine_is_omap_innovator()) { u32 rh = roothub_a (ohci); /* power switching (ganged by default) */ rh &= ~RH_A_NPS; /* TPS2045 switch for internal transceiver (port 1) */ if (machine_is_omap_osk()) { ohci_to_hcd(ohci)->power_budget = 250; rh &= ~RH_A_NOCP; /* gpio9 for overcurrent detction */ omap_cfg_reg(W8_1610_GPIO9); omap_request_gpio(9); omap_set_gpio_direction(9, 1 /* IN */); /* for paranoia's sake: disable USB.PUEN */ omap_cfg_reg(W4_USB_HIGHZ); } ohci_writel(ohci, rh, &ohci->regs->roothub.a); distrust_firmware = 0; } else if (machine_is_nokia770()) { /* We require a self-powered hub, which should have * plenty of power. */ ohci_to_hcd(ohci)->power_budget = 0; } /* FIXME khubd hub requests should manage power switching */ omap_ohci_transceiver_power(1); /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
/* * Sets the Omap MUX and PULL_DWN registers based on the table */ int __init_or_module omap_cfg_reg(const unsigned long index) { static DEFINE_RAW_SPINLOCK(mux_spin_lock); unsigned long flags; struct pin_config *cfg; unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, pull_orig = 0, pull = 0; unsigned int mask, warn = 0; if (!pin_table) BUG(); if (index >= pin_table_sz) { printk(KERN_ERR "Invalid pin mux index: %lu (%lu)\n", index, pin_table_sz); dump_stack(); return -ENODEV; } cfg = (struct pin_config *)&pin_table[index]; if (cpu_is_omap24xx()) { u8 reg = 0; reg |= cfg->mask & 0x7; if (cfg->pull_val) reg |= OMAP24XX_PULL_ENA; if(cfg->pu_pd_val) reg |= OMAP24XX_PULL_UP; #if defined(CONFIG_OMAP_MUX_DEBUG) || defined(CONFIG_OMAP_MUX_WARNINGS) { u8 orig = omap_readb(OMAP24XX_L4_BASE + cfg->mux_reg); u8 debug = 0; #ifdef CONFIG_OMAP_MUX_DEBUG debug = cfg->debug; #endif warn = (orig != reg); if (debug || warn) printk("MUX: setup %s (0x%08x): 0x%02x -> 0x%02x\n", cfg->name, OMAP24XX_L4_BASE + cfg->mux_reg, orig, reg); } #endif omap_writeb(reg, OMAP24XX_L4_BASE + cfg->mux_reg); return 0; } /* Check the mux register in question */ if (cfg->mux_reg) { unsigned tmp1, tmp2; spin_lock_irqsave(&mux_spin_lock, flags); reg_orig = omap_readl(cfg->mux_reg); /* The mux registers always seem to be 3 bits long */ mask = (0x7 << cfg->mask_offset); tmp1 = reg_orig & mask; reg = reg_orig & ~mask; tmp2 = (cfg->mask << cfg->mask_offset); reg |= tmp2; if (tmp1 != tmp2) warn = 1; omap_writel(reg, cfg->mux_reg); spin_unlock_irqrestore(&mux_spin_lock, flags); } /* Check for pull up or pull down selection on 1610 */ if (!cpu_is_omap1510()) { if (cfg->pu_pd_reg && cfg->pull_val) { spin_lock_irqsave(&mux_spin_lock, flags); pu_pd_orig = omap_readl(cfg->pu_pd_reg); mask = 1 << cfg->pull_bit; if (cfg->pu_pd_val) { if (!(pu_pd_orig & mask)) warn = 1; /* Use pull up */ pu_pd = pu_pd_orig | mask; } else { if (pu_pd_orig & mask) warn = 1; /* Use pull down */ pu_pd = pu_pd_orig & ~mask; } omap_writel(pu_pd, cfg->pu_pd_reg); spin_unlock_irqrestore(&mux_spin_lock, flags); } } /* Check for an associated pull down register */ if (cfg->pull_reg) { spin_lock_irqsave(&mux_spin_lock, flags); pull_orig = omap_readl(cfg->pull_reg); mask = 1 << cfg->pull_bit; if (cfg->pull_val) { if (pull_orig & mask) warn = 1; /* Low bit = pull enabled */ pull = pull_orig & ~mask; } else { if (!(pull_orig & mask)) warn = 1; /* High bit = pull disabled */ pull = pull_orig | mask; } omap_writel(pull, cfg->pull_reg); spin_unlock_irqrestore(&mux_spin_lock, flags); } if (warn) { #ifdef CONFIG_OMAP_MUX_WARNINGS printk(KERN_WARNING "MUX: initialized %s\n", cfg->name); #endif } #ifdef CONFIG_OMAP_MUX_DEBUG if (cfg->debug || warn) { printk("MUX: Setting register %s\n", cfg->name); printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg); if (!cpu_is_omap1510()) { if (cfg->pu_pd_reg && cfg->pull_val) { printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", cfg->pu_pd_name, cfg->pu_pd_reg, pu_pd_orig, pu_pd); } } if (cfg->pull_reg) printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", cfg->pull_name, cfg->pull_reg, pull_orig, pull); } #endif #ifdef CONFIG_OMAP_MUX_ERRORS return warn ? -ETXTBSY : 0; #else return 0; #endif }
/* * Sets the Omap MUX and PULL_DWN registers based on the table */ int __init_or_module omap_cfg_reg(const reg_cfg_t reg_cfg) { static DEFINE_SPINLOCK(mux_spin_lock); unsigned long flags; reg_cfg_set *cfg; unsigned int reg_orig = 0, reg = 0, pu_pd_orig = 0, pu_pd = 0, pull_orig = 0, pull = 0; unsigned int mask, warn = 0; if (reg_cfg > ARRAY_SIZE(reg_cfg_table)) { printk(KERN_ERR "MUX: reg_cfg %d\n", reg_cfg); return -EINVAL; } cfg = ®_cfg_table[reg_cfg]; /* * We do a pretty long section here with lock on, but pin muxing * should only happen on driver init for each driver, so it's not time * critical. */ spin_lock_irqsave(&mux_spin_lock, flags); /* Check the mux register in question */ if (cfg->mux_reg) { unsigned tmp1, tmp2; reg_orig = omap_readl(cfg->mux_reg); /* The mux registers always seem to be 3 bits long */ mask = (0x7 << cfg->mask_offset); tmp1 = reg_orig & mask; reg = reg_orig & ~mask; tmp2 = (cfg->mask << cfg->mask_offset); reg |= tmp2; if (tmp1 != tmp2) warn = 1; omap_writel(reg, cfg->mux_reg); } /* Check for pull up or pull down selection on 1610 */ if (!cpu_is_omap1510()) { if (cfg->pu_pd_reg && cfg->pull_val) { pu_pd_orig = omap_readl(cfg->pu_pd_reg); mask = 1 << cfg->pull_bit; if (cfg->pu_pd_val) { if (!(pu_pd_orig & mask)) warn = 1; /* Use pull up */ pu_pd = pu_pd_orig | mask; } else { if (pu_pd_orig & mask) warn = 1; /* Use pull down */ pu_pd = pu_pd_orig & ~mask; } omap_writel(pu_pd, cfg->pu_pd_reg); } } /* Check for an associated pull down register */ if (cfg->pull_reg) { pull_orig = omap_readl(cfg->pull_reg); mask = 1 << cfg->pull_bit; if (cfg->pull_val) { if (pull_orig & mask) warn = 1; /* Low bit = pull enabled */ pull = pull_orig & ~mask; } else { if (!(pull_orig & mask)) warn = 1; /* High bit = pull disabled */ pull = pull_orig | mask; } omap_writel(pull, cfg->pull_reg); } if (warn) { #ifdef CONFIG_OMAP_MUX_WARNINGS printk(KERN_WARNING "MUX: initialized %s\n", cfg->name); #endif } #ifdef CONFIG_OMAP_MUX_DEBUG if (cfg->debug || warn) { printk("MUX: Setting register %s\n", cfg->name); printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", cfg->mux_reg_name, cfg->mux_reg, reg_orig, reg); if (!cpu_is_omap1510()) { if (cfg->pu_pd_reg && cfg->pull_val) { printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", cfg->pu_pd_name, cfg->pu_pd_reg, pu_pd_orig, pu_pd); } } if (cfg->pull_reg) printk(" %s (0x%08x) = 0x%08x -> 0x%08x\n", cfg->pull_name, cfg->pull_reg, pull_orig, pull); } #endif spin_unlock_irqrestore(&mux_spin_lock, flags); #ifdef CONFIG_OMAP_MUX_ERRORS return warn ? -ETXTBSY : 0; #else return 0; #endif }
int __init omap1_clk_init(void) { struct omap_clk *c; const struct omap_clock_config *info; int crystal_type = 0; /* Default 12 MHz */ u32 reg, cpu_mask; #ifdef CONFIG_DEBUG_LL /* * Resets some clocks that may be left on from bootloader, * but leaves serial clocks on. */ omap_writel(0x3 << 29, MOD_CONF_CTRL_0); #endif /* USB_REQ_EN will be disabled later if necessary (usb_dc_ck) */ reg = omap_readw(SOFT_REQ_REG) & (1 << 4); omap_writew(reg, SOFT_REQ_REG); if (!cpu_is_omap15xx()) omap_writew(0, SOFT_REQ_REG2); clk_init(&omap1_clk_functions); /* By default all idlect1 clocks are allowed to idle */ arm_idlect1_mask = ~0; for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) clk_preinit(c->lk.clk); cpu_mask = 0; if (cpu_is_omap16xx()) cpu_mask |= CK_16XX; if (cpu_is_omap1510()) cpu_mask |= CK_1510; if (cpu_is_omap7xx()) cpu_mask |= CK_7XX; if (cpu_is_omap310()) cpu_mask |= CK_310; for (c = omap_clks; c < omap_clks + ARRAY_SIZE(omap_clks); c++) if (c->cpu & cpu_mask) { clkdev_add(&c->lk); clk_register(c->lk.clk); } /* Pointers to these clocks are needed by code in clock.c */ api_ck_p = clk_get(NULL, "api_ck"); ck_dpll1_p = clk_get(NULL, "ck_dpll1"); ck_ref_p = clk_get(NULL, "ck_ref"); info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config); if (info != NULL) { if (!cpu_is_omap15xx()) crystal_type = info->system_clock_type; } #if defined(CONFIG_ARCH_OMAP730) || defined(CONFIG_ARCH_OMAP850) ck_ref.rate = 13000000; #elif defined(CONFIG_ARCH_OMAP16XX) if (crystal_type == 2) ck_ref.rate = 19200000; #endif pr_info("Clocks: ARM_SYSST: 0x%04x DPLL_CTL: 0x%04x ARM_CKCTL: " "0x%04x\n", omap_readw(ARM_SYSST), omap_readw(DPLL_CTL), omap_readw(ARM_CKCTL)); /* We want to be in syncronous scalable mode */ omap_writew(0x1000, ARM_SYSST); #ifdef CONFIG_OMAP_CLOCKS_SET_BY_BOOTLOADER /* Use values set by bootloader. Determine PLL rate and recalculate * dependent clocks as if kernel had changed PLL or divisors. */ { unsigned pll_ctl_val = omap_readw(DPLL_CTL); ck_dpll1.rate = ck_ref.rate; /* Base xtal rate */ if (pll_ctl_val & 0x10) { /* PLL enabled, apply multiplier and divisor */ if (pll_ctl_val & 0xf80) ck_dpll1.rate *= (pll_ctl_val & 0xf80) >> 7; ck_dpll1.rate /= ((pll_ctl_val & 0x60) >> 5) + 1; } else { /* PLL disabled, apply bypass divisor */ switch (pll_ctl_val & 0xc) { case 0: break; case 0x4: ck_dpll1.rate /= 2; break; default: ck_dpll1.rate /= 4; break; } } }
static int omap_pcm_prepare(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct omap_runtime_data *prtd = runtime->private_data; struct omap_pcm_dma_data *dma_data = prtd->dma_data; struct omap_dma_channel_params dma_params; /* return if this is a bufferless transfer e.g. * codec <--> BT codec or GSM modem -- lg FIXME */ if (!prtd->dma_data) return 0; memset(&dma_params, 0, sizeof(dma_params)); /* * Note: Regardless of interface data formats supported by OMAP McBSP * or EAC blocks, internal representation is always fixed 16-bit/sample */ dma_params.data_type = OMAP_DMA_DATA_TYPE_S16; dma_params.trigger = dma_data->dma_req; dma_params.sync_mode = dma_data->sync_mode; if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { dma_params.src_amode = OMAP_DMA_AMODE_POST_INC; dma_params.dst_amode = OMAP_DMA_AMODE_CONSTANT; dma_params.src_or_dst_synch = OMAP_DMA_DST_SYNC; dma_params.src_start = runtime->dma_addr; dma_params.dst_start = dma_data->port_addr; dma_params.dst_port = OMAP_DMA_PORT_MPUI; } else { dma_params.src_amode = OMAP_DMA_AMODE_CONSTANT; dma_params.dst_amode = OMAP_DMA_AMODE_POST_INC; dma_params.src_or_dst_synch = OMAP_DMA_SRC_SYNC; dma_params.src_start = dma_data->port_addr; dma_params.dst_start = runtime->dma_addr; dma_params.src_port = OMAP_DMA_PORT_MPUI; } /* * Set DMA transfer frame size equal to ALSA period size and frame * count as no. of ALSA periods. Then with DMA frame interrupt enabled, * we can transfer the whole ALSA buffer with single DMA transfer but * still can get an interrupt at each period bounary */ dma_params.elem_count = snd_pcm_lib_period_bytes(substream) / 2; dma_params.frame_count = runtime->periods; omap_set_dma_params(prtd->dma_ch, &dma_params); if ((cpu_is_omap1510()) && (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); else omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ); if (!(cpu_class_is_omap1())) { omap_set_dma_src_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16); omap_set_dma_dest_burst_mode(prtd->dma_ch, OMAP_DMA_DATA_BURST_16); } return 0; }
static int omap_start_hc(struct ohci_hcd *ohci, struct platform_device *pdev) { struct omap_usb_config *config = pdev->dev.platform_data; int need_transceiver = (config->otg != 0); dev_dbg(&pdev->dev, "starting USB Controller\n"); if (config->otg) { ohci->hcd.self.otg_port = config->otg; /* default/minimum OTG power budget: 8 mA */ ohci->power_budget = 8; } /* boards can use OTG transceivers in non-OTG modes */ need_transceiver = need_transceiver || machine_is_omap_h2() || machine_is_omap_h3(); if (cpu_is_omap16xx()) ocpi_enable(); #ifdef CONFIG_ARCH_OMAP_OTG if (need_transceiver) { ohci->transceiver = otg_get_transceiver(); if (ohci->transceiver) { int status = otg_set_host(ohci->transceiver, &ohci->hcd.self); dev_dbg(&pdev->dev, "init %s transceiver, status %d\n", ohci->transceiver->label, status); if (status) { if (ohci->transceiver) put_device(ohci->transceiver->dev); return status; } } else { dev_err(&pdev->dev, "can't find transceiver\n"); return -ENODEV; } } #endif if (machine_is_omap_osk()) { omap_request_gpio(9); omap_set_gpio_direction(9, 1); omap_set_gpio_dataout(9, 1); } omap_ohci_clock_power(1); omap_ohci_transceiver_power(1); if (cpu_is_omap1510()) { omap_1510_local_bus_power(1); omap_1510_local_bus_init(); } /* board init will have already handled HMC and mux setup. * any external transceiver should already be initialized * too, so all configured ports use the right signaling now. */ return 0; }
void __init omap_init_irq(void) { int i, j; #ifdef CONFIG_ARCH_OMAP730 if (cpu_is_omap730()) { irq_banks = omap730_irq_banks; irq_bank_count = ARRAY_SIZE(omap730_irq_banks); } #endif #ifdef CONFIG_ARCH_OMAP15XX if (cpu_is_omap1510()) { irq_banks = omap1510_irq_banks; irq_bank_count = ARRAY_SIZE(omap1510_irq_banks); } if (cpu_is_omap310()) { irq_banks = omap310_irq_banks; irq_bank_count = ARRAY_SIZE(omap310_irq_banks); } #endif #if defined(CONFIG_ARCH_OMAP16XX) if (cpu_is_omap16xx()) { irq_banks = omap1610_irq_banks; irq_bank_count = ARRAY_SIZE(omap1610_irq_banks); } #endif printk("Total of %i interrupts in %i interrupt banks\n", irq_bank_count * 32, irq_bank_count); /* Mask and clear all interrupts */ for (i = 0; i < irq_bank_count; i++) { irq_bank_writel(~0x0, i, IRQ_MIR_REG_OFFSET); irq_bank_writel(0x0, i, IRQ_ITR_REG_OFFSET); } /* Clear any pending interrupts */ irq_bank_writel(0x03, 0, IRQ_CONTROL_REG_OFFSET); irq_bank_writel(0x03, 1, IRQ_CONTROL_REG_OFFSET); /* Enable interrupts in global mask */ if (cpu_is_omap730()) { irq_bank_writel(0x0, 0, IRQ_GMR_REG_OFFSET); } /* Install the interrupt handlers for each bank */ for (i = 0; i < irq_bank_count; i++) { for (j = i * 32; j < (i + 1) * 32; j++) { int irq_trigger; irq_trigger = irq_banks[i].trigger_map >> IRQ_BIT(j); omap_irq_set_cfg(j, 0, 0, irq_trigger); set_irq_chip(j, &omap_irq_chip); set_irq_handler(j, handle_level_irq); set_irq_flags(j, IRQF_VALID); } } /* Unmask level 2 handler */ if (cpu_is_omap730()) omap_unmask_irq(INT_730_IH2_IRQ); else if (cpu_is_omap15xx()) omap_unmask_irq(INT_1510_IH2_IRQ); else if (cpu_is_omap16xx()) omap_unmask_irq(INT_1610_IH2_IRQ); }
int __init init_ck(void) { const struct omap_clock_info *info; int crystal_type = 0; /* Default 12 MHz */ __ck_make_lookup_table(); info = omap_get_per_info(OMAP_TAG_CLOCK, struct omap_clock_info); if (info != NULL) { if (!cpu_is_omap1510()) crystal_type = info->system_clock_type; } /* We want to be in syncronous scalable mode */ omap_writew(0x1000, ARM_SYSST); #if defined(CONFIG_OMAP_ARM_30MHZ) omap_writew(0x1555, ARM_CKCTL); omap_writew(0x2290, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_60MHZ) omap_writew(0x1005, ARM_CKCTL); omap_writew(0x2290, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_96MHZ) omap_writew(0x1005, ARM_CKCTL); omap_writew(0x2410, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_120MHZ) omap_writew(0x110a, ARM_CKCTL); omap_writew(0x2510, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_168MHZ) omap_writew(0x110f, ARM_CKCTL); omap_writew(0x2710, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730) omap_writew(0x250E, ARM_CKCTL); omap_writew(0x2710, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912)) omap_writew(0x150f, ARM_CKCTL); if (crystal_type == 2) { source_clock = 13; /* MHz */ omap_writew(0x2510, DPLL_CTL); } else omap_writew(0x2810, DPLL_CTL); #elif defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730) omap_writew(0x250E, ARM_CKCTL); omap_writew(0x2790, DPLL_CTL); #else #error "OMAP MHZ not set, please run make xconfig" #endif #ifdef CONFIG_MACH_OMAP_PERSEUS2 /* Select slicer output as OMAP input clock */ omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL); #endif /* Turn off some other junk the bootloader might have turned on */ /* Turn off DSP, ARM_INTHCK, ARM_TIMXO */ omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL); /* Put DSP/MPUI into reset until needed */ omap_writew(0, ARM_RSTCT1); omap_writew(1, ARM_RSTCT2); omap_writew(0x400, ARM_IDLECT1); /* * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8) * of the ARM_IDLECT2 register must be set to zero. The power-on * default value of this bit is one. */ omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */ /* * Only enable those clocks we will need, let the drivers * enable other clocks as necessary */ ck_enable(OMAP_MPUPER_CK); ck_enable(OMAP_ARM_GPIO_CK); ck_enable(OMAP_MPUXOR_CK); //ck_set_rate(OMAP_MPUTIM_CK, OMAP_CLKIN); ck_enable(OMAP_MPUTIM_CK); start_mputimer1(0xffffffff); return 0; }