From patchwork Wed Aug 22 06:44:24 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajeshwari Shinde X-Patchwork-Id: 10856 Return-Path: X-Original-To: patchwork@peony.canonical.com Delivered-To: patchwork@peony.canonical.com Received: from fiordland.canonical.com (fiordland.canonical.com [91.189.94.145]) by peony.canonical.com (Postfix) with ESMTP id F2F0223F46 for ; Wed, 22 Aug 2012 06:39:40 +0000 (UTC) Received: from mail-gg0-f180.google.com (mail-gg0-f180.google.com [209.85.161.180]) by fiordland.canonical.com (Postfix) with ESMTP id 0BC84A18D73 for ; Wed, 22 Aug 2012 06:39:29 +0000 (UTC) Received: by mail-gg0-f180.google.com with SMTP id i2so471749ggm.11 for ; Tue, 21 Aug 2012 23:39:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-forwarded-to:x-forwarded-for:delivered-to:received-spf:x-auditid :from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references :x-brightmail-tracker:x-tm-as-mml:x-gm-message-state; bh=XArMukmNgBNJxBkR9DYqSaK7q7n43cyuEJAAJiX7o4Q=; b=eAc+q4FMWRv78fMyq2Q+CJY8nuaKOjrI24+Fdhl0yUHjacc/mMW1BASM5CnkHDMzJn lJrIDasjzcPzEaASqrLKR6296LAFrLzj2IrRLc7P58zQ4afsMZ/oP+mxN5y1JgSmVBFz lduMXrxh3N3HPcLVUHvXRgBFoa8blzb3bGaYzswJmJ1xvKJSHv0JbBi8qlbTNOIL8rbN RGIT3x9cC/TocfkdIRWwaoyQ8RYzB0kpoJ6HQ/SpY93P/oTe6gNLZDEsQMLXXFXtQnpr sya1GIyWNsEpzFGr2CmyeNS3mqs4WjmsEbasSdPR65VIsKNc7i1grNIp36uvDY3dqj7P oHtA== Received: by 10.50.45.162 with SMTP id o2mr1096527igm.0.1345617580135; Tue, 21 Aug 2012 23:39:40 -0700 (PDT) X-Forwarded-To: linaro-patchwork@canonical.com X-Forwarded-For: patch@linaro.org linaro-patchwork@canonical.com Delivered-To: patches@linaro.org Received: by 10.50.184.232 with SMTP id ex8csp185558igc; Tue, 21 Aug 2012 23:39:39 -0700 (PDT) Received: by 10.68.238.138 with SMTP id vk10mr50902950pbc.75.1345617579409; Tue, 21 Aug 2012 23:39:39 -0700 (PDT) Received: from mailout2.samsung.com (mailout2.samsung.com. [203.254.224.25]) by mx.google.com with ESMTP id qp4si6608216pbc.68.2012.08.21.23.39.39; Tue, 21 Aug 2012 23:39:39 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of rajeshwari.s@samsung.com designates 203.254.224.25 as permitted sender) client-ip=203.254.224.25; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of rajeshwari.s@samsung.com designates 203.254.224.25 as permitted sender) smtp.mail=rajeshwari.s@samsung.com Received: from epcpsbgm1.samsung.com (mailout2.samsung.com [203.254.224.25]) by mailout2.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0M95006AV95RLD40@mailout2.samsung.com>; Wed, 22 Aug 2012 15:39:31 +0900 (KST) X-AuditID: cbfee61a-b7fc66d0000043b7-04-50347ea3a2c8 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm1.samsung.com (EPCPMTA) with SMTP id 82.87.17335.3AE74305; Wed, 22 Aug 2012 15:39:31 +0900 (KST) Received: from rajeshwari-linux.sisodomain.com ([107.108.215.115]) by mmp1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTPA id <0M95002KV954XC70@mmp1.samsung.com>; Wed, 22 Aug 2012 15:39:31 +0900 (KST) From: Rajeshwari Shinde To: u-boot@lists.denx.de Cc: patches@linaro.org, alim.akhtar@samsung.com, sjg@chromium.org, mk7.kang@samsung.com, chander.kashyap@linaro.org, vapier@gentoo.org, amdyer@gmail.com Subject: [PATCH 8/9 V2] EXYNOS: Add clock for I2S Date: Wed, 22 Aug 2012 12:14:24 +0530 Message-id: <1345617865-14199-9-git-send-email-rajeshwari.s@samsung.com> X-Mailer: git-send-email 1.7.4.4 In-reply-to: <1345617865-14199-1-git-send-email-rajeshwari.s@samsung.com> References: <1345617865-14199-1-git-send-email-rajeshwari.s@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOJMWRmVeSWpSXmKPExsVy+t9jAd3FdSYBBl/naVk8XH+TxWLK4S8s Dkwed67tYQtgjOKySUnNySxLLdK3S+DKWPjxKVtBv3HFs7YjzA2Mi7W6GDk5JARMJJ42L2KG sMUkLtxbzwZiCwksYpS4vzC3i5ELyJ7IJNH0fjFYgk3ASGLryWmMILaIgITEr/6rYDazwBxG iRMvRUBsYQFDifv9D1lAbBYBVYnja04xgdi8Ah4Sr3qns0AsU5A4NvUrK4jNKeAp8fn5HCaI xR4Sj3+cYZ7AyLuAkWEVo2hqQXJBcVJ6rqFecWJucWleul5yfu4mRrD3n0ntYFzZYHGIUYCD UYmH1yPBJECINbGsuDL3EKMEB7OSCO/1WqAQb0piZVVqUX58UWlOavEhRmkOFiVxXv4+wwAh gfTEktTs1NSC1CKYLBMHp1QDYwfTf+F9Lb1vbPryHu4PXzxpYbm/vFRc4wu177d5OO5nhOga 56ls0qsP5D6noO9kFTT5T06/9DIRzZp6Rb+lX9Zv53JlUV4za8nba8fidpVe/cI4u/SE5rUp R22Z369d/PRz+bNwrlPT99ppp7ic3KxqJrA+NPPfAp7J85cUu5jVqjRWnmLaqsRSnJFoqMVc VJwIALYseO/6AQAA X-TM-AS-MML: No X-Gm-Message-State: ALoCoQl/jIGq2h+JSoLv4/YfKfs75CIJtRPKr9f4usyQRTZ22SJUYykgYjW6Pc22YbKW+DFUaEbv This patch adds clock support for I2S Signed-off-by: R. Chandrasekar Signed-off-by: Rajeshwari Shinde --- Changes in V2: - None arch/arm/cpu/armv7/exynos/clock.c | 119 ++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-exynos/clk.h | 3 + arch/arm/include/asm/arch-exynos/clock.h | 29 +++++++ 3 files changed, 151 insertions(+), 0 deletions(-) diff --git a/arch/arm/cpu/armv7/exynos/clock.c b/arch/arm/cpu/armv7/exynos/clock.c index 44dff2b..691f6d4 100644 --- a/arch/arm/cpu/armv7/exynos/clock.c +++ b/arch/arm/cpu/armv7/exynos/clock.c @@ -26,6 +26,16 @@ #include #include +/* Epll Clock division values to achive different frequency output */ +static struct st_epll_con_val epll_div[] = { + { 192000000, 0, 48, 3, 1, 0 }, + { 180000000, 0, 45, 3, 1, 0 }, + { 73728000, 1, 73, 3, 3, 47710 }, + { 67737600, 1, 90, 4, 3, 20762 }, + { 49152000, 0, 49, 3, 3, 9961 }, + { 45158400, 0, 45, 3, 3, 10381 }, + { 180633600, 0, 45, 3, 1, 10381 } +}; /* exynos4: return pll clock frequency */ static unsigned long exynos4_get_pll_clk(int pllreg) { @@ -848,6 +858,92 @@ static int exynos5_spi_set_clock_rate(enum periph_id periph_id, return 0; } +int exynos5_clock_epll_set_rate(unsigned long rate) +{ + unsigned int epll_con, epll_con_k; + unsigned int i; + unsigned int lockcnt; + unsigned int start; + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + + epll_con = readl(&clk->epll_con0); + epll_con &= ~((EPLL_CON0_LOCK_DET_EN_MASK << + EPLL_CON0_LOCK_DET_EN_SHIFT) | + EPLL_CON0_MDIV_MASK << EPLL_CON0_MDIV_SHIFT | + EPLL_CON0_PDIV_MASK << EPLL_CON0_PDIV_SHIFT | + EPLL_CON0_SDIV_MASK << EPLL_CON0_SDIV_SHIFT); + + for (i = 0; i < ARRAY_SIZE(epll_div); i++) { + if (epll_div[i].freq_out == rate) + break; + } + + if (i == ARRAY_SIZE(epll_div)) + return -1; + + epll_con_k = epll_div[i].k_dsm << 0; + epll_con |= epll_div[i].en_lock_det << EPLL_CON0_LOCK_DET_EN_SHIFT; + epll_con |= epll_div[i].m_div << EPLL_CON0_MDIV_SHIFT; + epll_con |= epll_div[i].p_div << EPLL_CON0_PDIV_SHIFT; + epll_con |= epll_div[i].s_div << EPLL_CON0_SDIV_SHIFT; + + /* + * Required period ( in cycles) to genarate a stable clock output. + * The maximum clock time can be up to 3000 * PDIV cycles of PLLs + * frequency input (as per spec) + */ + lockcnt = 3000 * epll_div[i].p_div; + + writel(lockcnt, &clk->epll_lock); + writel(epll_con, &clk->epll_con0); + writel(epll_con_k, &clk->epll_con1); + + start = get_timer(0); + + while (!(readl(&clk->epll_con0) & + (0x1 << EXYNOS5_EPLLCON0_LOCKED_SHIFT))) { + if (get_timer(start) > TIMEOUT_EPLL_LOCK) { + debug("%s: Timeout waiting for EPLL lock\n", __func__); + return -1; + } + } + return 0; +} + +void exynos5_clock_select_i2s_clk_source(void) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + + clrsetbits_le32(&clk->src_peric1, AUDIO1_SEL_MASK, + (CLK_SRC_SCLK_EPLL)); +} + +int exynos5_clock_set_i2s_clk_prescaler(unsigned int src_frq, + unsigned int dst_frq) +{ + struct exynos5_clock *clk = + (struct exynos5_clock *)samsung_get_base_clock(); + unsigned int div; + + if ((dst_frq == 0) || (src_frq == 0)) { + debug("%s: Invalid requency input for prescaler\n", __func__); + debug("src frq = %d des frq = %d ", src_frq, dst_frq); + return -1; + } + + div = (src_frq / dst_frq); + if (div > AUDIO_1_RATIO_MASK) { + debug("%s: Frequency ratio is out of range\n", __func__); + debug("src frq = %d des frq = %d ", src_frq, dst_frq); + return -1; + } + clrsetbits_le32(&clk->div_peric4, AUDIO_1_RATIO_MASK, + (div & AUDIO_1_RATIO_MASK)); + return 0; +} + unsigned long get_pll_clk(int pllreg) { if (cpu_is_exynos5()) @@ -927,3 +1023,26 @@ int spi_set_clock_rate(enum periph_id periph_id, unsigned int rate) else return 0; } + +int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq) +{ + + if (cpu_is_exynos5()) + return exynos5_clock_set_i2s_clk_prescaler(src_frq, dst_frq); + else + return 0; +} + +void clock_select_i2s_clk_source(void) +{ + if (cpu_is_exynos5()) + exynos5_clock_select_i2s_clk_source(); +} + +int clock_epll_set_rate(unsigned long rate) +{ + if (cpu_is_exynos5()) + return exynos5_clock_epll_set_rate(rate); + else + return 0; +} diff --git a/arch/arm/include/asm/arch-exynos/clk.h b/arch/arm/include/asm/arch-exynos/clk.h index 4e51402..f32c634 100644 --- a/arch/arm/include/asm/arch-exynos/clk.h +++ b/arch/arm/include/asm/arch-exynos/clk.h @@ -41,4 +41,7 @@ unsigned long get_lcd_clk(void); void set_lcd_clk(void); void set_mipi_clk(void); int spi_set_clock_rate(enum periph_id periph_id, unsigned int rate); +void clock_select_i2s_clk_source(void); +int clock_set_i2s_clk_prescaler(unsigned int src_frq, unsigned int dst_frq); +int clock_epll_set_rate(unsigned long rate); #endif diff --git a/arch/arm/include/asm/arch-exynos/clock.h b/arch/arm/include/asm/arch-exynos/clock.h index fce38ef..1df49a9 100644 --- a/arch/arm/include/asm/arch-exynos/clock.h +++ b/arch/arm/include/asm/arch-exynos/clock.h @@ -595,9 +595,38 @@ struct exynos5_clock { unsigned int pll_div2_sel; unsigned char res123[0xf5d8]; }; + +/* structure for epll configuration used in audio clock configuration */ +struct st_epll_con_val { + unsigned int freq_out; /* frequency out */ + unsigned int en_lock_det; /* enable lock detect */ + unsigned int m_div; /* m divider value */ + unsigned int p_div; /* p divider value */ + unsigned int s_div; /* s divider value */ + unsigned int k_dsm; /* k value of delta signal modulator */ +}; #endif #define MPLL_FOUT_SEL_SHIFT 4 +#define EXYNOS5_EPLLCON0_LOCKED_SHIFT 29 /* EPLL Locked bit position*/ +#define TIMEOUT_EPLL_LOCK 1000 + +#define AUDIO_0_RATIO_MASK 0x0f +#define AUDIO_1_RATIO_MASK 0x0f + +#define AUDIO1_SEL_MASK 0xf +#define CLK_SRC_SCLK_EPLL 0x7 + +/* CON0 bit-fields */ +#define EPLL_CON0_MDIV_MASK 0x1ff +#define EPLL_CON0_PDIV_MASK 0x3f +#define EPLL_CON0_SDIV_MASK 0x7 +#define EPLL_CON0_MDIV_SHIFT 16 +#define EPLL_CON0_PDIV_SHIFT 8 +#define EPLL_CON0_SDIV_SHIFT 0 +#define EPLL_CON0_LOCK_DET_EN_SHIFT 28 +#define EPLL_CON0_LOCK_DET_EN_MASK 1 + #define MPLL_FOUT_SEL_MASK 0x1 #define BPLL_FOUT_SEL_SHIFT 0 #define BPLL_FOUT_SEL_MASK 0x1