From patchwork Wed Jan 9 07:03:42 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Abhilash Kesavan X-Patchwork-Id: 1950931 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork2.kernel.org (Postfix) with ESMTP id 00B06DF2EB for ; Wed, 9 Jan 2013 06:58:41 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TspZj-0008Rq-2S; Wed, 09 Jan 2013 06:55:47 +0000 Received: from mailout4.samsung.com ([203.254.224.34]) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TspZc-0008RU-Oe for linux-arm-kernel@lists.infradead.org; Wed, 09 Jan 2013 06:55:43 +0000 Received: from epcpsbgm1.samsung.com (epcpsbgm1 [203.254.230.26]) by mailout4.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0MGC00FGPJ8KBLS0@mailout4.samsung.com> for linux-arm-kernel@lists.infradead.org; Wed, 09 Jan 2013 15:55:32 +0900 (KST) Received: from epcpsbgm1.samsung.com ( [172.20.52.123]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 49.CD.01231.4641DE05; Wed, 09 Jan 2013 15:55:32 +0900 (KST) X-AuditID: cbfee61a-b7fa66d0000004cf-4a-50ed1464fc44 Received: from epmmp2 ( [203.254.227.17]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id F8.CD.01231.4641DE05; Wed, 09 Jan 2013 15:55:32 +0900 (KST) Received: from abhilash-ubuntu.sisodomain.com ([107.108.73.92]) by mmp2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0MGC00JLYJ82TQA0@mmp2.samsung.com> for linux-arm-kernel@lists.infradead.org; Wed, 09 Jan 2013 15:55:32 +0900 (KST) From: Abhilash Kesavan To: linux-arm-kernel@lists.infradead.org, kgene.kim@samsung.com Subject: [PATCH] ARM: EXYNOS5: Add g3d clock hierarchy Date: Wed, 09 Jan 2013 12:33:42 +0530 Message-id: <1357715022-5728-1-git-send-email-a.kesavan@samsung.com> X-Mailer: git-send-email 1.7.9.5 DLP-Filter: Pass X-MTR: 20000000000000000@CPGS X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrALMWRmVeSWpSXmKPExsWyRsSkWjdF5G2Awe2NOhabHl9jdWD02Lyk PoAxissmJTUnsyy1SN8ugSvj4u0/TAXb/SpW/tzA1sD4xqGLkZNDQsBE4vvsi6wQtpjEhXvr 2boYuTiEBJYySjQvvcbcxcgBVrSktRQiPp1R4ljHJSaQBiGB7UwSO2Zbg9hsAnoSC/59ZQax RQTsJVacOAlmMwvoSGyYv54FxBYWMJOY0tLPCjKTRUBV4tNeWZAwr4CLxJ+GnSwQqxQk5kyy AQmzCAhIfJt8CCosK7HpADPIBRICO9gkdr45ywRxsqTEwRU3WCYwCi5gZFjFKJpakFxQnJSe a6hXnJhbXJqXrpecn7uJERhMp/89k9rBuLLB4hCjAAejEg+v5cw3AUKsiWXFlbmHGCU4mJVE eO96A4V4UxIrq1KL8uOLSnNSiw8x+gBdMpFZSjQ5HxjoeSXxhsYm5qbGppZGRmampjiElcR5 GU89CRASSE8sSc1OTS1ILYIZx8TBKdXA2Fd0/9aCiwHWCk/WLnnkPEVf7fUb/bPf3HI9Pj9c taZkSvGb4qhvz+V+Tkre8bbI7sfCy/IrtPv6M+PWnp0g8W5bonSpXen1VXl1kQf7HvvJ1lVP u8Db4HuSL0W4LPtqveT0Q7Fzr6ReEPDrf7TiZchfFz0rnw2XnKJ1Ocs4tE5mXeS9/M3TXoml OCPRUIu5qDgRAPCSIo5TAgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrPLMWRmVeSWpSXmKPExsVy+t9jQd0UkbcBBrvnKVtsenyN1YHRY/OS +gDGqAZGm4zUxJTUIoXUvOT8lMy8dFsl7+B453hTMwNDXUNLC3MlhbzE3FRbJRefAF23zByg qUoKZYk5pUChgMTiYiV9O0wTQkPcdC1gGiN0fUOC4HqMDNBAwhrGjIu3/zAVbPerWPlzA1sD 4xuHLkYODgkBE4klraVdjJxAppjEhXvr2boYuTiEBKYzShzruMQEkhAS2M4ksWO2NYjNJqAn seDfV2YQW0TAXmLFiZNgNrOAjsSG+etZQGxhATOJKS39rCDzWQRUJT7tlQUJ8wq4SPxp2MkC sVZBYs4kmwmM3AsYGVYxiqYWJBcUJ6XnGuoVJ+YWl+al6yXn525iBIfqM6kdjCsbLA4xCnAw KvHwWs58EyDEmlhWXJl7iFGCg1lJhPeuN1CINyWxsiq1KD++qDQntfgQow/Q7onMUqLJ+cA4 yiuJNzQ2MTc1NrU0sTAxs8QhrCTOy3jqSYCQQHpiSWp2ampBahHMOCYOTqkGRqbDr29Ne8nY 3hUueunEfp/181XLd98qOun1OW+GvW787QApiYM3evSPMS+aNcOLJT7ur/zLX7f22XrNPhmt mficuyDp0/+mQ7dftZ66lC7XomiTFzdFJmLqqorePt9V04ONCjaxnZ2qyN9zWP9d9IQkhv8u fyxc7pn7usy3UOFa9c5n1xa9LCWW4oxEQy3mouJEALVWfOqCAgAA X-CFilter-Loop: Reflected X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130109_015541_431299_6D0174F2 X-CRM114-Status: GOOD ( 17.34 ) X-Spam-Score: -7.6 (-------) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-7.6 points) pts rule name description ---- ---------------------- -------------------------------------------------- -5.0 RCVD_IN_DNSWL_HI RBL: Sender listed at http://www.dnswl.org/, high trust [203.254.224.34 listed in list.dnswl.org] -0.0 SPF_HELO_PASS SPF: HELO matches SPF record -0.7 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Abhilash Kesavan X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Add G3D clock support for Exynos5. To setup an initial frequency of 533MHz for the G3D block we need to have the parent source clock of MOUTACLK_400_G3D as sclk_gpll and the divisor register as 0. Signed-off-by: Abhilash Kesavan --- arch/arm/mach-exynos/clock-exynos5.c | 150 ++++++++++++++++++++++-- arch/arm/mach-exynos/include/mach/regs-clock.h | 4 + arch/arm/plat-samsung/include/plat/s5p-clock.h | 1 + 3 files changed, 146 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-exynos/clock-exynos5.c b/arch/arm/mach-exynos/clock-exynos5.c index 0208c3a..9b2bbf0 100644 --- a/arch/arm/mach-exynos/clock-exynos5.c +++ b/arch/arm/mach-exynos/clock-exynos5.c @@ -173,6 +173,11 @@ static int exynos5_clk_ip_mfc_ctrl(struct clk *clk, int enable) return s5p_gatectrl(EXYNOS5_CLKGATE_IP_MFC, clk, enable); } +static int exynos5_clk_ip_g3d_ctrl(struct clk *clk, int enable) +{ + return s5p_gatectrl(EXYNOS5_CLKGATE_IP_G3D, clk, enable); +} + static int exynos5_clk_ip_peric_ctrl(struct clk *clk, int enable) { return s5p_gatectrl(EXYNOS5_CLKGATE_IP_PERIC, clk, enable); @@ -205,6 +210,23 @@ static int exynos5_clk_hdmiphy_ctrl(struct clk *clk, int enable) /* Core list of CMU_CPU side */ +/* GPLL clock output */ +static struct clk clk_fout_gpll = { + .name = "fout_gpll", + .id = -1, +}; + +/* Possible clock sources for GPLL Mux */ +static struct clk *clk_src_gpll_list[] = { + [0] = &clk_fin_gpll, + [1] = &clk_fout_gpll, +}; + +static struct clksrc_sources clk_src_gpll = { + .sources = clk_src_gpll_list, + .nr_sources = ARRAY_SIZE(clk_src_gpll_list), +}; + static struct clksrc_clk exynos5_clk_mout_apll = { .clk = { .name = "mout_apll", @@ -484,12 +506,40 @@ static struct clksrc_sources exynos5_clkset_aclk = { .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_top_list), }; -static struct clksrc_clk exynos5_clk_aclk_400 = { +static struct clksrc_clk exynos5_clk_mout_gpll = { .clk = { - .name = "aclk_400", + .name = "mout_gpll", + }, + .sources = &clk_src_gpll, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP2, .shift = 28, .size = 1 }, +}; + +/* For ACLK_400_G3D_MID */ +static struct clksrc_clk exynos5_clk_aclk_400_g3d_mid = { + .clk = { + .name = "aclk_400_g3d_mid", }, .sources = &exynos5_clkset_aclk, .reg_src = { .reg = EXYNOS5_CLKSRC_TOP0, .shift = 20, .size = 1 }, +}; + +/* For ACLK_400_G3D */ +struct clk *exynos5_clkset_aclk_g3d_list[] = { + [0] = &exynos5_clk_aclk_400_g3d_mid.clk, + [1] = &exynos5_clk_mout_gpll.clk, +}; + +struct clksrc_sources exynos5_clkset_aclk_g3d = { + .sources = exynos5_clkset_aclk_g3d_list, + .nr_sources = ARRAY_SIZE(exynos5_clkset_aclk_g3d_list), +}; + +static struct clksrc_clk exynos5_clk_aclk_400_g3d = { + .clk = { + .name = "aclk_400_g3d", + }, + .sources = &exynos5_clkset_aclk_g3d, + .reg_src = { .reg = EXYNOS5_CLKSRC_TOP1, .shift = 28, .size = 1 }, .reg_div = { .reg = EXYNOS5_CLKDIV_TOP0, .shift = 24, .size = 3 }, }; @@ -952,6 +1002,10 @@ static struct clk exynos5_init_clocks_off[] = { .enable = &exynos5_clk_ip_acp_ctrl, .ops = &exynos5_gate_clk_ops, .ctrlbit = (1 << 7) + }, { + .name = "g3d", + .enable = exynos5_clk_ip_g3d_ctrl, + .ctrlbit = ((1 << 1) | (1 << 0)), } }; @@ -1342,6 +1396,7 @@ static struct clksrc_clk *exynos5_sysclks[] = { &exynos5_clk_mout_cpll, &exynos5_clk_mout_epll, &exynos5_clk_mout_mpll, + &exynos5_clk_mout_gpll, &exynos5_clk_mout_mpll_fout, &exynos5_clk_mout_mpll_user, &exynos5_clk_vpllsrc, @@ -1350,7 +1405,8 @@ static struct clksrc_clk *exynos5_sysclks[] = { &exynos5_clk_dout_armclk, &exynos5_clk_dout_arm2clk, &exynos5_clk_cdrex, - &exynos5_clk_aclk_400, + &exynos5_clk_aclk_400_g3d, + &exynos5_clk_aclk_400_g3d_mid, &exynos5_clk_aclk_333, &exynos5_clk_aclk_266, &exynos5_clk_aclk_200, @@ -1413,6 +1469,76 @@ static struct clk_lookup exynos5_clk_lookup[] = { CLKDEV_INIT("exynos5-fb.1", "lcd", &exynos5_clk_fimd1), }; +static u32 exynos5_gpll_div[][6] = { + /* rate, P, M, S, AFC_DNB, AFC */ + {1400000000, 3, 175, 0, 0, 0}, + { 800000000, 3, 100, 0, 0, 0}, + { 667000000, 7, 389, 1, 0, 0}, + { 600000000, 4, 200, 1, 0, 0}, + { 533000000, 12, 533, 1, 0, 0}, + { 450000000, 12, 450, 1, 0, 0}, + { 400000000, 3, 100, 1, 0, 0}, + { 333000000, 4, 222, 2, 0, 0}, + { 200000000, 3, 100, 2, 0, 0}, +}; + +static unsigned long exynos5_gpll_get_rate(struct clk *clk) +{ + return clk->rate; +} + +static int exynos5_gpll_set_rate(struct clk *clk, unsigned long rate) +{ + unsigned int gpll_con0; + unsigned int locktime; + unsigned int tmp; + unsigned int i; + + /* Return if no rate changed */ + if (clk->rate == rate) + return 0; + + gpll_con0 = __raw_readl(EXYNOS5_GPLL_CON0); + gpll_con0 &= ~(PLL35XX_MDIV_MASK << PLL35XX_MDIV_SHIFT | + PLL35XX_PDIV_MASK << PLL35XX_PDIV_SHIFT | + PLL35XX_SDIV_MASK << PLL35XX_SDIV_SHIFT); + + for (i = 0; i < ARRAY_SIZE(exynos5_gpll_div); i++) { + if (exynos5_gpll_div[i][0] == rate) { + gpll_con0 |= + exynos5_gpll_div[i][1] << PLL35XX_PDIV_SHIFT; + gpll_con0 |= + exynos5_gpll_div[i][2] << PLL35XX_MDIV_SHIFT; + gpll_con0 |= + exynos5_gpll_div[i][3] << PLL35XX_SDIV_SHIFT; + break; + } + } + + if (i == ARRAY_SIZE(exynos5_gpll_div)) { + pr_err("%s: Invalid GPLL clock frequency\n", __func__); + return -EINVAL; + } + + locktime = 270 * exynos5_gpll_div[i][1] + 1; + __raw_writel(locktime, EXYNOS5_GPLL_LOCK); + + __raw_writel(gpll_con0, EXYNOS5_GPLL_CON0); + + do { + tmp = __raw_readl(EXYNOS5_GPLL_CON0); + } while (!(tmp & (0x1 << EXYNOS5_GPLLCON0_LOCKED_SHIFT))); + + clk->rate = rate; + + return 0; +} + +static struct clk_ops exynos5_gpll_ops = { + .get_rate = exynos5_gpll_get_rate, + .set_rate = exynos5_gpll_set_rate, +}; + static unsigned long exynos5_epll_get_rate(struct clk *clk) { return clk->rate; @@ -1425,6 +1551,7 @@ static struct clk *exynos5_clks[] __initdata = { &clk_fout_bpll_div2, &clk_fout_cpll, &clk_fout_mpll_div2, + &clk_fout_gpll, &exynos5_clk_armclk, }; @@ -1551,11 +1678,12 @@ void __init_or_cpufreq exynos5_setup_clocks(void) unsigned long mpll; unsigned long epll; unsigned long vpll; + unsigned long gpll; unsigned long vpllsrc; unsigned long xtal; unsigned long armclk; unsigned long mout_cdrex; - unsigned long aclk_400; + unsigned long aclk_400_g3d; unsigned long aclk_333; unsigned long aclk_266; unsigned long aclk_200; @@ -1587,6 +1715,8 @@ void __init_or_cpufreq exynos5_setup_clocks(void) vpll = s5p_get_pll36xx(vpllsrc, __raw_readl(EXYNOS5_VPLL_CON0), __raw_readl(EXYNOS5_VPLL_CON1)); + gpll = s5p_get_pll35xx(xtal, __raw_readl(EXYNOS5_GPLL_CON0)); + clk_fout_apll.ops = &exynos5_fout_apll_ops; clk_fout_bpll.rate = bpll; clk_fout_bpll_div2.rate = bpll >> 1; @@ -1595,30 +1725,32 @@ void __init_or_cpufreq exynos5_setup_clocks(void) clk_fout_mpll_div2.rate = mpll >> 1; clk_fout_epll.rate = epll; clk_fout_vpll.rate = vpll; + clk_fout_gpll.rate = gpll; printk(KERN_INFO "EXYNOS5: PLL settings, A=%ld, B=%ld, C=%ld\n" - "M=%ld, E=%ld V=%ld", - apll, bpll, cpll, mpll, epll, vpll); + "M=%ld, E=%ld V=%ld G=%ld", + apll, bpll, cpll, mpll, epll, vpll, gpll); armclk = clk_get_rate(&exynos5_clk_armclk); mout_cdrex = clk_get_rate(&exynos5_clk_cdrex.clk); - aclk_400 = clk_get_rate(&exynos5_clk_aclk_400.clk); + aclk_400_g3d = clk_get_rate(&exynos5_clk_aclk_400_g3d.clk); aclk_333 = clk_get_rate(&exynos5_clk_aclk_333.clk); aclk_266 = clk_get_rate(&exynos5_clk_aclk_266.clk); aclk_200 = clk_get_rate(&exynos5_clk_aclk_200.clk); aclk_166 = clk_get_rate(&exynos5_clk_aclk_166.clk); aclk_66 = clk_get_rate(&exynos5_clk_aclk_66.clk); - printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400=%ld\n" + printk(KERN_INFO "EXYNOS5: ARMCLK=%ld, CDREX=%ld, ACLK400G3D=%ld\n" "ACLK333=%ld, ACLK266=%ld, ACLK200=%ld\n" "ACLK166=%ld, ACLK66=%ld\n", - armclk, mout_cdrex, aclk_400, + armclk, mout_cdrex, aclk_400_g3d, aclk_333, aclk_266, aclk_200, aclk_166, aclk_66); clk_fout_epll.ops = &exynos5_epll_ops; + clk_fout_gpll.ops = &exynos5_gpll_ops; if (clk_set_parent(&exynos5_clk_mout_epll.clk, &clk_fout_epll)) printk(KERN_ERR "Unable to set parent %s of clock %s.\n", diff --git a/arch/arm/mach-exynos/include/mach/regs-clock.h b/arch/arm/mach-exynos/include/mach/regs-clock.h index d36ad76..60ebf87 100644 --- a/arch/arm/mach-exynos/include/mach/regs-clock.h +++ b/arch/arm/mach-exynos/include/mach/regs-clock.h @@ -283,6 +283,8 @@ #define EXYNOS5_VPLL_CON0 EXYNOS_CLKREG(0x10140) #define EXYNOS5_VPLL_CON1 EXYNOS_CLKREG(0x10144) #define EXYNOS5_VPLL_CON2 EXYNOS_CLKREG(0x10148) +#define EXYNOS5_GPLL_CON0 EXYNOS_CLKREG(0x10150) +#define EXYNOS5_GPLL_CON1 EXYNOS_CLKREG(0x10154) #define EXYNOS5_CPLL_CON0 EXYNOS_CLKREG(0x10120) #define EXYNOS5_CLKSRC_TOP0 EXYNOS_CLKREG(0x10210) @@ -344,8 +346,10 @@ #define EXYNOS5_PLL_DIV2_SEL EXYNOS_CLKREG(0x20A24) #define EXYNOS5_EPLL_LOCK EXYNOS_CLKREG(0x10030) +#define EXYNOS5_GPLL_LOCK EXYNOS_CLKREG(0x10050) #define EXYNOS5_EPLLCON0_LOCKED_SHIFT (29) +#define EXYNOS5_GPLLCON0_LOCKED_SHIFT (29) #define PWR_CTRL1_CORE2_DOWN_RATIO (7 << 28) #define PWR_CTRL1_CORE1_DOWN_RATIO (7 << 16) diff --git a/arch/arm/plat-samsung/include/plat/s5p-clock.h b/arch/arm/plat-samsung/include/plat/s5p-clock.h index 8364b4b..aa8dcdd 100644 --- a/arch/arm/plat-samsung/include/plat/s5p-clock.h +++ b/arch/arm/plat-samsung/include/plat/s5p-clock.h @@ -19,6 +19,7 @@ #define clk_fin_apll clk_ext_xtal_mux #define clk_fin_bpll clk_ext_xtal_mux +#define clk_fin_gpll clk_ext_xtal_mux #define clk_fin_cpll clk_ext_xtal_mux #define clk_fin_mpll clk_ext_xtal_mux #define clk_fin_epll clk_ext_xtal_mux