Beispiel #1
0
int tegra_powergate_remove_clamping(int id)
{
	u32 mask;

	if (id < 0 || id >= tegra_num_powerdomains)
		return -EINVAL;

	/*
	 * The Tegra124 GPU has a separate register (with different semantics)
	 * to remove clamps.
	 */
	if (tegra_chip_id == TEGRA124) {
		if (id == TEGRA_POWERGATE_3D) {
			pmc_write(0, GPU_RG_CNTRL);
			return 0;
		}
	}

	/*
	 * Tegra 2 has a bug where PCIE and VDE clamping masks are
	 * swapped relatively to the partition ids
	 */
	if (id == TEGRA_POWERGATE_VDEC)
		mask = (1 << TEGRA_POWERGATE_PCIE);
	else if (id == TEGRA_POWERGATE_PCIE)
		mask = (1 << TEGRA_POWERGATE_VDEC);
	else
		mask = (1 << id);

	pmc_write(mask, REMOVE_CLAMPING);

	return 0;
}
Beispiel #2
0
int tegra_powergate_set(int id, bool new_state)
{
#ifndef CONFIG_TEGRA_SIMULATION_PLATFORM
	bool status;
	unsigned long flags;
	spinlock_t *lock = tegra_get_powergate_lock();

	/* 10us timeout for toggle operation if it takes affect*/
	int toggle_timeout = 10;

	/* 100 * 10 = 1000us timeout for toggle command to take affect in case
	   of contention with h/w initiated CPU power gating */
	int contention_timeout = 100;

	spin_lock_irqsave(lock, flags);

	status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));

	if (status == new_state) {
		spin_unlock_irqrestore(lock, flags);
		return 0;
	}

	if (TEGRA_IS_CPU_POWERGATE_ID(id)) {
		/* CPU ungated in s/w only during boot/resume with outer
		   waiting loop and no contention from other CPUs */
		pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
		spin_unlock_irqrestore(lock, flags);
		return 0;
	}

	pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);
	do {
		do {
			udelay(1);
			status = !!(pmc_read(PWRGATE_STATUS) & (1 << id));

			toggle_timeout--;
		} while ((status != new_state) && (toggle_timeout > 0));

		contention_timeout--;
	} while ((status != new_state) && (contention_timeout > 0));

	spin_unlock_irqrestore(lock, flags);

	if (status != new_state) {
		WARN(1, "Could not set powergate %d to %d", id, new_state);
		return -EBUSY;
	}

	trace_power_domain_target(tegra_powergate_get_name(id), new_state,
			smp_processor_id());
