Ejemplo n.º 1
0
static int sunxi_clk_periph_set_parent(struct clk_hw *hw, u8 index)
{
    unsigned long reg, flags = 0;
    struct sunxi_clk_periph *periph = to_clk_periph(hw);

    if(periph->flags & CLK_READONLY)
        return 0;
		
    if(!periph->mux.reg)
        return 0;
    if(periph->lock)
    {
        spin_lock_irqsave(periph->lock, flags);
        reg = periph_readl(periph,periph->mux.reg);
        reg = SET_BITS(periph->mux.shift, periph->mux.width, reg, index);
        periph_writel(periph,reg, periph->mux.reg);
        spin_unlock_irqrestore(periph->lock, flags);
    }
    else
    {
        reg = periph_readl(periph,periph->mux.reg);
        reg = SET_BITS(periph->mux.shift, periph->mux.width, reg, index);
        periph_writel(periph,reg, periph->mux.reg);
    }
    return 0;
}
Ejemplo n.º 2
0
static int __sunxi_clk_periph_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate)
{
    struct sunxi_clk_periph *periph = to_clk_periph(hw);
    struct sunxi_clk_periph_div *divider = &periph->divider;
    int i,j,m_max;
    int m=0,n=0;
    unsigned long cur_rate=0,new_rate=0;
    unsigned long cur_delta,new_delta;
    u32 reg;
    if(parent_rate == 4000000)
        m_max =1;
    else
        m_max = 8;
    for(i=0;i<m_max;i++)
        for(j=0;j<8;j++)
        {
            new_rate = parent_rate/(ac100_m_factor[i]*ac100_n_factor[j]);
            new_delta = (new_rate >rate)?(new_rate-rate):(rate-new_rate);
            cur_delta = (cur_rate >rate)?(cur_rate-rate):(rate-cur_rate);
            if(new_delta < cur_delta)
            {
                cur_rate = new_rate;
                m =i;
                n = j;
            }
        }
    reg = periph_readl(periph,divider->reg);
    if(divider->mwidth)
        reg = SET_BITS(divider->mshift, divider->mwidth, reg, m);
    if(divider->nwidth)
        reg = SET_BITS(divider->nshift, divider->nwidth, reg, n);
    periph_writel(periph,reg, divider->reg);
    return 0;
}
Ejemplo n.º 3
0
static int __sunxi_clk_periph_enable_shared(struct sunxi_clk_periph *periph)
{
    unsigned long reg;
    struct sunxi_clk_periph_gate *gate = &periph->gate;
    if(!periph->com_gate)
        return -1;        

    if(!periph->com_gate->val)
    {
        /* de-assert module */
        if(gate->reset && !(periph->flags & CLK_IGNORE_AUTORESET) && IS_SHARE_RST_GATE(periph)) {
            reg = periph_readl(periph,gate->reset);
            reg = SET_BITS(gate->rst_shift, 1, reg, 1);
            periph_writel(periph,reg, gate->reset);
        }
        /* enable bus gating */
        if(gate->bus && IS_SHARE_BUS_GATE(periph)) {
            reg = periph_readl(periph,gate->bus);
            reg = SET_BITS(gate->bus_shift, 1, reg, 1);
            periph_writel(periph,reg, gate->bus);
        }

        /* enable module gating */
        if(gate->enable&& IS_SHARE_MOD_GATE(periph)) {
            reg = periph_readl(periph,gate->enable);
            reg = SET_BITS(gate->enb_shift, 1, reg, 1);
            periph_writel(periph,reg, gate->enable);
        }

        /* enable dram gating */
        if(gate->dram&& IS_SHARE_MBUS_GATE(periph)) {
            reg = periph_readl(periph,gate->dram);
            reg = SET_BITS(gate->ddr_shift, 1, reg, 1);
            periph_writel(periph,reg, gate->dram);
        }       
    }
    periph->com_gate->val |= 1 << periph->com_gate_off;

    return 0;
}
Ejemplo n.º 4
0
static int __sunxi_clk_periph_enable(struct clk_hw *hw)
{
    unsigned long reg;
    struct sunxi_clk_periph *periph = to_clk_periph(hw);
    struct sunxi_clk_periph_gate *gate = &periph->gate;

    /* de-assert module */
    if(gate->reset && !(periph->flags & CLK_IGNORE_AUTORESET) && !IS_SHARE_RST_GATE(periph)) {
        reg = periph_readl(periph,gate->reset);
        reg = SET_BITS(gate->rst_shift, 1, reg, 1);
        periph_writel(periph,reg, gate->reset);
    }

    /* enable bus gating */
    if(gate->bus && !IS_SHARE_BUS_GATE(periph)) {
        reg = periph_readl(periph,gate->bus);
        reg = SET_BITS(gate->bus_shift, 1, reg, 1);
        periph_writel(periph,reg, gate->bus);
    }

    /* enable module gating */
    if(gate->enable&& !IS_SHARE_MOD_GATE(periph)) {
        reg = periph_readl(periph,gate->enable);
        if(periph->flags & CLK_REVERT_ENABLE)
            reg = SET_BITS(gate->enb_shift, 1, reg, 0);
        else
            reg = SET_BITS(gate->enb_shift, 1, reg, 1);
        periph_writel(periph,reg, gate->enable);
    }

    /* enable dram gating */
    if(gate->dram&& !IS_SHARE_MBUS_GATE(periph)) {
        reg = periph_readl(periph,gate->dram);
        reg = SET_BITS(gate->ddr_shift, 1, reg, 1);
        periph_writel(periph,reg, gate->dram);
    }

    return 0;
}