From patchwork Tue Aug 14 05:45:31 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rajeshwari Shinde X-Patchwork-Id: 10722 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 BD48A23E02 for ; Tue, 14 Aug 2012 05:42:04 +0000 (UTC) Received: from mail-gh0-f180.google.com (mail-gh0-f180.google.com [209.85.160.180]) by fiordland.canonical.com (Postfix) with ESMTP id 706DFA1896A for ; Tue, 14 Aug 2012 05:42:04 +0000 (UTC) Received: by ghbg10 with SMTP id g10so12012ghb.11 for ; Mon, 13 Aug 2012 22:42:04 -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=N1aU+TSAgoUwAUj4+ssL0Fl2Lb6ndd84H+Qpub9Un8U=; b=YgQhd/VI2a5UBDw2Ue1i9EcOuX1msxfUjHWMFOCZIDBA4NirVvEdxr5dE/LVipKBha XDv94TCOotS1rIiIGXtPQtSVDuDQlM6TOZUCNTcNATUwGFujpkvV+dxZP/sbiKyFQKgY swhb0SexsGK+yc+iGN1lnoT8hAF+WtkDjv059hIKma7TjTMBiVAw3+V7ZkppW/XB64GT H1BNTexL1T6XT5sDPaQ+N2hM0vt7wIDV23cw63BTytdiCh7XLmy+rHxTWiOunrUD1Rur fcdHVQULwgXq0sqay80T368nDGz9nuuE0A7IoWkWP0Ucw4Tg029oHXMT0jp6SliIqHIo oE8A== Received: by 10.42.75.73 with SMTP id z9mr10823282icj.46.1344922923712; Mon, 13 Aug 2012 22:42:03 -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.200 with SMTP id ew8csp214507igc; Mon, 13 Aug 2012 22:42:03 -0700 (PDT) Received: by 10.68.238.166 with SMTP id vl6mr21176428pbc.96.1344922923111; Mon, 13 Aug 2012 22:42:03 -0700 (PDT) Received: from mailout1.samsung.com (mailout1.samsung.com. [203.254.224.24]) by mx.google.com with ESMTP id px5si1295188pbb.322.2012.08.13.22.42.02; Mon, 13 Aug 2012 22:42:03 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of rajeshwari.s@samsung.com designates 203.254.224.24 as permitted sender) client-ip=203.254.224.24; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of rajeshwari.s@samsung.com designates 203.254.224.24 as permitted sender) smtp.mail=rajeshwari.s@samsung.com Received: from epcpsbgm2.samsung.com (mailout1.samsung.com [203.254.224.24]) by mailout1.samsung.com (Oracle Communications Messaging Server 7u4-24.01(7.0.4.24.0) 64bit (built Nov 17 2011)) with ESMTP id <0M8Q00KEMD5AXGO0@mailout1.samsung.com>; Tue, 14 Aug 2012 14:42:01 +0900 (KST) X-AuditID: cbfee61b-b7faf6d00000476a-dc-5029e529f2e9 Received: from epmmp1.local.host ( [203.254.227.16]) by epcpsbgm2.samsung.com (EPCPMTA) with SMTP id 93.92.18282.925E9205; Tue, 14 Aug 2012 14:42:01 +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 <0M8Q00064D2QKU20@mmp1.samsung.com>; Tue, 14 Aug 2012 14:42:01 +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 Subject: [PATCH 8/9] EXYNOS: Add clock for I2S Date: Tue, 14 Aug 2012 11:15:31 +0530 Message-id: <1344923132-31803-9-git-send-email-rajeshwari.s@samsung.com> X-Mailer: git-send-email 1.7.4.4 In-reply-to: <1344923132-31803-1-git-send-email-rajeshwari.s@samsung.com> References: <1344923132-31803-1-git-send-email-rajeshwari.s@samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOJMWRmVeSWpSXmKPExsVy+t9jAV3Np5oBBh9b9Swerr/JYjHl8BcW ByaPO9f2sAUwRnHZpKTmZJalFunbJXBl/D88lbHgm1HF3gV3WBoYJ2p1MXJySAiYSHS3/maE sMUkLtxbz9bFyMUhJLCIUWL/5Z9QzkQmicc7/rGAVLEJGElsPTkNrENEQELiV/9VIJuDg1mg VGLKxDyQsLCAnsT7TZtYQWwWAVWJW0vWsYPYvAIeEo+P9rNALFOQODb1K1gNp4CnxK3ry8BG CgHVrH93hnECI+8CRoZVjKKpBckFxUnpuUZ6xYm5xaV56XrJ+bmbGMHefya9g3FVg8UhRgEO RiUe3sJEzQAh1sSy4srcQ4wSHMxKIrz3e4BCvCmJlVWpRfnxRaU5qcWHGKU5WJTEeU28v/oL CaQnlqRmp6YWpBbBZJk4OKUaGGsudTWu8Hv1IMdZ58Sqp6bXMxcYm/QE3Qyr3BJlJ7XtmLIB 38WtoobV73w0FZTPiceaOhimKxryFE6b9HXl81dPtY+oV87dE3TmWvLmug/T70Uqe10v3Dyx SPzwcg8zieVH5m8PiOufl7m5b9oth4tLQjdOKeWOUzbMd59yQT/g0aWgk0kF/5VYijMSDbWY i4oTAdZMz2v6AQAA X-TM-AS-MML: No X-Gm-Message-State: ALoCoQnjxloMBgcCKyxzoE7cRtXRGPNue/8wUJ+y8gIQJ3wH5lpNNHpe3PfMNLM9LvUCWXpuDYvQ This patch adds clock support for I2S Signed-off-by: R. Chandrasekar Signed-off-by: Rajeshwari Shinde --- 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 2aa511e..ad47d22 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) { @@ -744,6 +754,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()) @@ -821,3 +917,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