From patchwork Wed Oct 27 16:24:26 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Guennadi Liakhovetski X-Patchwork-Id: 286222 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id o9RGOGwT014204 for ; Wed, 27 Oct 2010 16:24:16 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753726Ab0J0QYQ (ORCPT ); Wed, 27 Oct 2010 12:24:16 -0400 Received: from mailout-de.gmx.net ([213.165.64.22]:57896 "HELO mail.gmx.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with SMTP id S1753135Ab0J0QYP (ORCPT ); Wed, 27 Oct 2010 12:24:15 -0400 Received: (qmail invoked by alias); 27 Oct 2010 16:24:13 -0000 Received: from p50898A83.dip0.t-ipconnect.de (EHLO axis700.grange) [80.137.138.131] by mail.gmx.net (mp046) with SMTP; 27 Oct 2010 18:24:13 +0200 X-Authenticated: #20450766 X-Provags-ID: V01U2FsdGVkX1/4uCdisE34rEV45hCu5zn7zq+kc+iDgfKIpiYTGr OAcsi5Ea+lkpW9 Received: from lyakh (helo=localhost) by axis700.grange with local-esmtp (Exim 4.63) (envelope-from ) id 1PB8na-00034a-TK; Wed, 27 Oct 2010 18:24:26 +0200 Date: Wed, 27 Oct 2010 18:24:26 +0200 (CEST) From: Guennadi Liakhovetski To: linux-sh@vger.kernel.org cc: linux-fbdev@vger.kernel.org Subject: [PATCH/RFC 3/3] ARM: mach-shmobile: implement parent clock optimization for HDMI In-Reply-To: Message-ID: References: MIME-Version: 1.0 X-Y-GMX-Trusted: 0 Sender: linux-sh-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-sh@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 27 Oct 2010 16:24:17 +0000 (UTC) diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c index 7d0a8c4..8676e26 100644 --- a/arch/arm/mach-shmobile/board-ap4evb.c +++ b/arch/arm/mach-shmobile/board-ap4evb.c @@ -637,9 +637,69 @@ static struct platform_device lcdc1_device = { }, }; +#define MAX_DIVISOR 63 + +static long ap4evb_clk_optimize(unsigned long target, unsigned long *best_freq, + unsigned long *parent_freq) +{ + struct cpufreq_frequency_table *freq, *best = NULL; + unsigned long error = ULONG_MAX, freq_high, freq_low, div; + + for (freq = pllc2_clk.freq_table; freq->frequency != CPUFREQ_TABLE_END; + freq++) { + if (freq->frequency < target) { + if (error > target - freq->frequency) { + error = target - freq->frequency; + best = freq; + if (best_freq) + *best_freq = freq->frequency; + } + continue; + } + div = freq->frequency / target; + if (div > MAX_DIVISOR) + div = MAX_DIVISOR; + freq_high = freq->frequency / div; + freq_low = freq->frequency / (div + 1); + if (freq_high - target < error) { + error = freq_high - target; + best = freq; + if (best_freq) + *best_freq = freq_high; + } + if (target - freq_low < error) { + error = target - freq_low; + best = freq; + if (best_freq) + *best_freq = freq_low; + } + pr_debug("%u / %lu = %lu, / %lu = %lu, best %lu, parent %u\n", + freq->frequency, div, freq_high, div + 1, freq_low, + *best_freq, best->frequency); + if (!error) + break; + } + if (parent_freq) + *parent_freq = best->frequency; + return error; +} + +static int ap4evb_clk_set_rate(struct clk *clk, unsigned long rate) +{ + return clk_set_rate(clk->parent, rate); +} + +static unsigned long ap4evb_clk_get_rate(struct clk *clk) +{ + return clk_get_rate(clk->parent); +} + static struct sh_mobile_hdmi_info hdmi_info = { .lcd_chan = &sh_mobile_lcdc1_info.ch[0], .lcd_dev = &lcdc1_device.dev, + .clk_optimize_parent = ap4evb_clk_optimize, + .clk_set_rate_parent = ap4evb_clk_set_rate, + .clk_get_rate_parent = ap4evb_clk_get_rate, }; static struct resource hdmi_resources[] = {