From patchwork Mon Sep 18 09:05:33 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Nickey Yang X-Patchwork-Id: 9958919 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 88FF660568 for ; Tue, 19 Sep 2017 12:59:04 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id AF2E222299 for ; Tue, 19 Sep 2017 12:59:04 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id A3920286E6; Tue, 19 Sep 2017 12:59:04 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED autolearn=unavailable version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 128B522299 for ; Tue, 19 Sep 2017 12:59:04 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 30EAE6E596; Tue, 19 Sep 2017 12:57:34 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org X-Greylist: delayed 1514 seconds by postgrey-1.35 at gabe; Mon, 18 Sep 2017 09:06:09 UTC Received: from regular1.263xmail.com (regular1.263xmail.com [211.150.99.132]) by gabe.freedesktop.org (Postfix) with ESMTPS id 2B74F6E2E7 for ; Mon, 18 Sep 2017 09:06:09 +0000 (UTC) Received: from nickey.yang?rock-chips.com (unknown [192.168.165.103]) by regular1.263xmail.com (Postfix) with ESMTP id E66B495A1; Mon, 18 Sep 2017 17:06:04 +0800 (CST) X-263anti-spam: KSV:0; X-MAIL-GRAY: 0 X-MAIL-DELIVERY: 1 X-KSVirus-check: 0 X-ABS-CHECKED: 4 Received: from localhost.localdomain (localhost [127.0.0.1]) by smtp.263.net (Postfix) with ESMTPA id 505FB433; Mon, 18 Sep 2017 17:06:00 +0800 (CST) X-RL-SENDER: nickey.yang@rock-chips.com X-FST-TO: mark.yao@rock-chips.com X-SENDER-IP: 103.29.142.67 X-LOGIN-NAME: nickey.yang@rock-chips.com X-UNIQUE-TAG: <97945f70448dd6b83335538c49155ecd> X-ATTACHMENT-NUM: 0 X-SENDER: nickey.yang@rock-chips.com X-DNS-TYPE: 0 Received: from localhost.localdomain (unknown [103.29.142.67]) by smtp.263.net (Postfix) whith ESMTP id 24121USKWWW; Mon, 18 Sep 2017 17:06:04 +0800 (CST) From: Nickey Yang To: mark.yao@rock-chips.com, robh+dt@kernel.org, heiko@sntech.de, mark.rutland@arm.com, airlied@linux.ie Subject: [PATCH 1/7] drm/rockchip/dsi: correct Feedback divider setting Date: Mon, 18 Sep 2017 17:05:33 +0800 Message-Id: <1505725539-6309-1-git-send-email-nickey.yang@rock-chips.com> X-Mailer: git-send-email 1.9.1 MIME-Version: 1.0 X-Mailman-Approved-At: Tue, 19 Sep 2017 12:57:25 +0000 Cc: bivvy.bi@rock-chips.com, hl@rock-chips.com, briannorris@chromium.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-rockchip@lists.infradead.org, nickey.yang@rock-chips.com, zyw@rock-chips.com, xbl@rock-chips.com X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP This patch correct Feedback divider setting: 1、Set Feedback divider [8:5] when HIGH_PROGRAM_EN 2、Due to the use of a "by 2 pre-scaler," the range of the feedback multiplication Feedback divider is limited to even division numbers, and Feedback divider must be greater than 12, less than 1000. 3、Make the previously configured Feedback divider(LSB) factors effective Signed-off-by: Nickey Yang --- drivers/gpu/drm/rockchip/dw-mipi-dsi.c | 83 ++++++++++++++++++++++------------ 1 file changed, 54 insertions(+), 29 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c index 9a20b9d..52698b7 100644 --- a/drivers/gpu/drm/rockchip/dw-mipi-dsi.c +++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi.c @@ -228,7 +228,7 @@ #define LOW_PROGRAM_EN 0 #define HIGH_PROGRAM_EN BIT(7) #define LOOP_DIV_LOW_SEL(val) (((val) - 1) & 0x1f) -#define LOOP_DIV_HIGH_SEL(val) ((((val) - 1) >> 5) & 0x1f) +#define LOOP_DIV_HIGH_SEL(val) ((((val) - 1) >> 5) & 0xf) #define PLL_LOOP_DIV_EN BIT(5) #define PLL_INPUT_DIV_EN BIT(4) @@ -461,6 +461,7 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) dw_mipi_dsi_phy_write(dsi, 0x17, INPUT_DIVIDER(dsi->input_div)); dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_LOW_SEL(dsi->feedback_div) | LOW_PROGRAM_EN); + dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN); dw_mipi_dsi_phy_write(dsi, 0x18, LOOP_DIV_HIGH_SEL(dsi->feedback_div) | HIGH_PROGRAM_EN); dw_mipi_dsi_phy_write(dsi, 0x19, PLL_LOOP_DIV_EN | PLL_INPUT_DIV_EN); @@ -521,11 +522,16 @@ static int dw_mipi_dsi_phy_init(struct dw_mipi_dsi *dsi) static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi, struct drm_display_mode *mode) { - unsigned int i, pre; - unsigned long mpclk, pllref, tmp; - unsigned int m = 1, n = 1, target_mbps = 1000; + unsigned long mpclk, tmp; + unsigned int target_mbps = 1000; unsigned int max_mbps = dptdin_map[ARRAY_SIZE(dptdin_map) - 1].max_mbps; int bpp; + unsigned long best_freq = 0; + unsigned long fvco_min, fvco_max, fin ,fout; + unsigned int min_prediv, max_prediv; + unsigned int _prediv, uninitialized_var(best_prediv); + unsigned long _fbdiv, uninitialized_var(best_fbdiv); + unsigned long min_delta = UINT_MAX; bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); if (bpp < 0) { @@ -544,34 +550,53 @@ static int dw_mipi_dsi_get_lane_bps(struct dw_mipi_dsi *dsi, dev_err(dsi->dev, "DPHY clock frequency is out of range\n"); } - pllref = DIV_ROUND_UP(clk_get_rate(dsi->pllref_clk), USEC_PER_SEC); - tmp = pllref; - - /* - * The limits on the PLL divisor are: - * - * 5MHz <= (pllref / n) <= 40MHz - * - * we walk over these values in descreasing order so that if we hit - * an exact match for target_mbps it is more likely that "m" will be - * even. - * - * TODO: ensure that "m" is even after this loop. - */ - for (i = pllref / 5; i > (pllref / 40); i--) { - pre = pllref / i; - if ((tmp > (target_mbps % pre)) && (target_mbps / pre < 512)) { - tmp = target_mbps % pre; - n = i; - m = target_mbps / pre; + fin = clk_get_rate(dsi->pllref_clk); + fout = target_mbps * USEC_PER_SEC; + + /* constraint: 5Mhz < Fref / N < 40MHz */ + min_prediv = DIV_ROUND_UP(fin, 40 * USEC_PER_SEC); + max_prediv = fin / (5 * USEC_PER_SEC); + + /* constraint: 80MHz < Fvco < 1500Mhz */ + fvco_min = 80 * USEC_PER_SEC; + fvco_max = 1500 * USEC_PER_SEC; + + for (_prediv = min_prediv; _prediv <= max_prediv; _prediv++) { + u32 delta; + /* Fvco = Fref * M / N */ + tmp = fout * _prediv; + do_div(tmp, fin); + _fbdiv = tmp; + /* + * Due to the use of a "by 2 pre-scaler," the range of the + * feedback multiplication value M is limited to even division + * numbers, and m must be greater than 12, less than 1000. + */ + if (_fbdiv < 12 || _fbdiv > 1000) + continue; + + if (_fbdiv % 2) + ++_fbdiv; + + tmp = (u64)_fbdiv * fin; + do_div(tmp, _prediv); + if (tmp < fvco_min || tmp > fvco_max) + continue; + + delta = abs(fout - tmp); + if (delta < min_delta) { + best_prediv = _prediv; + best_fbdiv = _fbdiv; + min_delta = delta; + best_freq = tmp; } - if (tmp == 0) - break; } - dsi->lane_mbps = pllref / n * m; - dsi->input_div = n; - dsi->feedback_div = m; + if (best_freq) { + dsi->lane_mbps = DIV_ROUND_UP(best_freq, USEC_PER_SEC); + dsi->input_div = best_prediv; + dsi->feedback_div = best_fbdiv; + } return 0; }