From patchwork Wed Jun 10 17:18:17 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Hai Li X-Patchwork-Id: 6583751 X-Patchwork-Delegate: agross@codeaurora.org Return-Path: X-Original-To: patchwork-linux-arm-msm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id 45F21C0020 for ; Wed, 10 Jun 2015 17:18:54 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 34C842044C for ; Wed, 10 Jun 2015 17:18:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 58D542047B for ; Wed, 10 Jun 2015 17:18:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752444AbbFJRSr (ORCPT ); Wed, 10 Jun 2015 13:18:47 -0400 Received: from smtp.codeaurora.org ([198.145.29.96]:43139 "EHLO smtp.codeaurora.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933417AbbFJRSk (ORCPT ); Wed, 10 Jun 2015 13:18:40 -0400 Received: from smtp.codeaurora.org (localhost [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id E5F61140E8B; Wed, 10 Jun 2015 17:18:39 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 486) id D7D30140E97; Wed, 10 Jun 2015 17:18:39 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from yyzubuntu32.qualcomm.com (rrcs-67-52-130-30.west.biz.rr.com [67.52.130.30]) (using TLSv1.1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) (Authenticated sender: hali@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id F3D86140E8B; Wed, 10 Jun 2015 17:18:37 +0000 (UTC) From: Hai Li To: dri-devel@lists.freedesktop.org Cc: linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, robdclark@gmail.com, Hai Li Subject: [PATCH 1/2] drm/msm/dsi: Update source PLL selection in DSI PHY Date: Wed, 10 Jun 2015 13:18:17 -0400 Message-Id: <1433956698-7794-2-git-send-email-hali@codeaurora.org> X-Mailer: git-send-email 1.8.2.1 In-Reply-To: <1433956698-7794-1-git-send-email-hali@codeaurora.org> References: <1433956698-7794-1-git-send-email-hali@codeaurora.org> X-Virus-Scanned: ClamAV using ClamSMTP 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 The source PLL to be used by each DSI PHY should be decided by DSI manager based on dual DSI information, while the register programming to select PLL is different from one type of PHY to another. This change adds the H/W difference to PHY configuration and updates the interface between DSI manager and PHY. With this change, PLL selection can be supported on different targets. Signed-off-by: Hai Li --- drivers/gpu/drm/msm/dsi/dsi.h | 14 +------------- drivers/gpu/drm/msm/dsi/dsi_manager.c | 15 ++++++++++++++- drivers/gpu/drm/msm/dsi/dsi_phy.c | 34 ++++++++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 92d697d..5e29aad 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -27,18 +27,6 @@ #define DSI_1 1 #define DSI_MAX 2 -#define DSI_CLOCK_MASTER DSI_0 -#define DSI_CLOCK_SLAVE DSI_1 - -#define DSI_LEFT DSI_0 -#define DSI_RIGHT DSI_1 - -/* According to the current drm framework sequence, take the encoder of - * DSI_1 as master encoder - */ -#define DSI_ENCODER_MASTER DSI_1 -#define DSI_ENCODER_SLAVE DSI_0 - enum msm_dsi_phy_type { MSM_DSI_PHY_28NM_HPM, MSM_DSI_PHY_28NM_LP, @@ -153,7 +141,7 @@ int msm_dsi_host_init(struct msm_dsi *msm_dsi); struct msm_dsi_phy; void msm_dsi_phy_driver_register(void); void msm_dsi_phy_driver_unregister(void); -int msm_dsi_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel, +int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, const unsigned long bit_rate, const unsigned long esc_rate); int msm_dsi_phy_disable(struct msm_dsi_phy *phy); void msm_dsi_phy_get_clk_pre_post(struct msm_dsi_phy *phy, diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 87ac661..cfa632f 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -14,6 +14,18 @@ #include "msm_kms.h" #include "dsi.h" +#define DSI_CLOCK_MASTER DSI_0 +#define DSI_CLOCK_SLAVE DSI_1 + +#define DSI_LEFT DSI_0 +#define DSI_RIGHT DSI_1 + +/* According to the current drm framework sequence, take the encoder of + * DSI_1 as master encoder + */ +#define DSI_ENCODER_MASTER DSI_1 +#define DSI_ENCODER_SLAVE DSI_0 + struct msm_dsi_manager { struct msm_dsi *dsi[DSI_MAX]; @@ -598,9 +610,10 @@ int msm_dsi_manager_phy_enable(int id, { struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi_phy *phy = msm_dsi->phy; + int src_pll_id = IS_DUAL_PANEL() ? DSI_CLOCK_MASTER : id; int ret; - ret = msm_dsi_phy_enable(phy, IS_DUAL_PANEL(), bit_rate, esc_rate); + ret = msm_dsi_phy_enable(phy, src_pll_id, bit_rate, esc_rate); if (ret) return ret; diff --git a/drivers/gpu/drm/msm/dsi/dsi_phy.c b/drivers/gpu/drm/msm/dsi/dsi_phy.c index 2d3b33c..52b463e 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/dsi_phy.c @@ -21,7 +21,7 @@ #define dsi_phy_write(offset, data) msm_writel((data), (offset)) struct dsi_phy_ops { - int (*enable)(struct msm_dsi_phy *phy, bool is_dual_panel, + int (*enable)(struct msm_dsi_phy *phy, int src_pll_id, const unsigned long bit_rate, const unsigned long esc_rate); int (*disable)(struct msm_dsi_phy *phy); }; @@ -30,6 +30,12 @@ struct dsi_phy_cfg { enum msm_dsi_phy_type type; struct dsi_reg_config reg_cfg; struct dsi_phy_ops ops; + + /* Each cell {phy_id, pll_id} of the truth table indicates + * if the source PLL is on the right side of the PHY. + * Fill default H/W values in illegal cells, eg. cell {0, 1}. + */ + bool src_pll_truthtable[DSI_MAX][DSI_MAX]; }; struct dsi_dphy_timing { @@ -149,6 +155,19 @@ fail: return ret; } +static void dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg) +{ + int phy_id = phy->id; + + if ((phy_id >= DSI_MAX) || (pll_id >= DSI_MAX)) + return; + + if (phy->cfg->src_pll_truthtable[phy_id][pll_id]) + dsi_phy_write(phy->base + reg, 0x01); + else + dsi_phy_write(phy->base + reg, 0x00); +} + #define S_DIV_ROUND_UP(n, d) \ (((n) >= 0) ? (((n) + (d) - 1) / (d)) : (((n) - (d) + 1) / (d))) @@ -295,7 +314,7 @@ static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) dsi_phy_write(base + REG_DSI_28nm_PHY_REGULATOR_CTRL_4, 0x20); } -static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel, +static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, const unsigned long bit_rate, const unsigned long esc_rate) { struct dsi_dphy_timing *timing = &phy->timing; @@ -368,10 +387,7 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel, dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f); - if (is_dual_panel && (phy->id != DSI_CLOCK_MASTER)) - dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, 0x00); - else - dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, 0x01); + dsi_phy_set_src_pll(phy, src_pll_id, REG_DSI_28nm_PHY_GLBL_TEST_CTRL); return 0; } @@ -414,6 +430,7 @@ static void dsi_phy_disable_resource(struct msm_dsi_phy *phy) static const struct dsi_phy_cfg dsi_phy_cfgs[MSM_DSI_PHY_MAX] = { [MSM_DSI_PHY_28NM_HPM] = { .type = MSM_DSI_PHY_28NM_HPM, + .src_pll_truthtable = { {true, true}, {false, true} }, .reg_cfg = { .num = 1, .regs = { @@ -427,6 +444,7 @@ static const struct dsi_phy_cfg dsi_phy_cfgs[MSM_DSI_PHY_MAX] = { }, [MSM_DSI_PHY_28NM_LP] = { .type = MSM_DSI_PHY_28NM_LP, + .src_pll_truthtable = { {true, true}, {true, true} }, .reg_cfg = { .num = 1, .regs = { @@ -557,7 +575,7 @@ void __exit msm_dsi_phy_driver_unregister(void) platform_driver_unregister(&dsi_phy_platform_driver); } -int msm_dsi_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel, +int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, const unsigned long bit_rate, const unsigned long esc_rate) { int ret; @@ -572,7 +590,7 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, bool is_dual_panel, return ret; } - return phy->cfg->ops.enable(phy, is_dual_panel, bit_rate, esc_rate); + return phy->cfg->ops.enable(phy, src_pll_id, bit_rate, esc_rate); } int msm_dsi_phy_disable(struct msm_dsi_phy *phy)