Beispiel #1
0
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;

}
Beispiel #2
0
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;
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
0
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);
	}
}
Beispiel #10
0
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);
	}
}
Beispiel #13
0
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;
}
Beispiel #14
0
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;
    }
}
Beispiel #15
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;
}
Beispiel #16
0
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);
}
Beispiel #17
0
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;	
}
Beispiel #19
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;
}
Beispiel #20
0
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);
	}
}
Beispiel #21
0
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;
}
Beispiel #23
0
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);
}
Beispiel #24
0
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;
}
Beispiel #25
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;
}
Beispiel #27
0
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);
		}
	}
}
Beispiel #28
0
int can_change_ddr_freq(void)
{
	if (clk_get_usecount(epdc_clk) == 0)
		return 1;
	return 0;
}
Beispiel #29
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);
	}
}
Beispiel #30
0
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
}