예제 #1
0
파일: clk-main.c 프로젝트: 24hours/linux
static int clk_main_rc_osc_is_prepared(struct clk_hw *hw)
{
	struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw);
	struct at91_pmc *pmc = osc->pmc;

	return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS) &&
		  (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCRCEN));
}
예제 #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;
}
예제 #3
0
파일: clk-main.c 프로젝트: 24hours/linux
static int clk_main_osc_is_prepared(struct clk_hw *hw)
{
	struct clk_main_osc *osc = to_clk_main_osc(hw);
	struct at91_pmc *pmc = osc->pmc;
	u32 tmp = pmc_read(pmc, AT91_CKGR_MOR);

	if (tmp & AT91_PMC_OSCBYPASS)
		return 1;

	return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS) &&
		  (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN));
}
예제 #4
0
파일: clk-main.c 프로젝트: 24hours/linux
static int clk_sam9x5_main_prepare(struct clk_hw *hw)
{
	struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw);
	struct at91_pmc *pmc = clkmain->pmc;

	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 clk_main_probe_frequency(pmc);
}
예제 #5
0
static int clk_system_is_prepared(struct clk_hw *hw)
{
	struct clk_system *sys = to_clk_system(hw);
	struct at91_pmc *pmc = sys->pmc;

	if (!(pmc_read(pmc, AT91_PMC_SCSR) & (1 << sys->id)))
		return 0;

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

	return !!(pmc_read(pmc, AT91_PMC_SR) & (1 << sys->id));
}
예제 #6
0
파일: pmc.c 프로젝트: Truefans/KVMGT-kernel
static irqreturn_t pmc_irq_handler(int irq, void *data)
{
    struct at91_pmc *pmc = (struct at91_pmc *)data;
    unsigned long sr;
    int n;

    sr = pmc_read(pmc, AT91_PMC_SR) & pmc_read(pmc, AT91_PMC_IMR);
    if (!sr)
        return IRQ_NONE;

    for_each_set_bit(n, &sr, BITS_PER_LONG)
    generic_handle_irq(irq_find_mapping(pmc->irqdomain, n));

    return IRQ_HANDLED;
}
예제 #7
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;
}
static int clk_programmable_is_ready(struct clk_hw *hw)
{
	struct clk_programmable *prog = to_clk_programmable(hw);
	struct at91_pmc *pmc = prog->pmc;

	return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_PCKR(prog->id));
}
예제 #9
0
static int clk_utmi_is_prepared(struct clk_hw *hw)
{
	struct clk_utmi *utmi = to_clk_utmi(hw);
	struct at91_pmc *pmc = utmi->pmc;

	return !!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_LOCKU);
}
예제 #10
0
int
sys_sysarch(struct proc *p, void *v, register_t *retval)
{
	struct sys_sysarch_args /* {
		syscallarg(int) op;
		syscallarg(void *) parms;
	} */ *uap = v;
	int error = 0;

	switch(SCARG(uap, op)) {
#if defined(USER_LDT) && 0
	case AMD64_GET_LDT: 
		error = amd64_get_ldt(p, SCARG(uap, parms), retval);
		break;

	case AMD64_SET_LDT: 
		error = amd64_set_ldt(p, SCARG(uap, parms), retval);
		break;
#endif
	case AMD64_IOPL: 
		error = amd64_iopl(p, SCARG(uap, parms), retval);
		break;

#if 0
	case AMD64_GET_IOPERM: 
		error = amd64_get_ioperm(p, SCARG(uap, parms), retval);
		break;

	case AMD64_SET_IOPERM: 
		error = amd64_set_ioperm(p, SCARG(uap, parms), retval);
		break;
#endif
#ifdef MTRR
	case AMD64_GET_MTRR:
		error = amd64_get_mtrr(p, SCARG(uap, parms), retval);
		break;
	case AMD64_SET_MTRR:
		error = amd64_set_mtrr(p, SCARG(uap, parms), retval);
		break;
#endif

#if defined(PERFCTRS) && 0
	case AMD64_PMC_INFO:
		error = pmc_info(p, SCARG(uap, parms), retval);
		break;

	case AMD64_PMC_STARTSTOP:
		error = pmc_startstop(p, SCARG(uap, parms), retval);
		break;

	case AMD64_PMC_READ:
		error = pmc_read(p, SCARG(uap, parms), retval);
		break;
#endif
	default:
		error = EINVAL;
		break;
	}
	return (error);
}
예제 #11
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);
}
예제 #12
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;
}
예제 #13
0
파일: powergate.c 프로젝트: 08opt/linux
static bool tegra_powergate_is_powered(int id)
{
	u32 status;

	WARN_ON(id < 0 || id >= TEGRA_NUM_POWERGATE);

	status = pmc_read(PWRGATE_STATUS) & (1 << id);
	return !!status;
}
예제 #14
0
int tegra_powergate_is_powered(int id)
{
	u32 status;

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

	status = pmc_read(PWRGATE_STATUS) & (1 << id);
	return !!status;
}
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;
}
예제 #16
0
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);
}
예제 #17
0
static unsigned long clk_sama5d4_h32mx_recalc_rate(struct clk_hw *hw,
						 unsigned long parent_rate)
{
	struct clk_sama5d4_h32mx *h32mxclk = to_clk_sama5d4_h32mx(hw);

	if (pmc_read(h32mxclk->pmc, AT91_PMC_MCKR) & AT91_PMC_H32MXDIV)
		return parent_rate / 2;

	if (parent_rate > H32MX_MAX_FREQ)
		pr_warn("H32MX clock is too fast\n");
	return parent_rate;
}
예제 #18
0
파일: clk-main.c 프로젝트: 24hours/linux
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;
}
예제 #19
0
파일: clk-main.c 프로젝트: 24hours/linux
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);
}
예제 #20
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;
}
예제 #21
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;
}
static unsigned long clk_programmable_recalc_rate(struct clk_hw *hw,
						  unsigned long parent_rate)
{
	u32 tmp;
	struct clk_programmable *prog = to_clk_programmable(hw);
	struct at91_pmc *pmc = prog->pmc;
	const struct clk_programmable_layout *layout = prog->layout;

	tmp = pmc_read(pmc, AT91_PMC_PCKR(prog->id));
	prog->pres = (tmp >> layout->pres_shift) & PROG_PRES_MASK;

	return parent_rate >> prog->pres;
}
예제 #23
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);
}
예제 #24
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;
}
예제 #25
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;
}
예제 #26
0
파일: clk-main.c 프로젝트: 24hours/linux
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;
}
예제 #27
0
파일: clk-main.c 프로젝트: 24hours/linux
static unsigned long clk_main_recalc_rate(struct at91_pmc *pmc,
					  unsigned long parent_rate)
{
	u32 tmp;

	if (parent_rate)
		return parent_rate;

	tmp = pmc_read(pmc, AT91_CKGR_MCFR);
	if (!(tmp & AT91_PMC_MAINRDY))
		return 0;

	return ((tmp & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV;
}
예제 #28
0
파일: clk-main.c 프로젝트: 24hours/linux
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;
}
예제 #29
0
파일: clk-main.c 프로젝트: 24hours/linux
static struct clk * __init
at91_clk_register_sam9x5_main(struct at91_pmc *pmc,
			      unsigned int irq,
			      const char *name,
			      const char **parent_names,
			      int num_parents)
{
	int ret;
	struct clk_sam9x5_main *clkmain;
	struct clk *clk = NULL;
	struct clk_init_data init;

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

	if (!parent_names || !num_parents)
		return ERR_PTR(-EINVAL);

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

	init.name = name;
	init.ops = &sam9x5_main_ops;
	init.parent_names = parent_names;
	init.num_parents = num_parents;
	init.flags = CLK_SET_PARENT_GATE;

	clkmain->hw.init = &init;
	clkmain->pmc = pmc;
	clkmain->irq = irq;
	clkmain->parent = !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) &
			     AT91_PMC_MOSCEN);
	init_waitqueue_head(&clkmain->wait);
	irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN);
	ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler,
			  IRQF_TRIGGER_HIGH, name, clkmain);
	if (ret)
		return ERR_PTR(ret);

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

	return clk;
}
예제 #30
0
bool tegra_powergate_is_powered(int id)
{
	u32 status;

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

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

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

	return !!status;
}