From patchwork Sat Aug 8 16:10:42 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Russell King X-Patchwork-Id: 6975541 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 1293B9F402 for ; Sat, 8 Aug 2015 16:17:13 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 197E820625 for ; Sat, 8 Aug 2015 16:17:12 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 28A2020603 for ; Sat, 8 Aug 2015 16:17:11 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZO6mQ-00013T-3l; Sat, 08 Aug 2015 16:15:30 +0000 Received: from pandora.arm.linux.org.uk ([2001:4d48:ad52:3201:214:fdff:fe10:1be6]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ZO6jQ-000541-M5 for linux-arm-kernel@lists.infradead.org; Sat, 08 Aug 2015 16:12:34 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=arm.linux.org.uk; s=pandora-2014; h=Date:Sender:Message-Id:Content-Type:Content-Transfer-Encoding:MIME-Version:Subject:Cc:To:From:References:In-Reply-To; bh=Dn9uwoswZblg4Y1XTyuFyvPogqsQbWQxwgb445kJRbc=; b=NgNcf7qRS/OPoY97pDBxbeOqQt3RN+uZdDcaIj8gvnsb1yCTr45vtyrwXsq0vC2Eh2dB4HciDiuYcuSd3ZNngoC/Co1Aev7yJeaCVLnK1XxeerQG3sWj6kgbtECB8DKDG4qVSi2qu6sGf0Cnah2A9K+4ch/xygRysdS1OLsN6g0=; Received: from e0022681537dd.dyn.arm.linux.org.uk ([2002:4e20:1eda:1:222:68ff:fe15:37dd]:49576 helo=rmk-PC.arm.linux.org.uk) by pandora.arm.linux.org.uk with esmtpsa (TLSv1:AES128-SHA:128) (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1ZO6hx-0006TU-JW; Sat, 08 Aug 2015 17:10:53 +0100 Received: from rmk by rmk-PC.arm.linux.org.uk with local (Exim 4.82_1-5b7a7c0-XX) (envelope-from ) id 1ZO6hm-0003Ni-E0; Sat, 08 Aug 2015 17:10:42 +0100 In-Reply-To: <20150808160936.GN7557@n2100.arm.linux.org.uk> References: <20150808160936.GN7557@n2100.arm.linux.org.uk> From: Russell King To: linux-rockchip@lists.infradead.org, alsa-devel@alsa-project.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 8/9] drm: bridge/dw_hdmi: replace CTS calculation for the ACR MIME-Version: 1.0 Content-Disposition: inline Message-Id: Date: Sat, 08 Aug 2015 17:10:42 +0100 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150808_091225_943468_AC3A6C1B X-CRM114-Status: GOOD ( 17.05 ) X-Spam-Score: -2.4 (--) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Fabio Estevam , Takashi Iwai , Sascha Hauer , Jaroslav Kysela , David Airlie , Mark Brown , Philipp Zabel , Yakir Yang , Andy Yan , Jon Nettleton Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED,RP_MATCHES_RCVD,T_DKIM_INVALID,UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Given the TDMS clock, audio sample rate, and the N parameter, we can calculate the CTS value for the audio clock regenerator (ACR) using the following calculation given in the HDMI specification: CTS = ftdms * N / (128 * fs) The specification says that the CTS value is an average value, which is true if the source hardware measures it. Where source hardware needs it to be programmed, it is particularly difficult to alternate it between two values correctly to ensure that we achieve a correct "average" fractional value at the sink. Also, there's the problem that our "ftdms" is not a fully accurate value; it is rounded to a kHz value. This introduces an unnecessary (and harmless) fractional value into the above equation for combinations like 148.5MHz/1.001 for 44100Hz - we still calculate the correct CTS value. Signed-off-by: Russell King Reviewed-by: Douglas Anderson Tested-by: Douglas Anderson --- drivers/gpu/drm/bridge/dw_hdmi.c | 92 +++++++--------------------------------- 1 file changed, 16 insertions(+), 76 deletions(-) diff --git a/drivers/gpu/drm/bridge/dw_hdmi.c b/drivers/gpu/drm/bridge/dw_hdmi.c index 60487bff48e3..a4f9aecf1862 100644 --- a/drivers/gpu/drm/bridge/dw_hdmi.c +++ b/drivers/gpu/drm/bridge/dw_hdmi.c @@ -272,89 +272,29 @@ static unsigned int hdmi_compute_n(unsigned int freq, unsigned long pixel_clk) return n; } -static unsigned int hdmi_compute_cts(unsigned int freq, unsigned long pixel_clk) -{ - unsigned int cts = 0; - - pr_debug("%s: freq: %d pixel_clk: %ld\n", __func__, freq, pixel_clk); - - switch (freq) { - case 32000: - if (pixel_clk == 297000000) { - cts = 222750; - break; - } - case 48000: - case 96000: - case 192000: - switch (pixel_clk) { - case 25200000: - case 27000000: - case 54000000: - case 74250000: - case 148500000: - cts = pixel_clk / 1000; - break; - case 297000000: - cts = 247500; - break; - /* - * All other TMDS clocks are not supported by - * DWC_hdmi_tx. The TMDS clocks divided or - * multiplied by 1,001 coefficients are not - * supported. - */ - default: - break; - } - break; - case 44100: - case 88200: - case 176400: - switch (pixel_clk) { - case 25200000: - cts = 28000; - break; - case 27000000: - cts = 30000; - break; - case 54000000: - cts = 60000; - break; - case 74250000: - cts = 82500; - break; - case 148500000: - cts = 165000; - break; - case 297000000: - cts = 247500; - break; - default: - break; - } - break; - default: - break; - } - return cts; -} - static void hdmi_set_clk_regenerator(struct dw_hdmi *hdmi, unsigned long pixel_clk, unsigned int sample_rate) { + unsigned long ftdms = pixel_clk; unsigned int n, cts; + u64 tmp; n = hdmi_compute_n(sample_rate, pixel_clk); - cts = hdmi_compute_cts(sample_rate, pixel_clk); - if (!cts) { - dev_err(hdmi->dev, - "%s: pixel clock/sample rate not supported: %luMHz / %ukHz\n", - __func__, pixel_clk, sample_rate); - } - dev_dbg(hdmi->dev, "%s: samplerate=%ukHz pixelclk=%luMHz N=%d cts=%d\n", - __func__, sample_rate, pixel_clk, n, cts); + /* + * Compute the CTS value from the N value. Note that CTS and N + * can be up to 20 bits in total, so we need 64-bit math. Also + * note that our TDMS clock is not fully accurate; it is accurate + * to kHz. This can introduce an unnecessary remainder in the + * calculation below, so we don't try to warn about that. + */ + tmp = (u64)ftdms * n; + do_div(tmp, 128 * sample_rate); + cts = tmp; + + dev_dbg(hdmi->dev, "%s: fs=%uHz ftdms=%lu.%03luMHz N=%d cts=%d\n", + __func__, sample_rate, ftdms / 1000000, (ftdms / 1000) % 1000, + n, cts); spin_lock_irq(&hdmi->audio_lock); hdmi->audio_n = n;