static int __init osk_soc_init(void) { int err; u32 curRate; struct device *dev; if (!(machine_is_omap_osk())) return -ENODEV; osk_snd_device = platform_device_alloc("soc-audio", -1); if (!osk_snd_device) return -ENOMEM; platform_set_drvdata(osk_snd_device, &osk_snd_devdata); osk_snd_devdata.dev = &osk_snd_device->dev; *(unsigned int *)osk_dai.cpu_dai->private_data = 0; /* McBSP1 */ err = platform_device_add(osk_snd_device); if (err) goto err1; dev = &osk_snd_device->dev; tlv320aic23_mclk = clk_get(dev, "mclk"); if (IS_ERR(tlv320aic23_mclk)) { printk(KERN_ERR "Could not get mclk clock\n"); return -ENODEV; } if (clk_get_usecount(tlv320aic23_mclk) > 0) { /* MCLK is already in use */ printk(KERN_WARNING "MCLK in use at %d Hz. We change it to %d Hz\n", (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK); } /* * Configure 12 MHz output on MCLK. */ curRate = (uint) clk_get_rate(tlv320aic23_mclk); if (curRate != CODEC_CLOCK) { if (clk_set_rate(tlv320aic23_mclk, CODEC_CLOCK)) { printk(KERN_ERR "Cannot set MCLK for AIC23 CODEC\n"); err = -ECANCELED; goto err1; } } printk(KERN_INFO "MCLK = %d [%d], usecount = %d\n", (uint) clk_get_rate(tlv320aic23_mclk), CODEC_CLOCK, clk_get_usecount(tlv320aic23_mclk)); return 0; err1: clk_put(tlv320aic23_mclk); platform_device_del(osk_snd_device); platform_device_put(osk_snd_device); return err; }
int low_freq_bus_used(void) { if ((clk_get_usecount(ipu_clk) == 0) && (clk_get_usecount(vpu_clk) == 0)) return 1; else return 0; }
int low_freq_used(void) { if ((clk_get_usecount(usb_clk) == 0) && (clk_get_usecount(lcdif_clk) == 0)) return 1; else return 0; }
int is_hclk_autoslow_ok(void) { if ((clk_get_usecount(usb_clk0) == 0) && (clk_get_usecount(usb_clk1) == 0)) return 1; else return 0; }
int is_hclk_autoslow_ok(void) { if (clk_get_usecount(usb_clk) == 0) return 1; else return 0; }
static int imx_ssi_startup(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct imx_ssi *priv = (struct imx_ssi *)cpu_dai->private_data; void __iomem *ioaddr = priv->ioaddr; /* we cant really change any SSI values after SSI is enabled * need to fix in software for max flexibility - lrg */ if (cpu_dai->playback.active || cpu_dai->capture.active) return 0; /* reset the SSI port - Sect 45.4.4 */ if (clk_get_usecount(priv->ssi_clk) != 0) { clk_enable(priv->ssi_clk); return 0; } __raw_writel(0, ioaddr + SSI_SCR); clk_enable(priv->ssi_clk); /* BIG FAT WARNING * SDMA FIFO watermark must == SSI FIFO watermark for best results. */ __raw_writel((SSI_SFCSR_RFWM1(SSI_RXFIFO_WATERMARK) | SSI_SFCSR_RFWM0(SSI_RXFIFO_WATERMARK) | SSI_SFCSR_TFWM1(SSI_TXFIFO_WATERMARK) | SSI_SFCSR_TFWM0(SSI_TXFIFO_WATERMARK)), ioaddr + SSI_SFCSR); __raw_writel(0, ioaddr + SSI_SIER); SSI_DUMP(); return 0; }
/* * sysfs interface to CPU idle counts */ static ssize_t sysfs_show_idle_count(struct sys_device *dev, char *buf) { char *curr = buf; curr += sprintf(curr, "sdma_clk usecount: %d\n", clk_get_usecount(sdma_clk)); curr += sprintf(curr, "usb_ahb_clk usecount: %d\n", clk_get_usecount(usb_ahb_clk)); curr += sprintf(curr, "emi_clk_gating_count: %d\n", emi_zero_count); curr += sprintf(curr, "ipu_clk usecount: %d\n", clk_get_usecount(ipu_clk)); // curr += sprintf(curr, "Internal SD DMA: %d\n", sd_turn_of_dma); curr += sprintf(curr, "peri_pll_zero_count: %d\n", peri_pll_zero); curr += sprintf(curr, "emi_clk: %d\n", clk_get_usecount(emi_clk)); curr += sprintf(curr, "idle_time: %llu us\n", get_cpu_idle_time(0)); curr += sprintf(curr, "\n"); return curr - buf; }
void setup_pll(void) { u32 reg; u32 hfsm; struct cpu_wp *p; /* Setup the DPLL registers */ hfsm = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CTL) & MXC_PLL_DP_CTL_HFSM; reg = __raw_readl(MXC_DPLL1_BASE + MXC_PLL_DP_CONFIG); reg &= ~MXC_PLL_DP_CONFIG_AREN; __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_CONFIG); if (hfsm) { /* Running at lower frequency, need to bump up. */ p = &cpu_wp_tbl[0]; /* PDF and MFI */ reg = p->pdf | p->mfi << MXC_PLL_DP_OP_MFI_OFFSET; __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_OP); /* MFD */ __raw_writel(p->mfd, MXC_DPLL1_BASE + MXC_PLL_DP_MFD); /* MFI */ __raw_writel(p->mfn, MXC_DPLL1_BASE + MXC_PLL_DP_MFN); } else { /* Running at high frequency, need to lower it. */ p = &cpu_wp_tbl[1]; /* PDF and MFI */ reg = p->pdf | p->mfi << MXC_PLL_DP_OP_MFI_OFFSET; __raw_writel(reg, MXC_DPLL1_BASE + MXC_PLL_DP_HFS_OP); /* MFD */ __raw_writel(p->mfd, MXC_DPLL1_BASE + MXC_PLL_DP_HFS_MFD); /* MFN */ __raw_writel(p->mfn, MXC_DPLL1_BASE + MXC_PLL_DP_HFS_MFN); } if (clk_get_usecount(pll2) != 0) { /* Set the temporal frequency to be PLL2 */ /* Set PLL2_PODF to be 3. */ reg = __raw_readl(MXC_CCM_CCSR); reg |= 2 << MXC_CCM_CCSR_PLL2_PODF_OFFSET; __raw_writel(reg, MXC_CCM_CCSR); /* Set the parent of STEP_CLK to be PLL2 */ reg = __raw_readl(MXC_CCM_CCSR); reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) | (2 << MXC_CCM_CCSR_STEP_SEL_OFFSET); __raw_writel(reg, MXC_CCM_CCSR); } else { /* Set the temporal frequency to be lp-apm */ /* Set the parent of STEP_CLK to be lp-apm */ reg = __raw_readl(MXC_CCM_CCSR); reg = (reg & ~MXC_CCM_CCSR_STEP_SEL_MASK) | (0 << MXC_CCM_CCSR_STEP_SEL_OFFSET); __raw_writel(reg, MXC_CCM_CCSR); } }
/*! * This function puts the CPU into idle mode. It is called by default_idle() * in process.c file. */ void arch_idle(void) { if (likely(!mxc_jtag_enabled)) { if (ddr_clk == NULL) ddr_clk = clk_get(NULL, "ddr_clk"); if (gpc_dvfs_clk == NULL) gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk"); /* gpc clock is needed for SRPG */ clk_enable(gpc_dvfs_clk); mxc_cpu_lp_set(arch_idle_mode); if (cpu_is_mx50() && (clk_get_usecount(ddr_clk) == 0)) { memcpy(wait_in_iram_base, mx50_wait, SZ_4K); wait_in_iram = (void *)wait_in_iram_base; if (low_bus_freq_mode) { u32 reg, cpu_podf; reg = __raw_readl(apll_base + 0x50); reg = 0x120490; __raw_writel(reg, apll_base + 0x50); reg = __raw_readl(apll_base + 0x80); reg |= 1; __raw_writel(reg, apll_base + 0x80); /* Move ARM to be sourced from 24MHz XTAL. * when ARM is in WFI. */ if (pll1_sw_clk == NULL) pll1_sw_clk = clk_get(NULL, "pll1_sw_clk"); if (osc == NULL) osc = clk_get(NULL, "lp_apm"); if (pll1_main_clk == NULL) pll1_main_clk = clk_get(NULL, "pll1_main_clk"); clk_set_parent(pll1_sw_clk, osc); /* Set the ARM-PODF divider to 1. */ cpu_podf = __raw_readl(MXC_CCM_CACRR); __raw_writel(0x01, MXC_CCM_CACRR); wait_in_iram(ccm_base, databahn_base); /* Set the ARM-POD divider back * to the original. */ __raw_writel(cpu_podf, MXC_CCM_CACRR); clk_set_parent(pll1_sw_clk, pll1_main_clk); } else wait_in_iram(ccm_base, databahn_base); } else cpu_do_idle(); clk_disable(gpc_dvfs_clk); clk_put(ddr_clk); } }
static void usbotg_clock_gate(bool on) { pr_debug("%s: on is %d\n", __func__, on); if (on) { clk_enable(usb_oh3_clk); clk_enable(usb_phy1_clk); } else { clk_disable(usb_phy1_clk); clk_disable(usb_oh3_clk); } pr_debug("usb_oh3_clk:%d, usb_phy_clk1_ref_count:%d\n", clk_get_usecount(usb_oh3_clk), clk_get_usecount(usb_phy1_clk)); }
/* * Do some sanity check, set clock rate, starts it and turn codec audio on */ int tsc2101_clock_on(void) { int curUseCount; uint curRate; int err; curUseCount = clk_get_usecount(tsc2101_mclk); DPRINTK("clock use count = %d\n", curUseCount); if (curUseCount > 0) { // MCLK is already in use printk(KERN_WARNING "MCLK already in use at %d Hz. We change it to %d Hz\n", (uint) clk_get_rate(tsc2101_mclk), CODEC_CLOCK); } curRate = (uint)clk_get_rate(tsc2101_mclk); if (curRate != CODEC_CLOCK) { err = clk_set_rate(tsc2101_mclk, CODEC_CLOCK); if (err) { printk(KERN_WARNING "Cannot set MCLK clock rate for TSC2101 CODEC, error code = %d\n", err); return -ECANCELED; } } err = clk_enable(tsc2101_mclk); curRate = (uint)clk_get_rate(tsc2101_mclk); curUseCount = clk_get_usecount(tsc2101_mclk); DPRINTK("MCLK = %d [%d], usecount = %d, clk_enable retval = %d\n", curRate, CODEC_CLOCK, curUseCount, err); // Now turn the audio on omap_tsc2101_write(PAGE2_AUDIO_CODEC_REGISTERS, TSC2101_CODEC_POWER_CTRL, 0x0000); return 0; }
void enter_lpapm_mode_mx51() { u32 reg; /* Set PLL3 to 133Mhz if no-one is using it. */ if (clk_get_usecount(pll3) == 0) { u32 pll3_rate = clk_get_rate(pll3); clk_enable(pll3); clk_set_rate(pll3, clk_round_rate(pll3, 133000000)); /*Change the DDR freq to 133Mhz. */ clk_set_rate(ddr_hf_clk, clk_round_rate(ddr_hf_clk, ddr_low_rate)); /* Set the parent of Periph_apm_clk to be PLL3 */ clk_set_parent(periph_apm_clk, pll3); clk_set_parent(main_bus_clk, periph_apm_clk); /* Set the dividers to be 1, so the clock rates * are at 133MHz. */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MXC_CCM_CBCDR_EMI_PODF_MASK | MXC_CCM_CBCDR_NFC_PODF_OFFSET); reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET | 0 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET | 0 << MXC_CCM_CBCDR_AHB_PODF_OFFSET | 0 << MXC_CCM_CBCDR_EMI_PODF_OFFSET | 3 << MXC_CCM_CBCDR_NFC_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); clk_enable(emi_garb_clk); while (__raw_readl(MXC_CCM_CDHIPR) & 0x1F) udelay(10); clk_disable(emi_garb_clk); low_bus_freq_mode = 1; high_bus_freq_mode = 0; med_bus_freq_mode = 0; /* Set the source of Periph_APM_Clock to be lp-apm. */ clk_set_parent(periph_apm_clk, lp_apm); /* Set PLL3 back to original rate. */ clk_set_rate(pll3, clk_round_rate(pll3, pll3_rate)); clk_disable(pll3); } }
static int omap2_can_sleep(void) { if (!enable_dyn_sleep) return 0; if (omap2_fclks_active()) return 0; if (atomic_read(&sleep_block) > 0) return 0; if (clk_get_usecount(osc_ck) > 1) return 0; if (omap_dma_running()) return 0; return 1; }
static void serial_console_sleep(int enable) { if (console_iclk == NULL || console_fclk == NULL) return; if (enable) { BUG_ON(serial_console_clock_disabled); if (clk_get_usecount(console_fclk) == 0) return; if ((int) serial_console_next_disable - (int) omap2_read_32k_sync_counter() >= 0) return; serial_wait_tx(); clk_disable(console_iclk); clk_disable(console_fclk); serial_console_clock_disabled = 1; } else { int serial_wakeup = 0; u32 l; switch (serial_console_uart) { case 1: l = prm_read_mod_reg(CORE_MOD, PM_WKST1); if (l & OMAP24XX_ST_UART1) serial_wakeup = 1; break; case 2: l = prm_read_mod_reg(CORE_MOD, PM_WKST1); if (l & OMAP24XX_ST_UART2) serial_wakeup = 1; break; case 3: l = prm_read_mod_reg(CORE_MOD, OMAP24XX_PM_WKST2); if (l & OMAP24XX_ST_UART3) serial_wakeup = 1; break; } if (serial_wakeup) serial_console_kick(); if (!serial_console_clock_disabled) return; clk_enable(console_iclk); clk_enable(console_fclk); serial_console_clock_disabled = 0; } }
s32 CLK_Get_UseCnt(IN enum SERVICES_ClkId clk_id) { DSP_STATUS status = DSP_SOK; struct clk *pClk; s32 useCount = -1; DBC_Require(clk_id < SERVICESCLK_NOT_DEFINED); pClk = SERVICES_Clks[clk_id].clk_handle; if (pClk) { useCount = clk_get_usecount(pClk); } else { GT_2trace(CLK_debugMask, GT_7CLASS, "CLK_GetRate: failed to get CLK %s, " "CLK dev Id = %d\n", SERVICES_Clks[clk_id].clk_name, SERVICES_Clks[clk_id].id); status = DSP_EFAIL; } return useCount; }
static void imx_ssi_shutdown(struct snd_pcm_substream *substream, struct snd_soc_dai *cpu_dai) { struct imx_ssi *priv = (struct imx_ssi *)cpu_dai->private_data; void __iomem *ioaddr = priv->ioaddr; int id; id = cpu_dai->id; /* shutdown SSI if neither Tx or Rx is active */ if (cpu_dai->playback.active || cpu_dai->capture.active) return; if (clk_get_usecount(priv->ssi_clk) > 1) { clk_disable(priv->ssi_clk); return; } __raw_writel(0, ioaddr + SSI_SCR); clk_disable(priv->ssi_clk); }
unsigned int hdmi_irq_disable(int irq) { unsigned long flags; spin_lock_irqsave(&irq_spinlock, flags); WARN_ON (irq_enable_cnt == 0); irq_enable_cnt--; /* Only disable HDMI IRQ if IAHB clk is off */ if ((irq_enable_cnt == 0) && (clk_get_usecount(iahb_clk) == 0)) { disable_irq_nosync(irq); irq_enabled = false; spin_unlock_irqrestore(&irq_spinlock, flags); return IRQ_DISABLE_SUCCEED; } spin_unlock_irqrestore(&irq_spinlock, flags); return IRQ_DISABLE_FAIL; }
/* * Do some sanity check, turn clock off and then turn codec audio off */ int tsc2101_clock_off(void) { int curUseCount; int curRate; curUseCount = clk_get_usecount(tsc2101_mclk); DPRINTK("clock use count = %d\n", curUseCount); if (curUseCount > 0) { curRate = clk_get_rate(tsc2101_mclk); DPRINTK("clock rate = %d\n", curRate); if (curRate != CODEC_CLOCK) { printk(KERN_WARNING "MCLK for audio should be %d Hz. But is %d Hz\n", (uint) clk_get_rate(tsc2101_mclk), CODEC_CLOCK); } clk_disable(tsc2101_mclk); DPRINTK("clock disabled\n"); } tsc2101_audio_write(TSC2101_CODEC_POWER_CTRL, ~(CPC_SP1PWDN | CPC_SP2PWDN | CPC_BASSBC)); DPRINTK("audio codec off\n"); return 0; }
static void ldb_enable(int ipu_di) { uint32_t reg; spin_lock(&ldb_lock); reg = __raw_readl(ldb.control_reg); switch (ldb.chan_mode_opt) { case LDB_SIN_DI0: if (ldb.ch_working[0] || ipu_di != 0) { spin_unlock(&ldb_lock); return; } ldb.ldb_di_clk[0] = clk_get(g_ldb_dev, "ldb_di0_clk"); if (clk_get_usecount(ldb.ldb_di_clk[0]) == 0) clk_enable(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[0]); __raw_writel((reg & ~LDB_CH0_MODE_MASK) | LDB_CH0_MODE_EN_TO_DI0, ldb.control_reg); ldb.ch_working[0] = true; break; case LDB_SIN_DI1: if (ldb.ch_working[1] || ipu_di != 1) { spin_unlock(&ldb_lock); return; } ldb.ldb_di_clk[1] = clk_get(g_ldb_dev, "ldb_di1_clk"); if (clk_get_usecount(ldb.ldb_di_clk[1]) == 0) clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[1]); __raw_writel((reg & ~LDB_CH1_MODE_MASK) | LDB_CH1_MODE_EN_TO_DI1, ldb.control_reg); ldb.ch_working[1] = true; break; case LDB_SEP: if (ldb.ch_working[ipu_di]) { spin_unlock(&ldb_lock); return; } if (ipu_di == 0) { ldb.ldb_di_clk[0] = clk_get(g_ldb_dev, "ldb_di0_clk"); if (clk_get_usecount(ldb.ldb_di_clk[0]) == 0) clk_enable(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[0]); __raw_writel((reg & ~LDB_CH0_MODE_MASK) | LDB_CH0_MODE_EN_TO_DI0, ldb.control_reg); ldb.ch_working[0] = true; } else { ldb.ldb_di_clk[1] = clk_get(g_ldb_dev, "ldb_di1_clk"); if (clk_get_usecount(ldb.ldb_di_clk[1]) == 0) clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[1]); __raw_writel((reg & ~LDB_CH1_MODE_MASK) | LDB_CH1_MODE_EN_TO_DI1, ldb.control_reg); ldb.ch_working[1] = true; } break; case LDB_DUL_DI0: case LDB_SPL_DI0: if (ipu_di != 0) return; else goto proc; case LDB_DUL_DI1: case LDB_SPL_DI1: if (ipu_di != 1) return; proc: if (ldb.ch_working[0] || ldb.ch_working[1]) { spin_unlock(&ldb_lock); return; } ldb.ldb_di_clk[0] = clk_get(g_ldb_dev, "ldb_di0_clk"); ldb.ldb_di_clk[1] = clk_get(g_ldb_dev, "ldb_di1_clk"); if (clk_get_usecount(ldb.ldb_di_clk[0]) == 0) clk_enable(ldb.ldb_di_clk[0]); if (clk_get_usecount(ldb.ldb_di_clk[1]) == 0) clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[1]); if (ldb.chan_mode_opt == LDB_DUL_DI0 || ldb.chan_mode_opt == LDB_SPL_DI0) { __raw_writel((reg & ~LDB_CH0_MODE_MASK) | LDB_CH0_MODE_EN_TO_DI0, ldb.control_reg); reg = __raw_readl(ldb.control_reg); __raw_writel((reg & ~LDB_CH1_MODE_MASK) | LDB_CH1_MODE_EN_TO_DI0, ldb.control_reg); } else if (ldb.chan_mode_opt == LDB_DUL_DI1 || ldb.chan_mode_opt == LDB_SPL_DI1) { __raw_writel((reg & ~LDB_CH0_MODE_MASK) | LDB_CH0_MODE_EN_TO_DI1, ldb.control_reg); reg = __raw_readl(ldb.control_reg); __raw_writel((reg & ~LDB_CH1_MODE_MASK) | LDB_CH1_MODE_EN_TO_DI1, ldb.control_reg); } if (ldb.chan_mode_opt == LDB_SPL_DI0 || ldb.chan_mode_opt == LDB_SPL_DI1) { reg = __raw_readl(ldb.control_reg); __raw_writel(reg | LDB_SPLIT_MODE_EN, ldb.control_reg); } ldb.ch_working[0] = true; ldb.ch_working[1] = true; break; default: break; } spin_unlock(&ldb_lock); return; }
void enter_lpapm_mode_mx53() { u32 reg; struct timespec nstimeofday; struct timespec curtime; /* TBD: Reduce DDR frequency for DDR2 */ /* if (mx53_ddr_type == DDR_TYPE_DDR2) { } */ /* move cpu clk to pll2, 400 / 1 = 400MHZ for cpu */ /* Change the source of pll1_sw_clk to be the step_clk */ reg = __raw_readl(MXC_CCM_CCSR); reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; __raw_writel(reg, MXC_CCM_CCSR); cpu_podf = __raw_readl(MXC_CCM_CACRR); reg = __raw_readl(MXC_CCM_CDHIPR); while (1) { if ((reg & MXC_CCM_CDHIPR_ARM_PODF_BUSY) == 0) { __raw_writel(0x0, MXC_CCM_CACRR); break; } else { reg = __raw_readl(MXC_CCM_CDHIPR); printk(KERN_DEBUG "ARM_PODF still in busy!!!!\n"); } } clk_set_parent(pll1_sw_clk, pll2); /* ahb = pll2/8, axi_b = pll2/8, axi_a = pll2/1*/ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK); reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET | 7 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET | 7 << MXC_CCM_CBCDR_AHB_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); getnstimeofday(&nstimeofday); while (__raw_readl(MXC_CCM_CDHIPR) & (MXC_CCM_CDHIPR_AXI_A_PODF_BUSY | MXC_CCM_CDHIPR_AXI_B_PODF_BUSY | MXC_CCM_CDHIPR_AHB_PODF_BUSY)) { getnstimeofday(&curtime); if (curtime.tv_nsec - nstimeofday.tv_nsec > SPIN_DELAY) panic("low bus freq set rate error\n"); } /* keep this infront of propagating */ low_bus_freq_mode = 1; high_bus_freq_mode = 0; med_bus_freq_mode = 0; if (clk_get_usecount(pll1) == 0) { reg = __raw_readl(pll1_base + MXC_PLL_DP_CTL); reg &= ~MXC_PLL_DP_CTL_UPEN; __raw_writel(reg, pll1_base + MXC_PLL_DP_CTL); } if (clk_get_usecount(pll4) == 0) { reg = __raw_readl(pll4_base + MXC_PLL_DP_CTL); reg &= ~MXC_PLL_DP_CTL_UPEN; __raw_writel(reg, pll4_base + MXC_PLL_DP_CTL); } }
void exit_lpapm_mode_mx50(int high_bus_freq) { u32 reg; unsigned long flags; if (clk_get_usecount(pll1_sw_clk) == 1) { /* Relock PLL1 to 800MHz. */ clk_set_parent(pll1_sw_clk, pll2); /* Set the divider to ARM_PODF to 3, cpu is at 160MHz. */ __raw_writel(0x02, MXC_CCM_CACRR); clk_set_rate(pll1, cpu_wp_tbl[0].pll_rate); /* Set the divider to ARM_PODF to 5 before * switching the parent. */ __raw_writel(0x4, MXC_CCM_CACRR); clk_set_parent(pll1_sw_clk, pll1); } if (!completion_done(&voltage_change_cmpl)) wait_for_completion_interruptible(&voltage_change_cmpl); spin_lock_irqsave(&voltage_lock, flags); if (lp_voltage != LP_NORMAL_VOLTAGE) { INIT_COMPLETION(voltage_change_cmpl); lp_voltage = LP_NORMAL_VOLTAGE; if (!queue_work(voltage_wq, &voltage_change_handler)) printk(KERN_ERR "WORK_NOT_ADDED\n"); spin_unlock_irqrestore(&voltage_lock, flags); wait_for_completion_interruptible(&voltage_change_cmpl); } else { spin_unlock_irqrestore(&voltage_lock, flags); if (!completion_done(&voltage_change_cmpl)) wait_for_completion_interruptible(&voltage_change_cmpl); } spin_lock_irqsave(&freq_lock, flags); if (!low_bus_freq_mode) { spin_unlock_irqrestore(&freq_lock, flags); return; } /* Temporarily set the dividers when the source is PLL3. * No clock rate is above 133MHz. */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET |1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET |1 << MXC_CCM_CBCDR_AHB_PODF_OFFSET |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0xF) udelay(10); clk_set_parent(main_bus_clk, pll3); if (bus_freq_scaling_is_active && !high_bus_freq) { /* Set the dividers to the medium setpoint dividers */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET |3 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET |5 << MXC_CCM_CBCDR_AHB_PODF_OFFSET |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0xF) udelay(10); /*Set the main_bus_clk parent to be PLL2. */ clk_set_parent(main_bus_clk, pll2); /* Set to the medium setpoint. */ high_bus_freq_mode = 0; low_bus_freq_mode = 0; med_bus_freq_mode = 1; set_ddr_freq(ddr_med_rate); } else { /* Set the dividers to the default dividers */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET |1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET |2 << MXC_CCM_CBCDR_AHB_PODF_OFFSET |0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0xF) udelay(10); /*Set the main_bus_clk parent to be PLL2. */ clk_set_parent(main_bus_clk, pll2); /* Set to the high setpoint. */ high_bus_freq_mode = 1; low_bus_freq_mode = 0; med_bus_freq_mode = 0; set_ddr_freq(ddr_normal_rate); } spin_unlock_irqrestore(&freq_lock, flags); udelay(100); }
void bus_freq_update(struct clk *clk, bool flag) { mutex_lock(&bus_freq_mutex); if (flag) { if (clk == cpu_clk) { /* The CPU freq is being increased. * check if we need to increase the bus freq */ high_cpu_freq = 1; if (low_bus_freq_mode || audio_bus_freq_mode) set_high_bus_freq(0); } else { /* Update count */ if (clk->flags & AHB_HIGH_SET_POINT) lp_high_freq++; else if (clk->flags & AHB_MED_SET_POINT) lp_med_freq++; else if (clk->flags & AHB_AUDIO_SET_POINT) lp_audio_freq++; /* Update bus freq */ if ((clk->flags & CPU_FREQ_TRIG_UPDATE) && (clk_get_usecount(clk) == 0)) { if (!(clk->flags & (AHB_HIGH_SET_POINT | AHB_MED_SET_POINT))) { if (low_freq_bus_used()) set_low_bus_freq(); } else { if ((clk->flags & AHB_MED_SET_POINT) && !med_bus_freq_mode) { /* Set to Medium setpoint */ set_high_bus_freq(0); } else if ((clk->flags & AHB_HIGH_SET_POINT) && !high_bus_freq_mode) { /* Currently at low or medium * set point, need to set to * high setpoint */ set_high_bus_freq(1); } } } } } else { if (clk == cpu_clk) { /* CPU freq is dropped, check if we can * lower the bus freq. */ high_cpu_freq = 0; if (low_freq_bus_used() && !(low_bus_freq_mode || audio_bus_freq_mode)) set_low_bus_freq(); } else { /* Update count */ if (clk->flags & AHB_HIGH_SET_POINT) lp_high_freq--; else if (clk->flags & AHB_MED_SET_POINT) lp_med_freq--; else if (clk->flags & AHB_AUDIO_SET_POINT) lp_audio_freq--; /* Update bus freq */ if ((clk->flags & CPU_FREQ_TRIG_UPDATE) && (clk_get_usecount(clk) == 0)) { if (low_freq_bus_used()) set_low_bus_freq(); else { /* Set to either high or * medium setpoint. */ set_high_bus_freq(0); } } } } mutex_unlock(&bus_freq_mutex); return; }
void enter_lpapm_mode_mx50() { u32 reg; unsigned long flags; spin_lock_irqsave(&freq_lock, flags); set_ddr_freq(LP_APM_CLK); /* Set the parent of main_bus_clk to be PLL3 */ clk_set_parent(main_bus_clk, pll3); /* Set the AHB dividers to be 2. * Set the dividers so that clock rates * are not greater than current clock rate. */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (1 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET | 1 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET | 1 << MXC_CCM_CBCDR_AHB_PODF_OFFSET | 0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0x0F) udelay(10); low_bus_freq_mode = 1; high_bus_freq_mode = 0; med_bus_freq_mode = 0; /* Set the source of main_bus_clk to be lp-apm. */ clk_set_parent(main_bus_clk, lp_apm); /* Set the AHB dividers to be 1. */ /* Set the dividers to be 1, so the clock rates * are at 24Mhz */ reg = __raw_readl(MXC_CCM_CBCDR); reg &= ~(MXC_CCM_CBCDR_AXI_A_PODF_MASK | MXC_CCM_CBCDR_AXI_B_PODF_MASK | MXC_CCM_CBCDR_AHB_PODF_MASK | MX50_CCM_CBCDR_WEIM_PODF_MASK); reg |= (0 << MXC_CCM_CBCDR_AXI_A_PODF_OFFSET | 0 << MXC_CCM_CBCDR_AXI_B_PODF_OFFSET | 0 << MXC_CCM_CBCDR_AHB_PODF_OFFSET | 0 << MX50_CCM_CBCDR_WEIM_PODF_OFFSET); __raw_writel(reg, MXC_CCM_CBCDR); while (__raw_readl(MXC_CCM_CDHIPR) & 0x0F) udelay(10); spin_unlock_irqrestore(&freq_lock, flags); spin_lock_irqsave(&voltage_lock, flags); lp_voltage = LP_LOW_VOLTAGE; INIT_COMPLETION(voltage_change_cmpl); queue_work(voltage_wq, &voltage_change_handler); spin_unlock_irqrestore(&voltage_lock, flags); if (clk_get_usecount(pll1_sw_clk) == 1) { /* Relock PLL1 to 160MHz. */ clk_set_parent(pll1_sw_clk, pll2); /* Set the divider to ARM_PODF to 3. */ __raw_writel(0x02, MXC_CCM_CACRR); clk_set_rate(pll1, cpu_wp_tbl[cpu_wp_nr - 1].cpu_rate); clk_set_parent(pll1_sw_clk, pll1); /* Set the divider to ARM_PODF to 1. */ __raw_writel(0x0, MXC_CCM_CACRR); } udelay(100); }
static int ldb_fb_pre_setup(struct fb_info *fbi) { int ipu_di = 0; struct clk *di_clk, *ldb_clk_parent; unsigned long ldb_clk_prate = 455000000; fbi->mode = (struct fb_videomode *)fb_match_mode(&fbi->var, &fbi->modelist); if (!fbi->mode) { dev_warn(g_ldb_dev, "can not find mode for xres=%d, yres=%d\n", fbi->var.xres, fbi->var.yres); return 0; } if (fbi->fbops->fb_ioctl) { mm_segment_t old_fs; old_fs = get_fs(); set_fs(KERNEL_DS); fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_IPU_DI, (unsigned long)&ipu_di); fbi->fbops->fb_ioctl(fbi, MXCFB_GET_FB_BLANK, (unsigned int)(&ldb.blank[ipu_di])); set_fs(old_fs); /* * Default ldb mode: * 1080p: DI0 split, SPWG or DI1 split, SPWG * others: single, SPWG */ if (ldb.chan_mode_opt == LDB_NO_MODE) { if (fb_mode_is_equal(fbi->mode, &mxcfb_ldb_modedb[0])) { if (ipu_di == 0) { ldb.chan_mode_opt = LDB_SPL_DI0; dev_warn(g_ldb_dev, "default di0 split mode\n"); } else { ldb.chan_mode_opt = LDB_SPL_DI1; dev_warn(g_ldb_dev, "default di1 split mode\n"); } ldb.chan_bit_map[0] = LDB_BIT_MAP_SPWG; ldb.chan_bit_map[1] = LDB_BIT_MAP_SPWG; } else if (fb_mode_is_equal(fbi->mode, &mxcfb_ldb_modedb[1])) { if (ipu_di == 0) { ldb.chan_mode_opt = LDB_SIN_DI0; ldb.chan_bit_map[0] = LDB_BIT_MAP_SPWG; dev_warn(g_ldb_dev, "default di0 single mode\n"); } else { ldb.chan_mode_opt = LDB_SIN_DI1; ldb.chan_bit_map[1] = LDB_BIT_MAP_SPWG; dev_warn(g_ldb_dev, "default di1 single mode\n"); } } } /* TODO:Set the correct pll4 rate for all situations */ if (ipu_di == 1) { ldb.ldb_di_clk[1] = clk_get(g_ldb_dev, "ldb_di1_clk"); di_clk = clk_get(g_ldb_dev, "ipu_di1_clk"); ldb_clk_parent = clk_get_parent(ldb.ldb_di_clk[1]); clk_set_rate(ldb_clk_parent, ldb_clk_prate); clk_set_parent(di_clk, ldb.ldb_di_clk[1]); clk_put(di_clk); clk_put(ldb.ldb_di_clk[1]); } else { ldb.ldb_di_clk[0] = clk_get(g_ldb_dev, "ldb_di0_clk"); di_clk = clk_get(g_ldb_dev, "ipu_di0_clk"); ldb_clk_parent = clk_get_parent(ldb.ldb_di_clk[0]); clk_set_rate(ldb_clk_parent, ldb_clk_prate); clk_set_parent(di_clk, ldb.ldb_di_clk[0]); clk_put(di_clk); clk_put(ldb.ldb_di_clk[0]); } switch (ldb.chan_mode_opt) { case LDB_SIN_DI0: ldb.ldb_di_clk[0] = clk_get(g_ldb_dev, "ldb_di0_clk"); clk_set_rate(ldb.ldb_di_clk[0], ldb_clk_prate/7); if (ldb.blank[0] == FB_BLANK_UNBLANK && clk_get_usecount(ldb.ldb_di_clk[0]) == 0) clk_enable(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[0]); break; case LDB_SIN_DI1: ldb.ldb_di_clk[1] = clk_get(g_ldb_dev, "ldb_di1_clk"); clk_set_rate(ldb.ldb_di_clk[1], ldb_clk_prate/7); if (ldb.blank[1] == FB_BLANK_UNBLANK && clk_get_usecount(ldb.ldb_di_clk[1]) == 0) clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[1]); break; case LDB_SEP: if (ipu_di == 0) { ldb.ldb_di_clk[0] = clk_get(g_ldb_dev, "ldb_di0_clk"); clk_set_rate(ldb.ldb_di_clk[0], ldb_clk_prate/7); if (ldb.blank[0] == FB_BLANK_UNBLANK && clk_get_usecount(ldb.ldb_di_clk[0]) == 0) clk_enable(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[0]); } else { ldb.ldb_di_clk[1] = clk_get(g_ldb_dev, "ldb_di1_clk"); clk_set_rate(ldb.ldb_di_clk[1], ldb_clk_prate/7); if (ldb.blank[1] == FB_BLANK_UNBLANK && clk_get_usecount(ldb.ldb_di_clk[1]) == 0) clk_enable(ldb.ldb_di_clk[1]); clk_put(ldb.ldb_di_clk[1]); } break; case LDB_DUL_DI0: case LDB_SPL_DI0: ldb.ldb_di_clk[0] = clk_get(g_ldb_dev, "ldb_di0_clk"); ldb.ldb_di_clk[1] = clk_get(g_ldb_dev, "ldb_di1_clk"); if (ldb.chan_mode_opt == LDB_DUL_DI0) { clk_set_rate(ldb.ldb_di_clk[0], ldb_clk_prate/7); } else { clk_set_rate(ldb.ldb_di_clk[0], 2*ldb_clk_prate/7); clk_set_rate(ldb.ldb_di_clk[1], 2*ldb_clk_prate/7); } if (ldb.blank[0] == FB_BLANK_UNBLANK) { if (clk_get_usecount(ldb.ldb_di_clk[0]) == 0) clk_enable(ldb.ldb_di_clk[0]); if (clk_get_usecount(ldb.ldb_di_clk[1]) == 0) clk_enable(ldb.ldb_di_clk[1]); } clk_put(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[1]); break; case LDB_DUL_DI1: case LDB_SPL_DI1: ldb.ldb_di_clk[0] = clk_get(g_ldb_dev, "ldb_di0_clk"); ldb.ldb_di_clk[1] = clk_get(g_ldb_dev, "ldb_di1_clk"); if (ldb.chan_mode_opt == LDB_DUL_DI1) { clk_set_rate(ldb.ldb_di_clk[1], ldb_clk_prate/7); } else { clk_set_rate(ldb.ldb_di_clk[0], 2*ldb_clk_prate/7); clk_set_rate(ldb.ldb_di_clk[1], 2*ldb_clk_prate/7); } if (ldb.blank[1] == FB_BLANK_UNBLANK) { if (clk_get_usecount(ldb.ldb_di_clk[0]) == 0) clk_enable(ldb.ldb_di_clk[0]); if (clk_get_usecount(ldb.ldb_di_clk[1]) == 0) clk_enable(ldb.ldb_di_clk[1]); } clk_put(ldb.ldb_di_clk[0]); clk_put(ldb.ldb_di_clk[1]); break; default: break; } if (ldb.blank[ipu_di] == FB_BLANK_UNBLANK) ldb_enable(ipu_di); } return 0; }
void enter_lp_audio_mode(void) { struct clk *tclk; int ret; struct clk *p_clk; struct clk *amode_parent_clk; tclk = clk_get(NULL, "ipu_clk"); if (clk_get_usecount(tclk) != 0) { printk(KERN_INFO "Cannot enter AUDIO LPM mode - display is still active\n"); return; } tclk = clk_get(NULL, "cpu_clk"); org_cpu_rate = clk_get_rate(tclk); #ifdef CHANGE_DDR2_TO_PLL2 tclk = clk_get(NULL, "ddr_clk"); clk_set_parent(tclk, clk_get(NULL, "axi_a_clk")); /* Set CPU clock to be derived from PLL2 instead of PLL1 */ tclk = clk_get(NULL, "pll1_sw_clk"); clk_set_parent(tclk, clk_get(NULL, "pll2")); clk_enable(tclk); tclk = clk_get(NULL, "ddr_clk"); clk_set_parent(tclk, clk_get(NULL, "ddr_hf_clk")); #endif /*Change the DDR freq to 133Mhz. */ tclk = clk_get(NULL, "ddr_hf_clk"); clk_set_rate(tclk, clk_round_rate(tclk, 133000000)); tclk = clk_get(NULL, "cpu_clk"); ret = clk_set_rate(tclk, ARM_LP_CLK); if (ret != 0) printk(KERN_DEBUG "cannot set CPU clock rate\n"); clk_put(tclk); /* Set the voltage to 0.775v for the GP domain. */ ret = regulator_set_voltage(gp_core, GP_LPM_VOLTAGE, GP_LPM_VOLTAGE); if (ret < 0) printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!\n"); tclk = clk_get(NULL, "periph_apm_clk"); amode_parent_clk = clk_get(NULL, "lp_apm"); p_clk = clk_get_parent(tclk); /* Make sure osc_clk is the parent of lp_apm. */ clk_set_parent(amode_parent_clk, clk_get(NULL, "osc")); /* Set the parent of periph_apm_clk to be lp_apm */ clk_set_parent(tclk, amode_parent_clk); amode_parent_clk = tclk; tclk = clk_get(NULL, "main_bus_clk"); p_clk = clk_get_parent(tclk); /* Set the parent of main_bus_clk to be periph_apm_clk */ clk_set_parent(tclk, amode_parent_clk); clk_set_rate(clk_get(NULL, "axi_a_clk"), 24000000); clk_set_rate(clk_get(NULL, "axi_b_clk"), 24000000); clk_set_rate(clk_get(NULL, "ahb_clk"), 24000000); clk_set_rate(clk_get(NULL, "emi_slow_clk"), 24000000); clk_set_rate(clk_get(NULL, "nfc_clk"), 12000000); /* disable PLL3 */ tclk = clk_get(NULL, "pll3"); if (tclk->usecount == 1) clk_disable(tclk); /* disable PLL2 */ tclk = clk_get(NULL, "pll2"); if (tclk->usecount == 1) clk_disable(tclk); /* disable PLL1 */ tclk = clk_get(NULL, "pll1_main_clk"); if (tclk->usecount == 1) clk_disable(tclk); lp_audio_mode = 1; }
void enter_lp_audio_mode(void) { int ret = 0; struct clk *p_clk; struct clk *tclk; struct clk *amode_parent_clk; struct regulator *gp_core; struct regulator *lp_core; tclk = clk_get(NULL, "ipu_clk"); if (clk_get_usecount(tclk) != 0) { printk(KERN_INFO "Cannot enter AUDIO LPM mode - display is still active\n"); return; } tclk = clk_get(NULL, "periph_apm_clk"); amode_parent_clk = clk_get(NULL, "lp_apm"); p_clk = clk_get_parent(tclk); /* Make sure osc_clk is the parent of lp_apm. */ clk_set_parent(amode_parent_clk, clk_get(NULL, "osc")); /* Set the parent of periph_apm_clk to be lp_apm */ clk_set_parent(tclk, amode_parent_clk); amode_parent_clk = tclk; tclk = clk_get(NULL, "main_bus_clk"); p_clk = clk_get_parent(tclk); /* Set the parent of main_bus_clk to be periph_apm_clk */ clk_set_parent(tclk, amode_parent_clk); clk_set_rate(clk_get(NULL, "axi_a_clk"), 24000000); clk_set_rate(clk_get(NULL, "axi_b_clk"), 24000000); clk_set_rate(clk_get(NULL, "axi_c_clk"), 24000000); clk_set_rate(clk_get(NULL, "emi_core_clk"), 24000000); clk_set_rate(clk_get(NULL, "nfc_clk"), 4800000); clk_set_rate(clk_get(NULL, "ahb_clk"), 24000000); amode_parent_clk = clk_get(NULL, "emi_core_clk"); tclk = clk_get(NULL, "arm_axi_clk"); p_clk = clk_get_parent(tclk); if (p_clk != amode_parent_clk) { clk_set_parent(tclk, amode_parent_clk); } tclk = clk_get(NULL, "vpu_clk"); p_clk = clk_get_parent(tclk); if (p_clk != amode_parent_clk) { clk_set_parent(tclk, amode_parent_clk); } tclk = clk_get(NULL, "vpu_core_clk"); p_clk = clk_get_parent(tclk); if (p_clk != amode_parent_clk) { clk_set_parent(tclk, amode_parent_clk); } /* disable PLL3 */ tclk = clk_get(NULL, "pll3"); if (tclk->usecount == 1) clk_disable(tclk); /* disable PLL2 */ tclk = clk_get(NULL, "pll2"); if (tclk->usecount == 1) clk_disable(tclk); /* Set the voltage to 1.0v for the LP domain. */ if (!board_is_mx37(BOARD_REV_2)) lp_core = regulator_get(NULL, "DCDC4"); else lp_core = regulator_get(NULL, "SW2"); if (lp_core != NULL) { ret = regulator_set_voltage(lp_core, LP_LPM_VOLTAGE, LP_LPM_VOLTAGE); if (ret < 0) printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!!!\n"); } tclk = clk_get(NULL, "cpu_clk"); org_cpu_rate = clk_get_rate(tclk); ret = clk_set_rate(tclk, ARM_LP_CLK); if (ret != 0) printk(KERN_DEBUG "cannot set CPU clock rate\n"); /* Set the voltage to 0.8v for the GP domain. */ if (!board_is_mx37(BOARD_REV_2)) gp_core = regulator_get(NULL, "DCDC1"); else gp_core = regulator_get(NULL, "SW1"); if (gp_core != NULL) { ret = regulator_set_voltage(gp_core, GP_LPM_VOLTAGE, GP_LPM_VOLTAGE); if (ret < 0) printk(KERN_DEBUG "COULD NOT SET GP VOLTAGE!!!!!\n"); } lp_audio_mode = 1; }
void arch_idle_single_core(void) { u32 reg; if (cpu_is_mx6dl() && chip_rev > IMX_CHIP_REVISION_1_0) { /* * MX6DLS TO1.1 has the HW fix for the WAIT mode issue. * Ensure that the CGPR bit 17 is set to enable the fix. */ reg = __raw_readl(MXC_CCM_CGPR); reg |= MXC_CCM_CGPR_WAIT_MODE_FIX; __raw_writel(reg, MXC_CCM_CGPR); ca9_do_idle(); } else { if (low_bus_freq_mode || audio_bus_freq_mode) { int ddr_usecount = 0; if ((mmdc_ch0_axi != NULL)) ddr_usecount = clk_get_usecount(mmdc_ch0_axi); if (cpu_is_mx6sl() && low_bus_freq_mode && ddr_usecount == 1) { /* In this mode PLL2 i already in bypass, * ARM is sourced from PLL1. The code in IRAM * will set ARM to be sourced from STEP_CLK * at 24MHz. It will also set DDR to 1MHz to * reduce power. */ u32 org_arm_podf = __raw_readl(MXC_CCM_CACRR); /* Need to run WFI code from IRAM so that * we can lower DDR freq. */ mx6sl_wfi_iram(org_arm_podf, (unsigned long)mx6sl_wfi_iram_base); } else { /* Need to set ARM to run at 24MHz since IPG * is at 12MHz. This is valid for audio mode on * MX6SL, and all low power modes on MX6DLS. */ if (cpu_is_mx6sl() && low_bus_freq_mode) { /* ARM is from PLL1, need to switch to * STEP_CLK sourced from 24MHz. */ /* Swtich STEP_CLK to 24MHz. */ reg = __raw_readl(MXC_CCM_CCSR); reg &= ~MXC_CCM_CCSR_STEP_SEL; __raw_writel(reg, MXC_CCM_CCSR); /* Set PLL1_SW_CLK to be from *STEP_CLK. */ reg = __raw_readl(MXC_CCM_CCSR); reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; __raw_writel(reg, MXC_CCM_CCSR); } else { /* PLL1_SW_CLK is sourced from * PLL2_PFD2_400MHz at this point. * Move it to bypassed PLL1. */ reg = __raw_readl(MXC_CCM_CCSR); reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; __raw_writel(reg, MXC_CCM_CCSR); } ca9_do_idle(); if (cpu_is_mx6sl() && low_bus_freq_mode) { /* Set PLL1_SW_CLK to be from PLL1 */ reg = __raw_readl(MXC_CCM_CCSR); reg &= ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL; __raw_writel(reg, MXC_CCM_CCSR); } else { reg |= MXC_CCM_CCSR_PLL1_SW_CLK_SEL; __raw_writel(reg, MXC_CCM_CCSR); } } } else { /* * Implement the 12:5 ARM:IPG_CLK ratio * workaround for the WAIT mode issue. * We can directly use the divider to drop the ARM * core freq in a single core environment. * Set the ARM_PODF to get the max freq possible * to avoid the WAIT mode issue when IPG is at 66MHz. */ __raw_writel(wait_mode_arm_podf, MXC_CCM_CACRR); while (__raw_readl(MXC_CCM_CDHIPR)) ; ca9_do_idle(); __raw_writel(cur_arm_podf - 1, MXC_CCM_CACRR); } } }
int can_change_ddr_freq(void) { if (clk_get_usecount(epdc_clk) == 0) return 1; return 0; }
/*! * This function puts the CPU into idle mode. It is called by default_idle() * in process.c file. */ void arch_idle(void) { if (likely(!mxc_jtag_enabled)) { if (ddr_clk == NULL) ddr_clk = clk_get(NULL, "ddr_clk"); if (gpc_dvfs_clk == NULL) gpc_dvfs_clk = clk_get(NULL, "gpc_dvfs_clk"); /* gpc clock is needed for SRPG */ clk_enable(gpc_dvfs_clk); mxc_cpu_lp_set(arch_idle_mode); if (cpu_is_mx50() && (clk_get_usecount(ddr_clk) == 0)) { if (sys_clk == NULL) sys_clk = clk_get(NULL, "sys_clk"); if (low_bus_freq_mode) { u32 reg, cpu_podf; reg = __raw_readl(apll_base + 0x50); reg = 0x120490; __raw_writel(reg, apll_base + 0x50); reg = __raw_readl(apll_base + 0x80); reg |= 1; __raw_writel(reg, apll_base + 0x80); if (mx50_ddr_type != MX50_DDR2) { /* Move ARM to be sourced from 24MHz XTAL. * when ARM is in WFI. */ if (pll1_sw_clk == NULL) pll1_sw_clk = clk_get(NULL, "pll1_sw_clk"); if (osc == NULL) osc = clk_get(NULL, "lp_apm"); if (pll1_main_clk == NULL) pll1_main_clk = clk_get(NULL, "pll1_main_clk"); clk_set_parent(pll1_sw_clk, osc); /* Set the ARM-PODF divider to 1. */ cpu_podf = __raw_readl(MXC_CCM_CACRR); __raw_writel(0x01, MXC_CCM_CACRR); while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_ARM_PODF_BUSY) ; } wait_in_iram(ccm_base, databahn_base, clk_get_usecount(sys_clk)); if (mx50_ddr_type != MX50_DDR2) { /* Set the ARM-POD divider back * to the original. */ __raw_writel(cpu_podf, MXC_CCM_CACRR); while (__raw_readl(MXC_CCM_CDHIPR) & MXC_CCM_CDHIPR_ARM_PODF_BUSY) ; clk_set_parent(pll1_sw_clk, pll1_main_clk); } } else wait_in_iram(ccm_base, databahn_base, clk_get_usecount(sys_clk)); } else if (cpu_is_mx53() && (clk_get_usecount(ddr_clk) == 0) && low_bus_freq_mode) { suspend_in_iram(suspend_param1, NULL, NULL); } else cpu_do_idle(); clk_disable(gpc_dvfs_clk); clk_put(ddr_clk); } }
static int pnx_bl_set_intensity(struct backlight_device *bd) { /* ACER BobIHLee@20100505, support AS1 project*/ #if (defined ACER_L1_AU4) || (defined ACER_L1_K2) || defined (ACER_L1_AS1) /* End BobIHLee@20100505*/ int intensity = bd->props.brightness; int Jump_level; int i; if (bd->props.power != FB_BLANK_UNBLANK) intensity = 0; if (bd->props.fb_blank != FB_BLANK_UNBLANK) intensity = 0; if ( intensity == BackLight_Level ) { return 0; } if ( BackLight_Level == 0 ) { pnx_gpio_write_pin(pnx_bl_pdata->gpio, 1); udelay(30); Jump_level = 16 - intensity ; for ( i = 0 ; i < Jump_level ; i++) { pnx_gpio_write_pin(pnx_bl_pdata->gpio, 0); udelay(1); pnx_gpio_write_pin(pnx_bl_pdata->gpio, 1); udelay(1); } BackLight_Level = intensity; } else { if ( intensity == 0 ) { pnx_gpio_write_pin(pnx_bl_pdata->gpio, 0); /* backlight OFF */ mdelay(10); BackLight_Level = 0 ; return 0; } else if ( BackLight_Level > intensity ) { Jump_level = BackLight_Level - intensity ; for ( i = 0 ; i < Jump_level ; i++) { pnx_gpio_write_pin(pnx_bl_pdata->gpio, 0); udelay(1); pnx_gpio_write_pin(pnx_bl_pdata->gpio, 1); udelay(1); } BackLight_Level = intensity; }else { Jump_level = 16 + BackLight_Level - intensity ; for ( i = 0 ; i < Jump_level ; i++) { pnx_gpio_write_pin(pnx_bl_pdata->gpio, 0); udelay(1); pnx_gpio_write_pin(pnx_bl_pdata->gpio, 1); udelay(1); } BackLight_Level = intensity; } } return 0; #else int intensity = bd->props.brightness; int ret=0; if (bd->props.power != FB_BLANK_UNBLANK) intensity = 0; if (bd->props.fb_blank != FB_BLANK_UNBLANK) intensity = 0; if ( intensity < bd->props.max_brightness ) { pnx_gpio_set_mode(pnx_bl_pdata->gpio, GPIO_MODE_MUX1); if ((intensity !=0) && (clk_get_usecount(pwm1Clk) == 0)) clk_enable(pwm1Clk); ret = writel(intensity, pnx_bl_pdata->pwm_tmr); if (intensity==0) clk_disable(pwm1Clk); } else { /* Write value even if not used for pnx_bl_get_intensity usage */ ret = writel(intensity, pnx_bl_pdata->pwm_tmr); clk_disable(pwm1Clk); pnx_gpio_set_mode(pnx_bl_pdata->gpio, GPIO_MODE_MUX0); gpio_set_value(pnx_bl_pdata->gpio, 1); } return ret; #endif }