#endif

	return 0;
}
Beispiel #3
0
static void clk_audio_pll_disable(struct clk_hw *hw)
{
    struct clk_audio_frac *fck = to_clk_audio_frac(hw);
    struct at91_pmc *pmc = fck->pmc;
    u32 tmp;

    pmc_lock(pmc);
    tmp = pmc_read(pmc, AT91_PMC_AUDIO_PLL0) & ~AT91_PMC_AUDIO_PLL_PLLEN;
    pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp);
    /* do it in 2 separated writes */
    pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp & ~AT91_PMC_AUDIO_PLL_RESETN);
    pmc_unlock(pmc);
}
static void clk_system_unprepare(struct clk_hw *hw)
{
	struct clk_system *sys = to_clk_system(hw);
	struct at91_pmc *pmc = sys->pmc;

	pmc_write(pmc, AT91_PMC_SCDR, 1 << sys->id);
}
Beispiel #5
0
static void pmc_irq_suspend(struct irq_data *d)
{
	struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);

	pmc->imr = pmc_read(pmc, AT91_PMC_IMR);
	pmc_write(pmc, AT91_PMC_IDR, pmc->imr);
}
Beispiel #6
0
int tegra_io_rail_power_off(int id)
{
	unsigned long request, status, value;
	unsigned int bit, mask;
	int err;

	err = tegra_io_rail_prepare(id, &request, &status, &bit);
	if (err < 0)
		return err;

	mask = 1 << bit;

	value = pmc_read(request);
	value |= mask;
	value &= ~IO_DPD_REQ_CODE_MASK;
	value |= IO_DPD_REQ_CODE_ON;
	pmc_write(value, request);

	err = tegra_io_rail_poll(status, mask, mask, 250);
	if (err < 0)
		return err;

	tegra_io_rail_unprepare();

	return 0;
}
Beispiel #7
0
static void clk_utmi_unprepare(struct clk_hw *hw)
{
	struct clk_utmi *utmi = to_clk_utmi(hw);
	struct at91_pmc *pmc = utmi->pmc;
	u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) & ~AT91_PMC_UPLLEN;

	pmc_write(pmc, AT91_CKGR_UCKR, tmp);
}
static void clk_audio_pll_pmc_disable(struct clk_hw *hw)
{
	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
	struct at91_pmc *pmc = apmc_ck->pmc;
	u32 tmp;

	pmc_lock(pmc);
	tmp = pmc_read(pmc, AT91_PMC_AUDIO_PLL0) & ~AT91_PMC_AUDIO_PLL_PMCEN;
	pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp);
	pmc_unlock(pmc);
}
Beispiel #9
0
static void clk_main_rc_osc_unprepare(struct clk_hw *hw)
{
	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
	struct at91_pmc *pmc = osc->pmc;
	u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);

	if (!(tmp & AT91_PMC_MOSCRCEN))
		return;

	tmp &= ~(MOR_KEY_MASK | AT91_PMC_MOSCRCEN);
	pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY);
}
Beispiel #10
0
/* make sure that pll is in reset state beforehand */
static int clk_audio_pll_prepare(struct clk_hw *hw)
{
    struct clk_audio_frac *fck = to_clk_audio_frac(hw);
    struct at91_pmc *pmc = fck->pmc;
    u32 tmp;

    pmc_lock(pmc);
    tmp = pmc_read(pmc, AT91_PMC_AUDIO_PLL0) & ~AT91_PMC_AUDIO_PLL_RESETN;
    pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp);
    pmc_unlock(pmc);
    return 0;
}
Beispiel #11
0
static int tegra_io_rail_prepare(int id, unsigned long *request,
				 unsigned long *status, unsigned int *bit)
{
	unsigned long rate, value;
	struct clk *clk;

	*bit = id % 32;

	/*
	 * There are two sets of 30 bits to select IO rails, but bits 30 and
	 * 31 are control bits rather than IO rail selection bits.
	 */
	if (id > 63 || *bit == 30 || *bit == 31)
		return -EINVAL;

	if (id < 32) {
		*status = IO_DPD_STATUS;
		*request = IO_DPD_REQ;
	} else {
		*status = IO_DPD2_STATUS;
		*request = IO_DPD2_REQ;
	}

	clk = clk_get_sys(NULL, "pclk");
	if (IS_ERR(clk))
		return PTR_ERR(clk);

	rate = clk_get_rate(clk);
	clk_put(clk);

	pmc_write(DPD_SAMPLE_ENABLE, DPD_SAMPLE);

	/* must be at least 200 ns, in APB (PCLK) clock cycles */
	value = DIV_ROUND_UP(1000000000, rate);
	value = DIV_ROUND_UP(200, value);
	pmc_write(value, SEL_DPD_TIM);

	return 0;
}
static int clk_audio_pll_pmc_enable(struct clk_hw *hw)
{
	struct clk_audio_pmc *apmc_ck = to_clk_audio_pmc(hw);
	struct at91_pmc *pmc = apmc_ck->pmc;
	u32 tmp;

	pmc_lock(pmc);
	tmp = pmc_read(pmc, AT91_PMC_AUDIO_PLL0) & ~AT91_PMC_AUDIO_PLL_QDPMC_MASK;
	tmp |= AT91_PMC_AUDIO_PLL_PMCEN | AT91_PMC_AUDIO_PLL_QDPMC(apmc_ck->qdpmc);
	pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp);
	pmc_unlock(pmc);
	return 0;
}
Beispiel #13
0
static struct clk * __init
at91_clk_register_main_osc(struct at91_pmc *pmc,
			   unsigned int irq,
			   const char *name,
			   const char *parent_name,
			   bool bypass)
{
	int ret;
	struct clk_main_osc *osc;
	struct clk *clk = NULL;
	struct clk_init_data init;

	if (!pmc || !irq || !name || !parent_name)
		return ERR_PTR(-EINVAL);

	osc = kzalloc(sizeof(*osc), GFP_KERNEL);
	if (!osc)
		return ERR_PTR(-ENOMEM);

	init.name = name;
	init.ops = &main_osc_ops;
	init.parent_names = &parent_name;
	init.num_parents = 1;
	init.flags = CLK_IGNORE_UNUSED;

	osc->hw.init = &init;
	osc->pmc = pmc;
	osc->irq = irq;

	init_waitqueue_head(&osc->wait);
	irq_set_status_flags(osc->irq, IRQ_NOAUTOEN);
	ret = request_irq(osc->irq, clk_main_osc_irq_handler,
			  IRQF_TRIGGER_HIGH, name, osc);
	if (ret)
		return ERR_PTR(ret);

	if (bypass)
		pmc_write(pmc, AT91_CKGR_MOR,
			  (pmc_read(pmc, AT91_CKGR_MOR) &
			   ~(MOR_KEY_MASK | AT91_PMC_MOSCEN)) |
			  AT91_PMC_OSCBYPASS | AT91_PMC_KEY);

	clk = clk_register(NULL, &osc->hw);
	if (IS_ERR(clk)) {
		free_irq(irq, osc);
		kfree(osc);
	}

	return clk;
}
Beispiel #14
0
static int clk_audio_pll_enable(struct clk_hw *hw)
{
    struct clk_audio_frac *fck = to_clk_audio_frac(hw);
    struct at91_pmc *pmc = fck->pmc;
    u32 tmp, tmp2;

    pmc_lock(pmc);
    tmp = pmc_read(pmc, AT91_PMC_AUDIO_PLL0);
    pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp | AT91_PMC_AUDIO_PLL_RESETN);
    tmp2 = pmc_read(pmc, AT91_PMC_AUDIO_PLL1) & ~AT91_PMC_AUDIO_PLL_FRACR_MASK;
    pmc_write(pmc, AT91_PMC_AUDIO_PLL1, tmp2 | fck->fracr);

    /*
     * reset and enabled have to be done in 2 separated writes
     * for AT91_PMC_AUDIO_PLL0
     */
    tmp &= ~AT91_PMC_AUDIO_PLL_ND_MASK;
    pmc_write(pmc, AT91_PMC_AUDIO_PLL0, tmp | AT91_PMC_AUDIO_PLL_RESETN
              | AT91_PMC_AUDIO_PLL_PLLEN
              | AT91_PMC_AUDIO_PLL_ND(fck->nd));
    pmc_unlock(pmc);
    return 0;
}
Beispiel #15
0
static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
	struct at91_pmc *pmc = clkmain->pmc;
	u32 tmp;

	if (index > 1)
		return -EINVAL;

	tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;

	if (index && !(tmp & AT91_PMC_MOSCSEL))
		pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
	else if (!index && (tmp & AT91_PMC_MOSCSEL))
		pmc_write(pmc, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);

	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) {
		enable_irq(clkmain->irq);
		wait_event(clkmain->wait,
			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS);
	}

	return 0;
}
Beispiel #16
0
static int clk_utmi_prepare(struct clk_hw *hw)
{
	struct clk_utmi *utmi = to_clk_utmi(hw);
	struct at91_pmc *pmc = utmi->pmc;
	u32 tmp = at91_pmc_read(AT91_CKGR_UCKR) | AT91_PMC_UPLLEN |
		  AT91_PMC_UPLLCOUNT | AT91_PMC_BIASEN;

	pmc_write(pmc, AT91_CKGR_UCKR, tmp);

	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU)) {
		enable_irq(utmi->irq);
		wait_event(utmi->wait,
			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU);
	}

	return 0;
}
Beispiel #17
0
static int clk_sama5d4_h32mx_set_rate(struct clk_hw *hw, unsigned long rate,
				    unsigned long parent_rate)
{
	struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);
	struct at91_pmc *pmc = h32mxclk->pmc;
	u32 tmp;

	if (parent_rate != rate && (parent_rate / 2) != rate)
		return -EINVAL;

	pmc_lock(pmc);
	tmp = pmc_read(pmc, AT91_PMC_MCKR) & ~AT91_PMC_H32MXDIV;
	if ((parent_rate / 2) == rate)
		tmp |= AT91_PMC_H32MXDIV;
	pmc_write(pmc, AT91_PMC_MCKR, tmp);
	pmc_unlock(pmc);

	return 0;
}
static int clk_programmable_prepare(struct clk_hw *hw)
{
	u32 tmp;
	struct clk_programmable *prog = to_clk_programmable(hw);
	struct at91_pmc *pmc = prog->pmc;
	const struct clk_programmable_layout *layout = prog->layout;
	u8 id = prog->id;
	u32 mask = PROG_STATUS_MASK(id);

	tmp = prog->css | (prog->pres << layout->pres_shift);
	if (layout->have_slck_mck && prog->slckmck)
		tmp |= AT91_PMC_CSSMCK_MCK;

	pmc_write(pmc, AT91_PMC_PCKR(id), tmp);

	while (!(pmc_read(pmc, AT91_PMC_SR) & mask))
		wait_event(prog->wait, pmc_read(pmc, AT91_PMC_SR) & mask);

	return 0;
}
Beispiel #19
0
static int tegra_powergate_set(int id, bool new_state)
{
	bool status;
	unsigned long flags;

	spin_lock_irqsave(&tegra_powergate_lock, flags);

	status = pmc_read(PWRGATE_STATUS) & (1 << id);

	if (status == new_state) {
		spin_unlock_irqrestore(&tegra_powergate_lock, flags);
		return 0;
	}

	pmc_write(PWRGATE_TOGGLE_START | id, PWRGATE_TOGGLE);

	spin_unlock_irqrestore(&tegra_powergate_lock, flags);

	return 0;
}
Beispiel #20
0
static int clk_main_rc_osc_prepare(struct clk_hw *hw)
{
	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
	struct at91_pmc *pmc = osc->pmc;
	u32 tmp;

	tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK;

	if (!(tmp & AT91_PMC_MOSCRCEN)) {
		tmp |= AT91_PMC_MOSCRCEN | AT91_PMC_KEY;
		pmc_write(pmc, AT91_CKGR_MOR, tmp);
	}

	while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS)) {
		enable_irq(osc->irq);
		wait_event(osc->wait,
			   pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS);
	}

	return 0;
}
Beispiel #21
0
static int clk_system_prepare(struct clk_hw *hw)
{
	struct clk_system *sys = to_clk_system(hw);
	struct at91_pmc *pmc = sys->pmc;
	u32 mask = 1 << sys->id;

	pmc_write(pmc, AT91_PMC_SCER, mask);

	if (!is_pck(sys->id))
		return 0;

	while (!(pmc_read(pmc, AT91_PMC_SR) & mask)) {
		if (sys->irq) {
			enable_irq(sys->irq);
			wait_event(sys->wait,
				   pmc_read(pmc, AT91_PMC_SR) & mask);
		} else
			cpu_relax();
	}
	return 0;
}
Beispiel #22
0
int tegra_powergate_remove_clamping(int id)
{
	u32 mask;

	if (id < 0 || id >= tegra_num_powerdomains)
		return -EINVAL;

	/*
	 * Tegra 2 has a bug where PCIE and VDE clamping masks are
	 * swapped relatively to the partition ids
	 */
	if (id ==  TEGRA_POWERGATE_VDEC)
		mask = (1 << TEGRA_POWERGATE_PCIE);
	else if	(id == TEGRA_POWERGATE_PCIE)
		mask = (1 << TEGRA_POWERGATE_VDEC);
	else
		mask = (1 << id);

	pmc_write(mask, REMOVE_CLAMPING);

	return 0;
}
Beispiel #23
0
static struct at91_pmc *__init at91_pmc_init(struct device_node *np,
					     void __iomem *regbase, int virq,
					     const struct at91_pmc_caps *caps)
{
	struct at91_pmc *pmc;

	if (!regbase || !virq ||  !caps)
		return NULL;

	at91_pmc_base = regbase;

	pmc = kzalloc(sizeof(*pmc), GFP_KERNEL);
	if (!pmc)
		return NULL;

	spin_lock_init(&pmc->lock);
	pmc->regbase = regbase;
	pmc->virq = virq;
	pmc->caps = caps;

	pmc->irqdomain = irq_domain_add_linear(np, 32, &pmc_irq_ops, pmc);

	if (!pmc->irqdomain)
		goto out_free_pmc;

	pmc_write(pmc, AT91_PMC_IDR, 0xffffffff);
	if (request_irq(pmc->virq, pmc_irq_handler,
			IRQF_SHARED | IRQF_COND_SUSPEND, "pmc", pmc))
		goto out_remove_irqdomain;

	return pmc;

out_remove_irqdomain:
	irq_domain_remove(pmc->irqdomain);
out_free_pmc:
	kfree(pmc);

	return NULL;
}
Beispiel #24
0
int tegra_powergate_remove_clamping(int id)
{
	u32 mask;
	int contention_timeout = 100;

	if (!pg_ops) {
		pr_info("This SOC doesn't support powergating\n");
		return -EINVAL;
	}

	if (id < 0 || id >= pg_ops->num_powerdomains)
		return -EINVAL;

	/*
	 * PCIE and VDE clamping masks are swapped with respect to their
	 * partition ids
	 */
	if (id ==  TEGRA_POWERGATE_VDEC)
		mask = (1 << TEGRA_POWERGATE_PCIE);
	else if (id == TEGRA_POWERGATE_PCIE)
		mask = (1 << TEGRA_POWERGATE_VDEC);
	else
		mask = (1 << id);

	pmc_write(mask, REMOVE_CLAMPING);
	/* Wait until clamp is removed */
	do {
		udelay(1);
		contention_timeout--;
	} while ((contention_timeout > 0)
			&& (pmc_read(REMOVE_CLAMPING) & mask));

	WARN(contention_timeout <= 0, "Couldn't remove clamping");

	return 0;
}
Beispiel #25
0
static void pmc_irq_unmask(struct irq_data *d)
{
    struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);

    pmc_write(pmc, AT91_PMC_IER, 1 << d->hwirq);
}
Beispiel #26
0
static void pmc_irq_resume(struct irq_data *d)
{
	struct at91_pmc *pmc = irq_data_get_irq_chip_data(d);

	pmc_write(pmc, AT91_PMC_IER, pmc->imr);
}
Beispiel #27
0
static void tegra_io_rail_unprepare(void)
{
	pmc_write(DPD_SAMPLE_DISABLE, DPD_SAMPLE);
}