From patchwork Fri May 24 10:31:17 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Vikas C Sajjan X-Patchwork-Id: 2610381 Return-Path: X-Original-To: patchwork-linux-samsung-soc@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id A09ECDF24C for ; Fri, 24 May 2013 10:31:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1760264Ab3EXKbz (ORCPT ); Fri, 24 May 2013 06:31:55 -0400 Received: from mail-pb0-f54.google.com ([209.85.160.54]:39859 "EHLO mail-pb0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759437Ab3EXKby (ORCPT ); Fri, 24 May 2013 06:31:54 -0400 Received: by mail-pb0-f54.google.com with SMTP id ro12so4069580pbb.13 for ; Fri, 24 May 2013 03:31:54 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-gm-message-state; bh=sU3dgOp7/hgJ4jbbj8dG6FF3jPiD+eBTiazxl0YP8Qk=; b=NpJT06m4BTiMa4CXwvSnsSPWEzq6pGfRhJPuPqlh2+YznUH0wdeDEH6FP1unDaug8C PBHc92DHAllemrUTSe5WMF+i0FRobn2aPGymjEwzUjZkiNgEmLWJR8IW6GEOjBwKfOCW 5qR2UsgWP8L5ue9cnijZlZFGn3oM/be5BbL673Gh5QR1TzVknEKbr+8aIHviet3HNQry I6P2verXDi80dx8rpP7YJqkMijlArpd1aOrYf+KP7sb84tiHYHMNGAiUE4qMW28z0Bft MvBdE484H9W9o+WmICOP6VN+4o4/EJn4wMzWKmOd025KN+rKQo+homArLorxsnK6267f aA8w== X-Received: by 10.68.197.195 with SMTP id iw3mr16992156pbc.177.1369391514324; Fri, 24 May 2013 03:31:54 -0700 (PDT) Received: from localhost.localdomain ([115.113.119.130]) by mx.google.com with ESMTPSA id k8sm10164635pag.18.2013.05.24.03.31.49 for (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Fri, 24 May 2013 03:31:53 -0700 (PDT) From: Vikas Sajjan To: yadi.brar01@gmail.com, linux-samsung-soc@vger.kernel.org Cc: dianders@chromium.org, tomasz.figa@gmail.com, linux-arm-kernel@lists.infradead.org, kgene.kim@samsung.com, mturquette@linaro.org, thomas.abraham@linaro.org Subject: [RESEND PATCH 4/5] clk: samsung: Add set_rate() clk_ops for PLL36xx Date: Fri, 24 May 2013 16:01:17 +0530 Message-Id: <1369391478-7665-5-git-send-email-vikas.sajjan@linaro.org> X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1369391478-7665-1-git-send-email-vikas.sajjan@linaro.org> References: <1369391478-7665-1-git-send-email-vikas.sajjan@linaro.org> X-Gm-Message-State: ALoCoQnAM9dF0KzMtc+8qgbeK9Qu/qoc+38w6CIrk8FfeJJhvfhzmmFvTCp1K2V12BAarBIRsgyj Sender: linux-samsung-soc-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-samsung-soc@vger.kernel.org This patch adds set_rate and round_rate clk_ops for PLL36xx The round_rate() implementation as of now is dummy, it returns the same rate which is passed as input. Signed-off-by: Vikas Sajjan --- drivers/clk/samsung/clk-pll.c | 67 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 291cc9e..55ff5fd 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -224,6 +224,13 @@ struct clk * __init samsung_clk_register_pll35xx(const char *name, #define PLL36XX_MDIV_SHIFT (16) #define PLL36XX_PDIV_SHIFT (8) #define PLL36XX_SDIV_SHIFT (0) +#define PLL36XX_KDIV_SHIFT (0) +#define PLL36XX_LOCK_STAT_SHIFT (29) + +#define PLL36XX_MDIV(_tmp) ((_tmp) & (PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT)) +#define PLL36XX_PDIV(_tmp) ((_tmp) & (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT)) +#define PLL36XX_SDIV(_tmp) ((_tmp) & (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT)) +#define PLL36XX_KDIV(_tmp) ((_tmp) & (PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT)) static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) @@ -246,8 +253,65 @@ static unsigned long samsung_pll36xx_recalc_rate(struct clk_hw *hw, return (unsigned long)fvco; } +static long samsung_pll36xx_round_rate(struct clk_hw *hw, unsigned long drate, + unsigned long *prate) +{ + /* retruns the same 'drate' whichs comes as input */ + return drate; +} + +static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long parent_rate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 tmp, pll_con0, pll_con1, mdiv, pdiv, sdiv, kdiv; + struct samsung_pll_rate_table *rate; + + rate = samsung_get_pll_settings(pll, drate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, + drate, __clk_get_name(hw->clk)); + return -EINVAL; + } + + mdiv = PLL36XX_MDIV(rate->pll_con0); + pdiv = PLL36XX_PDIV(rate->pll_con0); + sdiv = PLL36XX_SDIV(rate->pll_con0); + kdiv = PLL36XX_KDIV(rate->pll_con1); + + pll_con0 = pll_readl(pll, PLL36XX_CON0_OFFSET); + pll_con1 = pll_readl(pll, PLL36XX_CON1_OFFSET); + + pll_con1 &= ~(PLL36XX_KDIV_MASK << PLL36XX_KDIV_SHIFT); + + /* Set PLL lock time. + Maximum lock time can be 3000 * PDIV cycles */ + pll_writel(pll, ((pdiv >> PLL36XX_PDIV_SHIFT) * 3000), + PLL36XX_LOCK_OFFSET); + + /* Change PLL PMS values */ + pll_con0 &= ~((PLL36XX_MDIV_MASK << PLL36XX_MDIV_SHIFT) | + (PLL36XX_PDIV_MASK << PLL36XX_PDIV_SHIFT) | + (PLL36XX_SDIV_MASK << PLL36XX_SDIV_SHIFT)); + pll_con0 |= mdiv | pdiv | sdiv; + pll_writel(pll, pll_con0, PLL36XX_CON0_OFFSET); + + pll_con1 |= kdiv; + pll_writel(pll, pll_con1, PLL36XX_CON1_OFFSET); + + /* wait_lock_time */ + do { + cpu_relax(); + tmp = pll_readl(pll, PLL36XX_CON0_OFFSET); + } while (!(tmp & (1 << PLL36XX_LOCK_STAT_SHIFT))); + + return 0; +} + static const struct clk_ops samsung_pll36xx_clk_ops = { .recalc_rate = samsung_pll36xx_recalc_rate, + .set_rate = samsung_pll36xx_set_rate, + .round_rate = samsung_pll36xx_round_rate, }; struct clk * __init samsung_clk_register_pll36xx(const char *name, @@ -280,6 +344,9 @@ struct clk * __init samsung_clk_register_pll36xx(const char *name, sort(pll->rate_table, pll->rate_count, sizeof(struct samsung_pll_rate_table), samsung_compare_rate, NULL); + } else { + samsung_pll35xx_clk_ops.round_rate = NULL; + samsung_pll35xx_clk_ops.set_rate = NULL; } clk = clk_register(NULL, &pll->hw);