static void xgene_clk_disable(struct clk_hw *hw) { struct xgene_clk *pclk = to_xgene_clk(hw); unsigned long flags = 0; u32 data; if (pclk->lock) spin_lock_irqsave(pclk->lock, flags); if (pclk->param.csr_reg != NULL) { pr_debug("%s clock disabled\n", __clk_get_name(hw->clk)); /* First put the CSR in reset */ data = xgene_clk_read(pclk->param.csr_reg + pclk->param.reg_csr_offset); data |= pclk->param.reg_csr_mask; xgene_clk_write(data, pclk->param.csr_reg + pclk->param.reg_csr_offset); /* Second disable the clock */ data = xgene_clk_read(pclk->param.csr_reg + pclk->param.reg_clk_offset); data &= ~pclk->param.reg_clk_mask; xgene_clk_write(data, pclk->param.csr_reg + pclk->param.reg_clk_offset); } if (pclk->lock) spin_unlock_irqrestore(pclk->lock, flags); }
static int xgene_clk_pll_is_enabled(struct clk_hw *hw) { struct xgene_clk_pll *pllclk = to_xgene_clk_pll(hw); u32 data; data = xgene_clk_read(pllclk->reg + pllclk->pll_offset); pr_debug("%s pll %s\n", __clk_get_name(hw->clk), data & REGSPEC_RESET_F1_MASK ? "disabled" : "enabled"); return data & REGSPEC_RESET_F1_MASK ? 0 : 1; }
static int xgene_clk_enable(struct clk_hw *hw) { struct xgene_clk *pclk = to_xgene_clk(hw); unsigned long flags = 0; u32 data; phys_addr_t reg; if (pclk->lock) spin_lock_irqsave(pclk->lock, flags); if (pclk->param.csr_reg != NULL) { pr_debug("%s clock enabled\n", __clk_get_name(hw->clk)); reg = __pa(pclk->param.csr_reg); /* First enable the clock */ data = xgene_clk_read(pclk->param.csr_reg + pclk->param.reg_clk_offset); data |= pclk->param.reg_clk_mask; xgene_clk_write(data, pclk->param.csr_reg + pclk->param.reg_clk_offset); pr_debug("%s clock PADDR base %pa clk offset 0x%08X mask 0x%08X value 0x%08X\n", __clk_get_name(hw->clk), ®, pclk->param.reg_clk_offset, pclk->param.reg_clk_mask, data); /* Second enable the CSR */ data = xgene_clk_read(pclk->param.csr_reg + pclk->param.reg_csr_offset); data &= ~pclk->param.reg_csr_mask; xgene_clk_write(data, pclk->param.csr_reg + pclk->param.reg_csr_offset); pr_debug("%s CSR RESET PADDR base %pa csr offset 0x%08X mask 0x%08X value 0x%08X\n", __clk_get_name(hw->clk), ®, pclk->param.reg_csr_offset, pclk->param.reg_csr_mask, data); } if (pclk->lock) spin_unlock_irqrestore(pclk->lock, flags); return 0; }
static unsigned long xgene_clk_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct xgene_clk_pll *pllclk = to_xgene_clk_pll(hw); unsigned long fref; unsigned long fvco; u32 pll; u32 nref; u32 nout; u32 nfb; pll = xgene_clk_read(pllclk->reg + pllclk->pll_offset); if (pllclk->version <= 1) { if (pllclk->type == PLL_TYPE_PCP) { /* * PLL VCO = Reference clock * NF * PCP PLL = PLL_VCO / 2 */ nout = 2; fvco = parent_rate * (N_DIV_RD(pll) + 4); } else { /* * Fref = Reference Clock / NREF; * Fvco = Fref * NFB; * Fout = Fvco / NOUT; */ nref = CLKR_RD(pll) + 1; nout = CLKOD_RD(pll) + 1; nfb = CLKF_RD(pll); fref = parent_rate / nref; fvco = fref * nfb; } } else { /* * fvco = Reference clock * FBDIVC * PLL freq = fvco / NOUT */ nout = SC_OUTDIV2(pll) ? 2 : 3; fvco = parent_rate * SC_N_DIV_RD(pll); } pr_debug("%s pll recalc rate %ld parent %ld version %d\n", clk_hw_get_name(hw), fvco / nout, parent_rate, pllclk->version); return fvco / nout; }
static unsigned long xgene_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct xgene_clk *pclk = to_xgene_clk(hw); u32 data; if (pclk->param.divider_reg) { data = xgene_clk_read(pclk->param.divider_reg + pclk->param.reg_divider_offset); data >>= pclk->param.reg_divider_shift; data &= (1 << pclk->param.reg_divider_width) - 1; pr_debug("%s clock recalc rate %ld parent %ld\n", __clk_get_name(hw->clk), parent_rate / data, parent_rate); return parent_rate / data; } else {
static int xgene_clk_is_enabled(struct clk_hw *hw) { struct xgene_clk *pclk = to_xgene_clk(hw); u32 data = 0; if (pclk->param.csr_reg != NULL) { pr_debug("%s clock checking\n", __clk_get_name(hw->clk)); data = xgene_clk_read(pclk->param.csr_reg + pclk->param.reg_clk_offset); pr_debug("%s clock is %s\n", __clk_get_name(hw->clk), data & pclk->param.reg_clk_mask ? "enabled" : "disabled"); } if (pclk->param.csr_reg == NULL) return 1; return data & pclk->param.reg_clk_mask ? 1 : 0; }