From patchwork Sat Jan 7 13:10:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Archit Taneja X-Patchwork-Id: 9503065 X-Patchwork-Delegate: agross@codeaurora.org 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 2A798606E1 for ; Sat, 7 Jan 2017 13:12:01 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 1BE6B2845D for ; Sat, 7 Jan 2017 13:12:01 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 10D29284B4; Sat, 7 Jan 2017 13:12:01 +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=-6.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 8206B2845D for ; Sat, 7 Jan 2017 13:12:00 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S937916AbdAGNLr (ORCPT ); Sat, 7 Jan 2017 08:11:47 -0500 Received: from smtp.codeaurora.org ([198.145.29.96]:32894 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S938227AbdAGNLe (ORCPT ); Sat, 7 Jan 2017 08:11:34 -0500 Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 7705A61269; Sat, 7 Jan 2017 13:11:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1483794693; bh=HkRXdG749krjP90OawCQZe3YPFkjDLomRKs8/rbzAME=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=RqvAeDssNi7KUGPGl6TWWuFSQW/HWPF+687kuD/D+JHJutoN9iyJG0D+85JeJRURc REPWxyXX3pXZOfdiBbY0CV1g2VMT98sobX4NjjfP0gkQQ3lMHCjUn+gnCyHgoLmNuA f0TlyPjm8buZDhHWunW5/ZEMtHC5YAs/LxEGSiMY= Received: from localhost (unknown [202.46.23.61]) (using TLSv1.2 with cipher DHE-RSA-AES128-SHA (128/128 bits)) (No client certificate requested) (Authenticated sender: architt@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id AF197612E9; Sat, 7 Jan 2017 13:11:27 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=codeaurora.org; s=default; t=1483794688; bh=HkRXdG749krjP90OawCQZe3YPFkjDLomRKs8/rbzAME=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=LcI/J7SAGrmiYm0ZQIU9qrBxza4nzmKi4YcpBrMjIYtRizTZV9lgEVCyhfheoXy+b Uh8VyUWt7b3Vgj1DPKDhmu71+T8s2M0aTQt466x5euAwV9/rYmu3SeOv3E55wly+YH ME4TST97up5MjqTlxd9AB5HZaiAb8peQhU/JMusU= DMARC-Filter: OpenDMARC Filter v1.3.1 smtp.codeaurora.org AF197612E9 Authentication-Results: pdx-caf-mail.web.codeaurora.org; dmarc=none header.from=codeaurora.org Authentication-Results: pdx-caf-mail.web.codeaurora.org; spf=pass smtp.mailfrom=architt@codeaurora.org From: Archit Taneja To: robdclark@gmail.com Cc: linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, Hai Li , Archit Taneja Subject: [PATCH 09/10] drm/msm/dsi: Add new method to calculate 14nm PHY timings Date: Sat, 7 Jan 2017 18:40:41 +0530 Message-Id: <1483794642-2184-10-git-send-email-architt@codeaurora.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1483794642-2184-1-git-send-email-architt@codeaurora.org> References: <1483794642-2184-1-git-send-email-architt@codeaurora.org> Sender: linux-arm-msm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-arm-msm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Hai Li The 14nm DSI PHY on 8x96 (called PHY v2 downstream) requires a different set of calculations for computing D-PHY timing params. Create a timing_calc_v2 func for the newer v2 PHYs. Signed-off-by: Hai Li Signed-off-by: Archit Taneja --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 117 ++++++++++++++++++++++++++++++++++ drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 11 +++- 2 files changed, 127 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index c9e1a79..11919bc 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -148,6 +148,123 @@ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing, return 0; } +int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, + struct msm_dsi_phy_clk_request *clk_req) +{ + const unsigned long bit_rate = clk_req->bitclk_rate; + const unsigned long esc_rate = clk_req->escclk_rate; + s32 ui, ui_x8, lpx; + s32 tmax, tmin; + s32 pcnt0 = 50; + s32 pcnt1 = 50; + s32 pcnt2 = 10; + s32 pcnt3 = 30; + s32 pcnt4 = 10; + s32 pcnt5 = 2; + s32 coeff = 1000; /* Precision, should avoid overflow */ + s32 hb_en, hb_en_ckln, pd_ckln, pd; + s32 val, val_ckln; + s32 temp; + + if (!bit_rate || !esc_rate) + return -EINVAL; + + timing->hs_halfbyte_en = 0; + hb_en = 0; + timing->hs_halfbyte_en_ckln = 0; + hb_en_ckln = 0; + timing->hs_prep_dly_ckln = (bit_rate > 100000000) ? 0 : 3; + pd_ckln = timing->hs_prep_dly_ckln; + timing->hs_prep_dly = (bit_rate > 120000000) ? 0 : 1; + pd = timing->hs_prep_dly; + + val = (hb_en << 2) + (pd << 1); + val_ckln = (hb_en_ckln << 2) + (pd_ckln << 1); + + ui = mult_frac(NSEC_PER_MSEC, coeff, bit_rate / 1000); + ui_x8 = ui << 3; + lpx = mult_frac(NSEC_PER_MSEC, coeff, esc_rate / 1000); + + temp = S_DIV_ROUND_UP(38 * coeff - val_ckln * ui, ui_x8); + tmin = max_t(s32, temp, 0); + temp = (95 * coeff - val_ckln * ui) / ui_x8; + tmax = max_t(s32, temp, 0); + timing->clk_prepare = linear_inter(tmax, tmin, pcnt0, 0, false); + + temp = 300 * coeff - ((timing->clk_prepare << 3) + val_ckln) * ui; + tmin = S_DIV_ROUND_UP(temp - 11 * ui, ui_x8) - 3; + tmax = (tmin > 255) ? 511 : 255; + timing->clk_zero = linear_inter(tmax, tmin, pcnt5, 0, false); + + tmin = DIV_ROUND_UP(60 * coeff + 3 * ui, ui_x8); + temp = 105 * coeff + 12 * ui - 20 * coeff; + tmax = (temp + 3 * ui) / ui_x8; + timing->clk_trail = linear_inter(tmax, tmin, pcnt3, 0, false); + + temp = S_DIV_ROUND_UP(40 * coeff + 4 * ui - val * ui, ui_x8); + tmin = max_t(s32, temp, 0); + temp = (85 * coeff + 6 * ui - val * ui) / ui_x8; + tmax = max_t(s32, temp, 0); + timing->hs_prepare = linear_inter(tmax, tmin, pcnt1, 0, false); + + temp = 145 * coeff + 10 * ui - ((timing->hs_prepare << 3) + val) * ui; + tmin = S_DIV_ROUND_UP(temp - 11 * ui, ui_x8) - 3; + tmax = 255; + timing->hs_zero = linear_inter(tmax, tmin, pcnt4, 0, false); + + tmin = DIV_ROUND_UP(60 * coeff + 4 * ui + 3 * ui, ui_x8); + temp = 105 * coeff + 12 * ui - 20 * coeff; + tmax = (temp + 3 * ui) / ui_x8; + timing->hs_trail = linear_inter(tmax, tmin, pcnt3, 0, false); + + temp = 50 * coeff + ((hb_en << 2) - 8) * ui; + timing->hs_rqst = S_DIV_ROUND_UP(temp, ui_x8); + + tmin = DIV_ROUND_UP(100 * coeff, ui_x8) - 1; + tmax = 255; + timing->hs_exit = linear_inter(tmax, tmin, pcnt2, 0, false); + + temp = 50 * coeff + ((hb_en_ckln << 2) - 8) * ui; + timing->hs_rqst_ckln = S_DIV_ROUND_UP(temp, ui_x8); + + temp = 60 * coeff + 52 * ui - 43 * ui; + tmin = DIV_ROUND_UP(temp, ui_x8) - 1; + tmax = 63; + timing->shared_timings.clk_post = + linear_inter(tmax, tmin, pcnt2, 0, false); + + temp = 8 * ui + ((timing->clk_prepare << 3) + val_ckln) * ui; + temp += (((timing->clk_zero + 3) << 3) + 11 - (pd_ckln << 1)) * ui; + temp += hb_en_ckln ? (((timing->hs_rqst_ckln << 3) + 4) * ui) : + (((timing->hs_rqst_ckln << 3) + 8) * ui); + tmin = S_DIV_ROUND_UP(temp, ui_x8) - 1; + tmax = 63; + if (tmin > tmax) { + temp = linear_inter(tmax << 1, tmin, pcnt2, 0, false); + timing->shared_timings.clk_pre = temp >> 1; + timing->shared_timings.clk_pre_inc_by_2 = 1; + } else { + timing->shared_timings.clk_pre = + linear_inter(tmax, tmin, pcnt2, 0, false); + timing->shared_timings.clk_pre_inc_by_2 = 0; + } + + timing->ta_go = 3; + timing->ta_sure = 0; + timing->ta_get = 4; + + DBG("%d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d, %d", + timing->shared_timings.clk_pre, timing->shared_timings.clk_post, + timing->shared_timings.clk_pre_inc_by_2, timing->clk_zero, + timing->clk_trail, timing->clk_prepare, timing->hs_exit, + timing->hs_zero, timing->hs_prepare, timing->hs_trail, + timing->hs_rqst, timing->hs_rqst_ckln, timing->hs_halfbyte_en, + timing->hs_halfbyte_en_ckln, timing->hs_prep_dly, + timing->hs_prep_dly_ckln); + + return 0; +} + void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, u32 bit_mask) { diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 6472b60..feee870 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -64,6 +64,13 @@ struct msm_dsi_dphy_timing { u32 ta_get; struct msm_dsi_phy_shared_timings shared_timings; + + /* For PHY v2 only */ + u32 hs_rqst_ckln; + u32 hs_prep_dly; + u32 hs_prep_dly_ckln; + u8 hs_halfbyte_en; + u8 hs_halfbyte_en_ckln; }; struct msm_dsi_phy { @@ -88,7 +95,9 @@ struct msm_dsi_phy { * PHY internal functions */ int msm_dsi_dphy_timing_calc(struct msm_dsi_dphy_timing *timing, - struct msm_dsi_phy_clk_request *clk_req); + struct msm_dsi_phy_clk_request *clk_req); +int msm_dsi_dphy_timing_calc_v2(struct msm_dsi_dphy_timing *timing, + struct msm_dsi_phy_clk_request *clk_req); void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, u32 bit_mask); int msm_dsi_phy_init_common(struct msm_dsi_phy *phy);