From patchwork Sat Mar 27 11:02:45 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 410174 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2279322jai; Sat, 27 Mar 2021 07:18:00 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxUD0Ma43ileuUvxdHs4dDfThuaGsRIg/0rmi2fH1C5utzpSsV74Fv4qjXXDBn/d5SaZCaa X-Received: by 2002:a62:7594:0:b029:203:2d6c:cea1 with SMTP id q142-20020a6275940000b02902032d6ccea1mr17962342pfc.33.1616854680031; Sat, 27 Mar 2021 07:18:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616854680; cv=none; d=google.com; s=arc-20160816; b=dJrFOH0t17/gL+Ut3oNzIAervB9J8Qz2QghRZrTh/FHFM0CpTTBkbc1LuL742/odOE EVoVTXdIuWKJ534vB2SmxF66u+ZdSIeezIlPaI+WwnuB4wxoLcqoGmZdthqdDlbLLDGv QffJ/dE/qMm6LJORu9TdtvgZrr+X7zERVnthDdVICFAk/39q3L10nQezd9SjheCa7lph sbysmqjsWxFZYmitbL71hcJtUb4pQzUk3pDas3Bxq7K54z9RTmh8xRTUgVRbtk6YpQ9M ECRe78qaiqUVzmYwcor1JIO/joecXxQZ5rNP5Cp3FQnuvJ+4UarWGMTWp+ttIABqa9qu q78Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:mime-version:references:in-reply-to:message-id:date :subject:to:from:dkim-signature:delivered-to; bh=veklmprrCvmBvWS6b9kQGHhBhpyMhIE4FJunPKxuMmk=; b=Hh/KdiPL+/WGsbdcpltpQmgmjShiateTY96t8JCBdhVK7EbWiYpSI/VkMqOPpHI3TI /orRcqKYNy5jpeWA6U8EpmtF0xT73vMqLnu6OhBFYyjcDH4gj4SE0JieTos95zWQWtpc 9qXVX/SbHWZC2qH3bcIq0JoVk88wOHEiRWz0smTVWdXTEQQ3mlecB1fx78Dddgpd8h1t d+N+f5g34tiywnho10O9pCjc+gqBX0lVBDgxnS79ULfUjvtFeSOZTUIOuhsgwVTdLobG I1ftYKHMj9xjFE92lb3KsNwWdvxH+Gz48gHwToZtKBNKmTi0nb9GmWWQ0LYZkgTZP607 PvAg== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=NRlEzi4R; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id o65si12824764pjo.70.2021.03.27.07.17.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 07:17:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=NRlEzi4R; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 37D836E157; Sat, 27 Mar 2021 14:17:57 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf1-x131.google.com (mail-lf1-x131.google.com [IPv6:2a00:1450:4864:20::131]) by gabe.freedesktop.org (Postfix) with ESMTPS id E3E4A6F527 for ; Sat, 27 Mar 2021 11:03:17 +0000 (UTC) Received: by mail-lf1-x131.google.com with SMTP id o126so11560854lfa.0 for ; Sat, 27 Mar 2021 04:03:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7L1y9407+TA3E7WMJt6VaJe+1tD9e8PVCS7dUfGesbk=; b=NRlEzi4Rc+x+EI97c8jAIITif+Qe91dSdlRYnwGKrq5AoFdp7fwM4MPwe4+MCk7IOp t6M+SrsYagUdQ3rHrM/2UssSgNvUDeq0UbdYwLhKl3puHOPxv1bA2ypIVNO1o0V0ePwN y1bRAVE/pdKrXdPWrEEJcYv4a7fEgqsflGlpzakfbWiA1PAGczJUzB2Bn7qhsf6lT1VZ n3iUBNczlNfiIiCeu0ZzVzEQwHlr+YtuKIn+6C05HNg3kibCJQf/qzjOXeM/N7kEozz5 o2ZidTk4v/UPTS08QzkACJ7ZpBGLyru6gRWhL5eMiYAqSvliKtADNI+C/fS+/cp89Gdh yv8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7L1y9407+TA3E7WMJt6VaJe+1tD9e8PVCS7dUfGesbk=; b=ltTC9a9mVSbaM4UA1DvO3znlMeWJMLXQY23881hlsWFDlGqksZshiWzdIGdFijoE0f 1vFK8iD0A43cGDDKBFjT6DNBl67Rm4z+Uqfdsp3znjd1RhxCQ7Z5YETIjPsJSEkzo0vr rJnwlarb7AYwtBk/LpHX1hUlPdzUXTFO9DYshA7wevmWDOZKb5xpU/za1SEi7UD4iw8f 1qF/K7saet/ePpY8LKA/OMZmNqbNeMaJNNyBtKaIhmuf62dlltVu8aw+NqXTZPbbBIFW TbQJCz/zNerT6CecoRkyi3CIjkK9u0w/ghqCLdGIN4rpkoedU4t8fvEL1M15jzdJZZV5 qj1g== X-Gm-Message-State: AOAM5303Ob19YBOYR2YpaqeY2g0T7mJLxwWAo8Ka2VHFahhj5uXb8VQ2 zOVPWiyR/oq/4TToOSkuM9FGVg== X-Received: by 2002:ac2:5dcf:: with SMTP id x15mr10624811lfq.176.1616842995608; Sat, 27 Mar 2021 04:03:15 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id a8sm1513801ljn.96.2021.03.27.04.03.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:14 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Jonathan Marek , Michael Turquette Subject: [PATCH v3 05/25] drm/msm/dsi: fuse dsi_pll_* code into dsi_phy_* code Date: Sat, 27 Mar 2021 14:02:45 +0300 Message-Id: <20210327110305.3289784-6-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> References: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-Mailman-Approved-At: Sat, 27 Mar 2021 14:17:56 +0000 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org, linux-clk@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Each phy version is tightly coupled with the corresponding PLL code, there is no need to keep them separate. Fuse source files together in order to simplify DSI code. Signed-off-by: Dmitry Baryshkov Reviewed-by: Abhinav Kumar --- drivers/gpu/drm/msm/Makefile | 9 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 873 +++++++++++++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 1089 ++++++++++++++++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 637 ++++++++++ .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 519 ++++++++ drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 905 ++++++++++++++ .../gpu/drm/msm/dsi/{pll => phy}/dsi_pll.c | 0 .../gpu/drm/msm/dsi/{pll => phy}/dsi_pll.h | 0 drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c | 881 ------------- drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c | 1096 ----------------- drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c | 643 ---------- .../gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c | 526 -------- drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c | 913 -------------- 13 files changed, 4024 insertions(+), 4067 deletions(-) rename drivers/gpu/drm/msm/dsi/{pll => phy}/dsi_pll.c (100%) rename drivers/gpu/drm/msm/dsi/{pll => phy}/dsi_pll.h (100%) delete mode 100644 drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c delete mode 100644 drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c delete mode 100644 drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c delete mode 100644 drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c delete mode 100644 drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c -- 2.30.2 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 3cc906121fb3..1be6996b80b7 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -136,13 +136,6 @@ msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o -ifeq ($(CONFIG_DRM_MSM_DSI_PLL),y) -msm-y += dsi/pll/dsi_pll.o -msm-$(CONFIG_DRM_MSM_DSI_28NM_PHY) += dsi/pll/dsi_pll_28nm.o -msm-$(CONFIG_DRM_MSM_DSI_28NM_8960_PHY) += dsi/pll/dsi_pll_28nm_8960.o -msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/pll/dsi_pll_14nm.o -msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/pll/dsi_pll_10nm.o -msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/pll/dsi_pll_7nm.o -endif +msm-$(CONFIG_DRM_MSM_DSI_PLL) += dsi/phy/dsi_pll.o obj-$(CONFIG_DRM_MSM) += msm.o diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 655fa17a0452..5da369b5c475 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -3,11 +3,884 @@ * Copyright (c) 2018, The Linux Foundation */ +#include +#include #include +#include "dsi_pll.h" #include "dsi_phy.h" #include "dsi.xml.h" +/* + * DSI PLL 10nm - clock diagram (eg: DSI0): + * + * dsi0_pll_out_div_clk dsi0_pll_bit_clk + * | | + * | | + * +---------+ | +----------+ | +----+ + * dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk + * +---------+ | +----------+ | +----+ + * | | + * | | dsi0_pll_by_2_bit_clk + * | | | + * | | +----+ | |\ dsi0_pclk_mux + * | |--| /2 |--o--| \ | + * | | +----+ | \ | +---------+ + * | --------------| |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk + * |------------------------------| / +---------+ + * | +-----+ | / + * -----------| /4? |--o----------|/ + * +-----+ | | + * | |dsiclk_sel + * | + * dsi0_pll_post_out_div_clk + */ + +#define DSI_BYTE_PLL_CLK 0 +#define DSI_PIXEL_PLL_CLK 1 +#define NUM_PROVIDED_CLKS 2 + +#define VCO_REF_CLK_RATE 19200000 + +struct dsi_pll_regs { + u32 pll_prop_gain_rate; + u32 pll_lockdet_rate; + u32 decimal_div_start; + u32 frac_div_start_low; + u32 frac_div_start_mid; + u32 frac_div_start_high; + u32 pll_clock_inverters; + u32 ssc_stepsize_low; + u32 ssc_stepsize_high; + u32 ssc_div_per_low; + u32 ssc_div_per_high; + u32 ssc_adjper_low; + u32 ssc_adjper_high; + u32 ssc_control; +}; + +struct dsi_pll_config { + u32 ref_freq; + bool div_override; + u32 output_div; + bool ignore_frac; + bool disable_prescaler; + bool enable_ssc; + bool ssc_center; + u32 dec_bits; + u32 frac_bits; + u32 lock_timer; + u32 ssc_freq; + u32 ssc_offset; + u32 ssc_adj_per; + u32 thresh_cycles; + u32 refclk_cycles; +}; + +struct pll_10nm_cached_state { + unsigned long vco_rate; + u8 bit_clk_div; + u8 pix_clk_div; + u8 pll_out_div; + u8 pll_mux; +}; + +struct dsi_pll_10nm { + struct msm_dsi_pll base; + + int id; + struct platform_device *pdev; + + void __iomem *phy_cmn_mmio; + void __iomem *mmio; + + u64 vco_ref_clk_rate; + u64 vco_current_rate; + + /* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */ + spinlock_t postdiv_lock; + + int vco_delay; + struct dsi_pll_config pll_configuration; + struct dsi_pll_regs reg_setup; + + /* private clocks: */ + struct clk_hw *out_div_clk_hw; + struct clk_hw *bit_clk_hw; + struct clk_hw *byte_clk_hw; + struct clk_hw *by_2_bit_clk_hw; + struct clk_hw *post_out_div_clk_hw; + struct clk_hw *pclk_mux_hw; + struct clk_hw *out_dsiclk_hw; + + /* clock-provider: */ + struct clk_hw_onecell_data *hw_data; + + struct pll_10nm_cached_state cached_state; + + enum msm_dsi_phy_usecase uc; + struct dsi_pll_10nm *slave; +}; + +#define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, base) + +/* + * Global list of private DSI PLL struct pointers. We need this for Dual DSI + * mode, where the master PLL's clk_ops needs access the slave's private data + */ +static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX]; + +static void dsi_pll_setup_config(struct dsi_pll_10nm *pll) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + + config->ref_freq = pll->vco_ref_clk_rate; + config->output_div = 1; + config->dec_bits = 8; + config->frac_bits = 18; + config->lock_timer = 64; + config->ssc_freq = 31500; + config->ssc_offset = 5000; + config->ssc_adj_per = 2; + config->thresh_cycles = 32; + config->refclk_cycles = 256; + + config->div_override = false; + config->ignore_frac = false; + config->disable_prescaler = false; + + config->enable_ssc = false; + config->ssc_center = 0; +} + +static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + struct dsi_pll_regs *regs = &pll->reg_setup; + u64 fref = pll->vco_ref_clk_rate; + u64 pll_freq; + u64 divider; + u64 dec, dec_multiple; + u32 frac; + u64 multiplier; + + pll_freq = pll->vco_current_rate; + + if (config->disable_prescaler) + divider = fref; + else + divider = fref * 2; + + multiplier = 1 << config->frac_bits; + dec_multiple = div_u64(pll_freq * multiplier, divider); + dec = div_u64_rem(dec_multiple, multiplier, &frac); + + if (pll_freq <= 1900000000UL) + regs->pll_prop_gain_rate = 8; + else if (pll_freq <= 3000000000UL) + regs->pll_prop_gain_rate = 10; + else + regs->pll_prop_gain_rate = 12; + if (pll_freq < 1100000000UL) + regs->pll_clock_inverters = 8; + else + regs->pll_clock_inverters = 0; + + regs->pll_lockdet_rate = config->lock_timer; + regs->decimal_div_start = dec; + regs->frac_div_start_low = (frac & 0xff); + regs->frac_div_start_mid = (frac & 0xff00) >> 8; + regs->frac_div_start_high = (frac & 0x30000) >> 16; +} + +#define SSC_CENTER BIT(0) +#define SSC_EN BIT(1) + +static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + struct dsi_pll_regs *regs = &pll->reg_setup; + u32 ssc_per; + u32 ssc_mod; + u64 ssc_step_size; + u64 frac; + + if (!config->enable_ssc) { + DBG("SSC not enabled\n"); + return; + } + + ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1; + ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1); + ssc_per -= ssc_mod; + + frac = regs->frac_div_start_low | + (regs->frac_div_start_mid << 8) | + (regs->frac_div_start_high << 16); + ssc_step_size = regs->decimal_div_start; + ssc_step_size *= (1 << config->frac_bits); + ssc_step_size += frac; + ssc_step_size *= config->ssc_offset; + ssc_step_size *= (config->ssc_adj_per + 1); + ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1)); + ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000); + + regs->ssc_div_per_low = ssc_per & 0xFF; + regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8; + regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF); + regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8); + regs->ssc_adjper_low = config->ssc_adj_per & 0xFF; + regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8; + + regs->ssc_control = config->ssc_center ? SSC_CENTER : 0; + + pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n", + regs->decimal_div_start, frac, config->frac_bits); + pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n", + ssc_per, (u32)ssc_step_size, config->ssc_adj_per); +} + +static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll) +{ + void __iomem *base = pll->mmio; + struct dsi_pll_regs *regs = &pll->reg_setup; + + if (pll->pll_configuration.enable_ssc) { + pr_debug("SSC is enabled\n"); + + pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1, + regs->ssc_stepsize_low); + pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1, + regs->ssc_stepsize_high); + pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1, + regs->ssc_div_per_low); + pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1, + regs->ssc_div_per_high); + pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1, + regs->ssc_adjper_low); + pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1, + regs->ssc_adjper_high); + pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL, + SSC_EN | regs->ssc_control); + } +} + +static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll) +{ + void __iomem *base = pll->mmio; + + pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80); + pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); + pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00); + pll_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00); + pll_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e); + pll_write(base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40); + pll_write(base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, + 0xba); + pll_write(base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); + pll_write(base + REG_DSI_10nm_PHY_PLL_OUTDIV, 0x00); + pll_write(base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE, 0x00); + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x08); + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1, 0xc0); + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0xfa); + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, + 0x4c); + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80); + pll_write(base + REG_DSI_10nm_PHY_PLL_PFILT, 0x29); + pll_write(base + REG_DSI_10nm_PHY_PLL_IFILT, 0x3f); +} + +static void dsi_pll_commit(struct dsi_pll_10nm *pll) +{ + void __iomem *base = pll->mmio; + struct dsi_pll_regs *reg = &pll->reg_setup; + + pll_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); + pll_write(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1, + reg->decimal_div_start); + pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1, + reg->frac_div_start_low); + pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1, + reg->frac_div_start_mid); + pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1, + reg->frac_div_start_high); + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1, + reg->pll_lockdet_rate); + pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); + pll_write(base + REG_DSI_10nm_PHY_PLL_CMODE, 0x10); + pll_write(base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS, + reg->pll_clock_inverters); +} + +static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + + DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->id, rate, + parent_rate); + + pll_10nm->vco_current_rate = rate; + pll_10nm->vco_ref_clk_rate = VCO_REF_CLK_RATE; + + dsi_pll_setup_config(pll_10nm); + + dsi_pll_calc_dec_frac(pll_10nm); + + dsi_pll_calc_ssc(pll_10nm); + + dsi_pll_commit(pll_10nm); + + dsi_pll_config_hzindep_reg(pll_10nm); + + dsi_pll_ssc_commit(pll_10nm); + + /* flush, ensure all register writes are done*/ + wmb(); + + return 0; +} + +static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) +{ + struct device *dev = &pll->pdev->dev; + int rc; + u32 status = 0; + u32 const delay_us = 100; + u32 const timeout_us = 5000; + + rc = readl_poll_timeout_atomic(pll->mmio + + REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE, + status, + ((status & BIT(0)) > 0), + delay_us, + timeout_us); + if (rc) + DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n", + pll->id, status); + + return rc; +} + +static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll) +{ + u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0); + + pll_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0); + pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0, + data & ~BIT(5)); + ndelay(250); +} + +static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll) +{ + u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0); + + pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0, + data | BIT(5)); + pll_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0); + ndelay(250); +} + +static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll) +{ + u32 data; + + data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1, + data & ~BIT(5)); +} + +static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll) +{ + u32 data; + + data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1, + data | BIT(5)); +} + +static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct device *dev = &pll_10nm->pdev->dev; + int rc; + + dsi_pll_enable_pll_bias(pll_10nm); + if (pll_10nm->slave) + dsi_pll_enable_pll_bias(pll_10nm->slave); + + rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0); + if (rc) { + DRM_DEV_ERROR(dev, "vco_set_rate failed, rc=%d\n", rc); + return rc; + } + + /* Start PLL */ + pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, + 0x01); + + /* + * ensure all PLL configurations are written prior to checking + * for PLL lock. + */ + wmb(); + + /* Check for PLL lock */ + rc = dsi_pll_10nm_lock_status(pll_10nm); + if (rc) { + DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->id); + goto error; + } + + pll->pll_on = true; + + dsi_pll_enable_global_clk(pll_10nm); + if (pll_10nm->slave) + dsi_pll_enable_global_clk(pll_10nm->slave); + + pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, + 0x01); + if (pll_10nm->slave) + pll_write(pll_10nm->slave->phy_cmn_mmio + + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01); + +error: + return rc; +} + +static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll) +{ + pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0); + dsi_pll_disable_pll_bias(pll); +} + +static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + + /* + * To avoid any stray glitches while abruptly powering down the PLL + * make sure to gate the clock using the clock enable bit before + * powering down the PLL + */ + dsi_pll_disable_global_clk(pll_10nm); + pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0); + dsi_pll_disable_sub(pll_10nm); + if (pll_10nm->slave) { + dsi_pll_disable_global_clk(pll_10nm->slave); + dsi_pll_disable_sub(pll_10nm->slave); + } + /* flush, ensure all register writes are done */ + wmb(); + pll->pll_on = false; +} + +static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct dsi_pll_config *config = &pll_10nm->pll_configuration; + void __iomem *base = pll_10nm->mmio; + u64 ref_clk = pll_10nm->vco_ref_clk_rate; + u64 vco_rate = 0x0; + u64 multiplier; + u32 frac; + u32 dec; + u64 pll_freq, tmp64; + + dec = pll_read(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1); + dec &= 0xff; + + frac = pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1); + frac |= ((pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) & + 0xff) << 8); + frac |= ((pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) & + 0x3) << 16); + + /* + * TODO: + * 1. Assumes prescaler is disabled + */ + multiplier = 1 << config->frac_bits; + pll_freq = dec * (ref_clk * 2); + tmp64 = (ref_clk * 2 * frac); + pll_freq += div_u64(tmp64, multiplier); + + vco_rate = pll_freq; + + DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", + pll_10nm->id, (unsigned long)vco_rate, dec, frac); + + return (unsigned long)vco_rate; +} + +static const struct clk_ops clk_ops_dsi_pll_10nm_vco = { + .round_rate = msm_dsi_pll_helper_clk_round_rate, + .set_rate = dsi_pll_10nm_vco_set_rate, + .recalc_rate = dsi_pll_10nm_vco_recalc_rate, + .prepare = dsi_pll_10nm_vco_prepare, + .unprepare = dsi_pll_10nm_vco_unprepare, +}; + +/* + * PLL Callbacks + */ + +static void dsi_pll_10nm_save_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; + void __iomem *phy_base = pll_10nm->phy_cmn_mmio; + u32 cmn_clk_cfg0, cmn_clk_cfg1; + + cached->pll_out_div = pll_read(pll_10nm->mmio + + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); + cached->pll_out_div &= 0x3; + + cmn_clk_cfg0 = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0); + cached->bit_clk_div = cmn_clk_cfg0 & 0xf; + cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4; + + cmn_clk_cfg1 = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + cached->pll_mux = cmn_clk_cfg1 & 0x3; + + DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", + pll_10nm->id, cached->pll_out_div, cached->bit_clk_div, + cached->pix_clk_div, cached->pll_mux); +} + +static int dsi_pll_10nm_restore_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; + void __iomem *phy_base = pll_10nm->phy_cmn_mmio; + u32 val; + int ret; + + val = pll_read(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); + val &= ~0x3; + val |= cached->pll_out_div; + pll_write(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val); + + pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0, + cached->bit_clk_div | (cached->pix_clk_div << 4)); + + val = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + val &= ~0x3; + val |= cached->pll_mux; + pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val); + + ret = dsi_pll_10nm_vco_set_rate(&pll->clk_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); + if (ret) { + DRM_DEV_ERROR(&pll_10nm->pdev->dev, + "restore vco rate failed. ret=%d\n", ret); + return ret; + } + + DBG("DSI PLL%d", pll_10nm->id); + + return 0; +} + +static int dsi_pll_10nm_set_usecase(struct msm_dsi_pll *pll, + enum msm_dsi_phy_usecase uc) +{ + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + void __iomem *base = pll_10nm->phy_cmn_mmio; + u32 data = 0x0; /* internal PLL */ + + DBG("DSI PLL%d", pll_10nm->id); + + switch (uc) { + case MSM_DSI_PHY_STANDALONE: + break; + case MSM_DSI_PHY_MASTER: + pll_10nm->slave = pll_10nm_list[(pll_10nm->id + 1) % DSI_MAX]; + break; + case MSM_DSI_PHY_SLAVE: + data = 0x1; /* external PLL */ + break; + default: + return -EINVAL; + } + + /* set PLL src */ + pll_write(base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, (data << 2)); + + pll_10nm->uc = uc; + + return 0; +} + +static int dsi_pll_10nm_get_provider(struct msm_dsi_pll *pll, + struct clk **byte_clk_provider, + struct clk **pixel_clk_provider) +{ + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct clk_hw_onecell_data *hw_data = pll_10nm->hw_data; + + DBG("DSI PLL%d", pll_10nm->id); + + if (byte_clk_provider) + *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk; + if (pixel_clk_provider) + *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk; + + return 0; +} + +static void dsi_pll_10nm_destroy(struct msm_dsi_pll *pll) +{ + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct device *dev = &pll_10nm->pdev->dev; + + DBG("DSI PLL%d", pll_10nm->id); + of_clk_del_provider(dev->of_node); + + clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw); + clk_hw_unregister_mux(pll_10nm->pclk_mux_hw); + clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw); + clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw); + clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw); + clk_hw_unregister_divider(pll_10nm->bit_clk_hw); + clk_hw_unregister_divider(pll_10nm->out_div_clk_hw); + clk_hw_unregister(&pll_10nm->base.clk_hw); +} + +/* + * The post dividers and mux clocks are created using the standard divider and + * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux + * state to follow the master PLL's divider/mux state. Therefore, we don't + * require special clock ops that also configure the slave PLL registers + */ +static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) +{ + char clk_name[32], parent[32], vco_name[32]; + char parent2[32], parent3[32], parent4[32]; + struct clk_init_data vco_init = { + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .name = vco_name, + .flags = CLK_IGNORE_UNUSED, + .ops = &clk_ops_dsi_pll_10nm_vco, + }; + struct device *dev = &pll_10nm->pdev->dev; + struct clk_hw_onecell_data *hw_data; + struct clk_hw *hw; + int ret; + + DBG("DSI%d", pll_10nm->id); + + hw_data = devm_kzalloc(dev, sizeof(*hw_data) + + NUM_PROVIDED_CLKS * sizeof(struct clk_hw *), + GFP_KERNEL); + if (!hw_data) + return -ENOMEM; + + snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->id); + pll_10nm->base.clk_hw.init = &vco_init; + + ret = clk_hw_register(dev, &pll_10nm->base.clk_hw); + if (ret) + return ret; + + snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); + snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->id); + + hw = clk_hw_register_divider(dev, clk_name, + parent, CLK_SET_RATE_PARENT, + pll_10nm->mmio + + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, + 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_base_clk_hw; + } + + pll_10nm->out_div_clk_hw = hw; + + snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->id); + snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); + + /* BIT CLK: DIV_CTRL_3_0 */ + hw = clk_hw_register_divider(dev, clk_name, parent, + CLK_SET_RATE_PARENT, + pll_10nm->phy_cmn_mmio + + REG_DSI_10nm_PHY_CMN_CLK_CFG0, + 0, 4, CLK_DIVIDER_ONE_BASED, + &pll_10nm->postdiv_lock); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_out_div_clk_hw; + } + + pll_10nm->bit_clk_hw = hw; + + snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); + + /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, + CLK_SET_RATE_PARENT, 1, 8); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_bit_clk_hw; + } + + pll_10nm->byte_clk_hw = hw; + hw_data->hws[DSI_BYTE_PLL_CLK] = hw; + + snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); + + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, + 0, 1, 2); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_byte_clk_hw; + } + + pll_10nm->by_2_bit_clk_hw = hw; + + snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); + snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); + + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, + 0, 1, 4); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_by_2_bit_clk_hw; + } + + pll_10nm->post_out_div_clk_hw = hw; + + snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); + snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id); + snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); + snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); + + hw = clk_hw_register_mux(dev, clk_name, + ((const char *[]){ + parent, parent2, parent3, parent4 + }), 4, 0, pll_10nm->phy_cmn_mmio + + REG_DSI_10nm_PHY_CMN_CLK_CFG1, + 0, 2, 0, NULL); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_post_out_div_clk_hw; + } + + pll_10nm->pclk_mux_hw = hw; + + snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->id); + snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->id); + + /* PIX CLK DIV : DIV_CTRL_7_4*/ + hw = clk_hw_register_divider(dev, clk_name, parent, + 0, pll_10nm->phy_cmn_mmio + + REG_DSI_10nm_PHY_CMN_CLK_CFG0, + 4, 4, CLK_DIVIDER_ONE_BASED, + &pll_10nm->postdiv_lock); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_pclk_mux_hw; + } + + pll_10nm->out_dsiclk_hw = hw; + hw_data->hws[DSI_PIXEL_PLL_CLK] = hw; + + hw_data->num = NUM_PROVIDED_CLKS; + pll_10nm->hw_data = hw_data; + + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + pll_10nm->hw_data); + if (ret) { + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); + goto err_dsiclk_hw; + } + + return 0; + +err_dsiclk_hw: + clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw); +err_pclk_mux_hw: + clk_hw_unregister_mux(pll_10nm->pclk_mux_hw); +err_post_out_div_clk_hw: + clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw); +err_by_2_bit_clk_hw: + clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw); +err_byte_clk_hw: + clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw); +err_bit_clk_hw: + clk_hw_unregister_divider(pll_10nm->bit_clk_hw); +err_out_div_clk_hw: + clk_hw_unregister_divider(pll_10nm->out_div_clk_hw); +err_base_clk_hw: + clk_hw_unregister(&pll_10nm->base.clk_hw); + + return ret; +} + +struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id) +{ + struct dsi_pll_10nm *pll_10nm; + struct msm_dsi_pll *pll; + int ret; + + pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL); + if (!pll_10nm) + return ERR_PTR(-ENOMEM); + + DBG("DSI PLL%d", id); + + pll_10nm->pdev = pdev; + pll_10nm->id = id; + pll_10nm_list[id] = pll_10nm; + + pll_10nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); + if (IS_ERR_OR_NULL(pll_10nm->phy_cmn_mmio)) { + DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); + return ERR_PTR(-ENOMEM); + } + + pll_10nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); + if (IS_ERR_OR_NULL(pll_10nm->mmio)) { + DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); + return ERR_PTR(-ENOMEM); + } + + spin_lock_init(&pll_10nm->postdiv_lock); + + pll = &pll_10nm->base; + pll->min_rate = 1000000000UL; + pll->max_rate = 3500000000UL; + pll->get_provider = dsi_pll_10nm_get_provider; + pll->destroy = dsi_pll_10nm_destroy; + pll->save_state = dsi_pll_10nm_save_state; + pll->restore_state = dsi_pll_10nm_restore_state; + pll->set_usecase = dsi_pll_10nm_set_usecase; + + pll_10nm->vco_delay = 1; + + ret = pll_10nm_register(pll_10nm); + if (ret) { + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); + return ERR_PTR(ret); + } + + /* TODO: Remove this when we have proper display handover support */ + msm_dsi_pll_save_state(pll); + + return pll; +} + static int dsi_phy_hw_v3_0_is_pll_on(struct msm_dsi_phy *phy) { void __iomem *base = phy->base; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 6989730b5fbd..6a63901da7a4 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -3,13 +3,1102 @@ * Copyright (c) 2016, The Linux Foundation. All rights reserved. */ +#include +#include #include #include "dsi_phy.h" +#include "dsi_pll.h" #include "dsi.xml.h" #define PHY_14NM_CKLN_IDX 4 +/* + * DSI PLL 14nm - clock diagram (eg: DSI0): + * + * dsi0n1_postdiv_clk + * | + * | + * +----+ | +----+ + * dsi0vco_clk ---| n1 |--o--| /8 |-- dsi0pllbyte + * +----+ | +----+ + * | dsi0n1_postdivby2_clk + * | +----+ | + * o---| /2 |--o--|\ + * | +----+ | \ +----+ + * | | |--| n2 |-- dsi0pll + * o--------------| / +----+ + * |/ + */ + +#define POLL_MAX_READS 15 +#define POLL_TIMEOUT_US 1000 + +#define NUM_PROVIDED_CLKS 2 + +#define VCO_REF_CLK_RATE 19200000 +#define VCO_MIN_RATE 1300000000UL +#define VCO_MAX_RATE 2600000000UL + +#define DSI_BYTE_PLL_CLK 0 +#define DSI_PIXEL_PLL_CLK 1 + +#define DSI_PLL_DEFAULT_VCO_POSTDIV 1 + +struct dsi_pll_input { + u32 fref; /* reference clk */ + u32 fdata; /* bit clock rate */ + u32 dsiclk_sel; /* Mux configuration (see diagram) */ + u32 ssc_en; /* SSC enable/disable */ + u32 ldo_en; + + /* fixed params */ + u32 refclk_dbler_en; + u32 vco_measure_time; + u32 kvco_measure_time; + u32 bandgap_timer; + u32 pll_wakeup_timer; + u32 plllock_cnt; + u32 plllock_rng; + u32 ssc_center; + u32 ssc_adj_period; + u32 ssc_spread; + u32 ssc_freq; + u32 pll_ie_trim; + u32 pll_ip_trim; + u32 pll_iptat_trim; + u32 pll_cpcset_cur; + u32 pll_cpmset_cur; + + u32 pll_icpmset; + u32 pll_icpcset; + + u32 pll_icpmset_p; + u32 pll_icpmset_m; + + u32 pll_icpcset_p; + u32 pll_icpcset_m; + + u32 pll_lpf_res1; + u32 pll_lpf_cap1; + u32 pll_lpf_cap2; + u32 pll_c3ctrl; + u32 pll_r3ctrl; +}; + +struct dsi_pll_output { + u32 pll_txclk_en; + u32 dec_start; + u32 div_frac_start; + u32 ssc_period; + u32 ssc_step_size; + u32 plllock_cmp; + u32 pll_vco_div_ref; + u32 pll_vco_count; + u32 pll_kvco_div_ref; + u32 pll_kvco_count; + u32 pll_misc1; + u32 pll_lpf2_postdiv; + u32 pll_resetsm_cntrl; + u32 pll_resetsm_cntrl2; + u32 pll_resetsm_cntrl5; + u32 pll_kvco_code; + + u32 cmn_clk_cfg0; + u32 cmn_clk_cfg1; + u32 cmn_ldo_cntrl; + + u32 pll_postdiv; + u32 fcvo; +}; + +struct pll_14nm_cached_state { + unsigned long vco_rate; + u8 n2postdiv; + u8 n1postdiv; +}; + +struct dsi_pll_14nm { + struct msm_dsi_pll base; + + int id; + struct platform_device *pdev; + + void __iomem *phy_cmn_mmio; + void __iomem *mmio; + + int vco_delay; + + struct dsi_pll_input in; + struct dsi_pll_output out; + + /* protects REG_DSI_14nm_PHY_CMN_CLK_CFG0 register */ + spinlock_t postdiv_lock; + + u64 vco_current_rate; + u64 vco_ref_clk_rate; + + /* private clocks: */ + struct clk_hw *hws[NUM_DSI_CLOCKS_MAX]; + u32 num_hws; + + /* clock-provider: */ + struct clk_hw_onecell_data *hw_data; + + struct pll_14nm_cached_state cached_state; + + enum msm_dsi_phy_usecase uc; + struct dsi_pll_14nm *slave; +}; + +#define to_pll_14nm(x) container_of(x, struct dsi_pll_14nm, base) + +/* + * Private struct for N1/N2 post-divider clocks. These clocks are similar to + * the generic clk_divider class of clocks. The only difference is that it + * also sets the slave DSI PLL's post-dividers if in Dual DSI mode + */ +struct dsi_pll_14nm_postdiv { + struct clk_hw hw; + + /* divider params */ + u8 shift; + u8 width; + u8 flags; /* same flags as used by clk_divider struct */ + + struct dsi_pll_14nm *pll; +}; + +#define to_pll_14nm_postdiv(_hw) container_of(_hw, struct dsi_pll_14nm_postdiv, hw) + +/* + * Global list of private DSI PLL struct pointers. We need this for Dual DSI + * mode, where the master PLL's clk_ops needs access the slave's private data + */ +static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX]; + +static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm, + u32 nb_tries, u32 timeout_us) +{ + bool pll_locked = false; + void __iomem *base = pll_14nm->mmio; + u32 tries, val; + + tries = nb_tries; + while (tries--) { + val = pll_read(base + + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); + pll_locked = !!(val & BIT(5)); + + if (pll_locked) + break; + + udelay(timeout_us); + } + + if (!pll_locked) { + tries = nb_tries; + while (tries--) { + val = pll_read(base + + REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); + pll_locked = !!(val & BIT(0)); + + if (pll_locked) + break; + + udelay(timeout_us); + } + } + + DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); + + return pll_locked; +} + +static void dsi_pll_14nm_input_init(struct dsi_pll_14nm *pll) +{ + pll->in.fref = pll->vco_ref_clk_rate; + pll->in.fdata = 0; + pll->in.dsiclk_sel = 1; /* Use the /2 path in Mux */ + pll->in.ldo_en = 0; /* disabled for now */ + + /* fixed input */ + pll->in.refclk_dbler_en = 0; + pll->in.vco_measure_time = 5; + pll->in.kvco_measure_time = 5; + pll->in.bandgap_timer = 4; + pll->in.pll_wakeup_timer = 5; + pll->in.plllock_cnt = 1; + pll->in.plllock_rng = 0; + + /* + * SSC is enabled by default. We might need DT props for configuring + * some SSC params like PPM and center/down spread etc. + */ + pll->in.ssc_en = 1; + pll->in.ssc_center = 0; /* down spread by default */ + pll->in.ssc_spread = 5; /* PPM / 1000 */ + pll->in.ssc_freq = 31500; /* default recommended */ + pll->in.ssc_adj_period = 37; + + pll->in.pll_ie_trim = 4; + pll->in.pll_ip_trim = 4; + pll->in.pll_cpcset_cur = 1; + pll->in.pll_cpmset_cur = 1; + pll->in.pll_icpmset = 4; + pll->in.pll_icpcset = 4; + pll->in.pll_icpmset_p = 0; + pll->in.pll_icpmset_m = 0; + pll->in.pll_icpcset_p = 0; + pll->in.pll_icpcset_m = 0; + pll->in.pll_lpf_res1 = 3; + pll->in.pll_lpf_cap1 = 11; + pll->in.pll_lpf_cap2 = 1; + pll->in.pll_iptat_trim = 7; + pll->in.pll_c3ctrl = 2; + pll->in.pll_r3ctrl = 1; +} + +#define CEIL(x, y) (((x) + ((y) - 1)) / (y)) + +static void pll_14nm_ssc_calc(struct dsi_pll_14nm *pll) +{ + u32 period, ssc_period; + u32 ref, rem; + u64 step_size; + + DBG("vco=%lld ref=%lld", pll->vco_current_rate, pll->vco_ref_clk_rate); + + ssc_period = pll->in.ssc_freq / 500; + period = (u32)pll->vco_ref_clk_rate / 1000; + ssc_period = CEIL(period, ssc_period); + ssc_period -= 1; + pll->out.ssc_period = ssc_period; + + DBG("ssc freq=%d spread=%d period=%d", pll->in.ssc_freq, + pll->in.ssc_spread, pll->out.ssc_period); + + step_size = (u32)pll->vco_current_rate; + ref = pll->vco_ref_clk_rate; + ref /= 1000; + step_size = div_u64(step_size, ref); + step_size <<= 20; + step_size = div_u64(step_size, 1000); + step_size *= pll->in.ssc_spread; + step_size = div_u64(step_size, 1000); + step_size *= (pll->in.ssc_adj_period + 1); + + rem = 0; + step_size = div_u64_rem(step_size, ssc_period + 1, &rem); + if (rem) + step_size++; + + DBG("step_size=%lld", step_size); + + step_size &= 0x0ffff; /* take lower 16 bits */ + + pll->out.ssc_step_size = step_size; +} + +static void pll_14nm_dec_frac_calc(struct dsi_pll_14nm *pll) +{ + struct dsi_pll_input *pin = &pll->in; + struct dsi_pll_output *pout = &pll->out; + u64 multiplier = BIT(20); + u64 dec_start_multiple, dec_start, pll_comp_val; + u32 duration, div_frac_start; + u64 vco_clk_rate = pll->vco_current_rate; + u64 fref = pll->vco_ref_clk_rate; + + DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref); + + dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref); + div_u64_rem(dec_start_multiple, multiplier, &div_frac_start); + + dec_start = div_u64(dec_start_multiple, multiplier); + + pout->dec_start = (u32)dec_start; + pout->div_frac_start = div_frac_start; + + if (pin->plllock_cnt == 0) + duration = 1024; + else if (pin->plllock_cnt == 1) + duration = 256; + else if (pin->plllock_cnt == 2) + duration = 128; + else + duration = 32; + + pll_comp_val = duration * dec_start_multiple; + pll_comp_val = div_u64(pll_comp_val, multiplier); + do_div(pll_comp_val, 10); + + pout->plllock_cmp = (u32)pll_comp_val; + + pout->pll_txclk_en = 1; + pout->cmn_ldo_cntrl = 0x3c; +} + +static u32 pll_14nm_kvco_slop(u32 vrate) +{ + u32 slop = 0; + + if (vrate > VCO_MIN_RATE && vrate <= 1800000000UL) + slop = 600; + else if (vrate > 1800000000UL && vrate < 2300000000UL) + slop = 400; + else if (vrate > 2300000000UL && vrate < VCO_MAX_RATE) + slop = 280; + + return slop; +} + +static void pll_14nm_calc_vco_count(struct dsi_pll_14nm *pll) +{ + struct dsi_pll_input *pin = &pll->in; + struct dsi_pll_output *pout = &pll->out; + u64 vco_clk_rate = pll->vco_current_rate; + u64 fref = pll->vco_ref_clk_rate; + u64 data; + u32 cnt; + + data = fref * pin->vco_measure_time; + do_div(data, 1000000); + data &= 0x03ff; /* 10 bits */ + data -= 2; + pout->pll_vco_div_ref = data; + + data = div_u64(vco_clk_rate, 1000000); /* unit is Mhz */ + data *= pin->vco_measure_time; + do_div(data, 10); + pout->pll_vco_count = data; + + data = fref * pin->kvco_measure_time; + do_div(data, 1000000); + data &= 0x03ff; /* 10 bits */ + data -= 1; + pout->pll_kvco_div_ref = data; + + cnt = pll_14nm_kvco_slop(vco_clk_rate); + cnt *= 2; + cnt /= 100; + cnt *= pin->kvco_measure_time; + pout->pll_kvco_count = cnt; + + pout->pll_misc1 = 16; + pout->pll_resetsm_cntrl = 48; + pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3; + pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer; + pout->pll_kvco_code = 0; +} + +static void pll_db_commit_ssc(struct dsi_pll_14nm *pll) +{ + void __iomem *base = pll->mmio; + struct dsi_pll_input *pin = &pll->in; + struct dsi_pll_output *pout = &pll->out; + u8 data; + + data = pin->ssc_adj_period; + data &= 0x0ff; + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1, data); + data = (pin->ssc_adj_period >> 8); + data &= 0x03; + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2, data); + + data = pout->ssc_period; + data &= 0x0ff; + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER1, data); + data = (pout->ssc_period >> 8); + data &= 0x0ff; + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER2, data); + + data = pout->ssc_step_size; + data &= 0x0ff; + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1, data); + data = (pout->ssc_step_size >> 8); + data &= 0x0ff; + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2, data); + + data = (pin->ssc_center & 0x01); + data <<= 1; + data |= 0x01; /* enable */ + pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER, data); + + wmb(); /* make sure register committed */ +} + +static void pll_db_commit_common(struct dsi_pll_14nm *pll, + struct dsi_pll_input *pin, + struct dsi_pll_output *pout) +{ + void __iomem *base = pll->mmio; + u8 data; + + /* confgiure the non frequency dependent pll registers */ + data = 0; + pll_write(base + REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET, data); + + data = pout->pll_txclk_en; + pll_write(base + REG_DSI_14nm_PHY_PLL_TXCLK_EN, data); + + data = pout->pll_resetsm_cntrl; + pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL, data); + data = pout->pll_resetsm_cntrl2; + pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2, data); + data = pout->pll_resetsm_cntrl5; + pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5, data); + + data = pout->pll_vco_div_ref & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1, data); + data = (pout->pll_vco_div_ref >> 8) & 0x3; + pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2, data); + + data = pout->pll_kvco_div_ref & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1, data); + data = (pout->pll_kvco_div_ref >> 8) & 0x3; + pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2, data); + + data = pout->pll_misc1; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_MISC1, data); + + data = pin->pll_ie_trim; + pll_write(base + REG_DSI_14nm_PHY_PLL_IE_TRIM, data); + + data = pin->pll_ip_trim; + pll_write(base + REG_DSI_14nm_PHY_PLL_IP_TRIM, data); + + data = pin->pll_cpmset_cur << 3 | pin->pll_cpcset_cur; + pll_write(base + REG_DSI_14nm_PHY_PLL_CP_SET_CUR, data); + + data = pin->pll_icpcset_p << 3 | pin->pll_icpcset_m; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPCSET, data); + + data = pin->pll_icpmset_p << 3 | pin->pll_icpcset_m; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPMSET, data); + + data = pin->pll_icpmset << 3 | pin->pll_icpcset; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICP_SET, data); + + data = pin->pll_lpf_cap2 << 4 | pin->pll_lpf_cap1; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF1, data); + + data = pin->pll_iptat_trim; + pll_write(base + REG_DSI_14nm_PHY_PLL_IPTAT_TRIM, data); + + data = pin->pll_c3ctrl | pin->pll_r3ctrl << 4; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_CRCTRL, data); +} + +static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm) +{ + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + + /* de assert pll start and apply pll sw reset */ + + /* stop pll */ + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); + + /* pll sw reset */ + pll_write_udelay(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x20, 10); + wmb(); /* make sure register committed */ + + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0); + wmb(); /* make sure register committed */ +} + +static void pll_db_commit_14nm(struct dsi_pll_14nm *pll, + struct dsi_pll_input *pin, + struct dsi_pll_output *pout) +{ + void __iomem *base = pll->mmio; + void __iomem *cmn_base = pll->phy_cmn_mmio; + u8 data; + + DBG("DSI%d PLL", pll->id); + + data = pout->cmn_ldo_cntrl; + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data); + + pll_db_commit_common(pll, pin, pout); + + pll_14nm_software_reset(pll); + + data = pin->dsiclk_sel; /* set dsiclk_sel = 1 */ + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG1, data); + + data = 0xff; /* data, clk, pll normal operation */ + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_0, data); + + /* configure the frequency dependent pll registers */ + data = pout->dec_start; + pll_write(base + REG_DSI_14nm_PHY_PLL_DEC_START, data); + + data = pout->div_frac_start & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1, data); + data = (pout->div_frac_start >> 8) & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2, data); + data = (pout->div_frac_start >> 16) & 0xf; + pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3, data); + + data = pout->plllock_cmp & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1, data); + + data = (pout->plllock_cmp >> 8) & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2, data); + + data = (pout->plllock_cmp >> 16) & 0x3; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3, data); + + data = pin->plllock_cnt << 1 | pin->plllock_rng << 3; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN, data); + + data = pout->pll_vco_count & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT1, data); + data = (pout->pll_vco_count >> 8) & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT2, data); + + data = pout->pll_kvco_count & 0xff; + pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT1, data); + data = (pout->pll_kvco_count >> 8) & 0x3; + pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT2, data); + + data = (pout->pll_postdiv - 1) << 4 | pin->pll_lpf_res1; + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV, data); + + if (pin->ssc_en) + pll_db_commit_ssc(pll); + + wmb(); /* make sure register committed */ +} + +/* + * VCO clock Callbacks + */ +static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct dsi_pll_input *pin = &pll_14nm->in; + struct dsi_pll_output *pout = &pll_14nm->out; + + DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_14nm->id, rate, + parent_rate); + + pll_14nm->vco_current_rate = rate; + pll_14nm->vco_ref_clk_rate = VCO_REF_CLK_RATE; + + dsi_pll_14nm_input_init(pll_14nm); + + /* + * This configures the post divider internal to the VCO. It's + * fixed to divide by 1 for now. + * + * tx_band = pll_postdiv. + * 0: divided by 1 + * 1: divided by 2 + * 2: divided by 4 + * 3: divided by 8 + */ + pout->pll_postdiv = DSI_PLL_DEFAULT_VCO_POSTDIV; + + pll_14nm_dec_frac_calc(pll_14nm); + + if (pin->ssc_en) + pll_14nm_ssc_calc(pll_14nm); + + pll_14nm_calc_vco_count(pll_14nm); + + /* commit the slave DSI PLL registers if we're master. Note that we + * don't lock the slave PLL. We just ensure that the PLL/PHY registers + * of the master and slave are identical + */ + if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { + struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; + + pll_db_commit_14nm(pll_14nm_slave, pin, pout); + } + + pll_db_commit_14nm(pll_14nm, pin, pout); + + return 0; +} + +static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + void __iomem *base = pll_14nm->mmio; + u64 vco_rate, multiplier = BIT(20); + u32 div_frac_start; + u32 dec_start; + u64 ref_clk = parent_rate; + + dec_start = pll_read(base + REG_DSI_14nm_PHY_PLL_DEC_START); + dec_start &= 0x0ff; + + DBG("dec_start = %x", dec_start); + + div_frac_start = (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3) + & 0xf) << 16; + div_frac_start |= (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2) + & 0xff) << 8; + div_frac_start |= pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1) + & 0xff; + + DBG("div_frac_start = %x", div_frac_start); + + vco_rate = ref_clk * dec_start; + + vco_rate += ((ref_clk * div_frac_start) / multiplier); + + /* + * Recalculating the rate from dec_start and frac_start doesn't end up + * the rate we originally set. Convert the freq to KHz, round it up and + * convert it back to MHz. + */ + vco_rate = DIV_ROUND_UP_ULL(vco_rate, 1000) * 1000; + + DBG("returning vco rate = %lu", (unsigned long)vco_rate); + + return (unsigned long)vco_rate; +} + +static const struct clk_ops clk_ops_dsi_pll_14nm_vco = { + .round_rate = msm_dsi_pll_helper_clk_round_rate, + .set_rate = dsi_pll_14nm_vco_set_rate, + .recalc_rate = dsi_pll_14nm_vco_recalc_rate, + .prepare = msm_dsi_pll_helper_clk_prepare, + .unprepare = msm_dsi_pll_helper_clk_unprepare, +}; + +/* + * N1 and N2 post-divider clock callbacks + */ +#define div_mask(width) ((1 << (width)) - 1) +static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); + struct dsi_pll_14nm *pll_14nm = postdiv->pll; + void __iomem *base = pll_14nm->phy_cmn_mmio; + u8 shift = postdiv->shift; + u8 width = postdiv->width; + u32 val; + + DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, parent_rate); + + val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift; + val &= div_mask(width); + + return divider_recalc_rate(hw, parent_rate, val, NULL, + postdiv->flags, width); +} + +static long dsi_pll_14nm_postdiv_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *prate) +{ + struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); + struct dsi_pll_14nm *pll_14nm = postdiv->pll; + + DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, rate); + + return divider_round_rate(hw, rate, prate, NULL, + postdiv->width, + postdiv->flags); +} + +static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); + struct dsi_pll_14nm *pll_14nm = postdiv->pll; + void __iomem *base = pll_14nm->phy_cmn_mmio; + spinlock_t *lock = &pll_14nm->postdiv_lock; + u8 shift = postdiv->shift; + u8 width = postdiv->width; + unsigned int value; + unsigned long flags = 0; + u32 val; + + DBG("DSI%d PLL parent rate=%lu parent rate %lu", pll_14nm->id, rate, + parent_rate); + + value = divider_get_val(rate, parent_rate, NULL, postdiv->width, + postdiv->flags); + + spin_lock_irqsave(lock, flags); + + val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); + val &= ~(div_mask(width) << shift); + + val |= value << shift; + pll_write(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); + + /* If we're master in dual DSI mode, then the slave PLL's post-dividers + * follow the master's post dividers + */ + if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { + struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; + void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; + + pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); + } + + spin_unlock_irqrestore(lock, flags); + + return 0; +} + +static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = { + .recalc_rate = dsi_pll_14nm_postdiv_recalc_rate, + .round_rate = dsi_pll_14nm_postdiv_round_rate, + .set_rate = dsi_pll_14nm_postdiv_set_rate, +}; + +/* + * PLL Callbacks + */ + +static int dsi_pll_14nm_enable_seq(struct msm_dsi_pll *pll) +{ + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + void __iomem *base = pll_14nm->mmio; + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + bool locked; + + DBG(""); + + pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); + + locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS, + POLL_TIMEOUT_US); + + if (unlikely(!locked)) + DRM_DEV_ERROR(&pll_14nm->pdev->dev, "DSI PLL lock failed\n"); + else + DBG("DSI PLL lock success"); + + return locked ? 0 : -EINVAL; +} + +static void dsi_pll_14nm_disable_seq(struct msm_dsi_pll *pll) +{ + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + + DBG(""); + + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); +} + +static void dsi_pll_14nm_save_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + u32 data; + + data = pll_read(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); + + cached_state->n1postdiv = data & 0xf; + cached_state->n2postdiv = (data >> 4) & 0xf; + + DBG("DSI%d PLL save state %x %x", pll_14nm->id, + cached_state->n1postdiv, cached_state->n2postdiv); + + cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw); +} + +static int dsi_pll_14nm_restore_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + u32 data; + int ret; + + ret = dsi_pll_14nm_vco_set_rate(&pll->clk_hw, + cached_state->vco_rate, 0); + if (ret) { + DRM_DEV_ERROR(&pll_14nm->pdev->dev, + "restore vco rate failed. ret=%d\n", ret); + return ret; + } + + data = cached_state->n1postdiv | (cached_state->n2postdiv << 4); + + DBG("DSI%d PLL restore state %x %x", pll_14nm->id, + cached_state->n1postdiv, cached_state->n2postdiv); + + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); + + /* also restore post-dividers for slave DSI PLL */ + if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { + struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; + void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; + + pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); + } + + return 0; +} + +static int dsi_pll_14nm_set_usecase(struct msm_dsi_pll *pll, + enum msm_dsi_phy_usecase uc) +{ + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + void __iomem *base = pll_14nm->mmio; + u32 clkbuflr_en, bandgap = 0; + + switch (uc) { + case MSM_DSI_PHY_STANDALONE: + clkbuflr_en = 0x1; + break; + case MSM_DSI_PHY_MASTER: + clkbuflr_en = 0x3; + pll_14nm->slave = pll_14nm_list[(pll_14nm->id + 1) % DSI_MAX]; + break; + case MSM_DSI_PHY_SLAVE: + clkbuflr_en = 0x0; + bandgap = 0x3; + break; + default: + return -EINVAL; + } + + pll_write(base + REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN, clkbuflr_en); + if (bandgap) + pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP, bandgap); + + pll_14nm->uc = uc; + + return 0; +} + +static int dsi_pll_14nm_get_provider(struct msm_dsi_pll *pll, + struct clk **byte_clk_provider, + struct clk **pixel_clk_provider) +{ + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct clk_hw_onecell_data *hw_data = pll_14nm->hw_data; + + if (byte_clk_provider) + *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk; + if (pixel_clk_provider) + *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk; + + return 0; +} + +static void dsi_pll_14nm_destroy(struct msm_dsi_pll *pll) +{ + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct platform_device *pdev = pll_14nm->pdev; + int num_hws = pll_14nm->num_hws; + + of_clk_del_provider(pdev->dev.of_node); + + while (num_hws--) + clk_hw_unregister(pll_14nm->hws[num_hws]); +} + +static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm, + const char *name, + const char *parent_name, + unsigned long flags, + u8 shift) +{ + struct dsi_pll_14nm_postdiv *pll_postdiv; + struct device *dev = &pll_14nm->pdev->dev; + struct clk_init_data postdiv_init = { + .parent_names = (const char *[]) { parent_name }, + .num_parents = 1, + .name = name, + .flags = flags, + .ops = &clk_ops_dsi_pll_14nm_postdiv, + }; + int ret; + + pll_postdiv = devm_kzalloc(dev, sizeof(*pll_postdiv), GFP_KERNEL); + if (!pll_postdiv) + return ERR_PTR(-ENOMEM); + + pll_postdiv->pll = pll_14nm; + pll_postdiv->shift = shift; + /* both N1 and N2 postdividers are 4 bits wide */ + pll_postdiv->width = 4; + /* range of each divider is from 1 to 15 */ + pll_postdiv->flags = CLK_DIVIDER_ONE_BASED; + pll_postdiv->hw.init = &postdiv_init; + + ret = clk_hw_register(dev, &pll_postdiv->hw); + if (ret) + return ERR_PTR(ret); + + return &pll_postdiv->hw; +} + +static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm) +{ + char clk_name[32], parent[32], vco_name[32]; + struct clk_init_data vco_init = { + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .name = vco_name, + .flags = CLK_IGNORE_UNUSED, + .ops = &clk_ops_dsi_pll_14nm_vco, + }; + struct device *dev = &pll_14nm->pdev->dev; + struct clk_hw **hws = pll_14nm->hws; + struct clk_hw_onecell_data *hw_data; + struct clk_hw *hw; + int num = 0; + int ret; + + DBG("DSI%d", pll_14nm->id); + + hw_data = devm_kzalloc(dev, sizeof(*hw_data) + + NUM_PROVIDED_CLKS * sizeof(struct clk_hw *), + GFP_KERNEL); + if (!hw_data) + return -ENOMEM; + + snprintf(vco_name, 32, "dsi%dvco_clk", pll_14nm->id); + pll_14nm->base.clk_hw.init = &vco_init; + + ret = clk_hw_register(dev, &pll_14nm->base.clk_hw); + if (ret) + return ret; + + hws[num++] = &pll_14nm->base.clk_hw; + + snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); + snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->id); + + /* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */ + hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, + CLK_SET_RATE_PARENT, 0); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + hws[num++] = hw; + + snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->id); + snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); + + /* DSI Byte clock = VCO_CLK / N1 / 8 */ + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, + CLK_SET_RATE_PARENT, 1, 8); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + hws[num++] = hw; + hw_data->hws[DSI_BYTE_PLL_CLK] = hw; + + snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id); + snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); + + /* + * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider + * on the way. Don't let it set parent. + */ + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 2); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + hws[num++] = hw; + + snprintf(clk_name, 32, "dsi%dpll", pll_14nm->id); + snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id); + + /* DSI pixel clock = VCO_CLK / N1 / 2 / N2 + * This is the output of N2 post-divider, bits 4-7 in + * REG_DSI_14nm_PHY_CMN_CLK_CFG0. Don't let it set parent. + */ + hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, 0, 4); + if (IS_ERR(hw)) + return PTR_ERR(hw); + + hws[num++] = hw; + hw_data->hws[DSI_PIXEL_PLL_CLK] = hw; + + pll_14nm->num_hws = num; + + hw_data->num = NUM_PROVIDED_CLKS; + pll_14nm->hw_data = hw_data; + + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + pll_14nm->hw_data); + if (ret) { + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); + return ret; + } + + return 0; +} + +struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id) +{ + struct dsi_pll_14nm *pll_14nm; + struct msm_dsi_pll *pll; + int ret; + + if (!pdev) + return ERR_PTR(-ENODEV); + + pll_14nm = devm_kzalloc(&pdev->dev, sizeof(*pll_14nm), GFP_KERNEL); + if (!pll_14nm) + return ERR_PTR(-ENOMEM); + + DBG("PLL%d", id); + + pll_14nm->pdev = pdev; + pll_14nm->id = id; + pll_14nm_list[id] = pll_14nm; + + pll_14nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); + if (IS_ERR_OR_NULL(pll_14nm->phy_cmn_mmio)) { + DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); + return ERR_PTR(-ENOMEM); + } + + pll_14nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); + if (IS_ERR_OR_NULL(pll_14nm->mmio)) { + DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); + return ERR_PTR(-ENOMEM); + } + + spin_lock_init(&pll_14nm->postdiv_lock); + + pll = &pll_14nm->base; + pll->min_rate = VCO_MIN_RATE; + pll->max_rate = VCO_MAX_RATE; + pll->get_provider = dsi_pll_14nm_get_provider; + pll->destroy = dsi_pll_14nm_destroy; + pll->disable_seq = dsi_pll_14nm_disable_seq; + pll->save_state = dsi_pll_14nm_save_state; + pll->restore_state = dsi_pll_14nm_restore_state; + pll->set_usecase = dsi_pll_14nm_set_usecase; + + pll_14nm->vco_delay = 1; + + pll->en_seq_cnt = 1; + pll->enable_seqs[0] = dsi_pll_14nm_enable_seq; + + ret = pll_14nm_register(pll_14nm); + if (ret) { + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); + return ERR_PTR(ret); + } + + return pll; +} + static void dsi_14nm_dphy_set_timing(struct msm_dsi_phy *phy, struct msm_dsi_dphy_timing *timing, int lane_idx) diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 5bf79de0da67..2f502efa4dd5 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -3,9 +3,646 @@ * Copyright (c) 2015, The Linux Foundation. All rights reserved. */ +#include +#include + #include "dsi_phy.h" +#include "dsi_pll.h" #include "dsi.xml.h" +/* + * DSI PLL 28nm - clock diagram (eg: DSI0): + * + * dsi0analog_postdiv_clk + * | dsi0indirect_path_div2_clk + * | | + * +------+ | +----+ | |\ dsi0byte_mux + * dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \ | + * | +------+ +----+ | m| | +----+ + * | | u|--o--| /4 |-- dsi0pllbyte + * | | x| +----+ + * o--------------------------| / + * | |/ + * | +------+ + * o----------| DIV3 |------------------------- dsi0pll + * +------+ + */ + +#define POLL_MAX_READS 10 +#define POLL_TIMEOUT_US 50 + +#define NUM_PROVIDED_CLKS 2 + +#define VCO_REF_CLK_RATE 19200000 +#define VCO_MIN_RATE 350000000 +#define VCO_MAX_RATE 750000000 + +#define DSI_BYTE_PLL_CLK 0 +#define DSI_PIXEL_PLL_CLK 1 + +#define LPFR_LUT_SIZE 10 +struct lpfr_cfg { + unsigned long vco_rate; + u32 resistance; +}; + +/* Loop filter resistance: */ +static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = { + { 479500000, 8 }, + { 480000000, 11 }, + { 575500000, 8 }, + { 576000000, 12 }, + { 610500000, 8 }, + { 659500000, 9 }, + { 671500000, 10 }, + { 672000000, 14 }, + { 708500000, 10 }, + { 750000000, 11 }, +}; + +struct pll_28nm_cached_state { + unsigned long vco_rate; + u8 postdiv3; + u8 postdiv1; + u8 byte_mux; +}; + +struct dsi_pll_28nm { + struct msm_dsi_pll base; + + int id; + struct platform_device *pdev; + void __iomem *mmio; + + int vco_delay; + + /* private clocks: */ + struct clk *clks[NUM_DSI_CLOCKS_MAX]; + u32 num_clks; + + /* clock-provider: */ + struct clk *provided_clks[NUM_PROVIDED_CLKS]; + struct clk_onecell_data clk_data; + + struct pll_28nm_cached_state cached_state; +}; + +#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base) + +static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, + u32 nb_tries, u32 timeout_us) +{ + bool pll_locked = false; + u32 val; + + while (nb_tries--) { + val = pll_read(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_STATUS); + pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY); + + if (pll_locked) + break; + + udelay(timeout_us); + } + DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); + + return pll_locked; +} + +static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm) +{ + void __iomem *base = pll_28nm->mmio; + + /* + * Add HW recommended delays after toggling the software + * reset bit off and back on. + */ + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, + DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, 1); + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, 0x00, 1); +} + +/* + * Clock Callbacks + */ +static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct device *dev = &pll_28nm->pdev->dev; + void __iomem *base = pll_28nm->mmio; + unsigned long div_fbx1000, gen_vco_clk; + u32 refclk_cfg, frac_n_mode, frac_n_value; + u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3; + u32 cal_cfg10, cal_cfg11; + u32 rem; + int i; + + VERB("rate=%lu, parent's=%lu", rate, parent_rate); + + /* Force postdiv2 to be div-4 */ + pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3); + + /* Configure the Loop filter resistance */ + for (i = 0; i < LPFR_LUT_SIZE; i++) + if (rate <= lpfr_lut[i].vco_rate) + break; + if (i == LPFR_LUT_SIZE) { + DRM_DEV_ERROR(dev, "unable to get loop filter resistance. vco=%lu\n", + rate); + return -EINVAL; + } + pll_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance); + + /* Loop filter capacitance values : c1 and c2 */ + pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70); + pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15); + + rem = rate % VCO_REF_CLK_RATE; + if (rem) { + refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR; + frac_n_mode = 1; + div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500); + gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500); + } else { + refclk_cfg = 0x0; + frac_n_mode = 0; + div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000); + gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000); + } + + DBG("refclk_cfg = %d", refclk_cfg); + + rem = div_fbx1000 % 1000; + frac_n_value = (rem << 16) / 1000; + + DBG("div_fb = %lu", div_fbx1000); + DBG("frac_n_value = %d", frac_n_value); + + DBG("Generated VCO Clock: %lu", gen_vco_clk); + rem = 0; + sdm_cfg1 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1); + sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK; + if (frac_n_mode) { + sdm_cfg0 = 0x0; + sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0); + sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET( + (u32)(((div_fbx1000 / 1000) & 0x3f) - 1)); + sdm_cfg3 = frac_n_value >> 8; + sdm_cfg2 = frac_n_value & 0xff; + } else { + sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP; + sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV( + (u32)(((div_fbx1000 / 1000) & 0x3f) - 1)); + sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0); + sdm_cfg2 = 0; + sdm_cfg3 = 0; + } + + DBG("sdm_cfg0=%d", sdm_cfg0); + DBG("sdm_cfg1=%d", sdm_cfg1); + DBG("sdm_cfg2=%d", sdm_cfg2); + DBG("sdm_cfg3=%d", sdm_cfg3); + + cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000)); + cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000); + DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11); + + pll_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3, 0x2b); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4, 0x06); + pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); + + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1); + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2, + DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2)); + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3, + DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3)); + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00); + + /* Add hardware recommended delay for correct PLL configuration */ + if (pll_28nm->vco_delay) + udelay(pll_28nm->vco_delay); + + pll_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg); + pll_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00); + pll_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31); + pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0, sdm_cfg0); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0, 0x12); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6, 0x30); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7, 0x00); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8, 0x60); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9, 0x00); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10, cal_cfg10 & 0xff); + pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11, cal_cfg11 & 0xff); + pll_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG, 0x20); + + return 0; +} + +static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS, + POLL_TIMEOUT_US); +} + +static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + void __iomem *base = pll_28nm->mmio; + u32 sdm0, doubler, sdm_byp_div; + u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3; + u32 ref_clk = VCO_REF_CLK_RATE; + unsigned long vco_rate; + + VERB("parent_rate=%lu", parent_rate); + + /* Check to see if the ref clk doubler is enabled */ + doubler = pll_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) & + DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR; + ref_clk += (doubler * VCO_REF_CLK_RATE); + + /* see if it is integer mode or sdm mode */ + sdm0 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0); + if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) { + /* integer mode */ + sdm_byp_div = FIELD( + pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0), + DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1; + vco_rate = ref_clk * sdm_byp_div; + } else { + /* sdm mode */ + sdm_dc_off = FIELD( + pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1), + DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET); + DBG("sdm_dc_off = %d", sdm_dc_off); + sdm2 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2), + DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0); + sdm3 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3), + DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8); + sdm_freq_seed = (sdm3 << 8) | sdm2; + DBG("sdm_freq_seed = %d", sdm_freq_seed); + + vco_rate = (ref_clk * (sdm_dc_off + 1)) + + mult_frac(ref_clk, sdm_freq_seed, BIT(16)); + DBG("vco rate = %lu", vco_rate); + } + + DBG("returning vco rate = %lu", vco_rate); + + return vco_rate; +} + +static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { + .round_rate = msm_dsi_pll_helper_clk_round_rate, + .set_rate = dsi_pll_28nm_clk_set_rate, + .recalc_rate = dsi_pll_28nm_clk_recalc_rate, + .prepare = msm_dsi_pll_helper_clk_prepare, + .unprepare = msm_dsi_pll_helper_clk_unprepare, + .is_enabled = dsi_pll_28nm_clk_is_enabled, +}; + +/* + * PLL Callbacks + */ +static int dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct device *dev = &pll_28nm->pdev->dev; + void __iomem *base = pll_28nm->mmio; + u32 max_reads = 5, timeout_us = 100; + bool locked; + u32 val; + int i; + + DBG("id=%d", pll_28nm->id); + + pll_28nm_software_reset(pll_28nm); + + /* + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600); + + for (i = 0; i < 2; i++) { + /* DSI Uniphy lock detect setting */ + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, + 0x0c, 100); + pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); + + /* poll for PLL ready status */ + locked = pll_28nm_poll_for_ready(pll_28nm, + max_reads, timeout_us); + if (locked) + break; + + pll_28nm_software_reset(pll_28nm); + + /* + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 250); + + val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600); + } + + if (unlikely(!locked)) + DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); + else + DBG("DSI PLL Lock success"); + + return locked ? 0 : -EINVAL; +} + +static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct device *dev = &pll_28nm->pdev->dev; + void __iomem *base = pll_28nm->mmio; + bool locked; + u32 max_reads = 10, timeout_us = 50; + u32 val; + + DBG("id=%d", pll_28nm->id); + + pll_28nm_software_reset(pll_28nm); + + /* + * PLL power up sequence. + * Add necessary delays recommended by hardware. + */ + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34, 500); + + val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B | + DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); + + /* DSI PLL toggle lock detect setting */ + pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x04, 500); + pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x05, 512); + + locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); + + if (unlikely(!locked)) + DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); + else + DBG("DSI PLL lock success"); + + return locked ? 0 : -EINVAL; +} + +static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + DBG("id=%d", pll_28nm->id); + pll_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00); +} + +static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; + void __iomem *base = pll_28nm->mmio; + + cached_state->postdiv3 = + pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG); + cached_state->postdiv1 = + pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG); + cached_state->byte_mux = pll_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG); + if (dsi_pll_28nm_clk_is_enabled(&pll->clk_hw)) + cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw); + else + cached_state->vco_rate = 0; +} + +static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; + void __iomem *base = pll_28nm->mmio; + int ret; + + ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw, + cached_state->vco_rate, 0); + if (ret) { + DRM_DEV_ERROR(&pll_28nm->pdev->dev, + "restore vco rate failed. ret=%d\n", ret); + return ret; + } + + pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, + cached_state->postdiv3); + pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, + cached_state->postdiv1); + pll_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG, + cached_state->byte_mux); + + return 0; +} + +static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll, + struct clk **byte_clk_provider, + struct clk **pixel_clk_provider) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + if (byte_clk_provider) + *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK]; + if (pixel_clk_provider) + *pixel_clk_provider = + pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK]; + + return 0; +} + +static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + int i; + + msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev, + pll_28nm->clks, pll_28nm->num_clks); + + for (i = 0; i < NUM_PROVIDED_CLKS; i++) + pll_28nm->provided_clks[i] = NULL; + + pll_28nm->num_clks = 0; + pll_28nm->clk_data.clks = NULL; + pll_28nm->clk_data.clk_num = 0; +} + +static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) +{ + char clk_name[32], parent1[32], parent2[32], vco_name[32]; + struct clk_init_data vco_init = { + .parent_names = (const char *[]){ "xo" }, + .num_parents = 1, + .name = vco_name, + .flags = CLK_IGNORE_UNUSED, + .ops = &clk_ops_dsi_pll_28nm_vco, + }; + struct device *dev = &pll_28nm->pdev->dev; + struct clk **clks = pll_28nm->clks; + struct clk **provided_clks = pll_28nm->provided_clks; + int num = 0; + int ret; + + DBG("%d", pll_28nm->id); + + snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); + pll_28nm->base.clk_hw.init = &vco_init; + clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw); + + snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); + clks[num++] = clk_register_divider(dev, clk_name, + parent1, CLK_SET_RATE_PARENT, + pll_28nm->mmio + + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, + 0, 4, 0, NULL); + + snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); + snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->id); + clks[num++] = clk_register_fixed_factor(dev, clk_name, + parent1, CLK_SET_RATE_PARENT, + 1, 2); + + snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); + clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] = + clk_register_divider(dev, clk_name, + parent1, 0, pll_28nm->mmio + + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, + 0, 8, 0, NULL); + + snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); + snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); + clks[num++] = clk_register_mux(dev, clk_name, + ((const char *[]){ + parent1, parent2 + }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio + + REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL); + + snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); + snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->id); + clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] = + clk_register_fixed_factor(dev, clk_name, + parent1, CLK_SET_RATE_PARENT, 1, 4); + + pll_28nm->num_clks = num; + + pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS; + pll_28nm->clk_data.clks = provided_clks; + + ret = of_clk_add_provider(dev->of_node, + of_clk_src_onecell_get, &pll_28nm->clk_data); + if (ret) { + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); + return ret; + } + + return 0; +} + +struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev, + enum msm_dsi_phy_type type, int id) +{ + struct dsi_pll_28nm *pll_28nm; + struct msm_dsi_pll *pll; + int ret; + + if (!pdev) + return ERR_PTR(-ENODEV); + + pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL); + if (!pll_28nm) + return ERR_PTR(-ENOMEM); + + pll_28nm->pdev = pdev; + pll_28nm->id = id; + + pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); + if (IS_ERR_OR_NULL(pll_28nm->mmio)) { + DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); + return ERR_PTR(-ENOMEM); + } + + pll = &pll_28nm->base; + pll->min_rate = VCO_MIN_RATE; + pll->max_rate = VCO_MAX_RATE; + pll->get_provider = dsi_pll_28nm_get_provider; + pll->destroy = dsi_pll_28nm_destroy; + pll->disable_seq = dsi_pll_28nm_disable_seq; + pll->save_state = dsi_pll_28nm_save_state; + pll->restore_state = dsi_pll_28nm_restore_state; + + if (type == MSM_DSI_PHY_28NM_HPM) { + pll_28nm->vco_delay = 1; + + pll->en_seq_cnt = 3; + pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_hpm; + pll->enable_seqs[1] = dsi_pll_28nm_enable_seq_hpm; + pll->enable_seqs[2] = dsi_pll_28nm_enable_seq_hpm; + } else if (type == MSM_DSI_PHY_28NM_LP) { + pll_28nm->vco_delay = 1000; + + pll->en_seq_cnt = 1; + pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_lp; + } else { + DRM_DEV_ERROR(&pdev->dev, "phy type (%d) is not 28nm\n", type); + return ERR_PTR(-EINVAL); + } + + ret = pll_28nm_register(pll_28nm); + if (ret) { + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); + return ERR_PTR(ret); + } + + return pll; +} + + static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy, struct msm_dsi_dphy_timing *timing) { diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index 5d33de27a0f4..4a40513057e8 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -3,11 +3,530 @@ * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. */ +#include #include #include "dsi_phy.h" +#include "dsi_pll.h" #include "dsi.xml.h" +/* + * DSI PLL 28nm (8960/A family) - clock diagram (eg: DSI1): + * + * + * +------+ + * dsi1vco_clk ----o-----| DIV1 |---dsi1pllbit (not exposed as clock) + * F * byte_clk | +------+ + * | bit clock divider (F / 8) + * | + * | +------+ + * o-----| DIV2 |---dsi0pllbyte---o---> To byte RCG + * | +------+ | (sets parent rate) + * | byte clock divider (F) | + * | | + * | o---> To esc RCG + * | (doesn't set parent rate) + * | + * | +------+ + * o-----| DIV3 |----dsi0pll------o---> To dsi RCG + * +------+ | (sets parent rate) + * dsi clock divider (F * magic) | + * | + * o---> To pixel rcg + * (doesn't set parent rate) + */ + +#define POLL_MAX_READS 8000 +#define POLL_TIMEOUT_US 1 + +#define NUM_PROVIDED_CLKS 2 + +#define VCO_REF_CLK_RATE 27000000 +#define VCO_MIN_RATE 600000000 +#define VCO_MAX_RATE 1200000000 + +#define DSI_BYTE_PLL_CLK 0 +#define DSI_PIXEL_PLL_CLK 1 + +#define VCO_PREF_DIV_RATIO 27 + +struct pll_28nm_cached_state { + unsigned long vco_rate; + u8 postdiv3; + u8 postdiv2; + u8 postdiv1; +}; + +struct clk_bytediv { + struct clk_hw hw; + void __iomem *reg; +}; + +struct dsi_pll_28nm { + struct msm_dsi_pll base; + + int id; + struct platform_device *pdev; + void __iomem *mmio; + + /* custom byte clock divider */ + struct clk_bytediv *bytediv; + + /* private clocks: */ + struct clk *clks[NUM_DSI_CLOCKS_MAX]; + u32 num_clks; + + /* clock-provider: */ + struct clk *provided_clks[NUM_PROVIDED_CLKS]; + struct clk_onecell_data clk_data; + + struct pll_28nm_cached_state cached_state; +}; + +#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base) + +static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, + int nb_tries, int timeout_us) +{ + bool pll_locked = false; + u32 val; + + while (nb_tries--) { + val = pll_read(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_RDY); + pll_locked = !!(val & DSI_28nm_8960_PHY_PLL_RDY_PLL_RDY); + + if (pll_locked) + break; + + udelay(timeout_us); + } + DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); + + return pll_locked; +} + +/* + * Clock Callbacks + */ +static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + void __iomem *base = pll_28nm->mmio; + u32 val, temp, fb_divider; + + DBG("rate=%lu, parent's=%lu", rate, parent_rate); + + temp = rate / 10; + val = VCO_REF_CLK_RATE / 10; + fb_divider = (temp * VCO_PREF_DIV_RATIO) / val; + fb_divider = fb_divider / 2 - 1; + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1, + fb_divider & 0xff); + + val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2); + + val |= (fb_divider >> 8) & 0x07; + + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2, + val); + + val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); + + val |= (VCO_PREF_DIV_RATIO - 1) & 0x3f; + + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3, + val); + + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_6, + 0xf); + + val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + val |= 0x7 << 4; + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, + val); + + return 0; +} + +static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS, + POLL_TIMEOUT_US); +} + +static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + void __iomem *base = pll_28nm->mmio; + unsigned long vco_rate; + u32 status, fb_divider, temp, ref_divider; + + VERB("parent_rate=%lu", parent_rate); + + status = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); + + if (status & DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE) { + fb_divider = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1); + fb_divider &= 0xff; + temp = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2) & 0x07; + fb_divider = (temp << 8) | fb_divider; + fb_divider += 1; + + ref_divider = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); + ref_divider &= 0x3f; + ref_divider += 1; + + /* multiply by 2 */ + vco_rate = (parent_rate / ref_divider) * fb_divider * 2; + } else { + vco_rate = 0; + } + + DBG("returning vco rate = %lu", vco_rate); + + return vco_rate; +} + +static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { + .round_rate = msm_dsi_pll_helper_clk_round_rate, + .set_rate = dsi_pll_28nm_clk_set_rate, + .recalc_rate = dsi_pll_28nm_clk_recalc_rate, + .prepare = msm_dsi_pll_helper_clk_prepare, + .unprepare = msm_dsi_pll_helper_clk_unprepare, + .is_enabled = dsi_pll_28nm_clk_is_enabled, +}; + +/* + * Custom byte clock divier clk_ops + * + * This clock is the entry point to configuring the PLL. The user (dsi host) + * will set this clock's rate to the desired byte clock rate. The VCO lock + * frequency is a multiple of the byte clock rate. The multiplication factor + * (shown as F in the diagram above) is a function of the byte clock rate. + * + * This custom divider clock ensures that its parent (VCO) is set to the + * desired rate, and that the byte clock postdivider (POSTDIV2) is configured + * accordingly + */ +#define to_clk_bytediv(_hw) container_of(_hw, struct clk_bytediv, hw) + +static unsigned long clk_bytediv_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_bytediv *bytediv = to_clk_bytediv(hw); + unsigned int div; + + div = pll_read(bytediv->reg) & 0xff; + + return parent_rate / (div + 1); +} + +/* find multiplication factor(wrt byte clock) at which the VCO should be set */ +static unsigned int get_vco_mul_factor(unsigned long byte_clk_rate) +{ + unsigned long bit_mhz; + + /* convert to bit clock in Mhz */ + bit_mhz = (byte_clk_rate * 8) / 1000000; + + if (bit_mhz < 125) + return 64; + else if (bit_mhz < 250) + return 32; + else if (bit_mhz < 600) + return 16; + else + return 8; +} + +static long clk_bytediv_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + unsigned long best_parent; + unsigned int factor; + + factor = get_vco_mul_factor(rate); + + best_parent = rate * factor; + *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); + + return *prate / factor; +} + +static int clk_bytediv_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct clk_bytediv *bytediv = to_clk_bytediv(hw); + u32 val; + unsigned int factor; + + factor = get_vco_mul_factor(rate); + + val = pll_read(bytediv->reg); + val |= (factor - 1) & 0xff; + pll_write(bytediv->reg, val); + + return 0; +} + +/* Our special byte clock divider ops */ +static const struct clk_ops clk_bytediv_ops = { + .round_rate = clk_bytediv_round_rate, + .set_rate = clk_bytediv_set_rate, + .recalc_rate = clk_bytediv_recalc_rate, +}; + +/* + * PLL Callbacks + */ +static int dsi_pll_28nm_enable_seq(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct device *dev = &pll_28nm->pdev->dev; + void __iomem *base = pll_28nm->mmio; + bool locked; + unsigned int bit_div, byte_div; + int max_reads = 1000, timeout_us = 100; + u32 val; + + DBG("id=%d", pll_28nm->id); + + /* + * before enabling the PLL, configure the bit clock divider since we + * don't expose it as a clock to the outside world + * 1: read back the byte clock divider that should already be set + * 2: divide by 8 to get bit clock divider + * 3: write it to POSTDIV1 + */ + val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); + byte_div = val + 1; + bit_div = byte_div / 8; + + val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + val &= ~0xf; + val |= (bit_div - 1); + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, val); + + /* enable the PLL */ + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, + DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE); + + locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); + + if (unlikely(!locked)) + DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); + else + DBG("DSI PLL lock success"); + + return locked ? 0 : -EINVAL; +} + +static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + DBG("id=%d", pll_28nm->id); + pll_write(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00); +} + +static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; + void __iomem *base = pll_28nm->mmio; + + cached_state->postdiv3 = + pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10); + cached_state->postdiv2 = + pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); + cached_state->postdiv1 = + pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + + cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw); +} + +static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; + void __iomem *base = pll_28nm->mmio; + int ret; + + ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw, + cached_state->vco_rate, 0); + if (ret) { + DRM_DEV_ERROR(&pll_28nm->pdev->dev, + "restore vco rate failed. ret=%d\n", ret); + return ret; + } + + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10, + cached_state->postdiv3); + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9, + cached_state->postdiv2); + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, + cached_state->postdiv1); + + return 0; +} + +static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll, + struct clk **byte_clk_provider, + struct clk **pixel_clk_provider) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + if (byte_clk_provider) + *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK]; + if (pixel_clk_provider) + *pixel_clk_provider = + pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK]; + + return 0; +} + +static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev, + pll_28nm->clks, pll_28nm->num_clks); +} + +static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) +{ + char *clk_name, *parent_name, *vco_name; + struct clk_init_data vco_init = { + .parent_names = (const char *[]){ "pxo" }, + .num_parents = 1, + .flags = CLK_IGNORE_UNUSED, + .ops = &clk_ops_dsi_pll_28nm_vco, + }; + struct device *dev = &pll_28nm->pdev->dev; + struct clk **clks = pll_28nm->clks; + struct clk **provided_clks = pll_28nm->provided_clks; + struct clk_bytediv *bytediv; + struct clk_init_data bytediv_init = { }; + int ret, num = 0; + + DBG("%d", pll_28nm->id); + + bytediv = devm_kzalloc(dev, sizeof(*bytediv), GFP_KERNEL); + if (!bytediv) + return -ENOMEM; + + vco_name = devm_kzalloc(dev, 32, GFP_KERNEL); + if (!vco_name) + return -ENOMEM; + + parent_name = devm_kzalloc(dev, 32, GFP_KERNEL); + if (!parent_name) + return -ENOMEM; + + clk_name = devm_kzalloc(dev, 32, GFP_KERNEL); + if (!clk_name) + return -ENOMEM; + + pll_28nm->bytediv = bytediv; + + snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); + vco_init.name = vco_name; + + pll_28nm->base.clk_hw.init = &vco_init; + + clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw); + + /* prepare and register bytediv */ + bytediv->hw.init = &bytediv_init; + bytediv->reg = pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_9; + + snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->id); + snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); + + bytediv_init.name = clk_name; + bytediv_init.ops = &clk_bytediv_ops; + bytediv_init.flags = CLK_SET_RATE_PARENT; + bytediv_init.parent_names = (const char * const *) &parent_name; + bytediv_init.num_parents = 1; + + /* DIV2 */ + clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] = + clk_register(dev, &bytediv->hw); + + snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); + /* DIV3 */ + clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] = + clk_register_divider(dev, clk_name, + parent_name, 0, pll_28nm->mmio + + REG_DSI_28nm_8960_PHY_PLL_CTRL_10, + 0, 8, 0, NULL); + + pll_28nm->num_clks = num; + + pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS; + pll_28nm->clk_data.clks = provided_clks; + + ret = of_clk_add_provider(dev->of_node, + of_clk_src_onecell_get, &pll_28nm->clk_data); + if (ret) { + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); + return ret; + } + + return 0; +} + +struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(struct platform_device *pdev, + int id) +{ + struct dsi_pll_28nm *pll_28nm; + struct msm_dsi_pll *pll; + int ret; + + if (!pdev) + return ERR_PTR(-ENODEV); + + pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL); + if (!pll_28nm) + return ERR_PTR(-ENOMEM); + + pll_28nm->pdev = pdev; + pll_28nm->id = id + 1; + + pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); + if (IS_ERR_OR_NULL(pll_28nm->mmio)) { + DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); + return ERR_PTR(-ENOMEM); + } + + pll = &pll_28nm->base; + pll->min_rate = VCO_MIN_RATE; + pll->max_rate = VCO_MAX_RATE; + pll->get_provider = dsi_pll_28nm_get_provider; + pll->destroy = dsi_pll_28nm_destroy; + pll->disable_seq = dsi_pll_28nm_disable_seq; + pll->save_state = dsi_pll_28nm_save_state; + pll->restore_state = dsi_pll_28nm_restore_state; + + pll->en_seq_cnt = 1; + pll->enable_seqs[0] = dsi_pll_28nm_enable_seq; + + ret = pll_28nm_register(pll_28nm); + if (ret) { + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); + return ERR_PTR(ret); + } + + return pll; +} + static void dsi_28nm_dphy_set_timing(struct msm_dsi_phy *phy, struct msm_dsi_dphy_timing *timing) { diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index cbfeec860e69..f9af9d70b56a 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -3,11 +3,916 @@ * Copyright (c) 2018, The Linux Foundation */ +#include +#include #include +#include "dsi_pll.h" #include "dsi_phy.h" #include "dsi.xml.h" +/* + * DSI PLL 7nm - clock diagram (eg: DSI0): TODO: updated CPHY diagram + * + * dsi0_pll_out_div_clk dsi0_pll_bit_clk + * | | + * | | + * +---------+ | +----------+ | +----+ + * dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk + * +---------+ | +----------+ | +----+ + * | | + * | | dsi0_pll_by_2_bit_clk + * | | | + * | | +----+ | |\ dsi0_pclk_mux + * | |--| /2 |--o--| \ | + * | | +----+ | \ | +---------+ + * | --------------| |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk + * |------------------------------| / +---------+ + * | +-----+ | / + * -----------| /4? |--o----------|/ + * +-----+ | | + * | |dsiclk_sel + * | + * dsi0_pll_post_out_div_clk + */ + +#define DSI_BYTE_PLL_CLK 0 +#define DSI_PIXEL_PLL_CLK 1 +#define NUM_PROVIDED_CLKS 2 + +#define VCO_REF_CLK_RATE 19200000 + +struct dsi_pll_regs { + u32 pll_prop_gain_rate; + u32 pll_lockdet_rate; + u32 decimal_div_start; + u32 frac_div_start_low; + u32 frac_div_start_mid; + u32 frac_div_start_high; + u32 pll_clock_inverters; + u32 ssc_stepsize_low; + u32 ssc_stepsize_high; + u32 ssc_div_per_low; + u32 ssc_div_per_high; + u32 ssc_adjper_low; + u32 ssc_adjper_high; + u32 ssc_control; +}; + +struct dsi_pll_config { + u32 ref_freq; + bool div_override; + u32 output_div; + bool ignore_frac; + bool disable_prescaler; + bool enable_ssc; + bool ssc_center; + u32 dec_bits; + u32 frac_bits; + u32 lock_timer; + u32 ssc_freq; + u32 ssc_offset; + u32 ssc_adj_per; + u32 thresh_cycles; + u32 refclk_cycles; +}; + +struct pll_7nm_cached_state { + unsigned long vco_rate; + u8 bit_clk_div; + u8 pix_clk_div; + u8 pll_out_div; + u8 pll_mux; +}; + +struct dsi_pll_7nm { + struct msm_dsi_pll base; + + int id; + struct platform_device *pdev; + + void __iomem *phy_cmn_mmio; + void __iomem *mmio; + + u64 vco_ref_clk_rate; + u64 vco_current_rate; + + /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */ + spinlock_t postdiv_lock; + + int vco_delay; + struct dsi_pll_config pll_configuration; + struct dsi_pll_regs reg_setup; + + /* private clocks: */ + struct clk_hw *out_div_clk_hw; + struct clk_hw *bit_clk_hw; + struct clk_hw *byte_clk_hw; + struct clk_hw *by_2_bit_clk_hw; + struct clk_hw *post_out_div_clk_hw; + struct clk_hw *pclk_mux_hw; + struct clk_hw *out_dsiclk_hw; + + /* clock-provider: */ + struct clk_hw_onecell_data *hw_data; + + struct pll_7nm_cached_state cached_state; + + enum msm_dsi_phy_usecase uc; + struct dsi_pll_7nm *slave; +}; + +#define to_pll_7nm(x) container_of(x, struct dsi_pll_7nm, base) + +/* + * Global list of private DSI PLL struct pointers. We need this for Dual DSI + * mode, where the master PLL's clk_ops needs access the slave's private data + */ +static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX]; + +static void dsi_pll_setup_config(struct dsi_pll_7nm *pll) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + + config->ref_freq = pll->vco_ref_clk_rate; + config->output_div = 1; + config->dec_bits = 8; + config->frac_bits = 18; + config->lock_timer = 64; + config->ssc_freq = 31500; + config->ssc_offset = 4800; + config->ssc_adj_per = 2; + config->thresh_cycles = 32; + config->refclk_cycles = 256; + + config->div_override = false; + config->ignore_frac = false; + config->disable_prescaler = false; + + /* TODO: ssc enable */ + config->enable_ssc = false; + config->ssc_center = 0; +} + +static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + struct dsi_pll_regs *regs = &pll->reg_setup; + u64 fref = pll->vco_ref_clk_rate; + u64 pll_freq; + u64 divider; + u64 dec, dec_multiple; + u32 frac; + u64 multiplier; + + pll_freq = pll->vco_current_rate; + + if (config->disable_prescaler) + divider = fref; + else + divider = fref * 2; + + multiplier = 1 << config->frac_bits; + dec_multiple = div_u64(pll_freq * multiplier, divider); + div_u64_rem(dec_multiple, multiplier, &frac); + + dec = div_u64(dec_multiple, multiplier); + + if (pll->base.type != MSM_DSI_PHY_7NM_V4_1) + regs->pll_clock_inverters = 0x28; + else if (pll_freq <= 1000000000ULL) + regs->pll_clock_inverters = 0xa0; + else if (pll_freq <= 2500000000ULL) + regs->pll_clock_inverters = 0x20; + else if (pll_freq <= 3020000000ULL) + regs->pll_clock_inverters = 0x00; + else + regs->pll_clock_inverters = 0x40; + + regs->pll_lockdet_rate = config->lock_timer; + regs->decimal_div_start = dec; + regs->frac_div_start_low = (frac & 0xff); + regs->frac_div_start_mid = (frac & 0xff00) >> 8; + regs->frac_div_start_high = (frac & 0x30000) >> 16; +} + +#define SSC_CENTER BIT(0) +#define SSC_EN BIT(1) + +static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll) +{ + struct dsi_pll_config *config = &pll->pll_configuration; + struct dsi_pll_regs *regs = &pll->reg_setup; + u32 ssc_per; + u32 ssc_mod; + u64 ssc_step_size; + u64 frac; + + if (!config->enable_ssc) { + DBG("SSC not enabled\n"); + return; + } + + ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1; + ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1); + ssc_per -= ssc_mod; + + frac = regs->frac_div_start_low | + (regs->frac_div_start_mid << 8) | + (regs->frac_div_start_high << 16); + ssc_step_size = regs->decimal_div_start; + ssc_step_size *= (1 << config->frac_bits); + ssc_step_size += frac; + ssc_step_size *= config->ssc_offset; + ssc_step_size *= (config->ssc_adj_per + 1); + ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1)); + ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000); + + regs->ssc_div_per_low = ssc_per & 0xFF; + regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8; + regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF); + regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8); + regs->ssc_adjper_low = config->ssc_adj_per & 0xFF; + regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8; + + regs->ssc_control = config->ssc_center ? SSC_CENTER : 0; + + pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n", + regs->decimal_div_start, frac, config->frac_bits); + pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n", + ssc_per, (u32)ssc_step_size, config->ssc_adj_per); +} + +static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll) +{ + void __iomem *base = pll->mmio; + struct dsi_pll_regs *regs = &pll->reg_setup; + + if (pll->pll_configuration.enable_ssc) { + pr_debug("SSC is enabled\n"); + + pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1, + regs->ssc_stepsize_low); + pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1, + regs->ssc_stepsize_high); + pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1, + regs->ssc_div_per_low); + pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1, + regs->ssc_div_per_high); + pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1, + regs->ssc_adjper_low); + pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1, + regs->ssc_adjper_high); + pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL, + SSC_EN | regs->ssc_control); + } +} + +static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll) +{ + void __iomem *base = pll->mmio; + u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00; + + if (pll->base.type == MSM_DSI_PHY_7NM_V4_1) { + if (pll->vco_current_rate >= 3100000000ULL) + analog_controls_five_1 = 0x03; + + if (pll->vco_current_rate < 1520000000ULL) + vco_config_1 = 0x08; + else if (pll->vco_current_rate < 2990000000ULL) + vco_config_1 = 0x01; + } + + pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1, + analog_controls_five_1); + pll_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1); + pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01); + pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); + pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00); + pll_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00); + pll_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e); + pll_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40); + pll_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba); + pll_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); + pll_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00); + pll_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80); + pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29); + pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f); + pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a); + pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT, + pll->base.type == MSM_DSI_PHY_7NM_V4_1 ? 0x3f : 0x22); + + if (pll->base.type == MSM_DSI_PHY_7NM_V4_1) { + pll_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); + if (pll->slave) + pll_write(pll->slave->mmio + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); + } +} + +static void dsi_pll_commit(struct dsi_pll_7nm *pll) +{ + void __iomem *base = pll->mmio; + struct dsi_pll_regs *reg = &pll->reg_setup; + + pll_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); + pll_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1, reg->decimal_div_start); + pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low); + pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid); + pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate); + pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); + pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */ + pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); +} + +static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + + DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->id, rate, + parent_rate); + + pll_7nm->vco_current_rate = rate; + pll_7nm->vco_ref_clk_rate = VCO_REF_CLK_RATE; + + dsi_pll_setup_config(pll_7nm); + + dsi_pll_calc_dec_frac(pll_7nm); + + dsi_pll_calc_ssc(pll_7nm); + + dsi_pll_commit(pll_7nm); + + dsi_pll_config_hzindep_reg(pll_7nm); + + dsi_pll_ssc_commit(pll_7nm); + + /* flush, ensure all register writes are done*/ + wmb(); + + return 0; +} + +static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll) +{ + int rc; + u32 status = 0; + u32 const delay_us = 100; + u32 const timeout_us = 5000; + + rc = readl_poll_timeout_atomic(pll->mmio + + REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE, + status, + ((status & BIT(0)) > 0), + delay_us, + timeout_us); + if (rc) + pr_err("DSI PLL(%d) lock failed, status=0x%08x\n", + pll->id, status); + + return rc; +} + +static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll) +{ + u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0); + + pll_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0); + pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5)); + ndelay(250); +} + +static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll) +{ + u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0); + + pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5)); + pll_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0); + ndelay(250); +} + +static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll) +{ + u32 data; + + data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5)); +} + +static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll) +{ + u32 data; + + pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04); + + data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1, + data | BIT(5) | BIT(4)); +} + +static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll) +{ + /* + * Reset the PHY digital domain. This would be needed when + * coming out of a CX or analog rail power collapse while + * ensuring that the pads maintain LP00 or LP11 state + */ + pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0)); + wmb(); /* Ensure that the reset is deasserted */ + pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0); + wmb(); /* Ensure that the reset is deasserted */ +} + +static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + int rc; + + dsi_pll_enable_pll_bias(pll_7nm); + if (pll_7nm->slave) + dsi_pll_enable_pll_bias(pll_7nm->slave); + + /* Start PLL */ + pll_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01); + + /* + * ensure all PLL configurations are written prior to checking + * for PLL lock. + */ + wmb(); + + /* Check for PLL lock */ + rc = dsi_pll_7nm_lock_status(pll_7nm); + if (rc) { + pr_err("PLL(%d) lock failed\n", pll_7nm->id); + goto error; + } + + pll->pll_on = true; + + /* + * assert power on reset for PHY digital in case the PLL is + * enabled after CX of analog domain power collapse. This needs + * to be done before enabling the global clk. + */ + dsi_pll_phy_dig_reset(pll_7nm); + if (pll_7nm->slave) + dsi_pll_phy_dig_reset(pll_7nm->slave); + + dsi_pll_enable_global_clk(pll_7nm); + if (pll_7nm->slave) + dsi_pll_enable_global_clk(pll_7nm->slave); + +error: + return rc; +} + +static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll) +{ + pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0); + dsi_pll_disable_pll_bias(pll); +} + +static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + + /* + * To avoid any stray glitches while abruptly powering down the PLL + * make sure to gate the clock using the clock enable bit before + * powering down the PLL + */ + dsi_pll_disable_global_clk(pll_7nm); + pll_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0); + dsi_pll_disable_sub(pll_7nm); + if (pll_7nm->slave) { + dsi_pll_disable_global_clk(pll_7nm->slave); + dsi_pll_disable_sub(pll_7nm->slave); + } + /* flush, ensure all register writes are done */ + wmb(); + pll->pll_on = false; +} + +static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct dsi_pll_config *config = &pll_7nm->pll_configuration; + void __iomem *base = pll_7nm->mmio; + u64 ref_clk = pll_7nm->vco_ref_clk_rate; + u64 vco_rate = 0x0; + u64 multiplier; + u32 frac; + u32 dec; + u64 pll_freq, tmp64; + + dec = pll_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1); + dec &= 0xff; + + frac = pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1); + frac |= ((pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) & + 0xff) << 8); + frac |= ((pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) & + 0x3) << 16); + + /* + * TODO: + * 1. Assumes prescaler is disabled + */ + multiplier = 1 << config->frac_bits; + pll_freq = dec * (ref_clk * 2); + tmp64 = (ref_clk * 2 * frac); + pll_freq += div_u64(tmp64, multiplier); + + vco_rate = pll_freq; + + DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", + pll_7nm->id, (unsigned long)vco_rate, dec, frac); + + return (unsigned long)vco_rate; +} + +static const struct clk_ops clk_ops_dsi_pll_7nm_vco = { + .round_rate = msm_dsi_pll_helper_clk_round_rate, + .set_rate = dsi_pll_7nm_vco_set_rate, + .recalc_rate = dsi_pll_7nm_vco_recalc_rate, + .prepare = dsi_pll_7nm_vco_prepare, + .unprepare = dsi_pll_7nm_vco_unprepare, +}; + +/* + * PLL Callbacks + */ + +static void dsi_pll_7nm_save_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; + void __iomem *phy_base = pll_7nm->phy_cmn_mmio; + u32 cmn_clk_cfg0, cmn_clk_cfg1; + + cached->pll_out_div = pll_read(pll_7nm->mmio + + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); + cached->pll_out_div &= 0x3; + + cmn_clk_cfg0 = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); + cached->bit_clk_div = cmn_clk_cfg0 & 0xf; + cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4; + + cmn_clk_cfg1 = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + cached->pll_mux = cmn_clk_cfg1 & 0x3; + + DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", + pll_7nm->id, cached->pll_out_div, cached->bit_clk_div, + cached->pix_clk_div, cached->pll_mux); +} + +static int dsi_pll_7nm_restore_state(struct msm_dsi_pll *pll) +{ + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; + void __iomem *phy_base = pll_7nm->phy_cmn_mmio; + u32 val; + int ret; + + val = pll_read(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); + val &= ~0x3; + val |= cached->pll_out_div; + pll_write(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val); + + pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0, + cached->bit_clk_div | (cached->pix_clk_div << 4)); + + val = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + val &= ~0x3; + val |= cached->pll_mux; + pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val); + + ret = dsi_pll_7nm_vco_set_rate(&pll->clk_hw, pll_7nm->vco_current_rate, pll_7nm->vco_ref_clk_rate); + if (ret) { + DRM_DEV_ERROR(&pll_7nm->pdev->dev, + "restore vco rate failed. ret=%d\n", ret); + return ret; + } + + DBG("DSI PLL%d", pll_7nm->id); + + return 0; +} + +static int dsi_pll_7nm_set_usecase(struct msm_dsi_pll *pll, + enum msm_dsi_phy_usecase uc) +{ + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + void __iomem *base = pll_7nm->phy_cmn_mmio; + u32 data = 0x0; /* internal PLL */ + + DBG("DSI PLL%d", pll_7nm->id); + + switch (uc) { + case MSM_DSI_PHY_STANDALONE: + break; + case MSM_DSI_PHY_MASTER: + pll_7nm->slave = pll_7nm_list[(pll_7nm->id + 1) % DSI_MAX]; + break; + case MSM_DSI_PHY_SLAVE: + data = 0x1; /* external PLL */ + break; + default: + return -EINVAL; + } + + /* set PLL src */ + pll_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2)); + + pll_7nm->uc = uc; + + return 0; +} + +static int dsi_pll_7nm_get_provider(struct msm_dsi_pll *pll, + struct clk **byte_clk_provider, + struct clk **pixel_clk_provider) +{ + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct clk_hw_onecell_data *hw_data = pll_7nm->hw_data; + + DBG("DSI PLL%d", pll_7nm->id); + + if (byte_clk_provider) + *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk; + if (pixel_clk_provider) + *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk; + + return 0; +} + +static void dsi_pll_7nm_destroy(struct msm_dsi_pll *pll) +{ + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct device *dev = &pll_7nm->pdev->dev; + + DBG("DSI PLL%d", pll_7nm->id); + of_clk_del_provider(dev->of_node); + + clk_hw_unregister_divider(pll_7nm->out_dsiclk_hw); + clk_hw_unregister_mux(pll_7nm->pclk_mux_hw); + clk_hw_unregister_fixed_factor(pll_7nm->post_out_div_clk_hw); + clk_hw_unregister_fixed_factor(pll_7nm->by_2_bit_clk_hw); + clk_hw_unregister_fixed_factor(pll_7nm->byte_clk_hw); + clk_hw_unregister_divider(pll_7nm->bit_clk_hw); + clk_hw_unregister_divider(pll_7nm->out_div_clk_hw); + clk_hw_unregister(&pll_7nm->base.clk_hw); +} + +/* + * The post dividers and mux clocks are created using the standard divider and + * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux + * state to follow the master PLL's divider/mux state. Therefore, we don't + * require special clock ops that also configure the slave PLL registers + */ +static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm) +{ + char clk_name[32], parent[32], vco_name[32]; + char parent2[32], parent3[32], parent4[32]; + struct clk_init_data vco_init = { + .parent_names = (const char *[]){ "bi_tcxo" }, + .num_parents = 1, + .name = vco_name, + .flags = CLK_IGNORE_UNUSED, + .ops = &clk_ops_dsi_pll_7nm_vco, + }; + struct device *dev = &pll_7nm->pdev->dev; + struct clk_hw_onecell_data *hw_data; + struct clk_hw *hw; + int ret; + + DBG("DSI%d", pll_7nm->id); + + hw_data = devm_kzalloc(dev, sizeof(*hw_data) + + NUM_PROVIDED_CLKS * sizeof(struct clk_hw *), + GFP_KERNEL); + if (!hw_data) + return -ENOMEM; + + snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->id); + pll_7nm->base.clk_hw.init = &vco_init; + + ret = clk_hw_register(dev, &pll_7nm->base.clk_hw); + if (ret) + return ret; + + snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); + snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->id); + + hw = clk_hw_register_divider(dev, clk_name, + parent, CLK_SET_RATE_PARENT, + pll_7nm->mmio + + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, + 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_base_clk_hw; + } + + pll_7nm->out_div_clk_hw = hw; + + snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->id); + snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); + + /* BIT CLK: DIV_CTRL_3_0 */ + hw = clk_hw_register_divider(dev, clk_name, parent, + CLK_SET_RATE_PARENT, + pll_7nm->phy_cmn_mmio + + REG_DSI_7nm_PHY_CMN_CLK_CFG0, + 0, 4, CLK_DIVIDER_ONE_BASED, + &pll_7nm->postdiv_lock); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_out_div_clk_hw; + } + + pll_7nm->bit_clk_hw = hw; + + snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); + + /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, + CLK_SET_RATE_PARENT, 1, 8); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_bit_clk_hw; + } + + pll_7nm->byte_clk_hw = hw; + hw_data->hws[DSI_BYTE_PLL_CLK] = hw; + + snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); + + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, + 0, 1, 2); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_byte_clk_hw; + } + + pll_7nm->by_2_bit_clk_hw = hw; + + snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id); + snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); + + hw = clk_hw_register_fixed_factor(dev, clk_name, parent, + 0, 1, 4); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_by_2_bit_clk_hw; + } + + pll_7nm->post_out_div_clk_hw = hw; + + snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); + snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id); + snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); + snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id); + + hw = clk_hw_register_mux(dev, clk_name, + ((const char *[]){ + parent, parent2, parent3, parent4 + }), 4, 0, pll_7nm->phy_cmn_mmio + + REG_DSI_7nm_PHY_CMN_CLK_CFG1, + 0, 2, 0, NULL); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_post_out_div_clk_hw; + } + + pll_7nm->pclk_mux_hw = hw; + + snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->id); + snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->id); + + /* PIX CLK DIV : DIV_CTRL_7_4*/ + hw = clk_hw_register_divider(dev, clk_name, parent, + 0, pll_7nm->phy_cmn_mmio + + REG_DSI_7nm_PHY_CMN_CLK_CFG0, + 4, 4, CLK_DIVIDER_ONE_BASED, + &pll_7nm->postdiv_lock); + if (IS_ERR(hw)) { + ret = PTR_ERR(hw); + goto err_pclk_mux_hw; + } + + pll_7nm->out_dsiclk_hw = hw; + hw_data->hws[DSI_PIXEL_PLL_CLK] = hw; + + hw_data->num = NUM_PROVIDED_CLKS; + pll_7nm->hw_data = hw_data; + + ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, + pll_7nm->hw_data); + if (ret) { + DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); + goto err_dsiclk_hw; + } + + return 0; + +err_dsiclk_hw: + clk_hw_unregister_divider(pll_7nm->out_dsiclk_hw); +err_pclk_mux_hw: + clk_hw_unregister_mux(pll_7nm->pclk_mux_hw); +err_post_out_div_clk_hw: + clk_hw_unregister_fixed_factor(pll_7nm->post_out_div_clk_hw); +err_by_2_bit_clk_hw: + clk_hw_unregister_fixed_factor(pll_7nm->by_2_bit_clk_hw); +err_byte_clk_hw: + clk_hw_unregister_fixed_factor(pll_7nm->byte_clk_hw); +err_bit_clk_hw: + clk_hw_unregister_divider(pll_7nm->bit_clk_hw); +err_out_div_clk_hw: + clk_hw_unregister_divider(pll_7nm->out_div_clk_hw); +err_base_clk_hw: + clk_hw_unregister(&pll_7nm->base.clk_hw); + + return ret; +} + +struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, + enum msm_dsi_phy_type type, int id) +{ + struct dsi_pll_7nm *pll_7nm; + struct msm_dsi_pll *pll; + int ret; + + pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL); + if (!pll_7nm) + return ERR_PTR(-ENOMEM); + + DBG("DSI PLL%d", id); + + pll_7nm->pdev = pdev; + pll_7nm->id = id; + pll_7nm_list[id] = pll_7nm; + + pll_7nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); + if (IS_ERR_OR_NULL(pll_7nm->phy_cmn_mmio)) { + DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); + return ERR_PTR(-ENOMEM); + } + + pll_7nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); + if (IS_ERR_OR_NULL(pll_7nm->mmio)) { + DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); + return ERR_PTR(-ENOMEM); + } + + spin_lock_init(&pll_7nm->postdiv_lock); + + pll = &pll_7nm->base; + pll->min_rate = 1000000000UL; + pll->max_rate = 3500000000UL; + if (type == MSM_DSI_PHY_7NM_V4_1) { + pll->min_rate = 600000000UL; + pll->max_rate = (unsigned long)5000000000ULL; + /* workaround for max rate overflowing on 32-bit builds: */ + pll->max_rate = max(pll->max_rate, 0xffffffffUL); + } + pll->get_provider = dsi_pll_7nm_get_provider; + pll->destroy = dsi_pll_7nm_destroy; + pll->save_state = dsi_pll_7nm_save_state; + pll->restore_state = dsi_pll_7nm_restore_state; + pll->set_usecase = dsi_pll_7nm_set_usecase; + + pll_7nm->vco_delay = 1; + + ret = pll_7nm_register(pll_7nm); + if (ret) { + DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); + return ERR_PTR(ret); + } + + /* TODO: Remove this when we have proper display handover support */ + msm_dsi_pll_save_state(pll); + + return pll; +} + static int dsi_phy_hw_v4_0_is_pll_on(struct msm_dsi_phy *phy) { void __iomem *base = phy->base; diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.c b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c similarity index 100% rename from drivers/gpu/drm/msm/dsi/pll/dsi_pll.c rename to drivers/gpu/drm/msm/dsi/phy/dsi_pll.c diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll.h b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h similarity index 100% rename from drivers/gpu/drm/msm/dsi/pll/dsi_pll.h rename to drivers/gpu/drm/msm/dsi/phy/dsi_pll.h diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c deleted file mode 100644 index de3b802ccd3d..000000000000 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_10nm.c +++ /dev/null @@ -1,881 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0 - * Copyright (c) 2018, The Linux Foundation - */ - -#include -#include -#include - -#include "dsi_pll.h" -#include "dsi.xml.h" - -/* - * DSI PLL 10nm - clock diagram (eg: DSI0): - * - * dsi0_pll_out_div_clk dsi0_pll_bit_clk - * | | - * | | - * +---------+ | +----------+ | +----+ - * dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk - * +---------+ | +----------+ | +----+ - * | | - * | | dsi0_pll_by_2_bit_clk - * | | | - * | | +----+ | |\ dsi0_pclk_mux - * | |--| /2 |--o--| \ | - * | | +----+ | \ | +---------+ - * | --------------| |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk - * |------------------------------| / +---------+ - * | +-----+ | / - * -----------| /4? |--o----------|/ - * +-----+ | | - * | |dsiclk_sel - * | - * dsi0_pll_post_out_div_clk - */ - -#define DSI_BYTE_PLL_CLK 0 -#define DSI_PIXEL_PLL_CLK 1 -#define NUM_PROVIDED_CLKS 2 - -#define VCO_REF_CLK_RATE 19200000 - -struct dsi_pll_regs { - u32 pll_prop_gain_rate; - u32 pll_lockdet_rate; - u32 decimal_div_start; - u32 frac_div_start_low; - u32 frac_div_start_mid; - u32 frac_div_start_high; - u32 pll_clock_inverters; - u32 ssc_stepsize_low; - u32 ssc_stepsize_high; - u32 ssc_div_per_low; - u32 ssc_div_per_high; - u32 ssc_adjper_low; - u32 ssc_adjper_high; - u32 ssc_control; -}; - -struct dsi_pll_config { - u32 ref_freq; - bool div_override; - u32 output_div; - bool ignore_frac; - bool disable_prescaler; - bool enable_ssc; - bool ssc_center; - u32 dec_bits; - u32 frac_bits; - u32 lock_timer; - u32 ssc_freq; - u32 ssc_offset; - u32 ssc_adj_per; - u32 thresh_cycles; - u32 refclk_cycles; -}; - -struct pll_10nm_cached_state { - unsigned long vco_rate; - u8 bit_clk_div; - u8 pix_clk_div; - u8 pll_out_div; - u8 pll_mux; -}; - -struct dsi_pll_10nm { - struct msm_dsi_pll base; - - int id; - struct platform_device *pdev; - - void __iomem *phy_cmn_mmio; - void __iomem *mmio; - - u64 vco_ref_clk_rate; - u64 vco_current_rate; - - /* protects REG_DSI_10nm_PHY_CMN_CLK_CFG0 register */ - spinlock_t postdiv_lock; - - int vco_delay; - struct dsi_pll_config pll_configuration; - struct dsi_pll_regs reg_setup; - - /* private clocks: */ - struct clk_hw *out_div_clk_hw; - struct clk_hw *bit_clk_hw; - struct clk_hw *byte_clk_hw; - struct clk_hw *by_2_bit_clk_hw; - struct clk_hw *post_out_div_clk_hw; - struct clk_hw *pclk_mux_hw; - struct clk_hw *out_dsiclk_hw; - - /* clock-provider: */ - struct clk_hw_onecell_data *hw_data; - - struct pll_10nm_cached_state cached_state; - - enum msm_dsi_phy_usecase uc; - struct dsi_pll_10nm *slave; -}; - -#define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, base) - -/* - * Global list of private DSI PLL struct pointers. We need this for Dual DSI - * mode, where the master PLL's clk_ops needs access the slave's private data - */ -static struct dsi_pll_10nm *pll_10nm_list[DSI_MAX]; - -static void dsi_pll_setup_config(struct dsi_pll_10nm *pll) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - - config->ref_freq = pll->vco_ref_clk_rate; - config->output_div = 1; - config->dec_bits = 8; - config->frac_bits = 18; - config->lock_timer = 64; - config->ssc_freq = 31500; - config->ssc_offset = 5000; - config->ssc_adj_per = 2; - config->thresh_cycles = 32; - config->refclk_cycles = 256; - - config->div_override = false; - config->ignore_frac = false; - config->disable_prescaler = false; - - config->enable_ssc = false; - config->ssc_center = 0; -} - -static void dsi_pll_calc_dec_frac(struct dsi_pll_10nm *pll) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - struct dsi_pll_regs *regs = &pll->reg_setup; - u64 fref = pll->vco_ref_clk_rate; - u64 pll_freq; - u64 divider; - u64 dec, dec_multiple; - u32 frac; - u64 multiplier; - - pll_freq = pll->vco_current_rate; - - if (config->disable_prescaler) - divider = fref; - else - divider = fref * 2; - - multiplier = 1 << config->frac_bits; - dec_multiple = div_u64(pll_freq * multiplier, divider); - dec = div_u64_rem(dec_multiple, multiplier, &frac); - - if (pll_freq <= 1900000000UL) - regs->pll_prop_gain_rate = 8; - else if (pll_freq <= 3000000000UL) - regs->pll_prop_gain_rate = 10; - else - regs->pll_prop_gain_rate = 12; - if (pll_freq < 1100000000UL) - regs->pll_clock_inverters = 8; - else - regs->pll_clock_inverters = 0; - - regs->pll_lockdet_rate = config->lock_timer; - regs->decimal_div_start = dec; - regs->frac_div_start_low = (frac & 0xff); - regs->frac_div_start_mid = (frac & 0xff00) >> 8; - regs->frac_div_start_high = (frac & 0x30000) >> 16; -} - -#define SSC_CENTER BIT(0) -#define SSC_EN BIT(1) - -static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - struct dsi_pll_regs *regs = &pll->reg_setup; - u32 ssc_per; - u32 ssc_mod; - u64 ssc_step_size; - u64 frac; - - if (!config->enable_ssc) { - DBG("SSC not enabled\n"); - return; - } - - ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1; - ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1); - ssc_per -= ssc_mod; - - frac = regs->frac_div_start_low | - (regs->frac_div_start_mid << 8) | - (regs->frac_div_start_high << 16); - ssc_step_size = regs->decimal_div_start; - ssc_step_size *= (1 << config->frac_bits); - ssc_step_size += frac; - ssc_step_size *= config->ssc_offset; - ssc_step_size *= (config->ssc_adj_per + 1); - ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1)); - ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000); - - regs->ssc_div_per_low = ssc_per & 0xFF; - regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8; - regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF); - regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8); - regs->ssc_adjper_low = config->ssc_adj_per & 0xFF; - regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8; - - regs->ssc_control = config->ssc_center ? SSC_CENTER : 0; - - pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n", - regs->decimal_div_start, frac, config->frac_bits); - pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n", - ssc_per, (u32)ssc_step_size, config->ssc_adj_per); -} - -static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll) -{ - void __iomem *base = pll->mmio; - struct dsi_pll_regs *regs = &pll->reg_setup; - - if (pll->pll_configuration.enable_ssc) { - pr_debug("SSC is enabled\n"); - - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_LOW_1, - regs->ssc_stepsize_low); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_STEPSIZE_HIGH_1, - regs->ssc_stepsize_high); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_LOW_1, - regs->ssc_div_per_low); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_PER_HIGH_1, - regs->ssc_div_per_high); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_LOW_1, - regs->ssc_adjper_low); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_DIV_ADJPER_HIGH_1, - regs->ssc_adjper_high); - pll_write(base + REG_DSI_10nm_PHY_PLL_SSC_CONTROL, - SSC_EN | regs->ssc_control); - } -} - -static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll) -{ - void __iomem *base = pll->mmio; - - pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80); - pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); - pll_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00); - pll_write(base + REG_DSI_10nm_PHY_PLL_DSM_DIVIDER, 0x00); - pll_write(base + REG_DSI_10nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e); - pll_write(base + REG_DSI_10nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40); - pll_write(base + REG_DSI_10nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, - 0xba); - pll_write(base + REG_DSI_10nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); - pll_write(base + REG_DSI_10nm_PHY_PLL_OUTDIV, 0x00); - pll_write(base + REG_DSI_10nm_PHY_PLL_CORE_OVERRIDE, 0x00); - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x08); - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_BAND_SET_RATE_1, 0xc0); - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0xfa); - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, - 0x4c); - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80); - pll_write(base + REG_DSI_10nm_PHY_PLL_PFILT, 0x29); - pll_write(base + REG_DSI_10nm_PHY_PLL_IFILT, 0x3f); -} - -static void dsi_pll_commit(struct dsi_pll_10nm *pll) -{ - void __iomem *base = pll->mmio; - struct dsi_pll_regs *reg = &pll->reg_setup; - - pll_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); - pll_write(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1, - reg->decimal_div_start); - pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1, - reg->frac_div_start_low); - pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1, - reg->frac_div_start_mid); - pll_write(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1, - reg->frac_div_start_high); - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCKDET_RATE_1, - reg->pll_lockdet_rate); - pll_write(base + REG_DSI_10nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); - pll_write(base + REG_DSI_10nm_PHY_PLL_CMODE, 0x10); - pll_write(base + REG_DSI_10nm_PHY_PLL_CLOCK_INVERTERS, - reg->pll_clock_inverters); -} - -static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - - DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->id, rate, - parent_rate); - - pll_10nm->vco_current_rate = rate; - pll_10nm->vco_ref_clk_rate = VCO_REF_CLK_RATE; - - dsi_pll_setup_config(pll_10nm); - - dsi_pll_calc_dec_frac(pll_10nm); - - dsi_pll_calc_ssc(pll_10nm); - - dsi_pll_commit(pll_10nm); - - dsi_pll_config_hzindep_reg(pll_10nm); - - dsi_pll_ssc_commit(pll_10nm); - - /* flush, ensure all register writes are done*/ - wmb(); - - return 0; -} - -static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) -{ - struct device *dev = &pll->pdev->dev; - int rc; - u32 status = 0; - u32 const delay_us = 100; - u32 const timeout_us = 5000; - - rc = readl_poll_timeout_atomic(pll->mmio + - REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE, - status, - ((status & BIT(0)) > 0), - delay_us, - timeout_us); - if (rc) - DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n", - pll->id, status); - - return rc; -} - -static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll) -{ - u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0); - - pll_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0); - pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0, - data & ~BIT(5)); - ndelay(250); -} - -static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll) -{ - u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0); - - pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0, - data | BIT(5)); - pll_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0); - ndelay(250); -} - -static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll) -{ - u32 data; - - data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1); - pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1, - data & ~BIT(5)); -} - -static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll) -{ - u32 data; - - data = pll_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1); - pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1, - data | BIT(5)); -} - -static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - struct device *dev = &pll_10nm->pdev->dev; - int rc; - - dsi_pll_enable_pll_bias(pll_10nm); - if (pll_10nm->slave) - dsi_pll_enable_pll_bias(pll_10nm->slave); - - rc = dsi_pll_10nm_vco_set_rate(hw,pll_10nm->vco_current_rate, 0); - if (rc) { - DRM_DEV_ERROR(dev, "vco_set_rate failed, rc=%d\n", rc); - return rc; - } - - /* Start PLL */ - pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, - 0x01); - - /* - * ensure all PLL configurations are written prior to checking - * for PLL lock. - */ - wmb(); - - /* Check for PLL lock */ - rc = dsi_pll_10nm_lock_status(pll_10nm); - if (rc) { - DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->id); - goto error; - } - - pll->pll_on = true; - - dsi_pll_enable_global_clk(pll_10nm); - if (pll_10nm->slave) - dsi_pll_enable_global_clk(pll_10nm->slave); - - pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, - 0x01); - if (pll_10nm->slave) - pll_write(pll_10nm->slave->phy_cmn_mmio + - REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01); - -error: - return rc; -} - -static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll) -{ - pll_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0); - dsi_pll_disable_pll_bias(pll); -} - -static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - - /* - * To avoid any stray glitches while abruptly powering down the PLL - * make sure to gate the clock using the clock enable bit before - * powering down the PLL - */ - dsi_pll_disable_global_clk(pll_10nm); - pll_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0); - dsi_pll_disable_sub(pll_10nm); - if (pll_10nm->slave) { - dsi_pll_disable_global_clk(pll_10nm->slave); - dsi_pll_disable_sub(pll_10nm->slave); - } - /* flush, ensure all register writes are done */ - wmb(); - pll->pll_on = false; -} - -static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - struct dsi_pll_config *config = &pll_10nm->pll_configuration; - void __iomem *base = pll_10nm->mmio; - u64 ref_clk = pll_10nm->vco_ref_clk_rate; - u64 vco_rate = 0x0; - u64 multiplier; - u32 frac; - u32 dec; - u64 pll_freq, tmp64; - - dec = pll_read(base + REG_DSI_10nm_PHY_PLL_DECIMAL_DIV_START_1); - dec &= 0xff; - - frac = pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_LOW_1); - frac |= ((pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_MID_1) & - 0xff) << 8); - frac |= ((pll_read(base + REG_DSI_10nm_PHY_PLL_FRAC_DIV_START_HIGH_1) & - 0x3) << 16); - - /* - * TODO: - * 1. Assumes prescaler is disabled - */ - multiplier = 1 << config->frac_bits; - pll_freq = dec * (ref_clk * 2); - tmp64 = (ref_clk * 2 * frac); - pll_freq += div_u64(tmp64, multiplier); - - vco_rate = pll_freq; - - DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", - pll_10nm->id, (unsigned long)vco_rate, dec, frac); - - return (unsigned long)vco_rate; -} - -static const struct clk_ops clk_ops_dsi_pll_10nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, - .set_rate = dsi_pll_10nm_vco_set_rate, - .recalc_rate = dsi_pll_10nm_vco_recalc_rate, - .prepare = dsi_pll_10nm_vco_prepare, - .unprepare = dsi_pll_10nm_vco_unprepare, -}; - -/* - * PLL Callbacks - */ - -static void dsi_pll_10nm_save_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; - void __iomem *phy_base = pll_10nm->phy_cmn_mmio; - u32 cmn_clk_cfg0, cmn_clk_cfg1; - - cached->pll_out_div = pll_read(pll_10nm->mmio + - REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); - cached->pll_out_div &= 0x3; - - cmn_clk_cfg0 = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0); - cached->bit_clk_div = cmn_clk_cfg0 & 0xf; - cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4; - - cmn_clk_cfg1 = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); - cached->pll_mux = cmn_clk_cfg1 & 0x3; - - DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", - pll_10nm->id, cached->pll_out_div, cached->bit_clk_div, - cached->pix_clk_div, cached->pll_mux); -} - -static int dsi_pll_10nm_restore_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; - void __iomem *phy_base = pll_10nm->phy_cmn_mmio; - u32 val; - int ret; - - val = pll_read(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); - val &= ~0x3; - val |= cached->pll_out_div; - pll_write(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val); - - pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0, - cached->bit_clk_div | (cached->pix_clk_div << 4)); - - val = pll_read(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); - val &= ~0x3; - val |= cached->pll_mux; - pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val); - - ret = dsi_pll_10nm_vco_set_rate(&pll->clk_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); - if (ret) { - DRM_DEV_ERROR(&pll_10nm->pdev->dev, - "restore vco rate failed. ret=%d\n", ret); - return ret; - } - - DBG("DSI PLL%d", pll_10nm->id); - - return 0; -} - -static int dsi_pll_10nm_set_usecase(struct msm_dsi_pll *pll, - enum msm_dsi_phy_usecase uc) -{ - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - void __iomem *base = pll_10nm->phy_cmn_mmio; - u32 data = 0x0; /* internal PLL */ - - DBG("DSI PLL%d", pll_10nm->id); - - switch (uc) { - case MSM_DSI_PHY_STANDALONE: - break; - case MSM_DSI_PHY_MASTER: - pll_10nm->slave = pll_10nm_list[(pll_10nm->id + 1) % DSI_MAX]; - break; - case MSM_DSI_PHY_SLAVE: - data = 0x1; /* external PLL */ - break; - default: - return -EINVAL; - } - - /* set PLL src */ - pll_write(base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, (data << 2)); - - pll_10nm->uc = uc; - - return 0; -} - -static int dsi_pll_10nm_get_provider(struct msm_dsi_pll *pll, - struct clk **byte_clk_provider, - struct clk **pixel_clk_provider) -{ - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - struct clk_hw_onecell_data *hw_data = pll_10nm->hw_data; - - DBG("DSI PLL%d", pll_10nm->id); - - if (byte_clk_provider) - *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk; - if (pixel_clk_provider) - *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk; - - return 0; -} - -static void dsi_pll_10nm_destroy(struct msm_dsi_pll *pll) -{ - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); - struct device *dev = &pll_10nm->pdev->dev; - - DBG("DSI PLL%d", pll_10nm->id); - of_clk_del_provider(dev->of_node); - - clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw); - clk_hw_unregister_mux(pll_10nm->pclk_mux_hw); - clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw); - clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw); - clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw); - clk_hw_unregister_divider(pll_10nm->bit_clk_hw); - clk_hw_unregister_divider(pll_10nm->out_div_clk_hw); - clk_hw_unregister(&pll_10nm->base.clk_hw); -} - -/* - * The post dividers and mux clocks are created using the standard divider and - * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux - * state to follow the master PLL's divider/mux state. Therefore, we don't - * require special clock ops that also configure the slave PLL registers - */ -static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm) -{ - char clk_name[32], parent[32], vco_name[32]; - char parent2[32], parent3[32], parent4[32]; - struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "xo" }, - .num_parents = 1, - .name = vco_name, - .flags = CLK_IGNORE_UNUSED, - .ops = &clk_ops_dsi_pll_10nm_vco, - }; - struct device *dev = &pll_10nm->pdev->dev; - struct clk_hw_onecell_data *hw_data; - struct clk_hw *hw; - int ret; - - DBG("DSI%d", pll_10nm->id); - - hw_data = devm_kzalloc(dev, sizeof(*hw_data) + - NUM_PROVIDED_CLKS * sizeof(struct clk_hw *), - GFP_KERNEL); - if (!hw_data) - return -ENOMEM; - - snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->id); - pll_10nm->base.clk_hw.init = &vco_init; - - ret = clk_hw_register(dev, &pll_10nm->base.clk_hw); - if (ret) - return ret; - - snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->id); - - hw = clk_hw_register_divider(dev, clk_name, - parent, CLK_SET_RATE_PARENT, - pll_10nm->mmio + - REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, - 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_base_clk_hw; - } - - pll_10nm->out_div_clk_hw = hw; - - snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); - - /* BIT CLK: DIV_CTRL_3_0 */ - hw = clk_hw_register_divider(dev, clk_name, parent, - CLK_SET_RATE_PARENT, - pll_10nm->phy_cmn_mmio + - REG_DSI_10nm_PHY_CMN_CLK_CFG0, - 0, 4, CLK_DIVIDER_ONE_BASED, - &pll_10nm->postdiv_lock); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_out_div_clk_hw; - } - - pll_10nm->bit_clk_hw = hw; - - snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); - - /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ - hw = clk_hw_register_fixed_factor(dev, clk_name, parent, - CLK_SET_RATE_PARENT, 1, 8); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_bit_clk_hw; - } - - pll_10nm->byte_clk_hw = hw; - hw_data->hws[DSI_BYTE_PLL_CLK] = hw; - - snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); - - hw = clk_hw_register_fixed_factor(dev, clk_name, parent, - 0, 1, 2); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_byte_clk_hw; - } - - pll_10nm->by_2_bit_clk_hw = hw; - - snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); - - hw = clk_hw_register_fixed_factor(dev, clk_name, parent, - 0, 1, 4); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_by_2_bit_clk_hw; - } - - pll_10nm->post_out_div_clk_hw = hw; - - snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); - snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id); - snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); - snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); - - hw = clk_hw_register_mux(dev, clk_name, - ((const char *[]){ - parent, parent2, parent3, parent4 - }), 4, 0, pll_10nm->phy_cmn_mmio + - REG_DSI_10nm_PHY_CMN_CLK_CFG1, - 0, 2, 0, NULL); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_post_out_div_clk_hw; - } - - pll_10nm->pclk_mux_hw = hw; - - snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->id); - - /* PIX CLK DIV : DIV_CTRL_7_4*/ - hw = clk_hw_register_divider(dev, clk_name, parent, - 0, pll_10nm->phy_cmn_mmio + - REG_DSI_10nm_PHY_CMN_CLK_CFG0, - 4, 4, CLK_DIVIDER_ONE_BASED, - &pll_10nm->postdiv_lock); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_pclk_mux_hw; - } - - pll_10nm->out_dsiclk_hw = hw; - hw_data->hws[DSI_PIXEL_PLL_CLK] = hw; - - hw_data->num = NUM_PROVIDED_CLKS; - pll_10nm->hw_data = hw_data; - - ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, - pll_10nm->hw_data); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); - goto err_dsiclk_hw; - } - - return 0; - -err_dsiclk_hw: - clk_hw_unregister_divider(pll_10nm->out_dsiclk_hw); -err_pclk_mux_hw: - clk_hw_unregister_mux(pll_10nm->pclk_mux_hw); -err_post_out_div_clk_hw: - clk_hw_unregister_fixed_factor(pll_10nm->post_out_div_clk_hw); -err_by_2_bit_clk_hw: - clk_hw_unregister_fixed_factor(pll_10nm->by_2_bit_clk_hw); -err_byte_clk_hw: - clk_hw_unregister_fixed_factor(pll_10nm->byte_clk_hw); -err_bit_clk_hw: - clk_hw_unregister_divider(pll_10nm->bit_clk_hw); -err_out_div_clk_hw: - clk_hw_unregister_divider(pll_10nm->out_div_clk_hw); -err_base_clk_hw: - clk_hw_unregister(&pll_10nm->base.clk_hw); - - return ret; -} - -struct msm_dsi_pll *msm_dsi_pll_10nm_init(struct platform_device *pdev, int id) -{ - struct dsi_pll_10nm *pll_10nm; - struct msm_dsi_pll *pll; - int ret; - - pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL); - if (!pll_10nm) - return ERR_PTR(-ENOMEM); - - DBG("DSI PLL%d", id); - - pll_10nm->pdev = pdev; - pll_10nm->id = id; - pll_10nm_list[id] = pll_10nm; - - pll_10nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); - if (IS_ERR_OR_NULL(pll_10nm->phy_cmn_mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); - return ERR_PTR(-ENOMEM); - } - - pll_10nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_10nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); - return ERR_PTR(-ENOMEM); - } - - spin_lock_init(&pll_10nm->postdiv_lock); - - pll = &pll_10nm->base; - pll->min_rate = 1000000000UL; - pll->max_rate = 3500000000UL; - pll->get_provider = dsi_pll_10nm_get_provider; - pll->destroy = dsi_pll_10nm_destroy; - pll->save_state = dsi_pll_10nm_save_state; - pll->restore_state = dsi_pll_10nm_restore_state; - pll->set_usecase = dsi_pll_10nm_set_usecase; - - pll_10nm->vco_delay = 1; - - ret = pll_10nm_register(pll_10nm); - if (ret) { - DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); - return ERR_PTR(ret); - } - - /* TODO: Remove this when we have proper display handover support */ - msm_dsi_pll_save_state(pll); - - return pll; -} diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c deleted file mode 100644 index f847376d501e..000000000000 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_14nm.c +++ /dev/null @@ -1,1096 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. - */ - -#include -#include - -#include "dsi_pll.h" -#include "dsi.xml.h" - -/* - * DSI PLL 14nm - clock diagram (eg: DSI0): - * - * dsi0n1_postdiv_clk - * | - * | - * +----+ | +----+ - * dsi0vco_clk ---| n1 |--o--| /8 |-- dsi0pllbyte - * +----+ | +----+ - * | dsi0n1_postdivby2_clk - * | +----+ | - * o---| /2 |--o--|\ - * | +----+ | \ +----+ - * | | |--| n2 |-- dsi0pll - * o--------------| / +----+ - * |/ - */ - -#define POLL_MAX_READS 15 -#define POLL_TIMEOUT_US 1000 - -#define NUM_PROVIDED_CLKS 2 - -#define VCO_REF_CLK_RATE 19200000 -#define VCO_MIN_RATE 1300000000UL -#define VCO_MAX_RATE 2600000000UL - -#define DSI_BYTE_PLL_CLK 0 -#define DSI_PIXEL_PLL_CLK 1 - -#define DSI_PLL_DEFAULT_VCO_POSTDIV 1 - -struct dsi_pll_input { - u32 fref; /* reference clk */ - u32 fdata; /* bit clock rate */ - u32 dsiclk_sel; /* Mux configuration (see diagram) */ - u32 ssc_en; /* SSC enable/disable */ - u32 ldo_en; - - /* fixed params */ - u32 refclk_dbler_en; - u32 vco_measure_time; - u32 kvco_measure_time; - u32 bandgap_timer; - u32 pll_wakeup_timer; - u32 plllock_cnt; - u32 plllock_rng; - u32 ssc_center; - u32 ssc_adj_period; - u32 ssc_spread; - u32 ssc_freq; - u32 pll_ie_trim; - u32 pll_ip_trim; - u32 pll_iptat_trim; - u32 pll_cpcset_cur; - u32 pll_cpmset_cur; - - u32 pll_icpmset; - u32 pll_icpcset; - - u32 pll_icpmset_p; - u32 pll_icpmset_m; - - u32 pll_icpcset_p; - u32 pll_icpcset_m; - - u32 pll_lpf_res1; - u32 pll_lpf_cap1; - u32 pll_lpf_cap2; - u32 pll_c3ctrl; - u32 pll_r3ctrl; -}; - -struct dsi_pll_output { - u32 pll_txclk_en; - u32 dec_start; - u32 div_frac_start; - u32 ssc_period; - u32 ssc_step_size; - u32 plllock_cmp; - u32 pll_vco_div_ref; - u32 pll_vco_count; - u32 pll_kvco_div_ref; - u32 pll_kvco_count; - u32 pll_misc1; - u32 pll_lpf2_postdiv; - u32 pll_resetsm_cntrl; - u32 pll_resetsm_cntrl2; - u32 pll_resetsm_cntrl5; - u32 pll_kvco_code; - - u32 cmn_clk_cfg0; - u32 cmn_clk_cfg1; - u32 cmn_ldo_cntrl; - - u32 pll_postdiv; - u32 fcvo; -}; - -struct pll_14nm_cached_state { - unsigned long vco_rate; - u8 n2postdiv; - u8 n1postdiv; -}; - -struct dsi_pll_14nm { - struct msm_dsi_pll base; - - int id; - struct platform_device *pdev; - - void __iomem *phy_cmn_mmio; - void __iomem *mmio; - - int vco_delay; - - struct dsi_pll_input in; - struct dsi_pll_output out; - - /* protects REG_DSI_14nm_PHY_CMN_CLK_CFG0 register */ - spinlock_t postdiv_lock; - - u64 vco_current_rate; - u64 vco_ref_clk_rate; - - /* private clocks: */ - struct clk_hw *hws[NUM_DSI_CLOCKS_MAX]; - u32 num_hws; - - /* clock-provider: */ - struct clk_hw_onecell_data *hw_data; - - struct pll_14nm_cached_state cached_state; - - enum msm_dsi_phy_usecase uc; - struct dsi_pll_14nm *slave; -}; - -#define to_pll_14nm(x) container_of(x, struct dsi_pll_14nm, base) - -/* - * Private struct for N1/N2 post-divider clocks. These clocks are similar to - * the generic clk_divider class of clocks. The only difference is that it - * also sets the slave DSI PLL's post-dividers if in Dual DSI mode - */ -struct dsi_pll_14nm_postdiv { - struct clk_hw hw; - - /* divider params */ - u8 shift; - u8 width; - u8 flags; /* same flags as used by clk_divider struct */ - - struct dsi_pll_14nm *pll; -}; - -#define to_pll_14nm_postdiv(_hw) container_of(_hw, struct dsi_pll_14nm_postdiv, hw) - -/* - * Global list of private DSI PLL struct pointers. We need this for Dual DSI - * mode, where the master PLL's clk_ops needs access the slave's private data - */ -static struct dsi_pll_14nm *pll_14nm_list[DSI_MAX]; - -static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm, - u32 nb_tries, u32 timeout_us) -{ - bool pll_locked = false; - void __iomem *base = pll_14nm->mmio; - u32 tries, val; - - tries = nb_tries; - while (tries--) { - val = pll_read(base + - REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); - pll_locked = !!(val & BIT(5)); - - if (pll_locked) - break; - - udelay(timeout_us); - } - - if (!pll_locked) { - tries = nb_tries; - while (tries--) { - val = pll_read(base + - REG_DSI_14nm_PHY_PLL_RESET_SM_READY_STATUS); - pll_locked = !!(val & BIT(0)); - - if (pll_locked) - break; - - udelay(timeout_us); - } - } - - DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); - - return pll_locked; -} - -static void dsi_pll_14nm_input_init(struct dsi_pll_14nm *pll) -{ - pll->in.fref = pll->vco_ref_clk_rate; - pll->in.fdata = 0; - pll->in.dsiclk_sel = 1; /* Use the /2 path in Mux */ - pll->in.ldo_en = 0; /* disabled for now */ - - /* fixed input */ - pll->in.refclk_dbler_en = 0; - pll->in.vco_measure_time = 5; - pll->in.kvco_measure_time = 5; - pll->in.bandgap_timer = 4; - pll->in.pll_wakeup_timer = 5; - pll->in.plllock_cnt = 1; - pll->in.plllock_rng = 0; - - /* - * SSC is enabled by default. We might need DT props for configuring - * some SSC params like PPM and center/down spread etc. - */ - pll->in.ssc_en = 1; - pll->in.ssc_center = 0; /* down spread by default */ - pll->in.ssc_spread = 5; /* PPM / 1000 */ - pll->in.ssc_freq = 31500; /* default recommended */ - pll->in.ssc_adj_period = 37; - - pll->in.pll_ie_trim = 4; - pll->in.pll_ip_trim = 4; - pll->in.pll_cpcset_cur = 1; - pll->in.pll_cpmset_cur = 1; - pll->in.pll_icpmset = 4; - pll->in.pll_icpcset = 4; - pll->in.pll_icpmset_p = 0; - pll->in.pll_icpmset_m = 0; - pll->in.pll_icpcset_p = 0; - pll->in.pll_icpcset_m = 0; - pll->in.pll_lpf_res1 = 3; - pll->in.pll_lpf_cap1 = 11; - pll->in.pll_lpf_cap2 = 1; - pll->in.pll_iptat_trim = 7; - pll->in.pll_c3ctrl = 2; - pll->in.pll_r3ctrl = 1; -} - -#define CEIL(x, y) (((x) + ((y) - 1)) / (y)) - -static void pll_14nm_ssc_calc(struct dsi_pll_14nm *pll) -{ - u32 period, ssc_period; - u32 ref, rem; - u64 step_size; - - DBG("vco=%lld ref=%lld", pll->vco_current_rate, pll->vco_ref_clk_rate); - - ssc_period = pll->in.ssc_freq / 500; - period = (u32)pll->vco_ref_clk_rate / 1000; - ssc_period = CEIL(period, ssc_period); - ssc_period -= 1; - pll->out.ssc_period = ssc_period; - - DBG("ssc freq=%d spread=%d period=%d", pll->in.ssc_freq, - pll->in.ssc_spread, pll->out.ssc_period); - - step_size = (u32)pll->vco_current_rate; - ref = pll->vco_ref_clk_rate; - ref /= 1000; - step_size = div_u64(step_size, ref); - step_size <<= 20; - step_size = div_u64(step_size, 1000); - step_size *= pll->in.ssc_spread; - step_size = div_u64(step_size, 1000); - step_size *= (pll->in.ssc_adj_period + 1); - - rem = 0; - step_size = div_u64_rem(step_size, ssc_period + 1, &rem); - if (rem) - step_size++; - - DBG("step_size=%lld", step_size); - - step_size &= 0x0ffff; /* take lower 16 bits */ - - pll->out.ssc_step_size = step_size; -} - -static void pll_14nm_dec_frac_calc(struct dsi_pll_14nm *pll) -{ - struct dsi_pll_input *pin = &pll->in; - struct dsi_pll_output *pout = &pll->out; - u64 multiplier = BIT(20); - u64 dec_start_multiple, dec_start, pll_comp_val; - u32 duration, div_frac_start; - u64 vco_clk_rate = pll->vco_current_rate; - u64 fref = pll->vco_ref_clk_rate; - - DBG("vco_clk_rate=%lld ref_clk_rate=%lld", vco_clk_rate, fref); - - dec_start_multiple = div_u64(vco_clk_rate * multiplier, fref); - div_u64_rem(dec_start_multiple, multiplier, &div_frac_start); - - dec_start = div_u64(dec_start_multiple, multiplier); - - pout->dec_start = (u32)dec_start; - pout->div_frac_start = div_frac_start; - - if (pin->plllock_cnt == 0) - duration = 1024; - else if (pin->plllock_cnt == 1) - duration = 256; - else if (pin->plllock_cnt == 2) - duration = 128; - else - duration = 32; - - pll_comp_val = duration * dec_start_multiple; - pll_comp_val = div_u64(pll_comp_val, multiplier); - do_div(pll_comp_val, 10); - - pout->plllock_cmp = (u32)pll_comp_val; - - pout->pll_txclk_en = 1; - pout->cmn_ldo_cntrl = 0x3c; -} - -static u32 pll_14nm_kvco_slop(u32 vrate) -{ - u32 slop = 0; - - if (vrate > VCO_MIN_RATE && vrate <= 1800000000UL) - slop = 600; - else if (vrate > 1800000000UL && vrate < 2300000000UL) - slop = 400; - else if (vrate > 2300000000UL && vrate < VCO_MAX_RATE) - slop = 280; - - return slop; -} - -static void pll_14nm_calc_vco_count(struct dsi_pll_14nm *pll) -{ - struct dsi_pll_input *pin = &pll->in; - struct dsi_pll_output *pout = &pll->out; - u64 vco_clk_rate = pll->vco_current_rate; - u64 fref = pll->vco_ref_clk_rate; - u64 data; - u32 cnt; - - data = fref * pin->vco_measure_time; - do_div(data, 1000000); - data &= 0x03ff; /* 10 bits */ - data -= 2; - pout->pll_vco_div_ref = data; - - data = div_u64(vco_clk_rate, 1000000); /* unit is Mhz */ - data *= pin->vco_measure_time; - do_div(data, 10); - pout->pll_vco_count = data; - - data = fref * pin->kvco_measure_time; - do_div(data, 1000000); - data &= 0x03ff; /* 10 bits */ - data -= 1; - pout->pll_kvco_div_ref = data; - - cnt = pll_14nm_kvco_slop(vco_clk_rate); - cnt *= 2; - cnt /= 100; - cnt *= pin->kvco_measure_time; - pout->pll_kvco_count = cnt; - - pout->pll_misc1 = 16; - pout->pll_resetsm_cntrl = 48; - pout->pll_resetsm_cntrl2 = pin->bandgap_timer << 3; - pout->pll_resetsm_cntrl5 = pin->pll_wakeup_timer; - pout->pll_kvco_code = 0; -} - -static void pll_db_commit_ssc(struct dsi_pll_14nm *pll) -{ - void __iomem *base = pll->mmio; - struct dsi_pll_input *pin = &pll->in; - struct dsi_pll_output *pout = &pll->out; - u8 data; - - data = pin->ssc_adj_period; - data &= 0x0ff; - pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER1, data); - data = (pin->ssc_adj_period >> 8); - data &= 0x03; - pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_ADJ_PER2, data); - - data = pout->ssc_period; - data &= 0x0ff; - pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER1, data); - data = (pout->ssc_period >> 8); - data &= 0x0ff; - pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_PER2, data); - - data = pout->ssc_step_size; - data &= 0x0ff; - pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE1, data); - data = (pout->ssc_step_size >> 8); - data &= 0x0ff; - pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_STEP_SIZE2, data); - - data = (pin->ssc_center & 0x01); - data <<= 1; - data |= 0x01; /* enable */ - pll_write(base + REG_DSI_14nm_PHY_PLL_SSC_EN_CENTER, data); - - wmb(); /* make sure register committed */ -} - -static void pll_db_commit_common(struct dsi_pll_14nm *pll, - struct dsi_pll_input *pin, - struct dsi_pll_output *pout) -{ - void __iomem *base = pll->mmio; - u8 data; - - /* confgiure the non frequency dependent pll registers */ - data = 0; - pll_write(base + REG_DSI_14nm_PHY_PLL_SYSCLK_EN_RESET, data); - - data = pout->pll_txclk_en; - pll_write(base + REG_DSI_14nm_PHY_PLL_TXCLK_EN, data); - - data = pout->pll_resetsm_cntrl; - pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL, data); - data = pout->pll_resetsm_cntrl2; - pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL2, data); - data = pout->pll_resetsm_cntrl5; - pll_write(base + REG_DSI_14nm_PHY_PLL_RESETSM_CNTRL5, data); - - data = pout->pll_vco_div_ref & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF1, data); - data = (pout->pll_vco_div_ref >> 8) & 0x3; - pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_DIV_REF2, data); - - data = pout->pll_kvco_div_ref & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF1, data); - data = (pout->pll_kvco_div_ref >> 8) & 0x3; - pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_DIV_REF2, data); - - data = pout->pll_misc1; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_MISC1, data); - - data = pin->pll_ie_trim; - pll_write(base + REG_DSI_14nm_PHY_PLL_IE_TRIM, data); - - data = pin->pll_ip_trim; - pll_write(base + REG_DSI_14nm_PHY_PLL_IP_TRIM, data); - - data = pin->pll_cpmset_cur << 3 | pin->pll_cpcset_cur; - pll_write(base + REG_DSI_14nm_PHY_PLL_CP_SET_CUR, data); - - data = pin->pll_icpcset_p << 3 | pin->pll_icpcset_m; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPCSET, data); - - data = pin->pll_icpmset_p << 3 | pin->pll_icpcset_m; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICPMSET, data); - - data = pin->pll_icpmset << 3 | pin->pll_icpcset; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_ICP_SET, data); - - data = pin->pll_lpf_cap2 << 4 | pin->pll_lpf_cap1; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF1, data); - - data = pin->pll_iptat_trim; - pll_write(base + REG_DSI_14nm_PHY_PLL_IPTAT_TRIM, data); - - data = pin->pll_c3ctrl | pin->pll_r3ctrl << 4; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_CRCTRL, data); -} - -static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm) -{ - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - - /* de assert pll start and apply pll sw reset */ - - /* stop pll */ - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); - - /* pll sw reset */ - pll_write_udelay(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x20, 10); - wmb(); /* make sure register committed */ - - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0); - wmb(); /* make sure register committed */ -} - -static void pll_db_commit_14nm(struct dsi_pll_14nm *pll, - struct dsi_pll_input *pin, - struct dsi_pll_output *pout) -{ - void __iomem *base = pll->mmio; - void __iomem *cmn_base = pll->phy_cmn_mmio; - u8 data; - - DBG("DSI%d PLL", pll->id); - - data = pout->cmn_ldo_cntrl; - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data); - - pll_db_commit_common(pll, pin, pout); - - pll_14nm_software_reset(pll); - - data = pin->dsiclk_sel; /* set dsiclk_sel = 1 */ - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG1, data); - - data = 0xff; /* data, clk, pll normal operation */ - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CTRL_0, data); - - /* configure the frequency dependent pll registers */ - data = pout->dec_start; - pll_write(base + REG_DSI_14nm_PHY_PLL_DEC_START, data); - - data = pout->div_frac_start & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1, data); - data = (pout->div_frac_start >> 8) & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2, data); - data = (pout->div_frac_start >> 16) & 0xf; - pll_write(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3, data); - - data = pout->plllock_cmp & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP1, data); - - data = (pout->plllock_cmp >> 8) & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP2, data); - - data = (pout->plllock_cmp >> 16) & 0x3; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP3, data); - - data = pin->plllock_cnt << 1 | pin->plllock_rng << 3; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLLLOCK_CMP_EN, data); - - data = pout->pll_vco_count & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT1, data); - data = (pout->pll_vco_count >> 8) & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_VCO_COUNT2, data); - - data = pout->pll_kvco_count & 0xff; - pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT1, data); - data = (pout->pll_kvco_count >> 8) & 0x3; - pll_write(base + REG_DSI_14nm_PHY_PLL_KVCO_COUNT2, data); - - data = (pout->pll_postdiv - 1) << 4 | pin->pll_lpf_res1; - pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_LPF2_POSTDIV, data); - - if (pin->ssc_en) - pll_db_commit_ssc(pll); - - wmb(); /* make sure register committed */ -} - -/* - * VCO clock Callbacks - */ -static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - struct dsi_pll_input *pin = &pll_14nm->in; - struct dsi_pll_output *pout = &pll_14nm->out; - - DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_14nm->id, rate, - parent_rate); - - pll_14nm->vco_current_rate = rate; - pll_14nm->vco_ref_clk_rate = VCO_REF_CLK_RATE; - - dsi_pll_14nm_input_init(pll_14nm); - - /* - * This configures the post divider internal to the VCO. It's - * fixed to divide by 1 for now. - * - * tx_band = pll_postdiv. - * 0: divided by 1 - * 1: divided by 2 - * 2: divided by 4 - * 3: divided by 8 - */ - pout->pll_postdiv = DSI_PLL_DEFAULT_VCO_POSTDIV; - - pll_14nm_dec_frac_calc(pll_14nm); - - if (pin->ssc_en) - pll_14nm_ssc_calc(pll_14nm); - - pll_14nm_calc_vco_count(pll_14nm); - - /* commit the slave DSI PLL registers if we're master. Note that we - * don't lock the slave PLL. We just ensure that the PLL/PHY registers - * of the master and slave are identical - */ - if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { - struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; - - pll_db_commit_14nm(pll_14nm_slave, pin, pout); - } - - pll_db_commit_14nm(pll_14nm, pin, pout); - - return 0; -} - -static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - void __iomem *base = pll_14nm->mmio; - u64 vco_rate, multiplier = BIT(20); - u32 div_frac_start; - u32 dec_start; - u64 ref_clk = parent_rate; - - dec_start = pll_read(base + REG_DSI_14nm_PHY_PLL_DEC_START); - dec_start &= 0x0ff; - - DBG("dec_start = %x", dec_start); - - div_frac_start = (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START3) - & 0xf) << 16; - div_frac_start |= (pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START2) - & 0xff) << 8; - div_frac_start |= pll_read(base + REG_DSI_14nm_PHY_PLL_DIV_FRAC_START1) - & 0xff; - - DBG("div_frac_start = %x", div_frac_start); - - vco_rate = ref_clk * dec_start; - - vco_rate += ((ref_clk * div_frac_start) / multiplier); - - /* - * Recalculating the rate from dec_start and frac_start doesn't end up - * the rate we originally set. Convert the freq to KHz, round it up and - * convert it back to MHz. - */ - vco_rate = DIV_ROUND_UP_ULL(vco_rate, 1000) * 1000; - - DBG("returning vco rate = %lu", (unsigned long)vco_rate); - - return (unsigned long)vco_rate; -} - -static const struct clk_ops clk_ops_dsi_pll_14nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, - .set_rate = dsi_pll_14nm_vco_set_rate, - .recalc_rate = dsi_pll_14nm_vco_recalc_rate, - .prepare = msm_dsi_pll_helper_clk_prepare, - .unprepare = msm_dsi_pll_helper_clk_unprepare, -}; - -/* - * N1 and N2 post-divider clock callbacks - */ -#define div_mask(width) ((1 << (width)) - 1) -static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); - struct dsi_pll_14nm *pll_14nm = postdiv->pll; - void __iomem *base = pll_14nm->phy_cmn_mmio; - u8 shift = postdiv->shift; - u8 width = postdiv->width; - u32 val; - - DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, parent_rate); - - val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift; - val &= div_mask(width); - - return divider_recalc_rate(hw, parent_rate, val, NULL, - postdiv->flags, width); -} - -static long dsi_pll_14nm_postdiv_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *prate) -{ - struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); - struct dsi_pll_14nm *pll_14nm = postdiv->pll; - - DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, rate); - - return divider_round_rate(hw, rate, prate, NULL, - postdiv->width, - postdiv->flags); -} - -static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); - struct dsi_pll_14nm *pll_14nm = postdiv->pll; - void __iomem *base = pll_14nm->phy_cmn_mmio; - spinlock_t *lock = &pll_14nm->postdiv_lock; - u8 shift = postdiv->shift; - u8 width = postdiv->width; - unsigned int value; - unsigned long flags = 0; - u32 val; - - DBG("DSI%d PLL parent rate=%lu parent rate %lu", pll_14nm->id, rate, - parent_rate); - - value = divider_get_val(rate, parent_rate, NULL, postdiv->width, - postdiv->flags); - - spin_lock_irqsave(lock, flags); - - val = pll_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); - val &= ~(div_mask(width) << shift); - - val |= value << shift; - pll_write(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); - - /* If we're master in dual DSI mode, then the slave PLL's post-dividers - * follow the master's post dividers - */ - if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { - struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; - void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; - - pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); - } - - spin_unlock_irqrestore(lock, flags); - - return 0; -} - -static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = { - .recalc_rate = dsi_pll_14nm_postdiv_recalc_rate, - .round_rate = dsi_pll_14nm_postdiv_round_rate, - .set_rate = dsi_pll_14nm_postdiv_set_rate, -}; - -/* - * PLL Callbacks - */ - -static int dsi_pll_14nm_enable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - void __iomem *base = pll_14nm->mmio; - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - bool locked; - - DBG(""); - - pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); - - locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS, - POLL_TIMEOUT_US); - - if (unlikely(!locked)) - DRM_DEV_ERROR(&pll_14nm->pdev->dev, "DSI PLL lock failed\n"); - else - DBG("DSI PLL lock success"); - - return locked ? 0 : -EINVAL; -} - -static void dsi_pll_14nm_disable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - - DBG(""); - - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); -} - -static void dsi_pll_14nm_save_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - u32 data; - - data = pll_read(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); - - cached_state->n1postdiv = data & 0xf; - cached_state->n2postdiv = (data >> 4) & 0xf; - - DBG("DSI%d PLL save state %x %x", pll_14nm->id, - cached_state->n1postdiv, cached_state->n2postdiv); - - cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw); -} - -static int dsi_pll_14nm_restore_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - u32 data; - int ret; - - ret = dsi_pll_14nm_vco_set_rate(&pll->clk_hw, - cached_state->vco_rate, 0); - if (ret) { - DRM_DEV_ERROR(&pll_14nm->pdev->dev, - "restore vco rate failed. ret=%d\n", ret); - return ret; - } - - data = cached_state->n1postdiv | (cached_state->n2postdiv << 4); - - DBG("DSI%d PLL restore state %x %x", pll_14nm->id, - cached_state->n1postdiv, cached_state->n2postdiv); - - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); - - /* also restore post-dividers for slave DSI PLL */ - if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { - struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; - void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; - - pll_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); - } - - return 0; -} - -static int dsi_pll_14nm_set_usecase(struct msm_dsi_pll *pll, - enum msm_dsi_phy_usecase uc) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - void __iomem *base = pll_14nm->mmio; - u32 clkbuflr_en, bandgap = 0; - - switch (uc) { - case MSM_DSI_PHY_STANDALONE: - clkbuflr_en = 0x1; - break; - case MSM_DSI_PHY_MASTER: - clkbuflr_en = 0x3; - pll_14nm->slave = pll_14nm_list[(pll_14nm->id + 1) % DSI_MAX]; - break; - case MSM_DSI_PHY_SLAVE: - clkbuflr_en = 0x0; - bandgap = 0x3; - break; - default: - return -EINVAL; - } - - pll_write(base + REG_DSI_14nm_PHY_PLL_CLKBUFLR_EN, clkbuflr_en); - if (bandgap) - pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP, bandgap); - - pll_14nm->uc = uc; - - return 0; -} - -static int dsi_pll_14nm_get_provider(struct msm_dsi_pll *pll, - struct clk **byte_clk_provider, - struct clk **pixel_clk_provider) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - struct clk_hw_onecell_data *hw_data = pll_14nm->hw_data; - - if (byte_clk_provider) - *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk; - if (pixel_clk_provider) - *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk; - - return 0; -} - -static void dsi_pll_14nm_destroy(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - struct platform_device *pdev = pll_14nm->pdev; - int num_hws = pll_14nm->num_hws; - - of_clk_del_provider(pdev->dev.of_node); - - while (num_hws--) - clk_hw_unregister(pll_14nm->hws[num_hws]); -} - -static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm, - const char *name, - const char *parent_name, - unsigned long flags, - u8 shift) -{ - struct dsi_pll_14nm_postdiv *pll_postdiv; - struct device *dev = &pll_14nm->pdev->dev; - struct clk_init_data postdiv_init = { - .parent_names = (const char *[]) { parent_name }, - .num_parents = 1, - .name = name, - .flags = flags, - .ops = &clk_ops_dsi_pll_14nm_postdiv, - }; - int ret; - - pll_postdiv = devm_kzalloc(dev, sizeof(*pll_postdiv), GFP_KERNEL); - if (!pll_postdiv) - return ERR_PTR(-ENOMEM); - - pll_postdiv->pll = pll_14nm; - pll_postdiv->shift = shift; - /* both N1 and N2 postdividers are 4 bits wide */ - pll_postdiv->width = 4; - /* range of each divider is from 1 to 15 */ - pll_postdiv->flags = CLK_DIVIDER_ONE_BASED; - pll_postdiv->hw.init = &postdiv_init; - - ret = clk_hw_register(dev, &pll_postdiv->hw); - if (ret) - return ERR_PTR(ret); - - return &pll_postdiv->hw; -} - -static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm) -{ - char clk_name[32], parent[32], vco_name[32]; - struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "xo" }, - .num_parents = 1, - .name = vco_name, - .flags = CLK_IGNORE_UNUSED, - .ops = &clk_ops_dsi_pll_14nm_vco, - }; - struct device *dev = &pll_14nm->pdev->dev; - struct clk_hw **hws = pll_14nm->hws; - struct clk_hw_onecell_data *hw_data; - struct clk_hw *hw; - int num = 0; - int ret; - - DBG("DSI%d", pll_14nm->id); - - hw_data = devm_kzalloc(dev, sizeof(*hw_data) + - NUM_PROVIDED_CLKS * sizeof(struct clk_hw *), - GFP_KERNEL); - if (!hw_data) - return -ENOMEM; - - snprintf(vco_name, 32, "dsi%dvco_clk", pll_14nm->id); - pll_14nm->base.clk_hw.init = &vco_init; - - ret = clk_hw_register(dev, &pll_14nm->base.clk_hw); - if (ret) - return ret; - - hws[num++] = &pll_14nm->base.clk_hw; - - snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->id); - - /* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */ - hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, - CLK_SET_RATE_PARENT, 0); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - hws[num++] = hw; - - snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->id); - snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); - - /* DSI Byte clock = VCO_CLK / N1 / 8 */ - hw = clk_hw_register_fixed_factor(dev, clk_name, parent, - CLK_SET_RATE_PARENT, 1, 8); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - hws[num++] = hw; - hw_data->hws[DSI_BYTE_PLL_CLK] = hw; - - snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id); - snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); - - /* - * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider - * on the way. Don't let it set parent. - */ - hw = clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 2); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - hws[num++] = hw; - - snprintf(clk_name, 32, "dsi%dpll", pll_14nm->id); - snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id); - - /* DSI pixel clock = VCO_CLK / N1 / 2 / N2 - * This is the output of N2 post-divider, bits 4-7 in - * REG_DSI_14nm_PHY_CMN_CLK_CFG0. Don't let it set parent. - */ - hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, 0, 4); - if (IS_ERR(hw)) - return PTR_ERR(hw); - - hws[num++] = hw; - hw_data->hws[DSI_PIXEL_PLL_CLK] = hw; - - pll_14nm->num_hws = num; - - hw_data->num = NUM_PROVIDED_CLKS; - pll_14nm->hw_data = hw_data; - - ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, - pll_14nm->hw_data); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); - return ret; - } - - return 0; -} - -struct msm_dsi_pll *msm_dsi_pll_14nm_init(struct platform_device *pdev, int id) -{ - struct dsi_pll_14nm *pll_14nm; - struct msm_dsi_pll *pll; - int ret; - - if (!pdev) - return ERR_PTR(-ENODEV); - - pll_14nm = devm_kzalloc(&pdev->dev, sizeof(*pll_14nm), GFP_KERNEL); - if (!pll_14nm) - return ERR_PTR(-ENOMEM); - - DBG("PLL%d", id); - - pll_14nm->pdev = pdev; - pll_14nm->id = id; - pll_14nm_list[id] = pll_14nm; - - pll_14nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); - if (IS_ERR_OR_NULL(pll_14nm->phy_cmn_mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); - return ERR_PTR(-ENOMEM); - } - - pll_14nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_14nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); - return ERR_PTR(-ENOMEM); - } - - spin_lock_init(&pll_14nm->postdiv_lock); - - pll = &pll_14nm->base; - pll->min_rate = VCO_MIN_RATE; - pll->max_rate = VCO_MAX_RATE; - pll->get_provider = dsi_pll_14nm_get_provider; - pll->destroy = dsi_pll_14nm_destroy; - pll->disable_seq = dsi_pll_14nm_disable_seq; - pll->save_state = dsi_pll_14nm_save_state; - pll->restore_state = dsi_pll_14nm_restore_state; - pll->set_usecase = dsi_pll_14nm_set_usecase; - - pll_14nm->vco_delay = 1; - - pll->en_seq_cnt = 1; - pll->enable_seqs[0] = dsi_pll_14nm_enable_seq; - - ret = pll_14nm_register(pll_14nm); - if (ret) { - DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); - return ERR_PTR(ret); - } - - return pll; -} diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c deleted file mode 100644 index 37a1f996a588..000000000000 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm.c +++ /dev/null @@ -1,643 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. - */ - -#include -#include - -#include "dsi_pll.h" -#include "dsi.xml.h" - -/* - * DSI PLL 28nm - clock diagram (eg: DSI0): - * - * dsi0analog_postdiv_clk - * | dsi0indirect_path_div2_clk - * | | - * +------+ | +----+ | |\ dsi0byte_mux - * dsi0vco_clk --o--| DIV1 |--o--| /2 |--o--| \ | - * | +------+ +----+ | m| | +----+ - * | | u|--o--| /4 |-- dsi0pllbyte - * | | x| +----+ - * o--------------------------| / - * | |/ - * | +------+ - * o----------| DIV3 |------------------------- dsi0pll - * +------+ - */ - -#define POLL_MAX_READS 10 -#define POLL_TIMEOUT_US 50 - -#define NUM_PROVIDED_CLKS 2 - -#define VCO_REF_CLK_RATE 19200000 -#define VCO_MIN_RATE 350000000 -#define VCO_MAX_RATE 750000000 - -#define DSI_BYTE_PLL_CLK 0 -#define DSI_PIXEL_PLL_CLK 1 - -#define LPFR_LUT_SIZE 10 -struct lpfr_cfg { - unsigned long vco_rate; - u32 resistance; -}; - -/* Loop filter resistance: */ -static const struct lpfr_cfg lpfr_lut[LPFR_LUT_SIZE] = { - { 479500000, 8 }, - { 480000000, 11 }, - { 575500000, 8 }, - { 576000000, 12 }, - { 610500000, 8 }, - { 659500000, 9 }, - { 671500000, 10 }, - { 672000000, 14 }, - { 708500000, 10 }, - { 750000000, 11 }, -}; - -struct pll_28nm_cached_state { - unsigned long vco_rate; - u8 postdiv3; - u8 postdiv1; - u8 byte_mux; -}; - -struct dsi_pll_28nm { - struct msm_dsi_pll base; - - int id; - struct platform_device *pdev; - void __iomem *mmio; - - int vco_delay; - - /* private clocks: */ - struct clk *clks[NUM_DSI_CLOCKS_MAX]; - u32 num_clks; - - /* clock-provider: */ - struct clk *provided_clks[NUM_PROVIDED_CLKS]; - struct clk_onecell_data clk_data; - - struct pll_28nm_cached_state cached_state; -}; - -#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base) - -static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, - u32 nb_tries, u32 timeout_us) -{ - bool pll_locked = false; - u32 val; - - while (nb_tries--) { - val = pll_read(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_STATUS); - pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY); - - if (pll_locked) - break; - - udelay(timeout_us); - } - DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); - - return pll_locked; -} - -static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm) -{ - void __iomem *base = pll_28nm->mmio; - - /* - * Add HW recommended delays after toggling the software - * reset bit off and back on. - */ - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, - DSI_28nm_PHY_PLL_TEST_CFG_PLL_SW_RESET, 1); - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_TEST_CFG, 0x00, 1); -} - -/* - * Clock Callbacks - */ -static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; - unsigned long div_fbx1000, gen_vco_clk; - u32 refclk_cfg, frac_n_mode, frac_n_value; - u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3; - u32 cal_cfg10, cal_cfg11; - u32 rem; - int i; - - VERB("rate=%lu, parent's=%lu", rate, parent_rate); - - /* Force postdiv2 to be div-4 */ - pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV2_CFG, 3); - - /* Configure the Loop filter resistance */ - for (i = 0; i < LPFR_LUT_SIZE; i++) - if (rate <= lpfr_lut[i].vco_rate) - break; - if (i == LPFR_LUT_SIZE) { - DRM_DEV_ERROR(dev, "unable to get loop filter resistance. vco=%lu\n", - rate); - return -EINVAL; - } - pll_write(base + REG_DSI_28nm_PHY_PLL_LPFR_CFG, lpfr_lut[i].resistance); - - /* Loop filter capacitance values : c1 and c2 */ - pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC1_CFG, 0x70); - pll_write(base + REG_DSI_28nm_PHY_PLL_LPFC2_CFG, 0x15); - - rem = rate % VCO_REF_CLK_RATE; - if (rem) { - refclk_cfg = DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR; - frac_n_mode = 1; - div_fbx1000 = rate / (VCO_REF_CLK_RATE / 500); - gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 500); - } else { - refclk_cfg = 0x0; - frac_n_mode = 0; - div_fbx1000 = rate / (VCO_REF_CLK_RATE / 1000); - gen_vco_clk = div_fbx1000 * (VCO_REF_CLK_RATE / 1000); - } - - DBG("refclk_cfg = %d", refclk_cfg); - - rem = div_fbx1000 % 1000; - frac_n_value = (rem << 16) / 1000; - - DBG("div_fb = %lu", div_fbx1000); - DBG("frac_n_value = %d", frac_n_value); - - DBG("Generated VCO Clock: %lu", gen_vco_clk); - rem = 0; - sdm_cfg1 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1); - sdm_cfg1 &= ~DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET__MASK; - if (frac_n_mode) { - sdm_cfg0 = 0x0; - sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV(0); - sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET( - (u32)(((div_fbx1000 / 1000) & 0x3f) - 1)); - sdm_cfg3 = frac_n_value >> 8; - sdm_cfg2 = frac_n_value & 0xff; - } else { - sdm_cfg0 = DSI_28nm_PHY_PLL_SDM_CFG0_BYP; - sdm_cfg0 |= DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV( - (u32)(((div_fbx1000 / 1000) & 0x3f) - 1)); - sdm_cfg1 |= DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET(0); - sdm_cfg2 = 0; - sdm_cfg3 = 0; - } - - DBG("sdm_cfg0=%d", sdm_cfg0); - DBG("sdm_cfg1=%d", sdm_cfg1); - DBG("sdm_cfg2=%d", sdm_cfg2); - DBG("sdm_cfg3=%d", sdm_cfg3); - - cal_cfg11 = (u32)(gen_vco_clk / (256 * 1000000)); - cal_cfg10 = (u32)((gen_vco_clk % (256 * 1000000)) / 1000000); - DBG("cal_cfg10=%d, cal_cfg11=%d", cal_cfg10, cal_cfg11); - - pll_write(base + REG_DSI_28nm_PHY_PLL_CHGPUMP_CFG, 0x02); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG3, 0x2b); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG4, 0x06); - pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); - - pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1, sdm_cfg1); - pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2, - DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0(sdm_cfg2)); - pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3, - DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8(sdm_cfg3)); - pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00); - - /* Add hardware recommended delay for correct PLL configuration */ - if (pll_28nm->vco_delay) - udelay(pll_28nm->vco_delay); - - pll_write(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG, refclk_cfg); - pll_write(base + REG_DSI_28nm_PHY_PLL_PWRGEN_CFG, 0x00); - pll_write(base + REG_DSI_28nm_PHY_PLL_VCOLPF_CFG, 0x31); - pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0, sdm_cfg0); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG0, 0x12); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG6, 0x30); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG7, 0x00); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG8, 0x60); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG9, 0x00); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG10, cal_cfg10 & 0xff); - pll_write(base + REG_DSI_28nm_PHY_PLL_CAL_CFG11, cal_cfg11 & 0xff); - pll_write(base + REG_DSI_28nm_PHY_PLL_EFUSE_CFG, 0x20); - - return 0; -} - -static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - - return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS, - POLL_TIMEOUT_US); -} - -static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - void __iomem *base = pll_28nm->mmio; - u32 sdm0, doubler, sdm_byp_div; - u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3; - u32 ref_clk = VCO_REF_CLK_RATE; - unsigned long vco_rate; - - VERB("parent_rate=%lu", parent_rate); - - /* Check to see if the ref clk doubler is enabled */ - doubler = pll_read(base + REG_DSI_28nm_PHY_PLL_REFCLK_CFG) & - DSI_28nm_PHY_PLL_REFCLK_CFG_DBLR; - ref_clk += (doubler * VCO_REF_CLK_RATE); - - /* see if it is integer mode or sdm mode */ - sdm0 = pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0); - if (sdm0 & DSI_28nm_PHY_PLL_SDM_CFG0_BYP) { - /* integer mode */ - sdm_byp_div = FIELD( - pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG0), - DSI_28nm_PHY_PLL_SDM_CFG0_BYP_DIV) + 1; - vco_rate = ref_clk * sdm_byp_div; - } else { - /* sdm mode */ - sdm_dc_off = FIELD( - pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG1), - DSI_28nm_PHY_PLL_SDM_CFG1_DC_OFFSET); - DBG("sdm_dc_off = %d", sdm_dc_off); - sdm2 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG2), - DSI_28nm_PHY_PLL_SDM_CFG2_FREQ_SEED_7_0); - sdm3 = FIELD(pll_read(base + REG_DSI_28nm_PHY_PLL_SDM_CFG3), - DSI_28nm_PHY_PLL_SDM_CFG3_FREQ_SEED_15_8); - sdm_freq_seed = (sdm3 << 8) | sdm2; - DBG("sdm_freq_seed = %d", sdm_freq_seed); - - vco_rate = (ref_clk * (sdm_dc_off + 1)) + - mult_frac(ref_clk, sdm_freq_seed, BIT(16)); - DBG("vco rate = %lu", vco_rate); - } - - DBG("returning vco rate = %lu", vco_rate); - - return vco_rate; -} - -static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, - .set_rate = dsi_pll_28nm_clk_set_rate, - .recalc_rate = dsi_pll_28nm_clk_recalc_rate, - .prepare = msm_dsi_pll_helper_clk_prepare, - .unprepare = msm_dsi_pll_helper_clk_unprepare, - .is_enabled = dsi_pll_28nm_clk_is_enabled, -}; - -/* - * PLL Callbacks - */ -static int dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; - u32 max_reads = 5, timeout_us = 100; - bool locked; - u32 val; - int i; - - DBG("id=%d", pll_28nm->id); - - pll_28nm_software_reset(pll_28nm); - - /* - * PLL power up sequence. - * Add necessary delays recommended by hardware. - */ - val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600); - - for (i = 0; i < 2; i++) { - /* DSI Uniphy lock detect setting */ - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, - 0x0c, 100); - pll_write(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x0d); - - /* poll for PLL ready status */ - locked = pll_28nm_poll_for_ready(pll_28nm, - max_reads, timeout_us); - if (locked) - break; - - pll_28nm_software_reset(pll_28nm); - - /* - * PLL power up sequence. - * Add necessary delays recommended by hardware. - */ - val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 1); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 250); - - val &= ~DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 200); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 600); - } - - if (unlikely(!locked)) - DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); - else - DBG("DSI PLL Lock success"); - - return locked ? 0 : -EINVAL; -} - -static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; - bool locked; - u32 max_reads = 10, timeout_us = 50; - u32 val; - - DBG("id=%d", pll_28nm->id); - - pll_28nm_software_reset(pll_28nm); - - /* - * PLL power up sequence. - * Add necessary delays recommended by hardware. - */ - pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_CAL_CFG1, 0x34, 500); - - val = DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRDN_B; - pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_PWRGEN_PWRDN_B; - pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); - - val |= DSI_28nm_PHY_PLL_GLB_CFG_PLL_LDO_PWRDN_B | - DSI_28nm_PHY_PLL_GLB_CFG_PLL_ENABLE; - pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_GLB_CFG, val, 500); - - /* DSI PLL toggle lock detect setting */ - pll_write_ndelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x04, 500); - pll_write_udelay(base + REG_DSI_28nm_PHY_PLL_LKDET_CFG2, 0x05, 512); - - locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); - - if (unlikely(!locked)) - DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); - else - DBG("DSI PLL lock success"); - - return locked ? 0 : -EINVAL; -} - -static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - - DBG("id=%d", pll_28nm->id); - pll_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00); -} - -static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; - void __iomem *base = pll_28nm->mmio; - - cached_state->postdiv3 = - pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG); - cached_state->postdiv1 = - pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG); - cached_state->byte_mux = pll_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG); - if (dsi_pll_28nm_clk_is_enabled(&pll->clk_hw)) - cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw); - else - cached_state->vco_rate = 0; -} - -static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; - void __iomem *base = pll_28nm->mmio; - int ret; - - ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw, - cached_state->vco_rate, 0); - if (ret) { - DRM_DEV_ERROR(&pll_28nm->pdev->dev, - "restore vco rate failed. ret=%d\n", ret); - return ret; - } - - pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, - cached_state->postdiv3); - pll_write(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, - cached_state->postdiv1); - pll_write(base + REG_DSI_28nm_PHY_PLL_VREG_CFG, - cached_state->byte_mux); - - return 0; -} - -static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll, - struct clk **byte_clk_provider, - struct clk **pixel_clk_provider) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - - if (byte_clk_provider) - *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK]; - if (pixel_clk_provider) - *pixel_clk_provider = - pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK]; - - return 0; -} - -static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - int i; - - msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev, - pll_28nm->clks, pll_28nm->num_clks); - - for (i = 0; i < NUM_PROVIDED_CLKS; i++) - pll_28nm->provided_clks[i] = NULL; - - pll_28nm->num_clks = 0; - pll_28nm->clk_data.clks = NULL; - pll_28nm->clk_data.clk_num = 0; -} - -static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) -{ - char clk_name[32], parent1[32], parent2[32], vco_name[32]; - struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "xo" }, - .num_parents = 1, - .name = vco_name, - .flags = CLK_IGNORE_UNUSED, - .ops = &clk_ops_dsi_pll_28nm_vco, - }; - struct device *dev = &pll_28nm->pdev->dev; - struct clk **clks = pll_28nm->clks; - struct clk **provided_clks = pll_28nm->provided_clks; - int num = 0; - int ret; - - DBG("%d", pll_28nm->id); - - snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); - pll_28nm->base.clk_hw.init = &vco_init; - clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw); - - snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); - clks[num++] = clk_register_divider(dev, clk_name, - parent1, CLK_SET_RATE_PARENT, - pll_28nm->mmio + - REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, - 0, 4, 0, NULL); - - snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); - snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->id); - clks[num++] = clk_register_fixed_factor(dev, clk_name, - parent1, CLK_SET_RATE_PARENT, - 1, 2); - - snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); - clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] = - clk_register_divider(dev, clk_name, - parent1, 0, pll_28nm->mmio + - REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, - 0, 8, 0, NULL); - - snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); - snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); - clks[num++] = clk_register_mux(dev, clk_name, - ((const char *[]){ - parent1, parent2 - }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio + - REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL); - - snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); - snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->id); - clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] = - clk_register_fixed_factor(dev, clk_name, - parent1, CLK_SET_RATE_PARENT, 1, 4); - - pll_28nm->num_clks = num; - - pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS; - pll_28nm->clk_data.clks = provided_clks; - - ret = of_clk_add_provider(dev->of_node, - of_clk_src_onecell_get, &pll_28nm->clk_data); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); - return ret; - } - - return 0; -} - -struct msm_dsi_pll *msm_dsi_pll_28nm_init(struct platform_device *pdev, - enum msm_dsi_phy_type type, int id) -{ - struct dsi_pll_28nm *pll_28nm; - struct msm_dsi_pll *pll; - int ret; - - if (!pdev) - return ERR_PTR(-ENODEV); - - pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL); - if (!pll_28nm) - return ERR_PTR(-ENOMEM); - - pll_28nm->pdev = pdev; - pll_28nm->id = id; - - pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_28nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); - return ERR_PTR(-ENOMEM); - } - - pll = &pll_28nm->base; - pll->min_rate = VCO_MIN_RATE; - pll->max_rate = VCO_MAX_RATE; - pll->get_provider = dsi_pll_28nm_get_provider; - pll->destroy = dsi_pll_28nm_destroy; - pll->disable_seq = dsi_pll_28nm_disable_seq; - pll->save_state = dsi_pll_28nm_save_state; - pll->restore_state = dsi_pll_28nm_restore_state; - - if (type == MSM_DSI_PHY_28NM_HPM) { - pll_28nm->vco_delay = 1; - - pll->en_seq_cnt = 3; - pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_hpm; - pll->enable_seqs[1] = dsi_pll_28nm_enable_seq_hpm; - pll->enable_seqs[2] = dsi_pll_28nm_enable_seq_hpm; - } else if (type == MSM_DSI_PHY_28NM_LP) { - pll_28nm->vco_delay = 1000; - - pll->en_seq_cnt = 1; - pll->enable_seqs[0] = dsi_pll_28nm_enable_seq_lp; - } else { - DRM_DEV_ERROR(&pdev->dev, "phy type (%d) is not 28nm\n", type); - return ERR_PTR(-EINVAL); - } - - ret = pll_28nm_register(pll_28nm); - if (ret) { - DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); - return ERR_PTR(ret); - } - - return pll; -} - diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c deleted file mode 100644 index a6e7a2525fe0..000000000000 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_28nm_8960.c +++ /dev/null @@ -1,526 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. - */ - -#include - -#include "dsi_pll.h" -#include "dsi.xml.h" - -/* - * DSI PLL 28nm (8960/A family) - clock diagram (eg: DSI1): - * - * - * +------+ - * dsi1vco_clk ----o-----| DIV1 |---dsi1pllbit (not exposed as clock) - * F * byte_clk | +------+ - * | bit clock divider (F / 8) - * | - * | +------+ - * o-----| DIV2 |---dsi0pllbyte---o---> To byte RCG - * | +------+ | (sets parent rate) - * | byte clock divider (F) | - * | | - * | o---> To esc RCG - * | (doesn't set parent rate) - * | - * | +------+ - * o-----| DIV3 |----dsi0pll------o---> To dsi RCG - * +------+ | (sets parent rate) - * dsi clock divider (F * magic) | - * | - * o---> To pixel rcg - * (doesn't set parent rate) - */ - -#define POLL_MAX_READS 8000 -#define POLL_TIMEOUT_US 1 - -#define NUM_PROVIDED_CLKS 2 - -#define VCO_REF_CLK_RATE 27000000 -#define VCO_MIN_RATE 600000000 -#define VCO_MAX_RATE 1200000000 - -#define DSI_BYTE_PLL_CLK 0 -#define DSI_PIXEL_PLL_CLK 1 - -#define VCO_PREF_DIV_RATIO 27 - -struct pll_28nm_cached_state { - unsigned long vco_rate; - u8 postdiv3; - u8 postdiv2; - u8 postdiv1; -}; - -struct clk_bytediv { - struct clk_hw hw; - void __iomem *reg; -}; - -struct dsi_pll_28nm { - struct msm_dsi_pll base; - - int id; - struct platform_device *pdev; - void __iomem *mmio; - - /* custom byte clock divider */ - struct clk_bytediv *bytediv; - - /* private clocks: */ - struct clk *clks[NUM_DSI_CLOCKS_MAX]; - u32 num_clks; - - /* clock-provider: */ - struct clk *provided_clks[NUM_PROVIDED_CLKS]; - struct clk_onecell_data clk_data; - - struct pll_28nm_cached_state cached_state; -}; - -#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base) - -static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, - int nb_tries, int timeout_us) -{ - bool pll_locked = false; - u32 val; - - while (nb_tries--) { - val = pll_read(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_RDY); - pll_locked = !!(val & DSI_28nm_8960_PHY_PLL_RDY_PLL_RDY); - - if (pll_locked) - break; - - udelay(timeout_us); - } - DBG("DSI PLL is %slocked", pll_locked ? "" : "*not* "); - - return pll_locked; -} - -/* - * Clock Callbacks - */ -static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - void __iomem *base = pll_28nm->mmio; - u32 val, temp, fb_divider; - - DBG("rate=%lu, parent's=%lu", rate, parent_rate); - - temp = rate / 10; - val = VCO_REF_CLK_RATE / 10; - fb_divider = (temp * VCO_PREF_DIV_RATIO) / val; - fb_divider = fb_divider / 2 - 1; - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1, - fb_divider & 0xff); - - val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2); - - val |= (fb_divider >> 8) & 0x07; - - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2, - val); - - val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); - - val |= (VCO_PREF_DIV_RATIO - 1) & 0x3f; - - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3, - val); - - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_6, - 0xf); - - val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); - val |= 0x7 << 4; - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, - val); - - return 0; -} - -static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - - return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS, - POLL_TIMEOUT_US); -} - -static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - void __iomem *base = pll_28nm->mmio; - unsigned long vco_rate; - u32 status, fb_divider, temp, ref_divider; - - VERB("parent_rate=%lu", parent_rate); - - status = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0); - - if (status & DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE) { - fb_divider = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_1); - fb_divider &= 0xff; - temp = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_2) & 0x07; - fb_divider = (temp << 8) | fb_divider; - fb_divider += 1; - - ref_divider = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_3); - ref_divider &= 0x3f; - ref_divider += 1; - - /* multiply by 2 */ - vco_rate = (parent_rate / ref_divider) * fb_divider * 2; - } else { - vco_rate = 0; - } - - DBG("returning vco rate = %lu", vco_rate); - - return vco_rate; -} - -static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, - .set_rate = dsi_pll_28nm_clk_set_rate, - .recalc_rate = dsi_pll_28nm_clk_recalc_rate, - .prepare = msm_dsi_pll_helper_clk_prepare, - .unprepare = msm_dsi_pll_helper_clk_unprepare, - .is_enabled = dsi_pll_28nm_clk_is_enabled, -}; - -/* - * Custom byte clock divier clk_ops - * - * This clock is the entry point to configuring the PLL. The user (dsi host) - * will set this clock's rate to the desired byte clock rate. The VCO lock - * frequency is a multiple of the byte clock rate. The multiplication factor - * (shown as F in the diagram above) is a function of the byte clock rate. - * - * This custom divider clock ensures that its parent (VCO) is set to the - * desired rate, and that the byte clock postdivider (POSTDIV2) is configured - * accordingly - */ -#define to_clk_bytediv(_hw) container_of(_hw, struct clk_bytediv, hw) - -static unsigned long clk_bytediv_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clk_bytediv *bytediv = to_clk_bytediv(hw); - unsigned int div; - - div = pll_read(bytediv->reg) & 0xff; - - return parent_rate / (div + 1); -} - -/* find multiplication factor(wrt byte clock) at which the VCO should be set */ -static unsigned int get_vco_mul_factor(unsigned long byte_clk_rate) -{ - unsigned long bit_mhz; - - /* convert to bit clock in Mhz */ - bit_mhz = (byte_clk_rate * 8) / 1000000; - - if (bit_mhz < 125) - return 64; - else if (bit_mhz < 250) - return 32; - else if (bit_mhz < 600) - return 16; - else - return 8; -} - -static long clk_bytediv_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - unsigned long best_parent; - unsigned int factor; - - factor = get_vco_mul_factor(rate); - - best_parent = rate * factor; - *prate = clk_hw_round_rate(clk_hw_get_parent(hw), best_parent); - - return *prate / factor; -} - -static int clk_bytediv_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clk_bytediv *bytediv = to_clk_bytediv(hw); - u32 val; - unsigned int factor; - - factor = get_vco_mul_factor(rate); - - val = pll_read(bytediv->reg); - val |= (factor - 1) & 0xff; - pll_write(bytediv->reg, val); - - return 0; -} - -/* Our special byte clock divider ops */ -static const struct clk_ops clk_bytediv_ops = { - .round_rate = clk_bytediv_round_rate, - .set_rate = clk_bytediv_set_rate, - .recalc_rate = clk_bytediv_recalc_rate, -}; - -/* - * PLL Callbacks - */ -static int dsi_pll_28nm_enable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; - bool locked; - unsigned int bit_div, byte_div; - int max_reads = 1000, timeout_us = 100; - u32 val; - - DBG("id=%d", pll_28nm->id); - - /* - * before enabling the PLL, configure the bit clock divider since we - * don't expose it as a clock to the outside world - * 1: read back the byte clock divider that should already be set - * 2: divide by 8 to get bit clock divider - * 3: write it to POSTDIV1 - */ - val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); - byte_div = val + 1; - bit_div = byte_div / 8; - - val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); - val &= ~0xf; - val |= (bit_div - 1); - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, val); - - /* enable the PLL */ - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, - DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE); - - locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); - - if (unlikely(!locked)) - DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); - else - DBG("DSI PLL lock success"); - - return locked ? 0 : -EINVAL; -} - -static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - - DBG("id=%d", pll_28nm->id); - pll_write(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00); -} - -static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; - void __iomem *base = pll_28nm->mmio; - - cached_state->postdiv3 = - pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10); - cached_state->postdiv2 = - pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); - cached_state->postdiv1 = - pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); - - cached_state->vco_rate = clk_hw_get_rate(&pll->clk_hw); -} - -static int dsi_pll_28nm_restore_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; - void __iomem *base = pll_28nm->mmio; - int ret; - - ret = dsi_pll_28nm_clk_set_rate(&pll->clk_hw, - cached_state->vco_rate, 0); - if (ret) { - DRM_DEV_ERROR(&pll_28nm->pdev->dev, - "restore vco rate failed. ret=%d\n", ret); - return ret; - } - - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10, - cached_state->postdiv3); - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9, - cached_state->postdiv2); - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, - cached_state->postdiv1); - - return 0; -} - -static int dsi_pll_28nm_get_provider(struct msm_dsi_pll *pll, - struct clk **byte_clk_provider, - struct clk **pixel_clk_provider) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - - if (byte_clk_provider) - *byte_clk_provider = pll_28nm->provided_clks[DSI_BYTE_PLL_CLK]; - if (pixel_clk_provider) - *pixel_clk_provider = - pll_28nm->provided_clks[DSI_PIXEL_PLL_CLK]; - - return 0; -} - -static void dsi_pll_28nm_destroy(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - - msm_dsi_pll_helper_unregister_clks(pll_28nm->pdev, - pll_28nm->clks, pll_28nm->num_clks); -} - -static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm) -{ - char *clk_name, *parent_name, *vco_name; - struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "pxo" }, - .num_parents = 1, - .flags = CLK_IGNORE_UNUSED, - .ops = &clk_ops_dsi_pll_28nm_vco, - }; - struct device *dev = &pll_28nm->pdev->dev; - struct clk **clks = pll_28nm->clks; - struct clk **provided_clks = pll_28nm->provided_clks; - struct clk_bytediv *bytediv; - struct clk_init_data bytediv_init = { }; - int ret, num = 0; - - DBG("%d", pll_28nm->id); - - bytediv = devm_kzalloc(dev, sizeof(*bytediv), GFP_KERNEL); - if (!bytediv) - return -ENOMEM; - - vco_name = devm_kzalloc(dev, 32, GFP_KERNEL); - if (!vco_name) - return -ENOMEM; - - parent_name = devm_kzalloc(dev, 32, GFP_KERNEL); - if (!parent_name) - return -ENOMEM; - - clk_name = devm_kzalloc(dev, 32, GFP_KERNEL); - if (!clk_name) - return -ENOMEM; - - pll_28nm->bytediv = bytediv; - - snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); - vco_init.name = vco_name; - - pll_28nm->base.clk_hw.init = &vco_init; - - clks[num++] = clk_register(dev, &pll_28nm->base.clk_hw); - - /* prepare and register bytediv */ - bytediv->hw.init = &bytediv_init; - bytediv->reg = pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_9; - - snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->id); - snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); - - bytediv_init.name = clk_name; - bytediv_init.ops = &clk_bytediv_ops; - bytediv_init.flags = CLK_SET_RATE_PARENT; - bytediv_init.parent_names = (const char * const *) &parent_name; - bytediv_init.num_parents = 1; - - /* DIV2 */ - clks[num++] = provided_clks[DSI_BYTE_PLL_CLK] = - clk_register(dev, &bytediv->hw); - - snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); - /* DIV3 */ - clks[num++] = provided_clks[DSI_PIXEL_PLL_CLK] = - clk_register_divider(dev, clk_name, - parent_name, 0, pll_28nm->mmio + - REG_DSI_28nm_8960_PHY_PLL_CTRL_10, - 0, 8, 0, NULL); - - pll_28nm->num_clks = num; - - pll_28nm->clk_data.clk_num = NUM_PROVIDED_CLKS; - pll_28nm->clk_data.clks = provided_clks; - - ret = of_clk_add_provider(dev->of_node, - of_clk_src_onecell_get, &pll_28nm->clk_data); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); - return ret; - } - - return 0; -} - -struct msm_dsi_pll *msm_dsi_pll_28nm_8960_init(struct platform_device *pdev, - int id) -{ - struct dsi_pll_28nm *pll_28nm; - struct msm_dsi_pll *pll; - int ret; - - if (!pdev) - return ERR_PTR(-ENODEV); - - pll_28nm = devm_kzalloc(&pdev->dev, sizeof(*pll_28nm), GFP_KERNEL); - if (!pll_28nm) - return ERR_PTR(-ENOMEM); - - pll_28nm->pdev = pdev; - pll_28nm->id = id + 1; - - pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_28nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); - return ERR_PTR(-ENOMEM); - } - - pll = &pll_28nm->base; - pll->min_rate = VCO_MIN_RATE; - pll->max_rate = VCO_MAX_RATE; - pll->get_provider = dsi_pll_28nm_get_provider; - pll->destroy = dsi_pll_28nm_destroy; - pll->disable_seq = dsi_pll_28nm_disable_seq; - pll->save_state = dsi_pll_28nm_save_state; - pll->restore_state = dsi_pll_28nm_restore_state; - - pll->en_seq_cnt = 1; - pll->enable_seqs[0] = dsi_pll_28nm_enable_seq; - - ret = pll_28nm_register(pll_28nm); - if (ret) { - DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); - return ERR_PTR(ret); - } - - return pll; -} diff --git a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c b/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c deleted file mode 100644 index e29b3bfd63d1..000000000000 --- a/drivers/gpu/drm/msm/dsi/pll/dsi_pll_7nm.c +++ /dev/null @@ -1,913 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0 - * Copyright (c) 2018, The Linux Foundation - */ - -#include -#include -#include - -#include "dsi_pll.h" -#include "dsi.xml.h" - -/* - * DSI PLL 7nm - clock diagram (eg: DSI0): TODO: updated CPHY diagram - * - * dsi0_pll_out_div_clk dsi0_pll_bit_clk - * | | - * | | - * +---------+ | +----------+ | +----+ - * dsi0vco_clk ---| out_div |--o--| divl_3_0 |--o--| /8 |-- dsi0_phy_pll_out_byteclk - * +---------+ | +----------+ | +----+ - * | | - * | | dsi0_pll_by_2_bit_clk - * | | | - * | | +----+ | |\ dsi0_pclk_mux - * | |--| /2 |--o--| \ | - * | | +----+ | \ | +---------+ - * | --------------| |--o--| div_7_4 |-- dsi0_phy_pll_out_dsiclk - * |------------------------------| / +---------+ - * | +-----+ | / - * -----------| /4? |--o----------|/ - * +-----+ | | - * | |dsiclk_sel - * | - * dsi0_pll_post_out_div_clk - */ - -#define DSI_BYTE_PLL_CLK 0 -#define DSI_PIXEL_PLL_CLK 1 -#define NUM_PROVIDED_CLKS 2 - -#define VCO_REF_CLK_RATE 19200000 - -struct dsi_pll_regs { - u32 pll_prop_gain_rate; - u32 pll_lockdet_rate; - u32 decimal_div_start; - u32 frac_div_start_low; - u32 frac_div_start_mid; - u32 frac_div_start_high; - u32 pll_clock_inverters; - u32 ssc_stepsize_low; - u32 ssc_stepsize_high; - u32 ssc_div_per_low; - u32 ssc_div_per_high; - u32 ssc_adjper_low; - u32 ssc_adjper_high; - u32 ssc_control; -}; - -struct dsi_pll_config { - u32 ref_freq; - bool div_override; - u32 output_div; - bool ignore_frac; - bool disable_prescaler; - bool enable_ssc; - bool ssc_center; - u32 dec_bits; - u32 frac_bits; - u32 lock_timer; - u32 ssc_freq; - u32 ssc_offset; - u32 ssc_adj_per; - u32 thresh_cycles; - u32 refclk_cycles; -}; - -struct pll_7nm_cached_state { - unsigned long vco_rate; - u8 bit_clk_div; - u8 pix_clk_div; - u8 pll_out_div; - u8 pll_mux; -}; - -struct dsi_pll_7nm { - struct msm_dsi_pll base; - - int id; - struct platform_device *pdev; - - void __iomem *phy_cmn_mmio; - void __iomem *mmio; - - u64 vco_ref_clk_rate; - u64 vco_current_rate; - - /* protects REG_DSI_7nm_PHY_CMN_CLK_CFG0 register */ - spinlock_t postdiv_lock; - - int vco_delay; - struct dsi_pll_config pll_configuration; - struct dsi_pll_regs reg_setup; - - /* private clocks: */ - struct clk_hw *out_div_clk_hw; - struct clk_hw *bit_clk_hw; - struct clk_hw *byte_clk_hw; - struct clk_hw *by_2_bit_clk_hw; - struct clk_hw *post_out_div_clk_hw; - struct clk_hw *pclk_mux_hw; - struct clk_hw *out_dsiclk_hw; - - /* clock-provider: */ - struct clk_hw_onecell_data *hw_data; - - struct pll_7nm_cached_state cached_state; - - enum msm_dsi_phy_usecase uc; - struct dsi_pll_7nm *slave; -}; - -#define to_pll_7nm(x) container_of(x, struct dsi_pll_7nm, base) - -/* - * Global list of private DSI PLL struct pointers. We need this for Dual DSI - * mode, where the master PLL's clk_ops needs access the slave's private data - */ -static struct dsi_pll_7nm *pll_7nm_list[DSI_MAX]; - -static void dsi_pll_setup_config(struct dsi_pll_7nm *pll) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - - config->ref_freq = pll->vco_ref_clk_rate; - config->output_div = 1; - config->dec_bits = 8; - config->frac_bits = 18; - config->lock_timer = 64; - config->ssc_freq = 31500; - config->ssc_offset = 4800; - config->ssc_adj_per = 2; - config->thresh_cycles = 32; - config->refclk_cycles = 256; - - config->div_override = false; - config->ignore_frac = false; - config->disable_prescaler = false; - - /* TODO: ssc enable */ - config->enable_ssc = false; - config->ssc_center = 0; -} - -static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - struct dsi_pll_regs *regs = &pll->reg_setup; - u64 fref = pll->vco_ref_clk_rate; - u64 pll_freq; - u64 divider; - u64 dec, dec_multiple; - u32 frac; - u64 multiplier; - - pll_freq = pll->vco_current_rate; - - if (config->disable_prescaler) - divider = fref; - else - divider = fref * 2; - - multiplier = 1 << config->frac_bits; - dec_multiple = div_u64(pll_freq * multiplier, divider); - div_u64_rem(dec_multiple, multiplier, &frac); - - dec = div_u64(dec_multiple, multiplier); - - if (pll->base.type != MSM_DSI_PHY_7NM_V4_1) - regs->pll_clock_inverters = 0x28; - else if (pll_freq <= 1000000000ULL) - regs->pll_clock_inverters = 0xa0; - else if (pll_freq <= 2500000000ULL) - regs->pll_clock_inverters = 0x20; - else if (pll_freq <= 3020000000ULL) - regs->pll_clock_inverters = 0x00; - else - regs->pll_clock_inverters = 0x40; - - regs->pll_lockdet_rate = config->lock_timer; - regs->decimal_div_start = dec; - regs->frac_div_start_low = (frac & 0xff); - regs->frac_div_start_mid = (frac & 0xff00) >> 8; - regs->frac_div_start_high = (frac & 0x30000) >> 16; -} - -#define SSC_CENTER BIT(0) -#define SSC_EN BIT(1) - -static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll) -{ - struct dsi_pll_config *config = &pll->pll_configuration; - struct dsi_pll_regs *regs = &pll->reg_setup; - u32 ssc_per; - u32 ssc_mod; - u64 ssc_step_size; - u64 frac; - - if (!config->enable_ssc) { - DBG("SSC not enabled\n"); - return; - } - - ssc_per = DIV_ROUND_CLOSEST(config->ref_freq, config->ssc_freq) / 2 - 1; - ssc_mod = (ssc_per + 1) % (config->ssc_adj_per + 1); - ssc_per -= ssc_mod; - - frac = regs->frac_div_start_low | - (regs->frac_div_start_mid << 8) | - (regs->frac_div_start_high << 16); - ssc_step_size = regs->decimal_div_start; - ssc_step_size *= (1 << config->frac_bits); - ssc_step_size += frac; - ssc_step_size *= config->ssc_offset; - ssc_step_size *= (config->ssc_adj_per + 1); - ssc_step_size = div_u64(ssc_step_size, (ssc_per + 1)); - ssc_step_size = DIV_ROUND_CLOSEST_ULL(ssc_step_size, 1000000); - - regs->ssc_div_per_low = ssc_per & 0xFF; - regs->ssc_div_per_high = (ssc_per & 0xFF00) >> 8; - regs->ssc_stepsize_low = (u32)(ssc_step_size & 0xFF); - regs->ssc_stepsize_high = (u32)((ssc_step_size & 0xFF00) >> 8); - regs->ssc_adjper_low = config->ssc_adj_per & 0xFF; - regs->ssc_adjper_high = (config->ssc_adj_per & 0xFF00) >> 8; - - regs->ssc_control = config->ssc_center ? SSC_CENTER : 0; - - pr_debug("SCC: Dec:%d, frac:%llu, frac_bits:%d\n", - regs->decimal_div_start, frac, config->frac_bits); - pr_debug("SSC: div_per:0x%X, stepsize:0x%X, adjper:0x%X\n", - ssc_per, (u32)ssc_step_size, config->ssc_adj_per); -} - -static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll) -{ - void __iomem *base = pll->mmio; - struct dsi_pll_regs *regs = &pll->reg_setup; - - if (pll->pll_configuration.enable_ssc) { - pr_debug("SSC is enabled\n"); - - pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_LOW_1, - regs->ssc_stepsize_low); - pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_STEPSIZE_HIGH_1, - regs->ssc_stepsize_high); - pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_LOW_1, - regs->ssc_div_per_low); - pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_DIV_PER_HIGH_1, - regs->ssc_div_per_high); - pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_LOW_1, - regs->ssc_adjper_low); - pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_ADJPER_HIGH_1, - regs->ssc_adjper_high); - pll_write(base + REG_DSI_7nm_PHY_PLL_SSC_CONTROL, - SSC_EN | regs->ssc_control); - } -} - -static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll) -{ - void __iomem *base = pll->mmio; - u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00; - - if (pll->base.type == MSM_DSI_PHY_7NM_V4_1) { - if (pll->vco_current_rate >= 3100000000ULL) - analog_controls_five_1 = 0x03; - - if (pll->vco_current_rate < 1520000000ULL) - vco_config_1 = 0x08; - else if (pll->vco_current_rate < 2990000000ULL) - vco_config_1 = 0x01; - } - - pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE_1, - analog_controls_five_1); - pll_write(base + REG_DSI_7nm_PHY_PLL_VCO_CONFIG_1, vco_config_1); - pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_FIVE, 0x01); - pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); - pll_write(base + REG_DSI_7nm_PHY_PLL_ANALOG_CONTROLS_THREE, 0x00); - pll_write(base + REG_DSI_7nm_PHY_PLL_DSM_DIVIDER, 0x00); - pll_write(base + REG_DSI_7nm_PHY_PLL_FEEDBACK_DIVIDER, 0x4e); - pll_write(base + REG_DSI_7nm_PHY_PLL_CALIBRATION_SETTINGS, 0x40); - pll_write(base + REG_DSI_7nm_PHY_PLL_BAND_SEL_CAL_SETTINGS_THREE, 0xba); - pll_write(base + REG_DSI_7nm_PHY_PLL_FREQ_DETECT_SETTINGS_ONE, 0x0c); - pll_write(base + REG_DSI_7nm_PHY_PLL_OUTDIV, 0x00); - pll_write(base + REG_DSI_7nm_PHY_PLL_CORE_OVERRIDE, 0x00); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_DIGITAL_TIMERS_TWO, 0x08); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_PROP_GAIN_RATE_1, 0x0a); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_BAND_SEL_RATE_1, 0xc0); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x84); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_INT_GAIN_IFILT_BAND_1, 0x82); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_FL_INT_GAIN_PFILT_BAND_1, 0x4c); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_OVERRIDE, 0x80); - pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x29); - pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f); - pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a); - pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT, - pll->base.type == MSM_DSI_PHY_7NM_V4_1 ? 0x3f : 0x22); - - if (pll->base.type == MSM_DSI_PHY_7NM_V4_1) { - pll_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); - if (pll->slave) - pll_write(pll->slave->mmio + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); - } -} - -static void dsi_pll_commit(struct dsi_pll_7nm *pll) -{ - void __iomem *base = pll->mmio; - struct dsi_pll_regs *reg = &pll->reg_setup; - - pll_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); - pll_write(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1, reg->decimal_div_start); - pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1, reg->frac_div_start_low); - pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1, reg->frac_div_start_mid); - pll_write(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1, reg->frac_div_start_high); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCKDET_RATE_1, reg->pll_lockdet_rate); - pll_write(base + REG_DSI_7nm_PHY_PLL_PLL_LOCK_DELAY, 0x06); - pll_write(base + REG_DSI_7nm_PHY_PLL_CMODE_1, 0x10); /* TODO: 0x00 for CPHY */ - pll_write(base + REG_DSI_7nm_PHY_PLL_CLOCK_INVERTERS, reg->pll_clock_inverters); -} - -static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - - DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->id, rate, - parent_rate); - - pll_7nm->vco_current_rate = rate; - pll_7nm->vco_ref_clk_rate = VCO_REF_CLK_RATE; - - dsi_pll_setup_config(pll_7nm); - - dsi_pll_calc_dec_frac(pll_7nm); - - dsi_pll_calc_ssc(pll_7nm); - - dsi_pll_commit(pll_7nm); - - dsi_pll_config_hzindep_reg(pll_7nm); - - dsi_pll_ssc_commit(pll_7nm); - - /* flush, ensure all register writes are done*/ - wmb(); - - return 0; -} - -static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll) -{ - int rc; - u32 status = 0; - u32 const delay_us = 100; - u32 const timeout_us = 5000; - - rc = readl_poll_timeout_atomic(pll->mmio + - REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE, - status, - ((status & BIT(0)) > 0), - delay_us, - timeout_us); - if (rc) - pr_err("DSI PLL(%d) lock failed, status=0x%08x\n", - pll->id, status); - - return rc; -} - -static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll) -{ - u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0); - - pll_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0); - pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5)); - ndelay(250); -} - -static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll) -{ - u32 data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0); - - pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5)); - pll_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0); - ndelay(250); -} - -static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll) -{ - u32 data; - - data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1); - pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5)); -} - -static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll) -{ - u32 data; - - pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04); - - data = pll_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1); - pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1, - data | BIT(5) | BIT(4)); -} - -static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll) -{ - /* - * Reset the PHY digital domain. This would be needed when - * coming out of a CX or analog rail power collapse while - * ensuring that the pads maintain LP00 or LP11 state - */ - pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0)); - wmb(); /* Ensure that the reset is deasserted */ - pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0); - wmb(); /* Ensure that the reset is deasserted */ -} - -static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - int rc; - - dsi_pll_enable_pll_bias(pll_7nm); - if (pll_7nm->slave) - dsi_pll_enable_pll_bias(pll_7nm->slave); - - /* Start PLL */ - pll_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01); - - /* - * ensure all PLL configurations are written prior to checking - * for PLL lock. - */ - wmb(); - - /* Check for PLL lock */ - rc = dsi_pll_7nm_lock_status(pll_7nm); - if (rc) { - pr_err("PLL(%d) lock failed\n", pll_7nm->id); - goto error; - } - - pll->pll_on = true; - - /* - * assert power on reset for PHY digital in case the PLL is - * enabled after CX of analog domain power collapse. This needs - * to be done before enabling the global clk. - */ - dsi_pll_phy_dig_reset(pll_7nm); - if (pll_7nm->slave) - dsi_pll_phy_dig_reset(pll_7nm->slave); - - dsi_pll_enable_global_clk(pll_7nm); - if (pll_7nm->slave) - dsi_pll_enable_global_clk(pll_7nm->slave); - -error: - return rc; -} - -static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll) -{ - pll_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0); - dsi_pll_disable_pll_bias(pll); -} - -static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - - /* - * To avoid any stray glitches while abruptly powering down the PLL - * make sure to gate the clock using the clock enable bit before - * powering down the PLL - */ - dsi_pll_disable_global_clk(pll_7nm); - pll_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0); - dsi_pll_disable_sub(pll_7nm); - if (pll_7nm->slave) { - dsi_pll_disable_global_clk(pll_7nm->slave); - dsi_pll_disable_sub(pll_7nm->slave); - } - /* flush, ensure all register writes are done */ - wmb(); - pll->pll_on = false; -} - -static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - struct dsi_pll_config *config = &pll_7nm->pll_configuration; - void __iomem *base = pll_7nm->mmio; - u64 ref_clk = pll_7nm->vco_ref_clk_rate; - u64 vco_rate = 0x0; - u64 multiplier; - u32 frac; - u32 dec; - u64 pll_freq, tmp64; - - dec = pll_read(base + REG_DSI_7nm_PHY_PLL_DECIMAL_DIV_START_1); - dec &= 0xff; - - frac = pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_LOW_1); - frac |= ((pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_MID_1) & - 0xff) << 8); - frac |= ((pll_read(base + REG_DSI_7nm_PHY_PLL_FRAC_DIV_START_HIGH_1) & - 0x3) << 16); - - /* - * TODO: - * 1. Assumes prescaler is disabled - */ - multiplier = 1 << config->frac_bits; - pll_freq = dec * (ref_clk * 2); - tmp64 = (ref_clk * 2 * frac); - pll_freq += div_u64(tmp64, multiplier); - - vco_rate = pll_freq; - - DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", - pll_7nm->id, (unsigned long)vco_rate, dec, frac); - - return (unsigned long)vco_rate; -} - -static const struct clk_ops clk_ops_dsi_pll_7nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, - .set_rate = dsi_pll_7nm_vco_set_rate, - .recalc_rate = dsi_pll_7nm_vco_recalc_rate, - .prepare = dsi_pll_7nm_vco_prepare, - .unprepare = dsi_pll_7nm_vco_unprepare, -}; - -/* - * PLL Callbacks - */ - -static void dsi_pll_7nm_save_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; - void __iomem *phy_base = pll_7nm->phy_cmn_mmio; - u32 cmn_clk_cfg0, cmn_clk_cfg1; - - cached->pll_out_div = pll_read(pll_7nm->mmio + - REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); - cached->pll_out_div &= 0x3; - - cmn_clk_cfg0 = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0); - cached->bit_clk_div = cmn_clk_cfg0 & 0xf; - cached->pix_clk_div = (cmn_clk_cfg0 & 0xf0) >> 4; - - cmn_clk_cfg1 = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); - cached->pll_mux = cmn_clk_cfg1 & 0x3; - - DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", - pll_7nm->id, cached->pll_out_div, cached->bit_clk_div, - cached->pix_clk_div, cached->pll_mux); -} - -static int dsi_pll_7nm_restore_state(struct msm_dsi_pll *pll) -{ - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; - void __iomem *phy_base = pll_7nm->phy_cmn_mmio; - u32 val; - int ret; - - val = pll_read(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); - val &= ~0x3; - val |= cached->pll_out_div; - pll_write(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val); - - pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0, - cached->bit_clk_div | (cached->pix_clk_div << 4)); - - val = pll_read(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); - val &= ~0x3; - val |= cached->pll_mux; - pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val); - - ret = dsi_pll_7nm_vco_set_rate(&pll->clk_hw, pll_7nm->vco_current_rate, pll_7nm->vco_ref_clk_rate); - if (ret) { - DRM_DEV_ERROR(&pll_7nm->pdev->dev, - "restore vco rate failed. ret=%d\n", ret); - return ret; - } - - DBG("DSI PLL%d", pll_7nm->id); - - return 0; -} - -static int dsi_pll_7nm_set_usecase(struct msm_dsi_pll *pll, - enum msm_dsi_phy_usecase uc) -{ - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - void __iomem *base = pll_7nm->phy_cmn_mmio; - u32 data = 0x0; /* internal PLL */ - - DBG("DSI PLL%d", pll_7nm->id); - - switch (uc) { - case MSM_DSI_PHY_STANDALONE: - break; - case MSM_DSI_PHY_MASTER: - pll_7nm->slave = pll_7nm_list[(pll_7nm->id + 1) % DSI_MAX]; - break; - case MSM_DSI_PHY_SLAVE: - data = 0x1; /* external PLL */ - break; - default: - return -EINVAL; - } - - /* set PLL src */ - pll_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2)); - - pll_7nm->uc = uc; - - return 0; -} - -static int dsi_pll_7nm_get_provider(struct msm_dsi_pll *pll, - struct clk **byte_clk_provider, - struct clk **pixel_clk_provider) -{ - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - struct clk_hw_onecell_data *hw_data = pll_7nm->hw_data; - - DBG("DSI PLL%d", pll_7nm->id); - - if (byte_clk_provider) - *byte_clk_provider = hw_data->hws[DSI_BYTE_PLL_CLK]->clk; - if (pixel_clk_provider) - *pixel_clk_provider = hw_data->hws[DSI_PIXEL_PLL_CLK]->clk; - - return 0; -} - -static void dsi_pll_7nm_destroy(struct msm_dsi_pll *pll) -{ - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); - struct device *dev = &pll_7nm->pdev->dev; - - DBG("DSI PLL%d", pll_7nm->id); - of_clk_del_provider(dev->of_node); - - clk_hw_unregister_divider(pll_7nm->out_dsiclk_hw); - clk_hw_unregister_mux(pll_7nm->pclk_mux_hw); - clk_hw_unregister_fixed_factor(pll_7nm->post_out_div_clk_hw); - clk_hw_unregister_fixed_factor(pll_7nm->by_2_bit_clk_hw); - clk_hw_unregister_fixed_factor(pll_7nm->byte_clk_hw); - clk_hw_unregister_divider(pll_7nm->bit_clk_hw); - clk_hw_unregister_divider(pll_7nm->out_div_clk_hw); - clk_hw_unregister(&pll_7nm->base.clk_hw); -} - -/* - * The post dividers and mux clocks are created using the standard divider and - * mux API. Unlike the 14nm PHY, the slave PLL doesn't need its dividers/mux - * state to follow the master PLL's divider/mux state. Therefore, we don't - * require special clock ops that also configure the slave PLL registers - */ -static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm) -{ - char clk_name[32], parent[32], vco_name[32]; - char parent2[32], parent3[32], parent4[32]; - struct clk_init_data vco_init = { - .parent_names = (const char *[]){ "bi_tcxo" }, - .num_parents = 1, - .name = vco_name, - .flags = CLK_IGNORE_UNUSED, - .ops = &clk_ops_dsi_pll_7nm_vco, - }; - struct device *dev = &pll_7nm->pdev->dev; - struct clk_hw_onecell_data *hw_data; - struct clk_hw *hw; - int ret; - - DBG("DSI%d", pll_7nm->id); - - hw_data = devm_kzalloc(dev, sizeof(*hw_data) + - NUM_PROVIDED_CLKS * sizeof(struct clk_hw *), - GFP_KERNEL); - if (!hw_data) - return -ENOMEM; - - snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->id); - pll_7nm->base.clk_hw.init = &vco_init; - - ret = clk_hw_register(dev, &pll_7nm->base.clk_hw); - if (ret) - return ret; - - snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->id); - - hw = clk_hw_register_divider(dev, clk_name, - parent, CLK_SET_RATE_PARENT, - pll_7nm->mmio + - REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, - 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_base_clk_hw; - } - - pll_7nm->out_div_clk_hw = hw; - - snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); - - /* BIT CLK: DIV_CTRL_3_0 */ - hw = clk_hw_register_divider(dev, clk_name, parent, - CLK_SET_RATE_PARENT, - pll_7nm->phy_cmn_mmio + - REG_DSI_7nm_PHY_CMN_CLK_CFG0, - 0, 4, CLK_DIVIDER_ONE_BASED, - &pll_7nm->postdiv_lock); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_out_div_clk_hw; - } - - pll_7nm->bit_clk_hw = hw; - - snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); - - /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ - hw = clk_hw_register_fixed_factor(dev, clk_name, parent, - CLK_SET_RATE_PARENT, 1, 8); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_bit_clk_hw; - } - - pll_7nm->byte_clk_hw = hw; - hw_data->hws[DSI_BYTE_PLL_CLK] = hw; - - snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); - - hw = clk_hw_register_fixed_factor(dev, clk_name, parent, - 0, 1, 2); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_byte_clk_hw; - } - - pll_7nm->by_2_bit_clk_hw = hw; - - snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); - - hw = clk_hw_register_fixed_factor(dev, clk_name, parent, - 0, 1, 4); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_by_2_bit_clk_hw; - } - - pll_7nm->post_out_div_clk_hw = hw; - - snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); - snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id); - snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); - snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id); - - hw = clk_hw_register_mux(dev, clk_name, - ((const char *[]){ - parent, parent2, parent3, parent4 - }), 4, 0, pll_7nm->phy_cmn_mmio + - REG_DSI_7nm_PHY_CMN_CLK_CFG1, - 0, 2, 0, NULL); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_post_out_div_clk_hw; - } - - pll_7nm->pclk_mux_hw = hw; - - snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->id); - - /* PIX CLK DIV : DIV_CTRL_7_4*/ - hw = clk_hw_register_divider(dev, clk_name, parent, - 0, pll_7nm->phy_cmn_mmio + - REG_DSI_7nm_PHY_CMN_CLK_CFG0, - 4, 4, CLK_DIVIDER_ONE_BASED, - &pll_7nm->postdiv_lock); - if (IS_ERR(hw)) { - ret = PTR_ERR(hw); - goto err_pclk_mux_hw; - } - - pll_7nm->out_dsiclk_hw = hw; - hw_data->hws[DSI_PIXEL_PLL_CLK] = hw; - - hw_data->num = NUM_PROVIDED_CLKS; - pll_7nm->hw_data = hw_data; - - ret = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, - pll_7nm->hw_data); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register clk provider: %d\n", ret); - goto err_dsiclk_hw; - } - - return 0; - -err_dsiclk_hw: - clk_hw_unregister_divider(pll_7nm->out_dsiclk_hw); -err_pclk_mux_hw: - clk_hw_unregister_mux(pll_7nm->pclk_mux_hw); -err_post_out_div_clk_hw: - clk_hw_unregister_fixed_factor(pll_7nm->post_out_div_clk_hw); -err_by_2_bit_clk_hw: - clk_hw_unregister_fixed_factor(pll_7nm->by_2_bit_clk_hw); -err_byte_clk_hw: - clk_hw_unregister_fixed_factor(pll_7nm->byte_clk_hw); -err_bit_clk_hw: - clk_hw_unregister_divider(pll_7nm->bit_clk_hw); -err_out_div_clk_hw: - clk_hw_unregister_divider(pll_7nm->out_div_clk_hw); -err_base_clk_hw: - clk_hw_unregister(&pll_7nm->base.clk_hw); - - return ret; -} - -struct msm_dsi_pll *msm_dsi_pll_7nm_init(struct platform_device *pdev, - enum msm_dsi_phy_type type, int id) -{ - struct dsi_pll_7nm *pll_7nm; - struct msm_dsi_pll *pll; - int ret; - - pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL); - if (!pll_7nm) - return ERR_PTR(-ENOMEM); - - DBG("DSI PLL%d", id); - - pll_7nm->pdev = pdev; - pll_7nm->id = id; - pll_7nm_list[id] = pll_7nm; - - pll_7nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); - if (IS_ERR_OR_NULL(pll_7nm->phy_cmn_mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); - return ERR_PTR(-ENOMEM); - } - - pll_7nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_7nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); - return ERR_PTR(-ENOMEM); - } - - spin_lock_init(&pll_7nm->postdiv_lock); - - pll = &pll_7nm->base; - pll->min_rate = 1000000000UL; - pll->max_rate = 3500000000UL; - if (type == MSM_DSI_PHY_7NM_V4_1) { - pll->min_rate = 600000000UL; - pll->max_rate = (unsigned long)5000000000ULL; - /* workaround for max rate overflowing on 32-bit builds: */ - pll->max_rate = max(pll->max_rate, 0xffffffffUL); - } - pll->get_provider = dsi_pll_7nm_get_provider; - pll->destroy = dsi_pll_7nm_destroy; - pll->save_state = dsi_pll_7nm_save_state; - pll->restore_state = dsi_pll_7nm_restore_state; - pll->set_usecase = dsi_pll_7nm_set_usecase; - - pll_7nm->vco_delay = 1; - - ret = pll_7nm_register(pll_7nm); - if (ret) { - DRM_DEV_ERROR(&pdev->dev, "failed to register PLL: %d\n", ret); - return ERR_PTR(ret); - } - - /* TODO: Remove this when we have proper display handover support */ - msm_dsi_pll_save_state(pll); - - return pll; -} From patchwork Sat Mar 27 11:02:57 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 410147 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2160909jai; Sat, 27 Mar 2021 04:03:49 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwpgrTl2UCi2O8/PxeYe8WxqsiitNpEN8n5vEA8ww3tisb0JSbOuXn1+1X2ejNHHR2YerEM X-Received: by 2002:a17:902:7792:b029:e6:caba:f836 with SMTP id o18-20020a1709027792b02900e6cabaf836mr19575950pll.41.1616843029195; Sat, 27 Mar 2021 04:03:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616843029; cv=none; d=google.com; s=arc-20160816; b=vQsYtBy+tr0/ZimEjl2J32OxJbwm96/mDdK5sdpzsjqQhmcyxMd1RfwQdyzBZtXhbL 2Ffy0bxfkQcUQ7jL2w4eg4wkcH0BWgwOka/MgDZYrfK8+grpIaczwyKMbkvTUnY2oaQj VRxH4Ji8NZ8th7C/SIZvHItdJbwfn53yYFDR6e6L/QUgG1+arEG5D/JjxKzh2WH2rdcL PLa/ub+Nv1G6JEOkMDLa/trQB+3KS52tSkMh2FS/y017y3SN/Vqle0aL/NKj1jlmI1ox IMJsL7hrp+nie/M6JGhissPifwfu71Qo48vyU8+HGdI1Ey2sbN7DCilM8W8idWUIXuGH QNXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:mime-version:references:in-reply-to:message-id:date :subject:to:from:dkim-signature:delivered-to; bh=IKCC8MwsnkjOWaatpXJkaXz5gz4LEuH/hmQyvT6I1SI=; b=MOPErpOOX9iB72SfDJvVniLgeVDeb4sK+ksWSdFUiN0ZSx9OqlWZN0atX7LYIh9rt8 REIaGUthnRaJWlH99L1m52llHoqJgsRAItLrCAnvYrCIZ0iztt0NAL84ikGwgfpmDdZh H0nWRuBowDJfpjbPJibbwp6UnsGaqymy9+RZyCdSZxBUVbB3+lbpiYS0A2duh7puUOFw N9kS490qDscJdAK8ImNcelMBHp2M656gCV+2++3BC3VTko2aNZ4MCFrMwdtJw9zA6KlF MFXywVmBQzWWN+FsnOWDwJfvjO7Qh13J1/13rUN7cNqtnE0A+/RTMo6slZn+W045KJgP /5rA== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=AFARRRH5; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [2610:10:20:722:a800:ff:fe36:1795]) by mx.google.com with ESMTPS id x16si7733770plg.256.2021.03.27.04.03.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:49 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) client-ip=2610:10:20:722:a800:ff:fe36:1795; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=AFARRRH5; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 6B5DD6F533; Sat, 27 Mar 2021 11:03:31 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lj1-x22c.google.com (mail-lj1-x22c.google.com [IPv6:2a00:1450:4864:20::22c]) by gabe.freedesktop.org (Postfix) with ESMTPS id 8B1486F527 for ; Sat, 27 Mar 2021 11:03:26 +0000 (UTC) Received: by mail-lj1-x22c.google.com with SMTP id 15so10371730ljj.0 for ; Sat, 27 Mar 2021 04:03:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EotCVI0RIUpvQprZS2AZF0b/Nng+PMwe9y5pfA/vxVw=; b=AFARRRH5H+QDopbzAd2Pr/8nYE2Fm2rV9G7o2DV0quJsR+QCHFIFWZV9s4AYZje3g2 msXIaiPaxCz/h6XLDoP5uWe5qJrBYZwnF+1aJFyS6g310oLM7NU8PwLx732nO+M0vsjZ m9QdgP+h2g1QP/xyqHveKpR/f2GpjMqZ6obYByjw2my9DoVdM5HuGYSfANDJUkGfOqa8 z/SsUZr5fzfuMA39UrhG1g3X0p4dXpI9OUXOXdikBH7qnkBvsCLOVxg4XCRGuiQar7HZ FPTrgv3ws7IWk9EekFwl2BjPn66ZPj81bPV2676fa+c4MYkBQGIHNmKZq1KWwOYXlauq fayw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=EotCVI0RIUpvQprZS2AZF0b/Nng+PMwe9y5pfA/vxVw=; b=IbAsxQSaFvA7hwYN5RzlTr/sQxiq6uOaSVKDalyAoPeNJAajvNggy3wFC5Z2THUd6w bUkXuWwaYtjv8znOvXQc3KmpexIbULl9pd0LH1iGE8attebVRssTAI8rkIOTJzNbmNUA zH15YIYWZBSVSJSwhPngYdPEmiMUlzO8fwe62AdrRgXrOped7bBC4l+9D3/4OP9VtfTr cF2XmpL2O7zryMMfKbVrYuBDnshhBSAop375oEzXz6Kl0155+Gp5l0FagMHgx5VDtbjS ZEZcQeY6FLlGzz+bIYpGJI5KUdUQG0pguurfWxvjVLaeaKLHOXtd60bZrvXX6/ljaJfD 3hHg== X-Gm-Message-State: AOAM533K6z1COv3z1fqpjwTjttFsBeNxaF8xl4smByyI1hzvPi/42HXt ZpHr0O9HIaxBzJtSLOQKa7gZJA== X-Received: by 2002:a2e:b4c3:: with SMTP id r3mr11607755ljm.232.1616843004898; Sat, 27 Mar 2021 04:03:24 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id a8sm1513801ljn.96.2021.03.27.04.03.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:24 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Jonathan Marek , Michael Turquette Subject: [PATCH v3 17/25] drm/msi/dsi: inline msm_dsi_pll_helper_clk_prepare/unprepare Date: Sat, 27 Mar 2021 14:02:57 +0300 Message-Id: <20210327110305.3289784-18-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> References: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org, linux-clk@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" 10nm and 7nm already do not use these helpers, as they handle setting slave DSI clocks after enabling VCO. Modify the rest of PHY drivers to remove unnecessary indirection and drop enable_seq/disable_seq PLL callbacks. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 2 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 87 +++++++------ drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 86 ++++++++----- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 120 ++++++++++-------- drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 35 ----- drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 2 - 6 files changed, 171 insertions(+), 161 deletions(-) -- 2.30.2 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel Reviewed-by: Abhinav Kumar diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 8133732e0c7f..b477d21804c8 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -32,8 +32,6 @@ struct msm_dsi_phy_ops { }; struct msm_dsi_pll_ops { - int (*enable_seq)(struct msm_dsi_pll *pll); - void (*disable_seq)(struct msm_dsi_pll *pll); void (*save_state)(struct msm_dsi_pll *pll); int (*restore_state)(struct msm_dsi_pll *pll); }; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 434d02ffa7fe..91c5bb2fd169 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -652,12 +652,58 @@ static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, return (unsigned long)vco_rate; } +static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + void __iomem *base = pll_14nm->mmio; + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + bool locked; + + DBG(""); + + if (unlikely(pll->pll_on)) + return 0; + + pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); + + locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS, + POLL_TIMEOUT_US); + + if (unlikely(!locked)) { + DRM_DEV_ERROR(&pll_14nm->pdev->dev, "DSI PLL lock failed\n"); + return -EINVAL; + } + + DBG("DSI PLL lock success"); + pll->pll_on = true; + + return 0; +} + +static void dsi_pll_14nm_vco_unprepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + + DBG(""); + + if (unlikely(!pll->pll_on)) + return; + + pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); + + pll->pll_on = false; +} + static const struct clk_ops clk_ops_dsi_pll_14nm_vco = { .round_rate = msm_dsi_pll_helper_clk_round_rate, .set_rate = dsi_pll_14nm_vco_set_rate, .recalc_rate = dsi_pll_14nm_vco_recalc_rate, - .prepare = msm_dsi_pll_helper_clk_prepare, - .unprepare = msm_dsi_pll_helper_clk_unprepare, + .prepare = dsi_pll_14nm_vco_prepare, + .unprepare = dsi_pll_14nm_vco_unprepare, }; /* @@ -749,39 +795,6 @@ static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = { * PLL Callbacks */ -static int dsi_pll_14nm_enable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - void __iomem *base = pll_14nm->mmio; - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - bool locked; - - DBG(""); - - pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 1); - - locked = pll_14nm_poll_for_ready(pll_14nm, POLL_MAX_READS, - POLL_TIMEOUT_US); - - if (unlikely(!locked)) - DRM_DEV_ERROR(&pll_14nm->pdev->dev, "DSI PLL lock failed\n"); - else - DBG("DSI PLL lock success"); - - return locked ? 0 : -EINVAL; -} - -static void dsi_pll_14nm_disable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; - - DBG(""); - - pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); -} - static void dsi_pll_14nm_save_state(struct msm_dsi_pll *pll) { struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); @@ -1157,8 +1170,6 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs = { .pll_ops = { .save_state = dsi_pll_14nm_save_state, .restore_state = dsi_pll_14nm_restore_state, - .disable_seq = dsi_pll_14nm_disable_seq, - .enable_seq = dsi_pll_14nm_enable_seq, }, .min_pll_rate = VCO_MIN_RATE, .max_pll_rate = VCO_MAX_RATE, @@ -1183,8 +1194,6 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs = { .pll_ops = { .save_state = dsi_pll_14nm_save_state, .restore_state = dsi_pll_14nm_restore_state, - .disable_seq = dsi_pll_14nm_disable_seq, - .enable_seq = dsi_pll_14nm_enable_seq, }, .min_pll_rate = VCO_MIN_RATE, .max_pll_rate = VCO_MAX_RATE, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index ed369eb18e9d..20b31398b540 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -289,19 +289,7 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, return vco_rate; } -static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, - .set_rate = dsi_pll_28nm_clk_set_rate, - .recalc_rate = dsi_pll_28nm_clk_recalc_rate, - .prepare = msm_dsi_pll_helper_clk_prepare, - .unprepare = msm_dsi_pll_helper_clk_unprepare, - .is_enabled = dsi_pll_28nm_clk_is_enabled, -}; - -/* - * PLL Callbacks - */ -static int _dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll) +static int _dsi_pll_28nm_vco_prepare_hpm(struct msm_dsi_pll *pll) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); struct device *dev = &pll_28nm->pdev->dev; @@ -376,21 +364,28 @@ static int _dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll) return locked ? 0 : -EINVAL; } -static int dsi_pll_28nm_enable_seq_hpm(struct msm_dsi_pll *pll) +static int dsi_pll_28nm_vco_prepare_hpm(struct clk_hw *hw) { + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); int i, ret; + if (unlikely(pll->pll_on)) + return 0; + for (i = 0; i < 3; i++) { - ret = _dsi_pll_28nm_enable_seq_hpm(pll); - if (!ret) + ret = _dsi_pll_28nm_vco_prepare_hpm(pll); + if (!ret) { + pll->pll_on = true; return 0; + } } return ret; } -static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll) +static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw) { + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); struct device *dev = &pll_28nm->pdev->dev; void __iomem *base = pll_28nm->mmio; @@ -400,6 +395,9 @@ static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll) DBG("id=%d", pll_28nm->id); + if (unlikely(pll->pll_on)) + return 0; + pll_28nm_software_reset(pll_28nm); /* @@ -424,22 +422,54 @@ static int dsi_pll_28nm_enable_seq_lp(struct msm_dsi_pll *pll) locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); - if (unlikely(!locked)) + if (unlikely(!locked)) { DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); - else - DBG("DSI PLL lock success"); + return -EINVAL; + } - return locked ? 0 : -EINVAL; + DBG("DSI PLL lock success"); + pll->pll_on = true; + + return 0; } -static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll) +static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) { + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); DBG("id=%d", pll_28nm->id); + + if (unlikely(!pll->pll_on)) + return; + pll_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00); + + pll->pll_on = false; } +static const struct clk_ops clk_ops_dsi_pll_28nm_vco_hpm = { + .round_rate = msm_dsi_pll_helper_clk_round_rate, + .set_rate = dsi_pll_28nm_clk_set_rate, + .recalc_rate = dsi_pll_28nm_clk_recalc_rate, + .prepare = dsi_pll_28nm_vco_prepare_hpm, + .unprepare = dsi_pll_28nm_vco_unprepare, + .is_enabled = dsi_pll_28nm_clk_is_enabled, +}; + +static const struct clk_ops clk_ops_dsi_pll_28nm_vco_lp = { + .round_rate = msm_dsi_pll_helper_clk_round_rate, + .set_rate = dsi_pll_28nm_clk_set_rate, + .recalc_rate = dsi_pll_28nm_clk_recalc_rate, + .prepare = dsi_pll_28nm_vco_prepare_lp, + .unprepare = dsi_pll_28nm_vco_unprepare, + .is_enabled = dsi_pll_28nm_clk_is_enabled, +}; + +/* + * PLL Callbacks + */ + static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); @@ -490,7 +520,6 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov .num_parents = 1, .name = vco_name, .flags = CLK_IGNORE_UNUSED, - .ops = &clk_ops_dsi_pll_28nm_vco, }; struct device *dev = &pll_28nm->pdev->dev; struct clk_hw *hw; @@ -498,6 +527,11 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov DBG("%d", pll_28nm->id); + if (pll_28nm->base.cfg->type == MSM_DSI_PHY_28NM_LP) + vco_init.ops = &clk_ops_dsi_pll_28nm_vco_lp; + else + vco_init.ops = &clk_ops_dsi_pll_28nm_vco_hpm; + snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); pll_28nm->base.clk_hw.init = &vco_init; ret = devm_clk_hw_register(dev, &pll_28nm->base.clk_hw); @@ -753,8 +787,6 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = { .pll_ops = { .save_state = dsi_pll_28nm_save_state, .restore_state = dsi_pll_28nm_restore_state, - .disable_seq = dsi_pll_28nm_disable_seq, - .enable_seq = dsi_pll_28nm_enable_seq_hpm, }, .min_pll_rate = VCO_MIN_RATE, .max_pll_rate = VCO_MAX_RATE, @@ -779,8 +811,6 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = { .pll_ops = { .save_state = dsi_pll_28nm_save_state, .restore_state = dsi_pll_28nm_restore_state, - .disable_seq = dsi_pll_28nm_disable_seq, - .enable_seq = dsi_pll_28nm_enable_seq_hpm, }, .min_pll_rate = VCO_MIN_RATE, .max_pll_rate = VCO_MAX_RATE, @@ -805,8 +835,6 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = { .pll_ops = { .save_state = dsi_pll_28nm_save_state, .restore_state = dsi_pll_28nm_restore_state, - .disable_seq = dsi_pll_28nm_disable_seq, - .enable_seq = dsi_pll_28nm_enable_seq_lp, }, .min_pll_rate = VCO_MIN_RATE, .max_pll_rate = VCO_MAX_RATE, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index 45b2bf482392..952444e3e8f0 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -178,12 +178,76 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, return vco_rate; } +static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct device *dev = &pll_28nm->pdev->dev; + void __iomem *base = pll_28nm->mmio; + bool locked; + unsigned int bit_div, byte_div; + int max_reads = 1000, timeout_us = 100; + u32 val; + + DBG("id=%d", pll_28nm->id); + + if (unlikely(pll->pll_on)) + return 0; + + /* + * before enabling the PLL, configure the bit clock divider since we + * don't expose it as a clock to the outside world + * 1: read back the byte clock divider that should already be set + * 2: divide by 8 to get bit clock divider + * 3: write it to POSTDIV1 + */ + val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); + byte_div = val + 1; + bit_div = byte_div / 8; + + val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); + val &= ~0xf; + val |= (bit_div - 1); + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, val); + + /* enable the PLL */ + pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, + DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE); + + locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); + + if (unlikely(!locked)) { + DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); + return -EINVAL; + } + + DBG("DSI PLL lock success"); + pll->pll_on = true; + + return 0; +} + +static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) +{ + struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + + DBG("id=%d", pll_28nm->id); + + if (unlikely(!pll->pll_on)) + return; + + pll_write(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00); + + pll->pll_on = false; +} + static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { .round_rate = msm_dsi_pll_helper_clk_round_rate, .set_rate = dsi_pll_28nm_clk_set_rate, .recalc_rate = dsi_pll_28nm_clk_recalc_rate, - .prepare = msm_dsi_pll_helper_clk_prepare, - .unprepare = msm_dsi_pll_helper_clk_unprepare, + .prepare = dsi_pll_28nm_vco_prepare, + .unprepare = dsi_pll_28nm_vco_unprepare, .is_enabled = dsi_pll_28nm_clk_is_enabled, }; @@ -270,56 +334,6 @@ static const struct clk_ops clk_bytediv_ops = { /* * PLL Callbacks */ -static int dsi_pll_28nm_enable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; - bool locked; - unsigned int bit_div, byte_div; - int max_reads = 1000, timeout_us = 100; - u32 val; - - DBG("id=%d", pll_28nm->id); - - /* - * before enabling the PLL, configure the bit clock divider since we - * don't expose it as a clock to the outside world - * 1: read back the byte clock divider that should already be set - * 2: divide by 8 to get bit clock divider - * 3: write it to POSTDIV1 - */ - val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9); - byte_div = val + 1; - bit_div = byte_div / 8; - - val = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); - val &= ~0xf; - val |= (bit_div - 1); - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8, val); - - /* enable the PLL */ - pll_write(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, - DSI_28nm_8960_PHY_PLL_CTRL_0_ENABLE); - - locked = pll_28nm_poll_for_ready(pll_28nm, max_reads, timeout_us); - - if (unlikely(!locked)) - DRM_DEV_ERROR(dev, "DSI PLL lock failed\n"); - else - DBG("DSI PLL lock success"); - - return locked ? 0 : -EINVAL; -} - -static void dsi_pll_28nm_disable_seq(struct msm_dsi_pll *pll) -{ - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); - - DBG("id=%d", pll_28nm->id); - pll_write(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00); -} - static void dsi_pll_28nm_save_state(struct msm_dsi_pll *pll) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); @@ -652,8 +666,6 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs = { .pll_ops = { .save_state = dsi_pll_28nm_save_state, .restore_state = dsi_pll_28nm_restore_state, - .disable_seq = dsi_pll_28nm_disable_seq, - .enable_seq = dsi_pll_28nm_enable_seq, }, .min_pll_rate = VCO_MIN_RATE, .max_pll_rate = VCO_MAX_RATE, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c index 652c2d6bfeec..cae668b669a4 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c @@ -21,38 +21,3 @@ long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw, else return rate; } - -int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - int ret = 0; - - /* - * Certain PLLs do not allow VCO rate update when it is on. - * Keep track of their status to turn on/off after set rate success. - */ - if (unlikely(pll->pll_on)) - return 0; - - ret = pll->cfg->pll_ops.enable_seq(pll); - if (ret) { - DRM_ERROR("DSI PLL failed to lock\n"); - return ret; - } - - pll->pll_on = true; - - return 0; -} - -void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - - if (unlikely(!pll->pll_on)) - return; - - pll->cfg->pll_ops.disable_seq(pll); - - pll->pll_on = false; -} diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h index eca13cf67c21..da83e4c11f4f 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h @@ -39,8 +39,6 @@ static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns) /* clock callbacks */ long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw, unsigned long rate, unsigned long *parent_rate); -int msm_dsi_pll_helper_clk_prepare(struct clk_hw *hw); -void msm_dsi_pll_helper_clk_unprepare(struct clk_hw *hw); #endif /* __DSI_PLL_H__ */ From patchwork Sat Mar 27 11:02:59 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 410148 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2160931jai; Sat, 27 Mar 2021 04:03:51 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwT6MUtuWcwjyPGAtXM0YpOcUgVqsYYhK93RsL92B+32BDTkKx0kHgIo9A2d8um7z3s5ipE X-Received: by 2002:a63:2316:: with SMTP id j22mr16495863pgj.392.1616843030844; Sat, 27 Mar 2021 04:03:50 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616843030; cv=none; d=google.com; s=arc-20160816; b=v59G/Mg087Sh7A7tV+biKfl5Jy/6kGip8T4+FYV8tpXwI8UWmrRMlxqr3OD6u8Ilpd 8dcFCMx4cJ8u0IG3LT/wUV+DVzyMbxsjbSLuJrsRo8PBtt6Dm0ANq3uleJkGhfTJr8v5 1GR9L+AHDx+LUHsWs55s6uaaQb9jxhgOGbJm3vXKlGnJ46Od455Q6Q/7N3l82ufHMQ9l uTTc464rz1Low0opAdNMnyUjxclSKFBrEm5f2gjlQObREONQsLAqDsudU/oBgbwAkfOH CBZE6njseoGrPj2n1Y7oleI2r153rRndkZczZvIh4hwl3+48eDsbsJrPt8af9/bkS2ZN NCJg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:mime-version:references:in-reply-to:message-id:date :subject:to:from:dkim-signature:delivered-to; bh=/2dEwlTIc0DxumTEoikkir+Yxpp19f1SXkUTu/BXT1E=; b=NfiD+GS3QErMdaxsUUSPAfhdPY7lrv8ezM/mndTHE4QGBc4FroEkPiVrUsqVI/V4Wj d2Q4jnXxR9Y7HU9OWQz+LziC5v6a5TX1UqzPTcVpjFnMejGJyAOuLq29UUUH4MrvEg94 TllyLDwEOrL5Xst1AljYIgrmR1iGoBryF94CiLq9FOcym1FZfmHTwVHu7n9UsXTmMRga V48h7T+syEU1/Y4n3ZOeeM9C/Do8fR1yM27LkUguVfp4bHQWJMWJOPAq87xGJdnyZln9 vtoB8ytDoVQl2Xbi/uSZ0HHeuTXLgr89f3OlW88QnSZi8KDk8CpJsbwN2PpwKXL2ptIR CEoQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=eLV1huDu; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id 129si10796744pff.18.2021.03.27.04.03.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:50 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=eLV1huDu; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 0E1A56F540; Sat, 27 Mar 2021 11:03:30 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf1-x130.google.com (mail-lf1-x130.google.com [IPv6:2a00:1450:4864:20::130]) by gabe.freedesktop.org (Postfix) with ESMTPS id 5D3776F526 for ; Sat, 27 Mar 2021 11:03:28 +0000 (UTC) Received: by mail-lf1-x130.google.com with SMTP id a198so11498756lfd.7 for ; Sat, 27 Mar 2021 04:03:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=daK+LvPJYTRA0d2fIPJN0NkidCn9oSmWkMxzdx3fDEY=; b=eLV1huDuS2Qx/u2r6g4i1Lp85PHu4/za7Nw8gtciSM/qdxVp2hukbuoQ3jutcgHWI3 xe5FQvLqsJwIXQsDvV9oJduMxH8ULdcgwojaGHoh/s7+tRHdMIlSCw7q9tQbVLCWb95s Jvz5zuIVpn+Tv6krcjRcKyXPhzVfqYmarC/Mda965a31xmn3Ds5qHo9r8wuPNTxSC7LZ c5NTejQiuMDG2mrUEEfquntmWt9UEYCaIcqvXHk89PJluozg/V3aFk1UJYTQ6AKYH/1M U6hLbmV2RAgBJtJZl6CESt5ctSQb8dci2l/G3wF8u5GpeR0ZIPLMH4IVPdFnmG63V+qo eAYA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=daK+LvPJYTRA0d2fIPJN0NkidCn9oSmWkMxzdx3fDEY=; b=AFJpl6u1jpl1vVBPklOwsxBXlidxnNWz8WxdIBsANS94Y4EtS7fa4KCsRRSiI6/bgl xHMuwjlGlP6C3/bx56Pn8Y0jaRXsfS1OAZ+xqPqSQRdX38In5H3p17v7d15Whqm4XAMH w61JiSpQa8ILmcmVbXODooDRw+nGfTc1K2bKpen+KTFrfeGGgUPJyVdlzOC9MpBcxOCM gXechbRYfrxRutHb2qoPBy7GcmI2NCZsbvFmHXAGcAYpxjx5BCbv8lHoSoTea6UYqVgA rYyrUwvfVTzmoBsdmdiX0I4rZJZ0O4b83D7mpJ9BVofjc1howBYreGOuFIsHCeBRCtcs c88g== X-Gm-Message-State: AOAM53125j1Gte7wFIKepqDzKR5+KteVMz3D2YiAuNHK6d9Bv/Bncv0t Rb9Nf9JB8yXciCrnJL4kV7jkJg== X-Received: by 2002:a19:3f85:: with SMTP id m127mr10683699lfa.648.1616843006538; Sat, 27 Mar 2021 04:03:26 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id a8sm1513801ljn.96.2021.03.27.04.03.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:26 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Jonathan Marek , Michael Turquette Subject: [PATCH v3 19/25] drm/msm/dsi: drop msm_dsi_pll abstracton Date: Sat, 27 Mar 2021 14:02:59 +0300 Message-Id: <20210327110305.3289784-20-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> References: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org, linux-clk@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Drop the struct msm_dsi_pll abstraction, by including vco's clk_hw directly into struct msm_dsi_phy. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Kconfig | 8 -- drivers/gpu/drm/msm/Makefile | 2 - drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 36 +++++--- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 66 ++++++++------- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 78 ++++++++--------- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 83 ++++++++++--------- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 65 ++++++++------- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 74 +++++++++-------- drivers/gpu/drm/msm/dsi/phy/dsi_pll.c | 23 ----- drivers/gpu/drm/msm/dsi/phy/dsi_pll.h | 44 ---------- 10 files changed, 221 insertions(+), 258 deletions(-) delete mode 100644 drivers/gpu/drm/msm/dsi/phy/dsi_pll.c delete mode 100644 drivers/gpu/drm/msm/dsi/phy/dsi_pll.h -- 2.30.2 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel Reviewed-by: Abhinav Kumar diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index dabb4a1ccdcf..1f0b3f0e7149 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -76,14 +76,6 @@ config DRM_MSM_DSI Choose this option if you have a need for MIPI DSI connector support. -config DRM_MSM_DSI_PLL - bool "Enable DSI PLL driver in MSM DRM" - depends on DRM_MSM_DSI && COMMON_CLK - default y - help - Choose this option to enable DSI PLL driver which provides DSI - source clocks under common clock framework. - config DRM_MSM_DSI_28NM_PHY bool "Enable DSI 28nm PHY driver in MSM DRM" depends on DRM_MSM_DSI diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 1be6996b80b7..610d630326bb 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -136,6 +136,4 @@ msm-$(CONFIG_DRM_MSM_DSI_14NM_PHY) += dsi/phy/dsi_phy_14nm.o msm-$(CONFIG_DRM_MSM_DSI_10NM_PHY) += dsi/phy/dsi_phy_10nm.o msm-$(CONFIG_DRM_MSM_DSI_7NM_PHY) += dsi/phy/dsi_phy_7nm.o -msm-$(CONFIG_DRM_MSM_DSI_PLL) += dsi/phy/dsi_pll.o - obj-$(CONFIG_DRM_MSM) += msm.o diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index fa09f4c2c071..4fe410c97d3a 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -7,6 +7,7 @@ #define __DSI_PHY_H__ #include +#include #include #include "dsi.h" @@ -14,15 +15,6 @@ #define dsi_phy_read(offset) msm_readl((offset)) #define dsi_phy_write(offset, data) msm_writel((data), (offset)) -struct msm_dsi_pll { - struct clk_hw clk_hw; - bool pll_on; - - const struct msm_dsi_phy_cfg *cfg; -}; - -#define hw_clk_to_pll(x) container_of(x, struct msm_dsi_pll, clk_hw) - struct msm_dsi_phy_ops { int (*pll_init)(struct msm_dsi_phy *phy); int (*enable)(struct msm_dsi_phy *phy, int src_pll_id, @@ -107,7 +99,8 @@ struct msm_dsi_phy { enum msm_dsi_phy_usecase usecase; bool regulator_ldo_mode; - struct msm_dsi_pll *pll; + struct clk_hw *vco_hw; + bool pll_on; struct clk_hw_onecell_data *provided_clocks; @@ -127,6 +120,27 @@ int msm_dsi_dphy_timing_calc_v4(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); +/* PLL accessors */ +static inline void pll_write(void __iomem *reg, u32 data) +{ + msm_writel(data, reg); +} + +static inline u32 pll_read(const void __iomem *reg) +{ + return msm_readl(reg); +} + +static inline void pll_write_udelay(void __iomem *reg, u32 data, u32 delay_us) +{ + pll_write(reg, data); + udelay(delay_us); +} + +static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns) +{ + pll_write((reg), data); + ndelay(delay_ns); +} #endif /* __DSI_PHY_H__ */ - diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 25fd4d860c4d..dec9beadddaa 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -7,7 +7,6 @@ #include #include -#include "dsi_pll.h" #include "dsi_phy.h" #include "dsi.xml.h" @@ -85,11 +84,13 @@ struct pll_10nm_cached_state { }; struct dsi_pll_10nm { - struct msm_dsi_pll base; + struct clk_hw clk_hw; int id; struct platform_device *pdev; + struct msm_dsi_phy *phy; + void __iomem *phy_cmn_mmio; void __iomem *mmio; @@ -104,11 +105,10 @@ struct dsi_pll_10nm { struct pll_10nm_cached_state cached_state; - enum msm_dsi_phy_usecase uc; struct dsi_pll_10nm *slave; }; -#define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, base) +#define to_pll_10nm(x) container_of(x, struct dsi_pll_10nm, clk_hw) /* * Global list of private DSI PLL struct pointers. We need this for Dual DSI @@ -302,8 +302,7 @@ static void dsi_pll_commit(struct dsi_pll_10nm *pll) static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->id, rate, parent_rate); @@ -390,8 +389,7 @@ static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll) static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); struct device *dev = &pll_10nm->pdev->dev; int rc; @@ -422,7 +420,7 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) goto error; } - pll->pll_on = true; + pll_10nm->phy->pll_on = true; dsi_pll_enable_global_clk(pll_10nm); if (pll_10nm->slave) @@ -446,8 +444,7 @@ static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll) static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); /* * To avoid any stray glitches while abruptly powering down the PLL @@ -463,14 +460,13 @@ static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw) } /* flush, ensure all register writes are done */ wmb(); - pll->pll_on = false; + pll_10nm->phy->pll_on = false; } static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); struct dsi_pll_config *config = &pll_10nm->pll_configuration; void __iomem *base = pll_10nm->mmio; u64 ref_clk = pll_10nm->vco_ref_clk_rate; @@ -506,8 +502,21 @@ static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, return (unsigned long)vco_rate; } +static long dsi_pll_10nm_clk_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate) +{ + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); + + if (rate < pll_10nm->phy->cfg->min_pll_rate) + return pll_10nm->phy->cfg->min_pll_rate; + else if (rate > pll_10nm->phy->cfg->max_pll_rate) + return pll_10nm->phy->cfg->max_pll_rate; + else + return rate; +} + static const struct clk_ops clk_ops_dsi_pll_10nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, + .round_rate = dsi_pll_10nm_clk_round_rate, .set_rate = dsi_pll_10nm_vco_set_rate, .recalc_rate = dsi_pll_10nm_vco_recalc_rate, .prepare = dsi_pll_10nm_vco_prepare, @@ -520,7 +529,7 @@ static const struct clk_ops clk_ops_dsi_pll_10nm_vco = { static void dsi_10nm_save_state(struct msm_dsi_phy *phy) { - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw); struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; void __iomem *phy_base = pll_10nm->phy_cmn_mmio; u32 cmn_clk_cfg0, cmn_clk_cfg1; @@ -543,7 +552,7 @@ static void dsi_10nm_save_state(struct msm_dsi_phy *phy) static int dsi_10nm_restore_state(struct msm_dsi_phy *phy) { - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw); struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; void __iomem *phy_base = pll_10nm->phy_cmn_mmio; u32 val; @@ -562,7 +571,7 @@ static int dsi_10nm_restore_state(struct msm_dsi_phy *phy) val |= cached->pll_mux; pll_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, val); - ret = dsi_pll_10nm_vco_set_rate(&phy->pll->clk_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); + ret = dsi_pll_10nm_vco_set_rate(phy->vco_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); if (ret) { DRM_DEV_ERROR(&pll_10nm->pdev->dev, "restore vco rate failed. ret=%d\n", ret); @@ -574,16 +583,15 @@ static int dsi_10nm_restore_state(struct msm_dsi_phy *phy) return 0; } -static int dsi_pll_10nm_set_usecase(struct msm_dsi_pll *pll, - enum msm_dsi_phy_usecase uc) +static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy) { - struct dsi_pll_10nm *pll_10nm = to_pll_10nm(pll); + struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw); void __iomem *base = pll_10nm->phy_cmn_mmio; u32 data = 0x0; /* internal PLL */ DBG("DSI PLL%d", pll_10nm->id); - switch (uc) { + switch (phy->usecase) { case MSM_DSI_PHY_STANDALONE: break; case MSM_DSI_PHY_MASTER: @@ -599,8 +607,6 @@ static int dsi_pll_10nm_set_usecase(struct msm_dsi_pll *pll, /* set PLL src */ pll_write(base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, (data << 2)); - pll_10nm->uc = uc; - return 0; } @@ -628,9 +634,9 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov DBG("DSI%d", pll_10nm->id); snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->id); - pll_10nm->base.clk_hw.init = &vco_init; + pll_10nm->clk_hw.init = &vco_init; - ret = devm_clk_hw_register(dev, &pll_10nm->base.clk_hw); + ret = devm_clk_hw_register(dev, &pll_10nm->clk_hw); if (ret) return ret; @@ -740,7 +746,6 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) struct platform_device *pdev = phy->pdev; int id = phy->id; struct dsi_pll_10nm *pll_10nm; - struct msm_dsi_pll *pll; int ret; pll_10nm = devm_kzalloc(&pdev->dev, sizeof(*pll_10nm), GFP_KERNEL); @@ -767,8 +772,7 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) spin_lock_init(&pll_10nm->postdiv_lock); - pll = &pll_10nm->base; - pll->cfg = phy->cfg; + pll_10nm->phy = phy; ret = pll_10nm_register(pll_10nm, phy->provided_clocks->hws); if (ret) { @@ -776,7 +780,7 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) return ret; } - phy->pll = pll; + phy->vco_hw = &pll_10nm->clk_hw; /* TODO: Remove this when we have proper display handover support */ msm_dsi_phy_save_state(phy); @@ -951,7 +955,7 @@ static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, /* Select full-rate mode */ dsi_phy_write(base + REG_DSI_10nm_PHY_CMN_CTRL_2, 0x40); - ret = dsi_pll_10nm_set_usecase(phy->pll, phy->usecase); + ret = dsi_10nm_set_usecase(phy); if (ret) { DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", __func__, ret); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index c7c462bfe96d..86f9aedd790f 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -8,7 +8,6 @@ #include #include "dsi_phy.h" -#include "dsi_pll.h" #include "dsi.xml.h" #define PHY_14NM_CKLN_IDX 4 @@ -114,7 +113,7 @@ struct pll_14nm_cached_state { }; struct dsi_pll_14nm { - struct msm_dsi_pll base; + struct clk_hw clk_hw; int id; struct platform_device *pdev; @@ -122,6 +121,8 @@ struct dsi_pll_14nm { void __iomem *phy_cmn_mmio; void __iomem *mmio; + struct msm_dsi_phy *phy; + struct dsi_pll_input in; struct dsi_pll_output out; @@ -133,11 +134,10 @@ struct dsi_pll_14nm { struct pll_14nm_cached_state cached_state; - enum msm_dsi_phy_usecase uc; struct dsi_pll_14nm *slave; }; -#define to_pll_14nm(x) container_of(x, struct dsi_pll_14nm, base) +#define to_pll_14nm(x) container_of(x, struct dsi_pll_14nm, clk_hw) /* * Private struct for N1/N2 post-divider clocks. These clocks are similar to @@ -564,8 +564,7 @@ static void pll_db_commit_14nm(struct dsi_pll_14nm *pll, static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw); struct dsi_pll_input *pin = &pll_14nm->in; struct dsi_pll_output *pout = &pll_14nm->out; @@ -600,7 +599,7 @@ static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, * don't lock the slave PLL. We just ensure that the PLL/PHY registers * of the master and slave are identical */ - if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { + if (pll_14nm->phy->usecase == MSM_DSI_PHY_MASTER) { struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; pll_db_commit_14nm(pll_14nm_slave, pin, pout); @@ -614,8 +613,7 @@ static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw); void __iomem *base = pll_14nm->mmio; u64 vco_rate, multiplier = BIT(20); u32 div_frac_start; @@ -654,15 +652,14 @@ static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw); void __iomem *base = pll_14nm->mmio; void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; bool locked; DBG(""); - if (unlikely(pll->pll_on)) + if (unlikely(pll_14nm->phy->pll_on)) return 0; pll_write(base + REG_DSI_14nm_PHY_PLL_VREF_CFG1, 0x10); @@ -677,29 +674,41 @@ static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) } DBG("DSI PLL lock success"); - pll->pll_on = true; + pll_14nm->phy->pll_on = true; return 0; } static void dsi_pll_14nm_vco_unprepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw); void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; DBG(""); - if (unlikely(!pll->pll_on)) + if (unlikely(!pll_14nm->phy->pll_on)) return; pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_PLL_CNTRL, 0); - pll->pll_on = false; + pll_14nm->phy->pll_on = false; +} + +static long dsi_pll_14nm_clk_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate) +{ + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw); + + if (rate < pll_14nm->phy->cfg->min_pll_rate) + return pll_14nm->phy->cfg->min_pll_rate; + else if (rate > pll_14nm->phy->cfg->max_pll_rate) + return pll_14nm->phy->cfg->max_pll_rate; + else + return rate; } static const struct clk_ops clk_ops_dsi_pll_14nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, + .round_rate = dsi_pll_14nm_clk_round_rate, .set_rate = dsi_pll_14nm_vco_set_rate, .recalc_rate = dsi_pll_14nm_vco_recalc_rate, .prepare = dsi_pll_14nm_vco_prepare, @@ -773,7 +782,7 @@ static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, /* If we're master in dual DSI mode, then the slave PLL's post-dividers * follow the master's post dividers */ - if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { + if (pll_14nm->phy->usecase == MSM_DSI_PHY_MASTER) { struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; @@ -797,7 +806,7 @@ static const struct clk_ops clk_ops_dsi_pll_14nm_postdiv = { static void dsi_14nm_save_state(struct msm_dsi_phy *phy) { - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->pll); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw); struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; u32 data; @@ -810,18 +819,18 @@ static void dsi_14nm_save_state(struct msm_dsi_phy *phy) DBG("DSI%d PLL save state %x %x", pll_14nm->id, cached_state->n1postdiv, cached_state->n2postdiv); - cached_state->vco_rate = clk_hw_get_rate(&phy->pll->clk_hw); + cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw); } static int dsi_14nm_restore_state(struct msm_dsi_phy *phy) { - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->pll); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw); struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; u32 data; int ret; - ret = dsi_pll_14nm_vco_set_rate(&phy->pll->clk_hw, + ret = dsi_pll_14nm_vco_set_rate(phy->vco_hw, cached_state->vco_rate, 0); if (ret) { DRM_DEV_ERROR(&pll_14nm->pdev->dev, @@ -837,7 +846,7 @@ static int dsi_14nm_restore_state(struct msm_dsi_phy *phy) pll_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); /* also restore post-dividers for slave DSI PLL */ - if (pll_14nm->uc == MSM_DSI_PHY_MASTER) { + if (phy->usecase == MSM_DSI_PHY_MASTER) { struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; @@ -847,14 +856,13 @@ static int dsi_14nm_restore_state(struct msm_dsi_phy *phy) return 0; } -static int dsi_pll_14nm_set_usecase(struct msm_dsi_pll *pll, - enum msm_dsi_phy_usecase uc) +static int dsi_14nm_set_usecase(struct msm_dsi_phy *phy) { - struct dsi_pll_14nm *pll_14nm = to_pll_14nm(pll); + struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw); void __iomem *base = pll_14nm->mmio; u32 clkbuflr_en, bandgap = 0; - switch (uc) { + switch (phy->usecase) { case MSM_DSI_PHY_STANDALONE: clkbuflr_en = 0x1; break; @@ -874,8 +882,6 @@ static int dsi_pll_14nm_set_usecase(struct msm_dsi_pll *pll, if (bandgap) pll_write(base + REG_DSI_14nm_PHY_PLL_PLL_BANDGAP, bandgap); - pll_14nm->uc = uc; - return 0; } @@ -932,9 +938,9 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov DBG("DSI%d", pll_14nm->id); snprintf(vco_name, 32, "dsi%dvco_clk", pll_14nm->id); - pll_14nm->base.clk_hw.init = &vco_init; + pll_14nm->clk_hw.init = &vco_init; - ret = devm_clk_hw_register(dev, &pll_14nm->base.clk_hw); + ret = devm_clk_hw_register(dev, &pll_14nm->clk_hw); if (ret) return ret; @@ -990,7 +996,6 @@ static int dsi_pll_14nm_init(struct msm_dsi_phy *phy) struct platform_device *pdev = phy->pdev; int id = phy->id; struct dsi_pll_14nm *pll_14nm; - struct msm_dsi_pll *pll; int ret; if (!pdev) @@ -1020,8 +1025,7 @@ static int dsi_pll_14nm_init(struct msm_dsi_phy *phy) spin_lock_init(&pll_14nm->postdiv_lock); - pll = &pll_14nm->base; - pll->cfg = phy->cfg; + pll_14nm->phy = phy; ret = pll_14nm_register(pll_14nm, phy->provided_clocks->hws); if (ret) { @@ -1029,7 +1033,7 @@ static int dsi_pll_14nm_init(struct msm_dsi_phy *phy) return ret; } - phy->pll = pll; + phy->vco_hw = &pll_14nm->clk_hw; return 0; } @@ -1131,7 +1135,7 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL); - ret = dsi_pll_14nm_set_usecase(phy->pll, phy->usecase); + ret = dsi_14nm_set_usecase(phy); if (ret) { DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", __func__, ret); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index bfd110eb25fc..1b95ea75235c 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -7,7 +7,6 @@ #include #include "dsi_phy.h" -#include "dsi_pll.h" #include "dsi.xml.h" /* @@ -66,16 +65,19 @@ struct pll_28nm_cached_state { }; struct dsi_pll_28nm { - struct msm_dsi_pll base; + struct clk_hw clk_hw; int id; struct platform_device *pdev; + + struct msm_dsi_phy *phy; + void __iomem *mmio; struct pll_28nm_cached_state cached_state; }; -#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base) +#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, clk_hw) static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, u32 nb_tries, u32 timeout_us) @@ -116,8 +118,7 @@ static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm) static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); struct device *dev = &pll_28nm->pdev->dev; void __iomem *base = pll_28nm->mmio; unsigned long div_fbx1000, gen_vco_clk; @@ -210,7 +211,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, pll_write(base + REG_DSI_28nm_PHY_PLL_SDM_CFG4, 0x00); /* Add hardware recommended delay for correct PLL configuration */ - if (pll->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) + if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) udelay(1000); else udelay(1); @@ -233,8 +234,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS, POLL_TIMEOUT_US); @@ -243,8 +243,7 @@ static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); void __iomem *base = pll_28nm->mmio; u32 sdm0, doubler, sdm_byp_div; u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3; @@ -289,9 +288,8 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, return vco_rate; } -static int _dsi_pll_28nm_vco_prepare_hpm(struct msm_dsi_pll *pll) +static int _dsi_pll_28nm_vco_prepare_hpm(struct dsi_pll_28nm *pll_28nm) { - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); struct device *dev = &pll_28nm->pdev->dev; void __iomem *base = pll_28nm->mmio; u32 max_reads = 5, timeout_us = 100; @@ -366,16 +364,16 @@ static int _dsi_pll_28nm_vco_prepare_hpm(struct msm_dsi_pll *pll) static int dsi_pll_28nm_vco_prepare_hpm(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); int i, ret; - if (unlikely(pll->pll_on)) + if (unlikely(pll_28nm->phy->pll_on)) return 0; for (i = 0; i < 3; i++) { - ret = _dsi_pll_28nm_vco_prepare_hpm(pll); + ret = _dsi_pll_28nm_vco_prepare_hpm(pll_28nm); if (!ret) { - pll->pll_on = true; + pll_28nm->phy->pll_on = true; return 0; } } @@ -385,8 +383,7 @@ static int dsi_pll_28nm_vco_prepare_hpm(struct clk_hw *hw) static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); struct device *dev = &pll_28nm->pdev->dev; void __iomem *base = pll_28nm->mmio; bool locked; @@ -395,7 +392,7 @@ static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw) DBG("id=%d", pll_28nm->id); - if (unlikely(pll->pll_on)) + if (unlikely(pll_28nm->phy->pll_on)) return 0; pll_28nm_software_reset(pll_28nm); @@ -428,28 +425,40 @@ static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw) } DBG("DSI PLL lock success"); - pll->pll_on = true; + pll_28nm->phy->pll_on = true; return 0; } static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); DBG("id=%d", pll_28nm->id); - if (unlikely(!pll->pll_on)) + if (unlikely(!pll_28nm->phy->pll_on)) return; pll_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00); - pll->pll_on = false; + pll_28nm->phy->pll_on = false; +} + +static long dsi_pll_28nm_clk_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); + + if (rate < pll_28nm->phy->cfg->min_pll_rate) + return pll_28nm->phy->cfg->min_pll_rate; + else if (rate > pll_28nm->phy->cfg->max_pll_rate) + return pll_28nm->phy->cfg->max_pll_rate; + else + return rate; } static const struct clk_ops clk_ops_dsi_pll_28nm_vco_hpm = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, + .round_rate = dsi_pll_28nm_clk_round_rate, .set_rate = dsi_pll_28nm_clk_set_rate, .recalc_rate = dsi_pll_28nm_clk_recalc_rate, .prepare = dsi_pll_28nm_vco_prepare_hpm, @@ -458,7 +467,7 @@ static const struct clk_ops clk_ops_dsi_pll_28nm_vco_hpm = { }; static const struct clk_ops clk_ops_dsi_pll_28nm_vco_lp = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, + .round_rate = dsi_pll_28nm_clk_round_rate, .set_rate = dsi_pll_28nm_clk_set_rate, .recalc_rate = dsi_pll_28nm_clk_recalc_rate, .prepare = dsi_pll_28nm_vco_prepare_lp, @@ -472,7 +481,7 @@ static const struct clk_ops clk_ops_dsi_pll_28nm_vco_lp = { static void dsi_28nm_save_state(struct msm_dsi_phy *phy) { - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; void __iomem *base = pll_28nm->mmio; @@ -481,20 +490,20 @@ static void dsi_28nm_save_state(struct msm_dsi_phy *phy) cached_state->postdiv1 = pll_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG); cached_state->byte_mux = pll_read(base + REG_DSI_28nm_PHY_PLL_VREG_CFG); - if (dsi_pll_28nm_clk_is_enabled(&phy->pll->clk_hw)) - cached_state->vco_rate = clk_hw_get_rate(&phy->pll->clk_hw); + if (dsi_pll_28nm_clk_is_enabled(phy->vco_hw)) + cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw); else cached_state->vco_rate = 0; } static int dsi_28nm_restore_state(struct msm_dsi_phy *phy) { - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; void __iomem *base = pll_28nm->mmio; int ret; - ret = dsi_pll_28nm_clk_set_rate(&phy->pll->clk_hw, + ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw, cached_state->vco_rate, 0); if (ret) { DRM_DEV_ERROR(&pll_28nm->pdev->dev, @@ -527,14 +536,14 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov DBG("%d", pll_28nm->id); - if (pll_28nm->base.cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) + if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) vco_init.ops = &clk_ops_dsi_pll_28nm_vco_lp; else vco_init.ops = &clk_ops_dsi_pll_28nm_vco_hpm; snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); - pll_28nm->base.clk_hw.init = &vco_init; - ret = devm_clk_hw_register(dev, &pll_28nm->base.clk_hw); + pll_28nm->clk_hw.init = &vco_init; + ret = devm_clk_hw_register(dev, &pll_28nm->clk_hw); if (ret) return ret; @@ -593,7 +602,6 @@ static int dsi_pll_28nm_init(struct msm_dsi_phy *phy) struct platform_device *pdev = phy->pdev; int id = phy->id; struct dsi_pll_28nm *pll_28nm; - struct msm_dsi_pll *pll; int ret; if (!pdev) @@ -612,8 +620,7 @@ static int dsi_pll_28nm_init(struct msm_dsi_phy *phy) return -ENOMEM; } - pll = &pll_28nm->base; - pll->cfg = phy->cfg; + pll_28nm->phy = phy; ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws); if (ret) { @@ -621,7 +628,7 @@ static int dsi_pll_28nm_init(struct msm_dsi_phy *phy) return ret; } - phy->pll = pll; + phy->vco_hw = &pll_28nm->clk_hw; return 0; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index c71c5f07666d..3e63a3b70818 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -7,7 +7,6 @@ #include #include "dsi_phy.h" -#include "dsi_pll.h" #include "dsi.xml.h" /* @@ -58,16 +57,19 @@ struct clk_bytediv { }; struct dsi_pll_28nm { - struct msm_dsi_pll base; + struct clk_hw clk_hw; int id; struct platform_device *pdev; + + struct msm_dsi_phy *phy; + void __iomem *mmio; struct pll_28nm_cached_state cached_state; }; -#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, base) +#define to_pll_28nm(x) container_of(x, struct dsi_pll_28nm, clk_hw) static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, int nb_tries, int timeout_us) @@ -95,8 +97,7 @@ static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); void __iomem *base = pll_28nm->mmio; u32 val, temp, fb_divider; @@ -136,8 +137,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); return pll_28nm_poll_for_ready(pll_28nm, POLL_MAX_READS, POLL_TIMEOUT_US); @@ -146,8 +146,7 @@ static int dsi_pll_28nm_clk_is_enabled(struct clk_hw *hw) static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); void __iomem *base = pll_28nm->mmio; unsigned long vco_rate; u32 status, fb_divider, temp, ref_divider; @@ -180,8 +179,7 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); struct device *dev = &pll_28nm->pdev->dev; void __iomem *base = pll_28nm->mmio; bool locked; @@ -191,7 +189,7 @@ static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw) DBG("id=%d", pll_28nm->id); - if (unlikely(pll->pll_on)) + if (unlikely(pll_28nm->phy->pll_on)) return 0; /* @@ -222,28 +220,40 @@ static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw) } DBG("DSI PLL lock success"); - pll->pll_on = true; + pll_28nm->phy->pll_on = true; return 0; } static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); DBG("id=%d", pll_28nm->id); - if (unlikely(!pll->pll_on)) + if (unlikely(!pll_28nm->phy->pll_on)) return; pll_write(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00); - pll->pll_on = false; + pll_28nm->phy->pll_on = false; +} + +static long dsi_pll_28nm_clk_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate) +{ + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); + + if (rate < pll_28nm->phy->cfg->min_pll_rate) + return pll_28nm->phy->cfg->min_pll_rate; + else if (rate > pll_28nm->phy->cfg->max_pll_rate) + return pll_28nm->phy->cfg->max_pll_rate; + else + return rate; } static const struct clk_ops clk_ops_dsi_pll_28nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, + .round_rate = dsi_pll_28nm_clk_round_rate, .set_rate = dsi_pll_28nm_clk_set_rate, .recalc_rate = dsi_pll_28nm_clk_recalc_rate, .prepare = dsi_pll_28nm_vco_prepare, @@ -336,7 +346,7 @@ static const struct clk_ops clk_bytediv_ops = { */ static void dsi_28nm_save_state(struct msm_dsi_phy *phy) { - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; void __iomem *base = pll_28nm->mmio; @@ -347,17 +357,17 @@ static void dsi_28nm_save_state(struct msm_dsi_phy *phy) cached_state->postdiv1 = pll_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_8); - cached_state->vco_rate = clk_hw_get_rate(&phy->pll->clk_hw); + cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw); } static int dsi_28nm_restore_state(struct msm_dsi_phy *phy) { - struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->pll); + struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; void __iomem *base = pll_28nm->mmio; int ret; - ret = dsi_pll_28nm_clk_set_rate(&phy->pll->clk_hw, + ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw, cached_state->vco_rate, 0); if (ret) { DRM_DEV_ERROR(&pll_28nm->pdev->dev, @@ -407,9 +417,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); vco_init.name = vco_name; - pll_28nm->base.clk_hw.init = &vco_init; + pll_28nm->clk_hw.init = &vco_init; - ret = devm_clk_hw_register(dev, &pll_28nm->base.clk_hw); + ret = devm_clk_hw_register(dev, &pll_28nm->clk_hw); if (ret) return ret; @@ -450,7 +460,6 @@ static int dsi_pll_28nm_8960_init(struct msm_dsi_phy *phy) struct platform_device *pdev = phy->pdev; int id = phy->id; struct dsi_pll_28nm *pll_28nm; - struct msm_dsi_pll *pll; int ret; if (!pdev) @@ -469,9 +478,7 @@ static int dsi_pll_28nm_8960_init(struct msm_dsi_phy *phy) return -ENOMEM; } - pll = &pll_28nm->base; - - pll->cfg = phy->cfg; + pll_28nm->phy = phy; ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws); if (ret) { @@ -479,7 +486,7 @@ static int dsi_pll_28nm_8960_init(struct msm_dsi_phy *phy) return ret; } - phy->pll = pll; + phy->vco_hw = &pll_28nm->clk_hw; return 0; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index 015e099d7b7f..c922e46f5241 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -7,7 +7,6 @@ #include #include -#include "dsi_pll.h" #include "dsi_phy.h" #include "dsi.xml.h" @@ -85,11 +84,13 @@ struct pll_7nm_cached_state { }; struct dsi_pll_7nm { - struct msm_dsi_pll base; + struct clk_hw clk_hw; int id; struct platform_device *pdev; + struct msm_dsi_phy *phy; + void __iomem *phy_cmn_mmio; void __iomem *mmio; @@ -104,11 +105,10 @@ struct dsi_pll_7nm { struct pll_7nm_cached_state cached_state; - enum msm_dsi_phy_usecase uc; struct dsi_pll_7nm *slave; }; -#define to_pll_7nm(x) container_of(x, struct dsi_pll_7nm, base) +#define to_pll_7nm(x) container_of(x, struct dsi_pll_7nm, clk_hw) /* * Global list of private DSI PLL struct pointers. We need this for Dual DSI @@ -164,7 +164,7 @@ static void dsi_pll_calc_dec_frac(struct dsi_pll_7nm *pll) dec = div_u64(dec_multiple, multiplier); - if (!(pll->base.cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1)) + if (!(pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1)) regs->pll_clock_inverters = 0x28; else if (pll_freq <= 1000000000ULL) regs->pll_clock_inverters = 0xa0; @@ -259,7 +259,7 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll) void __iomem *base = pll->mmio; u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00; - if (pll->base.cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) { + if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) { if (pll->vco_current_rate >= 3100000000ULL) analog_controls_five_1 = 0x03; @@ -293,9 +293,9 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll) pll_write(base + REG_DSI_7nm_PHY_PLL_PFILT, 0x2f); pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT, 0x2a); pll_write(base + REG_DSI_7nm_PHY_PLL_IFILT, - pll->base.cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1 ? 0x3f : 0x22); + pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1 ? 0x3f : 0x22); - if (pll->base.cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) { + if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) { pll_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); if (pll->slave) pll_write(pll->slave->mmio + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); @@ -321,8 +321,7 @@ static void dsi_pll_commit(struct dsi_pll_7nm *pll) static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw); DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->id, rate, parent_rate); @@ -420,8 +419,7 @@ static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll) static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw); int rc; dsi_pll_enable_pll_bias(pll_7nm); @@ -444,7 +442,7 @@ static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) goto error; } - pll->pll_on = true; + pll_7nm->phy->pll_on = true; /* * assert power on reset for PHY digital in case the PLL is @@ -471,8 +469,7 @@ static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll) static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw); /* * To avoid any stray glitches while abruptly powering down the PLL @@ -488,14 +485,13 @@ static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw) } /* flush, ensure all register writes are done */ wmb(); - pll->pll_on = false; + pll_7nm->phy->pll_on = false; } static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw); struct dsi_pll_config *config = &pll_7nm->pll_configuration; void __iomem *base = pll_7nm->mmio; u64 ref_clk = pll_7nm->vco_ref_clk_rate; @@ -531,8 +527,21 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, return (unsigned long)vco_rate; } +static long dsi_pll_7nm_clk_round_rate(struct clk_hw *hw, + unsigned long rate, unsigned long *parent_rate) +{ + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw); + + if (rate < pll_7nm->phy->cfg->min_pll_rate) + return pll_7nm->phy->cfg->min_pll_rate; + else if (rate > pll_7nm->phy->cfg->max_pll_rate) + return pll_7nm->phy->cfg->max_pll_rate; + else + return rate; +} + static const struct clk_ops clk_ops_dsi_pll_7nm_vco = { - .round_rate = msm_dsi_pll_helper_clk_round_rate, + .round_rate = dsi_pll_7nm_clk_round_rate, .set_rate = dsi_pll_7nm_vco_set_rate, .recalc_rate = dsi_pll_7nm_vco_recalc_rate, .prepare = dsi_pll_7nm_vco_prepare, @@ -545,7 +554,7 @@ static const struct clk_ops clk_ops_dsi_pll_7nm_vco = { static void dsi_7nm_save_state(struct msm_dsi_phy *phy) { - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->pll); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; void __iomem *phy_base = pll_7nm->phy_cmn_mmio; u32 cmn_clk_cfg0, cmn_clk_cfg1; @@ -568,7 +577,7 @@ static void dsi_7nm_save_state(struct msm_dsi_phy *phy) static int dsi_7nm_restore_state(struct msm_dsi_phy *phy) { - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->pll); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; void __iomem *phy_base = pll_7nm->phy_cmn_mmio; u32 val; @@ -587,7 +596,7 @@ static int dsi_7nm_restore_state(struct msm_dsi_phy *phy) val |= cached->pll_mux; pll_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, val); - ret = dsi_pll_7nm_vco_set_rate(&phy->pll->clk_hw, pll_7nm->vco_current_rate, pll_7nm->vco_ref_clk_rate); + ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw, pll_7nm->vco_current_rate, pll_7nm->vco_ref_clk_rate); if (ret) { DRM_DEV_ERROR(&pll_7nm->pdev->dev, "restore vco rate failed. ret=%d\n", ret); @@ -599,16 +608,15 @@ static int dsi_7nm_restore_state(struct msm_dsi_phy *phy) return 0; } -static int dsi_pll_7nm_set_usecase(struct msm_dsi_pll *pll, - enum msm_dsi_phy_usecase uc) +static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) { - struct dsi_pll_7nm *pll_7nm = to_pll_7nm(pll); + struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); void __iomem *base = pll_7nm->phy_cmn_mmio; u32 data = 0x0; /* internal PLL */ DBG("DSI PLL%d", pll_7nm->id); - switch (uc) { + switch (phy->usecase) { case MSM_DSI_PHY_STANDALONE: break; case MSM_DSI_PHY_MASTER: @@ -624,8 +632,6 @@ static int dsi_pll_7nm_set_usecase(struct msm_dsi_pll *pll, /* set PLL src */ pll_write(base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, (data << 2)); - pll_7nm->uc = uc; - return 0; } @@ -653,9 +659,9 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide DBG("DSI%d", pll_7nm->id); snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->id); - pll_7nm->base.clk_hw.init = &vco_init; + pll_7nm->clk_hw.init = &vco_init; - ret = devm_clk_hw_register(dev, &pll_7nm->base.clk_hw); + ret = devm_clk_hw_register(dev, &pll_7nm->clk_hw); if (ret) return ret; @@ -765,7 +771,6 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) struct platform_device *pdev = phy->pdev; int id = phy->id; struct dsi_pll_7nm *pll_7nm; - struct msm_dsi_pll *pll; int ret; pll_7nm = devm_kzalloc(&pdev->dev, sizeof(*pll_7nm), GFP_KERNEL); @@ -792,8 +797,7 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) spin_lock_init(&pll_7nm->postdiv_lock); - pll = &pll_7nm->base; - pll->cfg = phy->cfg; + pll_7nm->phy = phy; ret = pll_7nm_register(pll_7nm, phy->provided_clocks->hws); if (ret) { @@ -801,7 +805,7 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) return ret; } - phy->pll = pll; + phy->vco_hw = &pll_7nm->clk_hw; /* TODO: Remove this when we have proper display handover support */ msm_dsi_phy_save_state(phy); @@ -966,7 +970,7 @@ static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, /* Select full-rate mode */ dsi_phy_write(base + REG_DSI_7nm_PHY_CMN_CTRL_2, 0x40); - ret = dsi_pll_7nm_set_usecase(phy->pll, phy->usecase); + ret = dsi_7nm_set_usecase(phy); if (ret) { DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", __func__, ret); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c deleted file mode 100644 index cae668b669a4..000000000000 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.c +++ /dev/null @@ -1,23 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. - */ - -#include "dsi_phy.h" -#include "dsi_pll.h" - -/* - * DSI PLL Helper functions - */ -long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw, - unsigned long rate, unsigned long *parent_rate) -{ - struct msm_dsi_pll *pll = hw_clk_to_pll(hw); - - if (rate < pll->cfg->min_pll_rate) - return pll->cfg->min_pll_rate; - else if (rate > pll->cfg->max_pll_rate) - return pll->cfg->max_pll_rate; - else - return rate; -} diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h b/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h deleted file mode 100644 index da83e4c11f4f..000000000000 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_pll.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright (c) 2012-2015, The Linux Foundation. All rights reserved. - */ - -#ifndef __DSI_PLL_H__ -#define __DSI_PLL_H__ - -#include - -#include "dsi.h" - -static inline void pll_write(void __iomem *reg, u32 data) -{ - msm_writel(data, reg); -} - -static inline u32 pll_read(const void __iomem *reg) -{ - return msm_readl(reg); -} - -static inline void pll_write_udelay(void __iomem *reg, u32 data, u32 delay_us) -{ - pll_write(reg, data); - udelay(delay_us); -} - -static inline void pll_write_ndelay(void __iomem *reg, u32 data, u32 delay_ns) -{ - pll_write((reg), data); - ndelay(delay_ns); -} - -/* - * DSI PLL Helper functions - */ - -/* clock callbacks */ -long msm_dsi_pll_helper_clk_round_rate(struct clk_hw *hw, - unsigned long rate, unsigned long *parent_rate); - -#endif /* __DSI_PLL_H__ */ - From patchwork Sat Mar 27 11:03:01 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 410149 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2161099jai; Sat, 27 Mar 2021 04:04:02 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxDU7NegvPuFfgA8WU+ZvUuaHVRoYyptTf4H+TjZ1fmC18eu6MZ+jgc3M/eWC8eS8NMVeHc X-Received: by 2002:a62:e708:0:b029:1f8:c092:ff93 with SMTP id s8-20020a62e7080000b02901f8c092ff93mr16637410pfh.21.1616843042059; Sat, 27 Mar 2021 04:04:02 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616843042; cv=none; d=google.com; s=arc-20160816; b=tV6OhYAOiBkvoOTDL+ozxKnzY6VrdqKCEEPzx4YZdXlaZ8513Xw9rbwrlAr/qrw4G4 TXZ31hCdzDwBiSrTD3SZANvGP4qbKHjqgWtGKpEZ8oZOfEWnWdEoDRnxJOTVem0SVjzJ pLmb/FO/ksLOR6s63NKzVr2Tq3nOQA4f31nEeTsVShpMkbOfY1YyR/aAPBEbfVfS0pYP lZut0KzQWhwG9X+nqHhoxjvGUqD71Qk1u0PaRIKDaI9FxF4BOlMs5no9fPqiQ12sVUFy zCvkA35tvefCSIBJYPytbh/rR8EmGkTRwyKxtTE+noJ4QRpNFa0GKUWM4D+rhVdXvtn5 MtZA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:mime-version:references:in-reply-to:message-id:date :subject:to:from:dkim-signature:delivered-to; bh=7eJv4q9JbQjBuikoSfu59gSon//OUknGMWrMPKqLdAo=; b=eeYYGDd3PVM8jXzn4+srPgbP3m0p1nBEAecJp+EmOrJi8Mr2qtaRrumSsBJLomq3gL ioKYjWiL2gDLO4P6nUslrSSZOvsoqAmYzWG2lucf6vaGvwVhTdMGat3XAr0abklOqgRH 5YlcFAdmwgqOSPE/DLIodyIrWYM41+8rXfpO/Bvn4DQuvTWzM9oQDmpMyHnfuypsp5CM gVGRbqtGzRPdzbHvMJWSwC/+ezGpAX6n0hELxUWS8uoMEn3BsZ1I+KBv7KvI9LzsMjGc QFqK16hT5PXxvc1PxgdW5JG5De0JG4YFb9Z2JaVVDKk24qz0RY7hDna3FFrHV5EOFEZm 6I6A== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=tq5f83X8; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id 23si16271307pjx.137.2021.03.27.04.04.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:04:02 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=tq5f83X8; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 13EF26F550; Sat, 27 Mar 2021 11:03:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf1-x12d.google.com (mail-lf1-x12d.google.com [IPv6:2a00:1450:4864:20::12d]) by gabe.freedesktop.org (Postfix) with ESMTPS id 358986F537 for ; Sat, 27 Mar 2021 11:03:30 +0000 (UTC) Received: by mail-lf1-x12d.google.com with SMTP id o10so11464955lfb.9 for ; Sat, 27 Mar 2021 04:03:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=a2KY4XfBGMxiJrOVObHkY7WmIQm7DjGK52CozDQR2B8=; b=tq5f83X8Amu7d2LHnde6jHDHER7PkCOADKRImOQOFV9R0zdMPNfixgAmjltDIc/ryq KL8ge4Pa4pJhRnWcV8Kc8R4wRqQVUjAnqkY7KetKhuJzb5q5U6MV8gzF/+MyZChdPLt1 YMYtHWZK3SCokvmXQpBLMd0NykSS+3CD8lqJUcSA0YJn+1ZuRH4O4XTHn6t8u6rdLkjx KixtjSXozxpYEXvTcd0X/V6+oyllBpjFlUj95IAAsa3I0Nl1zBIL58dkrWIz0DO4oaAS +em9u7tAtoWJ7fsamc/2KFyQBZm0NFSyEy2ZsT9iOO60oZwXxLmckE2QBYg/ujkM6i9B 9tCw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=a2KY4XfBGMxiJrOVObHkY7WmIQm7DjGK52CozDQR2B8=; b=uDeRY9FxCAqq01BC4+nyDiv947em6z5mOKqCkhOhLwp8u+UyYyhjLEXp53TQd0KUqQ 6By+dnO5S2EmtYzVav6InDd3kOjMTRN6/yfJp+nC9pTBkISnWHtDzWfZXnMGQMn3tuAB HQKttUKwwIc+Pxcos1TdHPrz8ZWUxMw4r2nRADwHdbZWoxm77MoGtX3reaqnRK64Fm26 nLuEexjg6Ls5dfwOlUEecaKTiXDiKotEtdcG7Nte/dpQycA3TaVfUI93ujGlb4HZvZYV VGCpBj0WFiov4vokpe8LrAHMN3+pICCi+i9Q72N0lcjgYhHOm6pTcofoLXrGTiXVbjzG 0BXQ== X-Gm-Message-State: AOAM531lhISP3dEL7FJEpNWWjLZm3iy8q4t5r0vpMgUzVeoXbRqDIAzm AiL1JRQZ8pKHk1DHges8FYoAyg== X-Received: by 2002:a05:6512:2386:: with SMTP id c6mr10388637lfv.142.1616843008223; Sat, 27 Mar 2021 04:03:28 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id a8sm1513801ljn.96.2021.03.27.04.03.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:27 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Jonathan Marek , Michael Turquette Subject: [PATCH v3 21/25] drm/msm/dsi: move ioremaps to dsi_phy_driver_probe Date: Sat, 27 Mar 2021 14:03:01 +0300 Message-Id: <20210327110305.3289784-22-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> References: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org, linux-clk@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" All PHY drivers would map dsi_pll area. Some PHY drivers would also map dsi_phy area again (a leftover from old PHY/PLL separation). Move all ioremaps to the common dsi_phy driver code and drop individual ioremapped areas from PHY drivers. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 7 ++ drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 1 + drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 75 +++++++----------- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 49 ++++-------- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 33 +++----- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 27 +++---- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 79 ++++++++----------- 7 files changed, 108 insertions(+), 163 deletions(-) -- 2.30.2 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel Reviewed-by: Abhinav Kumar diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index f21f3babec68..74cc11c84d71 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -682,6 +682,13 @@ static int dsi_phy_driver_probe(struct platform_device *pdev) goto fail; } + phy->pll_base = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); + if (IS_ERR(phy->pll_base)) { + DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); + ret = -ENOMEM; + goto fail; + } + if (phy->cfg->has_phy_lane) { phy->lane_base = msm_ioremap(pdev, "dsi_phy_lane", "DSI_PHY_LANE"); if (IS_ERR(phy->lane_base)) { diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index d7031a35e2da..8e828c5ca8f4 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -88,6 +88,7 @@ struct msm_dsi_dphy_timing { struct msm_dsi_phy { struct platform_device *pdev; void __iomem *base; + void __iomem *pll_base; void __iomem *reg_base; void __iomem *lane_base; int id; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 73afbb597a9f..8a15ae91d44b 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -91,9 +91,6 @@ struct dsi_pll_10nm { struct msm_dsi_phy *phy; - void __iomem *phy_cmn_mmio; - void __iomem *mmio; - u64 vco_ref_clk_rate; u64 vco_current_rate; @@ -228,7 +225,7 @@ static void dsi_pll_calc_ssc(struct dsi_pll_10nm *pll) static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; struct dsi_pll_regs *regs = &pll->reg_setup; if (pll->pll_configuration.enable_ssc) { @@ -253,7 +250,7 @@ static void dsi_pll_ssc_commit(struct dsi_pll_10nm *pll) static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_ONE, 0x80); dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_ANALOG_CONTROLS_TWO, 0x03); @@ -279,7 +276,7 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_10nm *pll) static void dsi_pll_commit(struct dsi_pll_10nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; struct dsi_pll_regs *reg = &pll->reg_setup; dsi_phy_write(base + REG_DSI_10nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); @@ -336,7 +333,7 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) u32 const delay_us = 100; u32 const timeout_us = 5000; - rc = readl_poll_timeout_atomic(pll->mmio + + rc = readl_poll_timeout_atomic(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_COMMON_STATUS_ONE, status, ((status & BIT(0)) > 0), @@ -351,21 +348,21 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) static void dsi_pll_disable_pll_bias(struct dsi_pll_10nm *pll) { - u32 data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0); + u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); - dsi_phy_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0, + dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0); + dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0, data & ~BIT(5)); ndelay(250); } static void dsi_pll_enable_pll_bias(struct dsi_pll_10nm *pll) { - u32 data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0); + u32 data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CTRL_0, + dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CTRL_0, data | BIT(5)); - dsi_phy_write(pll->mmio + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0); + dsi_phy_write(pll->phy->pll_base + REG_DSI_10nm_PHY_PLL_SYSTEM_MUXES, 0xc0); ndelay(250); } @@ -373,8 +370,8 @@ static void dsi_pll_disable_global_clk(struct dsi_pll_10nm *pll) { u32 data; - data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1, + data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, data & ~BIT(5)); } @@ -382,8 +379,8 @@ static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll) { u32 data; - data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_CLK_CFG1, + data = dsi_phy_read(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1); + dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, data | BIT(5)); } @@ -404,7 +401,7 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) } /* Start PLL */ - dsi_phy_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, + dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0x01); /* @@ -426,10 +423,10 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) if (pll_10nm->slave) dsi_pll_enable_global_clk(pll_10nm->slave); - dsi_phy_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, + dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01); if (pll_10nm->slave) - dsi_phy_write(pll_10nm->slave->phy_cmn_mmio + + dsi_phy_write(pll_10nm->slave->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0x01); error: @@ -438,7 +435,7 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) static void dsi_pll_disable_sub(struct dsi_pll_10nm *pll) { - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0); + dsi_phy_write(pll->phy->base + REG_DSI_10nm_PHY_CMN_RBUF_CTRL, 0); dsi_pll_disable_pll_bias(pll); } @@ -452,7 +449,7 @@ static void dsi_pll_10nm_vco_unprepare(struct clk_hw *hw) * powering down the PLL */ dsi_pll_disable_global_clk(pll_10nm); - dsi_phy_write(pll_10nm->phy_cmn_mmio + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0); + dsi_phy_write(pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_PLL_CNTRL, 0); dsi_pll_disable_sub(pll_10nm); if (pll_10nm->slave) { dsi_pll_disable_global_clk(pll_10nm->slave); @@ -468,7 +465,7 @@ static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, { struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); struct dsi_pll_config *config = &pll_10nm->pll_configuration; - void __iomem *base = pll_10nm->mmio; + void __iomem *base = pll_10nm->phy->pll_base; u64 ref_clk = pll_10nm->vco_ref_clk_rate; u64 vco_rate = 0x0; u64 multiplier; @@ -531,10 +528,10 @@ static void dsi_10nm_save_state(struct msm_dsi_phy *phy) { struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw); struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; - void __iomem *phy_base = pll_10nm->phy_cmn_mmio; + void __iomem *phy_base = pll_10nm->phy->base; u32 cmn_clk_cfg0, cmn_clk_cfg1; - cached->pll_out_div = dsi_phy_read(pll_10nm->mmio + + cached->pll_out_div = dsi_phy_read(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); cached->pll_out_div &= 0x3; @@ -554,14 +551,14 @@ static int dsi_10nm_restore_state(struct msm_dsi_phy *phy) { struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw); struct pll_10nm_cached_state *cached = &pll_10nm->cached_state; - void __iomem *phy_base = pll_10nm->phy_cmn_mmio; + void __iomem *phy_base = pll_10nm->phy->base; u32 val; int ret; - val = dsi_phy_read(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); + val = dsi_phy_read(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE); val &= ~0x3; val |= cached->pll_out_div; - dsi_phy_write(pll_10nm->mmio + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val); + dsi_phy_write(pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, val); dsi_phy_write(phy_base + REG_DSI_10nm_PHY_CMN_CLK_CFG0, cached->bit_clk_div | (cached->pix_clk_div << 4)); @@ -586,7 +583,7 @@ static int dsi_10nm_restore_state(struct msm_dsi_phy *phy) static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy) { struct dsi_pll_10nm *pll_10nm = to_pll_10nm(phy->vco_hw); - void __iomem *base = pll_10nm->phy_cmn_mmio; + void __iomem *base = phy->base; u32 data = 0x0; /* internal PLL */ DBG("DSI PLL%d", pll_10nm->id); @@ -645,7 +642,7 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov hw = devm_clk_hw_register_divider(dev, clk_name, parent, CLK_SET_RATE_PARENT, - pll_10nm->mmio + + pll_10nm->phy->pll_base + REG_DSI_10nm_PHY_PLL_PLL_OUTDIV_RATE, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); if (IS_ERR(hw)) { @@ -659,7 +656,7 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov /* BIT CLK: DIV_CTRL_3_0 */ hw = devm_clk_hw_register_divider(dev, clk_name, parent, CLK_SET_RATE_PARENT, - pll_10nm->phy_cmn_mmio + + pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG0, 0, 4, CLK_DIVIDER_ONE_BASED, &pll_10nm->postdiv_lock); @@ -710,7 +707,7 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov hw = devm_clk_hw_register_mux(dev, clk_name, ((const char *[]){ parent, parent2, parent3, parent4 - }), 4, 0, pll_10nm->phy_cmn_mmio + + }), 4, 0, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG1, 0, 2, 0, NULL); if (IS_ERR(hw)) { @@ -723,7 +720,7 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov /* PIX CLK DIV : DIV_CTRL_7_4*/ hw = devm_clk_hw_register_divider(dev, clk_name, parent, - 0, pll_10nm->phy_cmn_mmio + + 0, pll_10nm->phy->base + REG_DSI_10nm_PHY_CMN_CLK_CFG0, 4, 4, CLK_DIVIDER_ONE_BASED, &pll_10nm->postdiv_lock); @@ -758,18 +755,6 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) pll_10nm->id = id; pll_10nm_list[id] = pll_10nm; - pll_10nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); - if (IS_ERR_OR_NULL(pll_10nm->phy_cmn_mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); - return -ENOMEM; - } - - pll_10nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_10nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); - return -ENOMEM; - } - spin_lock_init(&pll_10nm->postdiv_lock); pll_10nm->phy = phy; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 408192ae1456..5a92c2c1e815 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -118,9 +118,6 @@ struct dsi_pll_14nm { int id; struct platform_device *pdev; - void __iomem *phy_cmn_mmio; - void __iomem *mmio; - struct msm_dsi_phy *phy; struct dsi_pll_input in; @@ -167,7 +164,7 @@ static bool pll_14nm_poll_for_ready(struct dsi_pll_14nm *pll_14nm, u32 nb_tries, u32 timeout_us) { bool pll_locked = false; - void __iomem *base = pll_14nm->mmio; + void __iomem *base = pll_14nm->phy->pll_base; u32 tries, val; tries = nb_tries; @@ -380,7 +377,7 @@ static void pll_14nm_calc_vco_count(struct dsi_pll_14nm *pll) static void pll_db_commit_ssc(struct dsi_pll_14nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; struct dsi_pll_input *pin = &pll->in; struct dsi_pll_output *pout = &pll->out; u8 data; @@ -418,7 +415,7 @@ static void pll_db_commit_common(struct dsi_pll_14nm *pll, struct dsi_pll_input *pin, struct dsi_pll_output *pout) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; u8 data; /* confgiure the non frequency dependent pll registers */ @@ -478,7 +475,7 @@ static void pll_db_commit_common(struct dsi_pll_14nm *pll, static void pll_14nm_software_reset(struct dsi_pll_14nm *pll_14nm) { - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + void __iomem *cmn_base = pll_14nm->phy->base; /* de assert pll start and apply pll sw reset */ @@ -497,8 +494,8 @@ static void pll_db_commit_14nm(struct dsi_pll_14nm *pll, struct dsi_pll_input *pin, struct dsi_pll_output *pout) { - void __iomem *base = pll->mmio; - void __iomem *cmn_base = pll->phy_cmn_mmio; + void __iomem *base = pll->phy->pll_base; + void __iomem *cmn_base = pll->phy->base; u8 data; DBG("DSI%d PLL", pll->id); @@ -614,7 +611,7 @@ static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw); - void __iomem *base = pll_14nm->mmio; + void __iomem *base = pll_14nm->phy->pll_base; u64 vco_rate, multiplier = BIT(20); u32 div_frac_start; u32 dec_start; @@ -653,8 +650,8 @@ static unsigned long dsi_pll_14nm_vco_recalc_rate(struct clk_hw *hw, static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) { struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw); - void __iomem *base = pll_14nm->mmio; - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + void __iomem *base = pll_14nm->phy->pll_base; + void __iomem *cmn_base = pll_14nm->phy->base; bool locked; DBG(""); @@ -682,7 +679,7 @@ static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) static void dsi_pll_14nm_vco_unprepare(struct clk_hw *hw) { struct dsi_pll_14nm *pll_14nm = to_pll_14nm(hw); - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + void __iomem *cmn_base = pll_14nm->phy->base; DBG(""); @@ -724,7 +721,7 @@ static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw, { struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); struct dsi_pll_14nm *pll_14nm = postdiv->pll; - void __iomem *base = pll_14nm->phy_cmn_mmio; + void __iomem *base = pll_14nm->phy->base; u8 shift = postdiv->shift; u8 width = postdiv->width; u32 val; @@ -757,7 +754,7 @@ static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, { struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); struct dsi_pll_14nm *pll_14nm = postdiv->pll; - void __iomem *base = pll_14nm->phy_cmn_mmio; + void __iomem *base = pll_14nm->phy->base; spinlock_t *lock = &pll_14nm->postdiv_lock; u8 shift = postdiv->shift; u8 width = postdiv->width; @@ -784,7 +781,7 @@ static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, */ if (pll_14nm->phy->usecase == MSM_DSI_PHY_MASTER) { struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; - void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; + void __iomem *slave_base = pll_14nm_slave->phy->base; dsi_phy_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, val); } @@ -808,7 +805,7 @@ static void dsi_14nm_save_state(struct msm_dsi_phy *phy) { struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw); struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + void __iomem *cmn_base = pll_14nm->phy->base; u32 data; data = dsi_phy_read(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0); @@ -826,7 +823,7 @@ static int dsi_14nm_restore_state(struct msm_dsi_phy *phy) { struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw); struct pll_14nm_cached_state *cached_state = &pll_14nm->cached_state; - void __iomem *cmn_base = pll_14nm->phy_cmn_mmio; + void __iomem *cmn_base = pll_14nm->phy->base; u32 data; int ret; @@ -848,7 +845,7 @@ static int dsi_14nm_restore_state(struct msm_dsi_phy *phy) /* also restore post-dividers for slave DSI PLL */ if (phy->usecase == MSM_DSI_PHY_MASTER) { struct dsi_pll_14nm *pll_14nm_slave = pll_14nm->slave; - void __iomem *slave_base = pll_14nm_slave->phy_cmn_mmio; + void __iomem *slave_base = pll_14nm_slave->phy->base; dsi_phy_write(slave_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); } @@ -859,7 +856,7 @@ static int dsi_14nm_restore_state(struct msm_dsi_phy *phy) static int dsi_14nm_set_usecase(struct msm_dsi_phy *phy) { struct dsi_pll_14nm *pll_14nm = to_pll_14nm(phy->vco_hw); - void __iomem *base = pll_14nm->mmio; + void __iomem *base = phy->pll_base; u32 clkbuflr_en, bandgap = 0; switch (phy->usecase) { @@ -1011,18 +1008,6 @@ static int dsi_pll_14nm_init(struct msm_dsi_phy *phy) pll_14nm->id = id; pll_14nm_list[id] = pll_14nm; - pll_14nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); - if (IS_ERR_OR_NULL(pll_14nm->phy_cmn_mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); - return -ENOMEM; - } - - pll_14nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_14nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); - return -ENOMEM; - } - spin_lock_init(&pll_14nm->postdiv_lock); pll_14nm->phy = phy; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index e964ea210c0b..bdb117938bcc 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -72,8 +72,6 @@ struct dsi_pll_28nm { struct msm_dsi_phy *phy; - void __iomem *mmio; - struct pll_28nm_cached_state cached_state; }; @@ -86,7 +84,7 @@ static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, u32 val; while (nb_tries--) { - val = dsi_phy_read(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_STATUS); + val = dsi_phy_read(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_STATUS); pll_locked = !!(val & DSI_28nm_PHY_PLL_STATUS_PLL_RDY); if (pll_locked) @@ -101,7 +99,7 @@ static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, static void pll_28nm_software_reset(struct dsi_pll_28nm *pll_28nm) { - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; /* * Add HW recommended delays after toggling the software @@ -120,7 +118,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; unsigned long div_fbx1000, gen_vco_clk; u32 refclk_cfg, frac_n_mode, frac_n_value; u32 sdm_cfg0, sdm_cfg1, sdm_cfg2, sdm_cfg3; @@ -244,7 +242,7 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; u32 sdm0, doubler, sdm_byp_div; u32 sdm_dc_off, sdm_freq_seed, sdm2, sdm3; u32 ref_clk = VCO_REF_CLK_RATE; @@ -291,7 +289,7 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, static int _dsi_pll_28nm_vco_prepare_hpm(struct dsi_pll_28nm *pll_28nm) { struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; u32 max_reads = 5, timeout_us = 100; bool locked; u32 val; @@ -385,7 +383,7 @@ static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; bool locked; u32 max_reads = 10, timeout_us = 50; u32 val; @@ -439,7 +437,7 @@ static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) if (unlikely(!pll_28nm->phy->pll_on)) return; - dsi_phy_write(pll_28nm->mmio + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00); + dsi_phy_write(pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_GLB_CFG, 0x00); pll_28nm->phy->pll_on = false; } @@ -483,7 +481,7 @@ static void dsi_28nm_save_state(struct msm_dsi_phy *phy) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; cached_state->postdiv3 = dsi_phy_read(base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG); @@ -500,7 +498,7 @@ static int dsi_28nm_restore_state(struct msm_dsi_phy *phy) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; int ret; ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw, @@ -551,7 +549,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); hw = devm_clk_hw_register_divider(dev, clk_name, parent1, CLK_SET_RATE_PARENT, - pll_28nm->mmio + + pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_POSTDIV1_CFG, 0, 4, 0, NULL); if (IS_ERR(hw)) @@ -568,7 +566,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); hw = devm_clk_hw_register_divider(dev, clk_name, - parent1, 0, pll_28nm->mmio + + parent1, 0, pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, 0, 8, 0, NULL); if (IS_ERR(hw)) @@ -581,7 +579,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov hw = devm_clk_hw_register_mux(dev, clk_name, ((const char *[]){ parent1, parent2 - }), 2, CLK_SET_RATE_PARENT, pll_28nm->mmio + + }), 2, CLK_SET_RATE_PARENT, pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_VREG_CFG, 1, 1, 0, NULL); if (IS_ERR(hw)) return PTR_ERR(hw); @@ -613,13 +611,6 @@ static int dsi_pll_28nm_init(struct msm_dsi_phy *phy) pll_28nm->pdev = pdev; pll_28nm->id = id; - - pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_28nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); - return -ENOMEM; - } - pll_28nm->phy = phy; ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index faefae5ec23c..36ee3f15d1e0 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -64,8 +64,6 @@ struct dsi_pll_28nm { struct msm_dsi_phy *phy; - void __iomem *mmio; - struct pll_28nm_cached_state cached_state; }; @@ -78,7 +76,7 @@ static bool pll_28nm_poll_for_ready(struct dsi_pll_28nm *pll_28nm, u32 val; while (nb_tries--) { - val = dsi_phy_read(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_RDY); + val = dsi_phy_read(pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_RDY); pll_locked = !!(val & DSI_28nm_8960_PHY_PLL_RDY_PLL_RDY); if (pll_locked) @@ -98,7 +96,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; u32 val, temp, fb_divider; DBG("rate=%lu, parent's=%lu", rate, parent_rate); @@ -147,7 +145,7 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; unsigned long vco_rate; u32 status, fb_divider, temp, ref_divider; @@ -181,7 +179,7 @@ static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); struct device *dev = &pll_28nm->pdev->dev; - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; bool locked; unsigned int bit_div, byte_div; int max_reads = 1000, timeout_us = 100; @@ -234,7 +232,7 @@ static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) if (unlikely(!pll_28nm->phy->pll_on)) return; - dsi_phy_write(pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00); + dsi_phy_write(pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_0, 0x00); pll_28nm->phy->pll_on = false; } @@ -348,7 +346,7 @@ static void dsi_28nm_save_state(struct msm_dsi_phy *phy) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; cached_state->postdiv3 = dsi_phy_read(base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10); @@ -364,7 +362,7 @@ static int dsi_28nm_restore_state(struct msm_dsi_phy *phy) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(phy->vco_hw); struct pll_28nm_cached_state *cached_state = &pll_28nm->cached_state; - void __iomem *base = pll_28nm->mmio; + void __iomem *base = pll_28nm->phy->pll_base; int ret; ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw, @@ -425,7 +423,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov /* prepare and register bytediv */ bytediv->hw.init = &bytediv_init; - bytediv->reg = pll_28nm->mmio + REG_DSI_28nm_8960_PHY_PLL_CTRL_9; + bytediv->reg = pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9; snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->id); snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); @@ -445,7 +443,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); /* DIV3 */ hw = devm_clk_hw_register_divider(dev, clk_name, - parent_name, 0, pll_28nm->mmio + + parent_name, 0, pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_10, 0, 8, 0, NULL); if (IS_ERR(hw)) @@ -471,13 +469,6 @@ static int dsi_pll_28nm_8960_init(struct msm_dsi_phy *phy) pll_28nm->pdev = pdev; pll_28nm->id = id + 1; - - pll_28nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_28nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "%s: failed to map pll base\n", __func__); - return -ENOMEM; - } - pll_28nm->phy = phy; ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index b873b2f67e3a..8e8cf9e63e8f 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -91,9 +91,6 @@ struct dsi_pll_7nm { struct msm_dsi_phy *phy; - void __iomem *phy_cmn_mmio; - void __iomem *mmio; - u64 vco_ref_clk_rate; u64 vco_current_rate; @@ -231,7 +228,7 @@ static void dsi_pll_calc_ssc(struct dsi_pll_7nm *pll) static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; struct dsi_pll_regs *regs = &pll->reg_setup; if (pll->pll_configuration.enable_ssc) { @@ -256,7 +253,7 @@ static void dsi_pll_ssc_commit(struct dsi_pll_7nm *pll) static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; u8 analog_controls_five_1 = 0x01, vco_config_1 = 0x00; if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) { @@ -298,13 +295,13 @@ static void dsi_pll_config_hzindep_reg(struct dsi_pll_7nm *pll) if (pll->phy->cfg->quirks & DSI_PHY_7NM_QUIRK_V4_1) { dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); if (pll->slave) - dsi_phy_write(pll->slave->mmio + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); + dsi_phy_write(pll->slave->phy->pll_base + REG_DSI_7nm_PHY_PLL_PERF_OPTIMIZE, 0x22); } } static void dsi_pll_commit(struct dsi_pll_7nm *pll) { - void __iomem *base = pll->mmio; + void __iomem *base = pll->phy->pll_base; struct dsi_pll_regs *reg = &pll->reg_setup; dsi_phy_write(base + REG_DSI_7nm_PHY_PLL_CORE_INPUT_OVERRIDE, 0x12); @@ -354,7 +351,7 @@ static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll) u32 const delay_us = 100; u32 const timeout_us = 5000; - rc = readl_poll_timeout_atomic(pll->mmio + + rc = readl_poll_timeout_atomic(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_COMMON_STATUS_ONE, status, ((status & BIT(0)) > 0), @@ -369,19 +366,19 @@ static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll) static void dsi_pll_disable_pll_bias(struct dsi_pll_7nm *pll) { - u32 data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0); + u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); - dsi_phy_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5)); + dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0); + dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data & ~BIT(5)); ndelay(250); } static void dsi_pll_enable_pll_bias(struct dsi_pll_7nm *pll) { - u32 data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0); + u32 data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5)); - dsi_phy_write(pll->mmio + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0); + dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_0, data | BIT(5)); + dsi_phy_write(pll->phy->pll_base + REG_DSI_7nm_PHY_PLL_SYSTEM_MUXES, 0xc0); ndelay(250); } @@ -389,18 +386,18 @@ static void dsi_pll_disable_global_clk(struct dsi_pll_7nm *pll) { u32 data; - data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5)); + data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data & ~BIT(5)); } static void dsi_pll_enable_global_clk(struct dsi_pll_7nm *pll) { u32 data; - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04); + dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CTRL_3, 0x04); - data = dsi_phy_read(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1); - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_CLK_CFG1, + data = dsi_phy_read(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1); + dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, data | BIT(5) | BIT(4)); } @@ -411,9 +408,9 @@ static void dsi_pll_phy_dig_reset(struct dsi_pll_7nm *pll) * coming out of a CX or analog rail power collapse while * ensuring that the pads maintain LP00 or LP11 state */ - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0)); + dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, BIT(0)); wmb(); /* Ensure that the reset is deasserted */ - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0); + dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_GLBL_DIGTOP_SPARE4, 0x0); wmb(); /* Ensure that the reset is deasserted */ } @@ -427,7 +424,7 @@ static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) dsi_pll_enable_pll_bias(pll_7nm->slave); /* Start PLL */ - dsi_phy_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01); + dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0x01); /* * ensure all PLL configurations are written prior to checking @@ -463,7 +460,7 @@ static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) static void dsi_pll_disable_sub(struct dsi_pll_7nm *pll) { - dsi_phy_write(pll->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0); + dsi_phy_write(pll->phy->base + REG_DSI_7nm_PHY_CMN_RBUF_CTRL, 0); dsi_pll_disable_pll_bias(pll); } @@ -477,7 +474,7 @@ static void dsi_pll_7nm_vco_unprepare(struct clk_hw *hw) * powering down the PLL */ dsi_pll_disable_global_clk(pll_7nm); - dsi_phy_write(pll_7nm->phy_cmn_mmio + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0); + dsi_phy_write(pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_PLL_CNTRL, 0); dsi_pll_disable_sub(pll_7nm); if (pll_7nm->slave) { dsi_pll_disable_global_clk(pll_7nm->slave); @@ -493,7 +490,7 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, { struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw); struct dsi_pll_config *config = &pll_7nm->pll_configuration; - void __iomem *base = pll_7nm->mmio; + void __iomem *base = pll_7nm->phy->pll_base; u64 ref_clk = pll_7nm->vco_ref_clk_rate; u64 vco_rate = 0x0; u64 multiplier; @@ -556,10 +553,10 @@ static void dsi_7nm_save_state(struct msm_dsi_phy *phy) { struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; - void __iomem *phy_base = pll_7nm->phy_cmn_mmio; + void __iomem *phy_base = pll_7nm->phy->base; u32 cmn_clk_cfg0, cmn_clk_cfg1; - cached->pll_out_div = dsi_phy_read(pll_7nm->mmio + + cached->pll_out_div = dsi_phy_read(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); cached->pll_out_div &= 0x3; @@ -579,14 +576,14 @@ static int dsi_7nm_restore_state(struct msm_dsi_phy *phy) { struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); struct pll_7nm_cached_state *cached = &pll_7nm->cached_state; - void __iomem *phy_base = pll_7nm->phy_cmn_mmio; + void __iomem *phy_base = pll_7nm->phy->base; u32 val; int ret; - val = dsi_phy_read(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); + val = dsi_phy_read(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE); val &= ~0x3; val |= cached->pll_out_div; - dsi_phy_write(pll_7nm->mmio + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val); + dsi_phy_write(pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, val); dsi_phy_write(phy_base + REG_DSI_7nm_PHY_CMN_CLK_CFG0, cached->bit_clk_div | (cached->pix_clk_div << 4)); @@ -611,7 +608,7 @@ static int dsi_7nm_restore_state(struct msm_dsi_phy *phy) static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) { struct dsi_pll_7nm *pll_7nm = to_pll_7nm(phy->vco_hw); - void __iomem *base = pll_7nm->phy_cmn_mmio; + void __iomem *base = phy->base; u32 data = 0x0; /* internal PLL */ DBG("DSI PLL%d", pll_7nm->id); @@ -670,7 +667,7 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide hw = devm_clk_hw_register_divider(dev, clk_name, parent, CLK_SET_RATE_PARENT, - pll_7nm->mmio + + pll_7nm->phy->pll_base + REG_DSI_7nm_PHY_PLL_PLL_OUTDIV_RATE, 0, 2, CLK_DIVIDER_POWER_OF_TWO, NULL); if (IS_ERR(hw)) { @@ -684,7 +681,7 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide /* BIT CLK: DIV_CTRL_3_0 */ hw = devm_clk_hw_register_divider(dev, clk_name, parent, CLK_SET_RATE_PARENT, - pll_7nm->phy_cmn_mmio + + pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0, 0, 4, CLK_DIVIDER_ONE_BASED, &pll_7nm->postdiv_lock); @@ -735,7 +732,7 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide hw = devm_clk_hw_register_mux(dev, clk_name, ((const char *[]){ parent, parent2, parent3, parent4 - }), 4, 0, pll_7nm->phy_cmn_mmio + + }), 4, 0, pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG1, 0, 2, 0, NULL); if (IS_ERR(hw)) { @@ -748,7 +745,7 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide /* PIX CLK DIV : DIV_CTRL_7_4*/ hw = devm_clk_hw_register_divider(dev, clk_name, parent, - 0, pll_7nm->phy_cmn_mmio + + 0, pll_7nm->phy->base + REG_DSI_7nm_PHY_CMN_CLK_CFG0, 4, 4, CLK_DIVIDER_ONE_BASED, &pll_7nm->postdiv_lock); @@ -783,18 +780,6 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) pll_7nm->id = id; pll_7nm_list[id] = pll_7nm; - pll_7nm->phy_cmn_mmio = msm_ioremap(pdev, "dsi_phy", "DSI_PHY"); - if (IS_ERR_OR_NULL(pll_7nm->phy_cmn_mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map CMN PHY base\n"); - return -ENOMEM; - } - - pll_7nm->mmio = msm_ioremap(pdev, "dsi_pll", "DSI_PLL"); - if (IS_ERR_OR_NULL(pll_7nm->mmio)) { - DRM_DEV_ERROR(&pdev->dev, "failed to map PLL base\n"); - return -ENOMEM; - } - spin_lock_init(&pll_7nm->postdiv_lock); pll_7nm->phy = phy; From patchwork Sat Mar 27 11:03:02 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 410151 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2161158jai; Sat, 27 Mar 2021 04:04:06 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwJ9Cd7oViFSAFpyOYj58DYf5F5SngIlqhoy+tEOGeOOpRNFunTQwGHMJAtnkKAMKPFan97 X-Received: by 2002:a62:7ac3:0:b029:1f1:5d13:5ec6 with SMTP id v186-20020a627ac30000b02901f15d135ec6mr17437859pfc.14.1616843045936; Sat, 27 Mar 2021 04:04:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616843045; cv=none; d=google.com; s=arc-20160816; b=ZjivUHf9XcpEYhns5ZTKGulylM3FaXJGWXpIUlf+n/JwiYSLnv1raPDjOjY3Tf2U23 zEBB1ObcFcvRFd2dh2/apTip9p6BISsaPx8dtEPUAbrOYJDG86GprWnk56Q5UgUycQ9P mA8E3J8td+BJhGlbv937BZkITFPC7SJUVmH4osvW//LatMp967EyZbdsNr7RxcjDAQuC 0M/aTsoxDGhOEi+fDFcLG2DOTDERxM5MvmuPSHBiaOwHUsA2XmFazW5WSzRaEymBqXTd MLbTDU2igfwTMEs8knaWfOSw6+thgSDTQV0NONVRxffX4MOSJHBJHJmkGkU7kzPFCvlP V3WQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:mime-version:references:in-reply-to:message-id:date :subject:to:from:dkim-signature:delivered-to; bh=3QcLhCuFrJbdHVOi0Zy9txI8q2TCGgA7H41jX+O0OnA=; b=cO9r95+ENT2elfN4qzNE61kyeUohak6cORl09ZsiXJWLEXyByCE1qjsh+4dk81CEwq nb7cD59WsVkDX27Ub9LlYr56U5neL/xbOyieuForH52pxXWrICaqu03Ch937KbpQOrbF OGhQ6d1FOqhU35g7d39y8/YGcN5gyyRWOK4L2wtbnU529gSTr27v5t21lAXMc1P7qO69 vr4H140xjWLToDr/rwPtHVud5BeNI/4A4fXqpKshWIeAlWTZ0tEUiRIA9FNK5rhy598D fPhtANvUxrzdytC8EvGN3pcT15/jByGcZWtrlVEJlMwZnnjK3pHgzpwt9GVh1Io4SsFw +43w== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=DZ8T0o5l; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [131.252.210.177]) by mx.google.com with ESMTPS id f18si11767657plj.63.2021.03.27.04.04.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:04:05 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) client-ip=131.252.210.177; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=DZ8T0o5l; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 131.252.210.177 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id AF1526F568; Sat, 27 Mar 2021 11:03:59 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lj1-x22d.google.com (mail-lj1-x22d.google.com [IPv6:2a00:1450:4864:20::22d]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1E9186F541 for ; Sat, 27 Mar 2021 11:03:30 +0000 (UTC) Received: by mail-lj1-x22d.google.com with SMTP id u20so10242058lja.13 for ; Sat, 27 Mar 2021 04:03:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OKlbm2TBeZKhGBSZlaOiXdTXR0bZwoLPGpSQO9yNWP0=; b=DZ8T0o5ls8t2MFCLWzTlJHKYx1TJX7FBwXcXIJ/eCLu2SJbnu9r1vmeBvY1hj1hnae ONo2a99RJM0GdPb6jxiShKRKZLHP3RmiiQrXNTWQJ279ZLWkVJeaAAmHSvPTiy8XjPPm R51fLu4zWzhPwcA8ggIiAsXmn52wqEkgjlUYTzwaevPOwCbA/0UCZklcOueoZQkFl+BT 0RAA0lanjBADn5fda8HAmvmneHOfB+uSZA2NhU9LryqgCNTnXBAwGZkDlZU2dduJ5+sl uqghwNVWzKQzwy94WzqHN/gPX+ui58lX8rDKV1JZgA+uRQk8LtcmOKiJr6iBFdoMNUDb iStw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=OKlbm2TBeZKhGBSZlaOiXdTXR0bZwoLPGpSQO9yNWP0=; b=i6fyjZQ5ZfRc6JnpYFtZi+lp3Nl0vWvAud21l5OBb06NawDqySHQpeuPwqoFC8zkq1 yfNk3XkyBt7Gr+0zfqpRsfAnf/g+2K65N0kwUwZApjxIbL0FfXoXP0z0LUhCTcQZEqon FClKWV6R1hPquLZBy/EovYss63/6/kBQFtZLJTcVCbl4WtK8RAe2U0m4lfa4Zk74yFhw OC8+F5yajyQ5+GupulzIHVcHQUXg+huUVeanvmMXcX9+Ctlz2m54d3WzNm7FZXZjtUrI e3Tzhjm0fnBBtLRak8cyt4XKb/X0Hww+cx+000AXLNgcFNhBjhWwndgwu8IdfE3zSkvm oD7g== X-Gm-Message-State: AOAM532Hb9S0hDRnVsF8JhyriUyY/0pxFxOD4yGs3NNh5R1ReF31xDtS K0k1qpqKM8UN/fZdf9hfQHlVPg== X-Received: by 2002:a2e:9dc2:: with SMTP id x2mr12322737ljj.306.1616843009165; Sat, 27 Mar 2021 04:03:29 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id a8sm1513801ljn.96.2021.03.27.04.03.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:28 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Jonathan Marek , Michael Turquette Subject: [PATCH v3 22/25] drm/msm/dsi: remove duplicate fields from dsi_pll_Nnm instances Date: Sat, 27 Mar 2021 14:03:02 +0300 Message-Id: <20210327110305.3289784-23-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> References: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org, linux-clk@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Drop duplicate fields pdev and id from dsi_pll_Nnm instances. Reuse those fields from the provided msm_dsi_phy. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 72 +++++++++---------- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 54 +++++++------- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 48 ++++++------- .../gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 26 +++---- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 68 ++++++++---------- 5 files changed, 119 insertions(+), 149 deletions(-) -- 2.30.2 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel Reviewed-by: Abhinav Kumar diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 8a15ae91d44b..b937e77b3c37 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -86,9 +86,6 @@ struct pll_10nm_cached_state { struct dsi_pll_10nm { struct clk_hw clk_hw; - int id; - struct platform_device *pdev; - struct msm_dsi_phy *phy; u64 vco_ref_clk_rate; @@ -301,7 +298,7 @@ static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, { struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); - DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->id, rate, + DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_10nm->phy->id, rate, parent_rate); pll_10nm->vco_current_rate = rate; @@ -327,7 +324,7 @@ static int dsi_pll_10nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) { - struct device *dev = &pll->pdev->dev; + struct device *dev = &pll->phy->pdev->dev; int rc; u32 status = 0; u32 const delay_us = 100; @@ -341,7 +338,7 @@ static int dsi_pll_10nm_lock_status(struct dsi_pll_10nm *pll) timeout_us); if (rc) DRM_DEV_ERROR(dev, "DSI PLL(%d) lock failed, status=0x%08x\n", - pll->id, status); + pll->phy->id, status); return rc; } @@ -387,7 +384,7 @@ static void dsi_pll_enable_global_clk(struct dsi_pll_10nm *pll) static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) { struct dsi_pll_10nm *pll_10nm = to_pll_10nm(hw); - struct device *dev = &pll_10nm->pdev->dev; + struct device *dev = &pll_10nm->phy->pdev->dev; int rc; dsi_pll_enable_pll_bias(pll_10nm); @@ -413,7 +410,7 @@ static int dsi_pll_10nm_vco_prepare(struct clk_hw *hw) /* Check for PLL lock */ rc = dsi_pll_10nm_lock_status(pll_10nm); if (rc) { - DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->id); + DRM_DEV_ERROR(dev, "PLL(%d) lock failed\n", pll_10nm->phy->id); goto error; } @@ -494,7 +491,7 @@ static unsigned long dsi_pll_10nm_vco_recalc_rate(struct clk_hw *hw, vco_rate = pll_freq; DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", - pll_10nm->id, (unsigned long)vco_rate, dec, frac); + pll_10nm->phy->id, (unsigned long)vco_rate, dec, frac); return (unsigned long)vco_rate; } @@ -543,7 +540,7 @@ static void dsi_10nm_save_state(struct msm_dsi_phy *phy) cached->pll_mux = cmn_clk_cfg1 & 0x3; DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", - pll_10nm->id, cached->pll_out_div, cached->bit_clk_div, + pll_10nm->phy->id, cached->pll_out_div, cached->bit_clk_div, cached->pix_clk_div, cached->pll_mux); } @@ -570,12 +567,12 @@ static int dsi_10nm_restore_state(struct msm_dsi_phy *phy) ret = dsi_pll_10nm_vco_set_rate(phy->vco_hw, pll_10nm->vco_current_rate, pll_10nm->vco_ref_clk_rate); if (ret) { - DRM_DEV_ERROR(&pll_10nm->pdev->dev, + DRM_DEV_ERROR(&pll_10nm->phy->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } - DBG("DSI PLL%d", pll_10nm->id); + DBG("DSI PLL%d", pll_10nm->phy->id); return 0; } @@ -586,13 +583,13 @@ static int dsi_10nm_set_usecase(struct msm_dsi_phy *phy) void __iomem *base = phy->base; u32 data = 0x0; /* internal PLL */ - DBG("DSI PLL%d", pll_10nm->id); + DBG("DSI PLL%d", pll_10nm->phy->id); switch (phy->usecase) { case MSM_DSI_PHY_STANDALONE: break; case MSM_DSI_PHY_MASTER: - pll_10nm->slave = pll_10nm_list[(pll_10nm->id + 1) % DSI_MAX]; + pll_10nm->slave = pll_10nm_list[(pll_10nm->phy->id + 1) % DSI_MAX]; break; case MSM_DSI_PHY_SLAVE: data = 0x1; /* external PLL */ @@ -624,21 +621,21 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov .flags = CLK_IGNORE_UNUSED, .ops = &clk_ops_dsi_pll_10nm_vco, }; - struct device *dev = &pll_10nm->pdev->dev; + struct device *dev = &pll_10nm->phy->pdev->dev; struct clk_hw *hw; int ret; - DBG("DSI%d", pll_10nm->id); + DBG("DSI%d", pll_10nm->phy->id); - snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->id); + snprintf(vco_name, 32, "dsi%dvco_clk", pll_10nm->phy->id); pll_10nm->clk_hw.init = &vco_init; ret = devm_clk_hw_register(dev, &pll_10nm->clk_hw); if (ret) return ret; - snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id); + snprintf(parent, 32, "dsi%dvco_clk", pll_10nm->phy->id); hw = devm_clk_hw_register_divider(dev, clk_name, parent, CLK_SET_RATE_PARENT, @@ -650,8 +647,8 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov goto fail; } - snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id); /* BIT CLK: DIV_CTRL_3_0 */ hw = devm_clk_hw_register_divider(dev, clk_name, parent, @@ -665,8 +662,8 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov goto fail; } - snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_10nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id); /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, @@ -678,8 +675,8 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov provided_clocks[DSI_BYTE_PLL_CLK] = hw; - snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id); hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 2); @@ -688,8 +685,8 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov goto fail; } - snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id); hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 4); @@ -698,11 +695,11 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov goto fail; } - snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->id); - snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->id); - snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_10nm->id); - snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_10nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_10nm->phy->id); + snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_10nm->phy->id); + snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_10nm->phy->id); + snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_10nm->phy->id); hw = devm_clk_hw_register_mux(dev, clk_name, ((const char *[]){ @@ -715,8 +712,8 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov goto fail; } - snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->id); - snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->id); + snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_10nm->phy->id); + snprintf(parent, 32, "dsi%d_pclk_mux", pll_10nm->phy->id); /* PIX CLK DIV : DIV_CTRL_7_4*/ hw = devm_clk_hw_register_divider(dev, clk_name, parent, @@ -741,7 +738,6 @@ static int pll_10nm_register(struct dsi_pll_10nm *pll_10nm, struct clk_hw **prov static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) { struct platform_device *pdev = phy->pdev; - int id = phy->id; struct dsi_pll_10nm *pll_10nm; int ret; @@ -749,11 +745,9 @@ static int dsi_pll_10nm_init(struct msm_dsi_phy *phy) if (!pll_10nm) return -ENOMEM; - DBG("DSI PLL%d", id); + DBG("DSI PLL%d", phy->id); - pll_10nm->pdev = pdev; - pll_10nm->id = id; - pll_10nm_list[id] = pll_10nm; + pll_10nm_list[phy->id] = pll_10nm; spin_lock_init(&pll_10nm->postdiv_lock); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 5a92c2c1e815..8b4865c5796d 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -115,9 +115,6 @@ struct pll_14nm_cached_state { struct dsi_pll_14nm { struct clk_hw clk_hw; - int id; - struct platform_device *pdev; - struct msm_dsi_phy *phy; struct dsi_pll_input in; @@ -498,7 +495,7 @@ static void pll_db_commit_14nm(struct dsi_pll_14nm *pll, void __iomem *cmn_base = pll->phy->base; u8 data; - DBG("DSI%d PLL", pll->id); + DBG("DSI%d PLL", pll->phy->id); data = pout->cmn_ldo_cntrl; dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_LDO_CNTRL, data); @@ -565,7 +562,7 @@ static int dsi_pll_14nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, struct dsi_pll_input *pin = &pll_14nm->in; struct dsi_pll_output *pout = &pll_14nm->out; - DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_14nm->id, rate, + DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_14nm->phy->id, rate, parent_rate); pll_14nm->vco_current_rate = rate; @@ -666,7 +663,7 @@ static int dsi_pll_14nm_vco_prepare(struct clk_hw *hw) POLL_TIMEOUT_US); if (unlikely(!locked)) { - DRM_DEV_ERROR(&pll_14nm->pdev->dev, "DSI PLL lock failed\n"); + DRM_DEV_ERROR(&pll_14nm->phy->pdev->dev, "DSI PLL lock failed\n"); return -EINVAL; } @@ -726,7 +723,7 @@ static unsigned long dsi_pll_14nm_postdiv_recalc_rate(struct clk_hw *hw, u8 width = postdiv->width; u32 val; - DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, parent_rate); + DBG("DSI%d PLL parent rate=%lu", pll_14nm->phy->id, parent_rate); val = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_CLK_CFG0) >> shift; val &= div_mask(width); @@ -742,7 +739,7 @@ static long dsi_pll_14nm_postdiv_round_rate(struct clk_hw *hw, struct dsi_pll_14nm_postdiv *postdiv = to_pll_14nm_postdiv(hw); struct dsi_pll_14nm *pll_14nm = postdiv->pll; - DBG("DSI%d PLL parent rate=%lu", pll_14nm->id, rate); + DBG("DSI%d PLL parent rate=%lu", pll_14nm->phy->id, rate); return divider_round_rate(hw, rate, prate, NULL, postdiv->width, @@ -762,7 +759,7 @@ static int dsi_pll_14nm_postdiv_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long flags = 0; u32 val; - DBG("DSI%d PLL parent rate=%lu parent rate %lu", pll_14nm->id, rate, + DBG("DSI%d PLL parent rate=%lu parent rate %lu", pll_14nm->phy->id, rate, parent_rate); value = divider_get_val(rate, parent_rate, NULL, postdiv->width, @@ -813,7 +810,7 @@ static void dsi_14nm_save_state(struct msm_dsi_phy *phy) cached_state->n1postdiv = data & 0xf; cached_state->n2postdiv = (data >> 4) & 0xf; - DBG("DSI%d PLL save state %x %x", pll_14nm->id, + DBG("DSI%d PLL save state %x %x", pll_14nm->phy->id, cached_state->n1postdiv, cached_state->n2postdiv); cached_state->vco_rate = clk_hw_get_rate(phy->vco_hw); @@ -830,14 +827,14 @@ static int dsi_14nm_restore_state(struct msm_dsi_phy *phy) ret = dsi_pll_14nm_vco_set_rate(phy->vco_hw, cached_state->vco_rate, 0); if (ret) { - DRM_DEV_ERROR(&pll_14nm->pdev->dev, + DRM_DEV_ERROR(&pll_14nm->phy->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } data = cached_state->n1postdiv | (cached_state->n2postdiv << 4); - DBG("DSI%d PLL restore state %x %x", pll_14nm->id, + DBG("DSI%d PLL restore state %x %x", pll_14nm->phy->id, cached_state->n1postdiv, cached_state->n2postdiv); dsi_phy_write(cmn_base + REG_DSI_14nm_PHY_CMN_CLK_CFG0, data); @@ -865,7 +862,7 @@ static int dsi_14nm_set_usecase(struct msm_dsi_phy *phy) break; case MSM_DSI_PHY_MASTER: clkbuflr_en = 0x3; - pll_14nm->slave = pll_14nm_list[(pll_14nm->id + 1) % DSI_MAX]; + pll_14nm->slave = pll_14nm_list[(pll_14nm->phy->id + 1) % DSI_MAX]; break; case MSM_DSI_PHY_SLAVE: clkbuflr_en = 0x0; @@ -889,7 +886,7 @@ static struct clk_hw *pll_14nm_postdiv_register(struct dsi_pll_14nm *pll_14nm, u8 shift) { struct dsi_pll_14nm_postdiv *pll_postdiv; - struct device *dev = &pll_14nm->pdev->dev; + struct device *dev = &pll_14nm->phy->pdev->dev; struct clk_init_data postdiv_init = { .parent_names = (const char *[]) { parent_name }, .num_parents = 1, @@ -928,21 +925,21 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov .flags = CLK_IGNORE_UNUSED, .ops = &clk_ops_dsi_pll_14nm_vco, }; - struct device *dev = &pll_14nm->pdev->dev; + struct device *dev = &pll_14nm->phy->pdev->dev; struct clk_hw *hw; int ret; - DBG("DSI%d", pll_14nm->id); + DBG("DSI%d", pll_14nm->phy->id); - snprintf(vco_name, 32, "dsi%dvco_clk", pll_14nm->id); + snprintf(vco_name, 32, "dsi%dvco_clk", pll_14nm->phy->id); pll_14nm->clk_hw.init = &vco_init; ret = devm_clk_hw_register(dev, &pll_14nm->clk_hw); if (ret) return ret; - snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->id); + snprintf(clk_name, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); + snprintf(parent, 32, "dsi%dvco_clk", pll_14nm->phy->id); /* N1 postdiv, bits 0-3 in REG_DSI_14nm_PHY_CMN_CLK_CFG0 */ hw = pll_14nm_postdiv_register(pll_14nm, clk_name, parent, @@ -950,8 +947,8 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov if (IS_ERR(hw)) return PTR_ERR(hw); - snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->id); - snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); + snprintf(clk_name, 32, "dsi%dpllbyte", pll_14nm->phy->id); + snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); /* DSI Byte clock = VCO_CLK / N1 / 8 */ hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, @@ -961,8 +958,8 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov provided_clocks[DSI_BYTE_PLL_CLK] = hw; - snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id); - snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->id); + snprintf(clk_name, 32, "dsi%dn1_postdivby2_clk", pll_14nm->phy->id); + snprintf(parent, 32, "dsi%dn1_postdiv_clk", pll_14nm->phy->id); /* * Skip the mux for now, force DSICLK_SEL to 1, Add a /2 divider @@ -972,8 +969,8 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov if (IS_ERR(hw)) return PTR_ERR(hw); - snprintf(clk_name, 32, "dsi%dpll", pll_14nm->id); - snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->id); + snprintf(clk_name, 32, "dsi%dpll", pll_14nm->phy->id); + snprintf(parent, 32, "dsi%dn1_postdivby2_clk", pll_14nm->phy->id); /* DSI pixel clock = VCO_CLK / N1 / 2 / N2 * This is the output of N2 post-divider, bits 4-7 in @@ -991,7 +988,6 @@ static int pll_14nm_register(struct dsi_pll_14nm *pll_14nm, struct clk_hw **prov static int dsi_pll_14nm_init(struct msm_dsi_phy *phy) { struct platform_device *pdev = phy->pdev; - int id = phy->id; struct dsi_pll_14nm *pll_14nm; int ret; @@ -1002,11 +998,9 @@ static int dsi_pll_14nm_init(struct msm_dsi_phy *phy) if (!pll_14nm) return -ENOMEM; - DBG("PLL%d", id); + DBG("PLL%d", phy->id); - pll_14nm->pdev = pdev; - pll_14nm->id = id; - pll_14nm_list[id] = pll_14nm; + pll_14nm_list[phy->id] = pll_14nm; spin_lock_init(&pll_14nm->postdiv_lock); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index bdb117938bcc..0bcea3f3eca3 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -67,9 +67,6 @@ struct pll_28nm_cached_state { struct dsi_pll_28nm { struct clk_hw clk_hw; - int id; - struct platform_device *pdev; - struct msm_dsi_phy *phy; struct pll_28nm_cached_state cached_state; @@ -117,7 +114,7 @@ static int dsi_pll_28nm_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long parent_rate) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); - struct device *dev = &pll_28nm->pdev->dev; + struct device *dev = &pll_28nm->phy->pdev->dev; void __iomem *base = pll_28nm->phy->pll_base; unsigned long div_fbx1000, gen_vco_clk; u32 refclk_cfg, frac_n_mode, frac_n_value; @@ -288,14 +285,14 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, static int _dsi_pll_28nm_vco_prepare_hpm(struct dsi_pll_28nm *pll_28nm) { - struct device *dev = &pll_28nm->pdev->dev; + struct device *dev = &pll_28nm->phy->pdev->dev; void __iomem *base = pll_28nm->phy->pll_base; u32 max_reads = 5, timeout_us = 100; bool locked; u32 val; int i; - DBG("id=%d", pll_28nm->id); + DBG("id=%d", pll_28nm->phy->id); pll_28nm_software_reset(pll_28nm); @@ -382,13 +379,13 @@ static int dsi_pll_28nm_vco_prepare_hpm(struct clk_hw *hw) static int dsi_pll_28nm_vco_prepare_lp(struct clk_hw *hw) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); - struct device *dev = &pll_28nm->pdev->dev; + struct device *dev = &pll_28nm->phy->pdev->dev; void __iomem *base = pll_28nm->phy->pll_base; bool locked; u32 max_reads = 10, timeout_us = 50; u32 val; - DBG("id=%d", pll_28nm->id); + DBG("id=%d", pll_28nm->phy->id); if (unlikely(pll_28nm->phy->pll_on)) return 0; @@ -432,7 +429,7 @@ static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); - DBG("id=%d", pll_28nm->id); + DBG("id=%d", pll_28nm->phy->id); if (unlikely(!pll_28nm->phy->pll_on)) return; @@ -504,7 +501,7 @@ static int dsi_28nm_restore_state(struct msm_dsi_phy *phy) ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw, cached_state->vco_rate, 0); if (ret) { - DRM_DEV_ERROR(&pll_28nm->pdev->dev, + DRM_DEV_ERROR(&pll_28nm->phy->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } @@ -528,25 +525,25 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov .name = vco_name, .flags = CLK_IGNORE_UNUSED, }; - struct device *dev = &pll_28nm->pdev->dev; + struct device *dev = &pll_28nm->phy->pdev->dev; struct clk_hw *hw; int ret; - DBG("%d", pll_28nm->id); + DBG("%d", pll_28nm->phy->id); if (pll_28nm->phy->cfg->quirks & DSI_PHY_28NM_QUIRK_PHY_LP) vco_init.ops = &clk_ops_dsi_pll_28nm_vco_lp; else vco_init.ops = &clk_ops_dsi_pll_28nm_vco_hpm; - snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); + snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->phy->id); pll_28nm->clk_hw.init = &vco_init; ret = devm_clk_hw_register(dev, &pll_28nm->clk_hw); if (ret) return ret; - snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); + snprintf(clk_name, 32, "dsi%danalog_postdiv_clk", pll_28nm->phy->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); hw = devm_clk_hw_register_divider(dev, clk_name, parent1, CLK_SET_RATE_PARENT, pll_28nm->phy->pll_base + @@ -555,16 +552,16 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov if (IS_ERR(hw)) return PTR_ERR(hw); - snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); - snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->id); + snprintf(clk_name, 32, "dsi%dindirect_path_div2_clk", pll_28nm->phy->id); + snprintf(parent1, 32, "dsi%danalog_postdiv_clk", pll_28nm->phy->id); hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent1, CLK_SET_RATE_PARENT, 1, 2); if (IS_ERR(hw)) return PTR_ERR(hw); - snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); + snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); hw = devm_clk_hw_register_divider(dev, clk_name, parent1, 0, pll_28nm->phy->pll_base + REG_DSI_28nm_PHY_PLL_POSTDIV3_CFG, @@ -573,9 +570,9 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov return PTR_ERR(hw); provided_clocks[DSI_PIXEL_PLL_CLK] = hw; - snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->id); - snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->id); - snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->id); + snprintf(clk_name, 32, "dsi%dbyte_mux", pll_28nm->phy->id); + snprintf(parent1, 32, "dsi%dvco_clk", pll_28nm->phy->id); + snprintf(parent2, 32, "dsi%dindirect_path_div2_clk", pll_28nm->phy->id); hw = devm_clk_hw_register_mux(dev, clk_name, ((const char *[]){ parent1, parent2 @@ -584,8 +581,8 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov if (IS_ERR(hw)) return PTR_ERR(hw); - snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); - snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->id); + snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id); + snprintf(parent1, 32, "dsi%dbyte_mux", pll_28nm->phy->id); hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent1, CLK_SET_RATE_PARENT, 1, 4); if (IS_ERR(hw)) @@ -598,7 +595,6 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov static int dsi_pll_28nm_init(struct msm_dsi_phy *phy) { struct platform_device *pdev = phy->pdev; - int id = phy->id; struct dsi_pll_28nm *pll_28nm; int ret; @@ -609,8 +605,6 @@ static int dsi_pll_28nm_init(struct msm_dsi_phy *phy) if (!pll_28nm) return -ENOMEM; - pll_28nm->pdev = pdev; - pll_28nm->id = id; pll_28nm->phy = phy; ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index 36ee3f15d1e0..9ddd0adccce3 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -59,9 +59,6 @@ struct clk_bytediv { struct dsi_pll_28nm { struct clk_hw clk_hw; - int id; - struct platform_device *pdev; - struct msm_dsi_phy *phy; struct pll_28nm_cached_state cached_state; @@ -178,14 +175,14 @@ static unsigned long dsi_pll_28nm_clk_recalc_rate(struct clk_hw *hw, static int dsi_pll_28nm_vco_prepare(struct clk_hw *hw) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); - struct device *dev = &pll_28nm->pdev->dev; + struct device *dev = &pll_28nm->phy->pdev->dev; void __iomem *base = pll_28nm->phy->pll_base; bool locked; unsigned int bit_div, byte_div; int max_reads = 1000, timeout_us = 100; u32 val; - DBG("id=%d", pll_28nm->id); + DBG("id=%d", pll_28nm->phy->id); if (unlikely(pll_28nm->phy->pll_on)) return 0; @@ -227,7 +224,7 @@ static void dsi_pll_28nm_vco_unprepare(struct clk_hw *hw) { struct dsi_pll_28nm *pll_28nm = to_pll_28nm(hw); - DBG("id=%d", pll_28nm->id); + DBG("id=%d", pll_28nm->phy->id); if (unlikely(!pll_28nm->phy->pll_on)) return; @@ -368,7 +365,7 @@ static int dsi_28nm_restore_state(struct msm_dsi_phy *phy) ret = dsi_pll_28nm_clk_set_rate(phy->vco_hw, cached_state->vco_rate, 0); if (ret) { - DRM_DEV_ERROR(&pll_28nm->pdev->dev, + DRM_DEV_ERROR(&pll_28nm->phy->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } @@ -392,13 +389,13 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov .flags = CLK_IGNORE_UNUSED, .ops = &clk_ops_dsi_pll_28nm_vco, }; - struct device *dev = &pll_28nm->pdev->dev; + struct device *dev = &pll_28nm->phy->pdev->dev; struct clk_hw *hw; struct clk_bytediv *bytediv; struct clk_init_data bytediv_init = { }; int ret; - DBG("%d", pll_28nm->id); + DBG("%d", pll_28nm->phy->id); bytediv = devm_kzalloc(dev, sizeof(*bytediv), GFP_KERNEL); if (!bytediv) @@ -412,7 +409,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov if (!clk_name) return -ENOMEM; - snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->id); + snprintf(vco_name, 32, "dsi%dvco_clk", pll_28nm->phy->id); vco_init.name = vco_name; pll_28nm->clk_hw.init = &vco_init; @@ -425,8 +422,8 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov bytediv->hw.init = &bytediv_init; bytediv->reg = pll_28nm->phy->pll_base + REG_DSI_28nm_8960_PHY_PLL_CTRL_9; - snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->id); - snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->id); + snprintf(parent_name, 32, "dsi%dvco_clk", pll_28nm->phy->id); + snprintf(clk_name, 32, "dsi%dpllbyte", pll_28nm->phy->id); bytediv_init.name = clk_name; bytediv_init.ops = &clk_bytediv_ops; @@ -440,7 +437,7 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov return ret; provided_clocks[DSI_BYTE_PLL_CLK] = &bytediv->hw; - snprintf(clk_name, 32, "dsi%dpll", pll_28nm->id); + snprintf(clk_name, 32, "dsi%dpll", pll_28nm->phy->id); /* DIV3 */ hw = devm_clk_hw_register_divider(dev, clk_name, parent_name, 0, pll_28nm->phy->pll_base + @@ -456,7 +453,6 @@ static int pll_28nm_register(struct dsi_pll_28nm *pll_28nm, struct clk_hw **prov static int dsi_pll_28nm_8960_init(struct msm_dsi_phy *phy) { struct platform_device *pdev = phy->pdev; - int id = phy->id; struct dsi_pll_28nm *pll_28nm; int ret; @@ -467,8 +463,6 @@ static int dsi_pll_28nm_8960_init(struct msm_dsi_phy *phy) if (!pll_28nm) return -ENOMEM; - pll_28nm->pdev = pdev; - pll_28nm->id = id + 1; pll_28nm->phy = phy; ret = pll_28nm_register(pll_28nm, phy->provided_clocks->hws); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index 8e8cf9e63e8f..4df237ad0eaf 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -86,9 +86,6 @@ struct pll_7nm_cached_state { struct dsi_pll_7nm { struct clk_hw clk_hw; - int id; - struct platform_device *pdev; - struct msm_dsi_phy *phy; u64 vco_ref_clk_rate; @@ -320,7 +317,7 @@ static int dsi_pll_7nm_vco_set_rate(struct clk_hw *hw, unsigned long rate, { struct dsi_pll_7nm *pll_7nm = to_pll_7nm(hw); - DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->id, rate, + DBG("DSI PLL%d rate=%lu, parent's=%lu", pll_7nm->phy->id, rate, parent_rate); pll_7nm->vco_current_rate = rate; @@ -359,7 +356,7 @@ static int dsi_pll_7nm_lock_status(struct dsi_pll_7nm *pll) timeout_us); if (rc) pr_err("DSI PLL(%d) lock failed, status=0x%08x\n", - pll->id, status); + pll->phy->id, status); return rc; } @@ -435,7 +432,7 @@ static int dsi_pll_7nm_vco_prepare(struct clk_hw *hw) /* Check for PLL lock */ rc = dsi_pll_7nm_lock_status(pll_7nm); if (rc) { - pr_err("PLL(%d) lock failed\n", pll_7nm->id); + pr_err("PLL(%d) lock failed\n", pll_7nm->phy->id); goto error; } @@ -519,7 +516,7 @@ static unsigned long dsi_pll_7nm_vco_recalc_rate(struct clk_hw *hw, vco_rate = pll_freq; DBG("DSI PLL%d returning vco rate = %lu, dec = %x, frac = %x", - pll_7nm->id, (unsigned long)vco_rate, dec, frac); + pll_7nm->phy->id, (unsigned long)vco_rate, dec, frac); return (unsigned long)vco_rate; } @@ -568,7 +565,7 @@ static void dsi_7nm_save_state(struct msm_dsi_phy *phy) cached->pll_mux = cmn_clk_cfg1 & 0x3; DBG("DSI PLL%d outdiv %x bit_clk_div %x pix_clk_div %x pll_mux %x", - pll_7nm->id, cached->pll_out_div, cached->bit_clk_div, + pll_7nm->phy->id, cached->pll_out_div, cached->bit_clk_div, cached->pix_clk_div, cached->pll_mux); } @@ -595,12 +592,12 @@ static int dsi_7nm_restore_state(struct msm_dsi_phy *phy) ret = dsi_pll_7nm_vco_set_rate(phy->vco_hw, pll_7nm->vco_current_rate, pll_7nm->vco_ref_clk_rate); if (ret) { - DRM_DEV_ERROR(&pll_7nm->pdev->dev, + DRM_DEV_ERROR(&pll_7nm->phy->pdev->dev, "restore vco rate failed. ret=%d\n", ret); return ret; } - DBG("DSI PLL%d", pll_7nm->id); + DBG("DSI PLL%d", pll_7nm->phy->id); return 0; } @@ -611,13 +608,13 @@ static int dsi_7nm_set_usecase(struct msm_dsi_phy *phy) void __iomem *base = phy->base; u32 data = 0x0; /* internal PLL */ - DBG("DSI PLL%d", pll_7nm->id); + DBG("DSI PLL%d", pll_7nm->phy->id); switch (phy->usecase) { case MSM_DSI_PHY_STANDALONE: break; case MSM_DSI_PHY_MASTER: - pll_7nm->slave = pll_7nm_list[(pll_7nm->id + 1) % DSI_MAX]; + pll_7nm->slave = pll_7nm_list[(pll_7nm->phy->id + 1) % DSI_MAX]; break; case MSM_DSI_PHY_SLAVE: data = 0x1; /* external PLL */ @@ -649,21 +646,21 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide .flags = CLK_IGNORE_UNUSED, .ops = &clk_ops_dsi_pll_7nm_vco, }; - struct device *dev = &pll_7nm->pdev->dev; + struct device *dev = &pll_7nm->phy->pdev->dev; struct clk_hw *hw; int ret; - DBG("DSI%d", pll_7nm->id); + DBG("DSI%d", pll_7nm->phy->id); - snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->id); + snprintf(vco_name, 32, "dsi%dvco_clk", pll_7nm->phy->id); pll_7nm->clk_hw.init = &vco_init; ret = devm_clk_hw_register(dev, &pll_7nm->clk_hw); if (ret) return ret; - snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); - snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->id); + snprintf(clk_name, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); + snprintf(parent, 32, "dsi%dvco_clk", pll_7nm->phy->id); hw = devm_clk_hw_register_divider(dev, clk_name, parent, CLK_SET_RATE_PARENT, @@ -675,8 +672,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide goto fail; } - snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); + snprintf(clk_name, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); /* BIT CLK: DIV_CTRL_3_0 */ hw = devm_clk_hw_register_divider(dev, clk_name, parent, @@ -690,8 +687,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide goto fail; } - snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); + snprintf(clk_name, 32, "dsi%d_phy_pll_out_byteclk", pll_7nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); /* DSI Byte clock = VCO_CLK / OUT_DIV / BIT_DIV / 8 */ hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, @@ -703,8 +700,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide provided_clocks[DSI_BYTE_PLL_CLK] = hw; - snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); + snprintf(clk_name, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 2); @@ -713,8 +710,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide goto fail; } - snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); + snprintf(clk_name, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); hw = devm_clk_hw_register_fixed_factor(dev, clk_name, parent, 0, 1, 4); @@ -723,11 +720,11 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide goto fail; } - snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->id); - snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->id); - snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->id); - snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->id); + snprintf(clk_name, 32, "dsi%d_pclk_mux", pll_7nm->phy->id); + snprintf(parent, 32, "dsi%d_pll_bit_clk", pll_7nm->phy->id); + snprintf(parent2, 32, "dsi%d_pll_by_2_bit_clk", pll_7nm->phy->id); + snprintf(parent3, 32, "dsi%d_pll_out_div_clk", pll_7nm->phy->id); + snprintf(parent4, 32, "dsi%d_pll_post_out_div_clk", pll_7nm->phy->id); hw = devm_clk_hw_register_mux(dev, clk_name, ((const char *[]){ @@ -740,8 +737,8 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide goto fail; } - snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->id); - snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->id); + snprintf(clk_name, 32, "dsi%d_phy_pll_out_dsiclk", pll_7nm->phy->id); + snprintf(parent, 32, "dsi%d_pclk_mux", pll_7nm->phy->id); /* PIX CLK DIV : DIV_CTRL_7_4*/ hw = devm_clk_hw_register_divider(dev, clk_name, parent, @@ -766,7 +763,6 @@ static int pll_7nm_register(struct dsi_pll_7nm *pll_7nm, struct clk_hw **provide static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) { struct platform_device *pdev = phy->pdev; - int id = phy->id; struct dsi_pll_7nm *pll_7nm; int ret; @@ -774,11 +770,9 @@ static int dsi_pll_7nm_init(struct msm_dsi_phy *phy) if (!pll_7nm) return -ENOMEM; - DBG("DSI PLL%d", id); + DBG("DSI PLL%d", phy->id); - pll_7nm->pdev = pdev; - pll_7nm->id = id; - pll_7nm_list[id] = pll_7nm; + pll_7nm_list[phy->id] = pll_7nm; spin_lock_init(&pll_7nm->postdiv_lock); From patchwork Sat Mar 27 11:03:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 410150 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2161131jai; Sat, 27 Mar 2021 04:04:04 -0700 (PDT) X-Google-Smtp-Source: ABdhPJw5AQZnGHsJB8ugRwOkdBVgHIKdOe6sGhLy0pQNgxYfNn9tZCXWVZBHFPVkhux7+B3sOY4A X-Received: by 2002:a17:902:c407:b029:e7:2272:d164 with SMTP id k7-20020a170902c407b02900e72272d164mr7579477plk.84.1616843044370; Sat, 27 Mar 2021 04:04:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616843044; cv=none; d=google.com; s=arc-20160816; b=043ZHH3qtjUntaEJCW3IRKWIaAevM8E3fbYJDfm5590zf03Pma+N4Z3fNCluCryVHa +dAf65E1Ij0YGuJK0c54x+0YCMClkSuQGiMdMKnWPOPht2SSJAdzARL8Z5/nv94JRdAO EYoGjLjoLFgEpCJWT4EBAE2A+55bzvE3Qv8bjs6IIRcsDqyaTeZcatnXUpG3bBtoGK7G tibDsylWqqngRsAbD0hEqaAQJC1RkSsX9xhCVgSkKdhFVgstYgxCRcIWlBqpii9JIYle 8NQJ5cVTPIlIBCouYMCdESBNgCx6oF8JAQ3kERewOgy1LqDZW1klOptovN5X9nG8k3nF 4PCg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:mime-version:references:in-reply-to:message-id:date :subject:to:from:dkim-signature:delivered-to; bh=FyB2ppc6E0Qs36txqSyzV91/Kwh6fNaPgwO2i0yiJtI=; b=uolPH5qp5h9u6viN/vAmO8WVtjUFx6SBgHKQcTqH6RP0BU10aVcow7Gp9Nln7teLum CNiUd9THx4l1lGCkvKev9I+n4UQwgjUU/SXdF2ESJjdocIZsqZ7glKFgpLpB4aZaVhHx hJRLLG05T3EHtvWX+rQPMdCKns7KEhWwgO+kLSkixg4X6aln5m99KTXtBMcvHgeGsQ2p vVHYEot5wJIbgFu/ju4rCU3/puQ5R1VjmN7O1cN1MF+Vb6gFZ3SJV71XF+7wFHYL7EQ3 oKTbQ+NXuWogd811fhgjoA/spKrlmEVrYXgNJVAeJFFESP/xqVsl4cU/Yx/T7XA4sUeh jXNw== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=QqEK6Zen; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [2610:10:20:722:a800:ff:fe36:1795]) by mx.google.com with ESMTPS id t134si8100004pgb.562.2021.03.27.04.04.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:04:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) client-ip=2610:10:20:722:a800:ff:fe36:1795; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=QqEK6Zen; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 4681B6F552; Sat, 27 Mar 2021 11:03:58 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lf1-x131.google.com (mail-lf1-x131.google.com [IPv6:2a00:1450:4864:20::131]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3EA486F547 for ; Sat, 27 Mar 2021 11:03:32 +0000 (UTC) Received: by mail-lf1-x131.google.com with SMTP id i26so11480427lfl.1 for ; Sat, 27 Mar 2021 04:03:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/njt+uUCZNJzAIJu6Xawu+LDgQvUw34OuhMj4mb0BLs=; b=QqEK6Zen3lcqSQu3uYxHdP67ui3VPrYbBX701avXFJDgZF9dPwl38w7Qm5ZO0p/F0r bDzjSk2q6y5/TeUlEAJ1XN83X3hbpthS95mE8PPcSTu1FzPSCb7Kq6iYldbHMX+FUc0P oH6Wqi9sUDKZCtkQtcSYW0+KoueIpqSH2WfGI9lIGc/rBxxwxVjCTYVaIAEDpQV0FVqV gBTBbfPanc14jooffb9iHDsX205NRCajTspC91V0npLt1CCUgx5YL8eZNdjBw47KXNOy AYTIQ1f1NTq0oMBLKLmBHI/iNWoZXtNNHDeGNBXkSMhVD4SdN8prachPgtzbbQwac6Nt BKOA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=/njt+uUCZNJzAIJu6Xawu+LDgQvUw34OuhMj4mb0BLs=; b=dBuJB9w3UbKUDfW6kJVxXjVJnDafcEOoVYB4DZyWpHnQ45tFdfYf6vXM5G70FIuK3w VLmjHUBbghRC+Pwt31mVaKww9h71ty7GTbYSM/hfeNgebxk6nDqVQpSdUw+gHBm7vLw2 em1K0ZOd+oZvBvwD+MmOB9nQS4ozp7pc9Ki2cOnNviqdZg0ATyPhZ7Ac716ZiG/CETYP IdT4tXe1sjZrT79ZW/2QGFWhyVMjLmkzDl1tFiQeRqFaot+bpBKkQqKoPnE0pxvMFLPS bPSiCQV5n/V/RBgH2m+Mz1ywv/MC2iq1CdXZ1wdXOyw7Iq0eKA0zdkQUgIJlsQZ1c+C9 zaDQ== X-Gm-Message-State: AOAM531c0ZAgIiLrwzc2Yf1ObZkQFxWp7sZbM0Q4/NvWTJx3rNd3sSVx Fxo5zs3dUK6j7Pm823DADnC5XQ== X-Received: by 2002:a19:6d16:: with SMTP id i22mr11576942lfc.510.1616843010679; Sat, 27 Mar 2021 04:03:30 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id a8sm1513801ljn.96.2021.03.27.04.03.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:30 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Jonathan Marek , Michael Turquette Subject: [PATCH v3 24/25] drm/msm/dsi: inline msm_dsi_phy_set_src_pll Date: Sat, 27 Mar 2021 14:03:04 +0300 Message-Id: <20210327110305.3289784-25-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> References: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org, linux-clk@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" The src_truthtable config is not used for some of phys, which use other means of configuring the master/slave usecases. Inline this function with the goal of removing src_pll_id argument in the next commit. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 17 ----------------- drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 8 -------- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 2 -- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 13 +++++++------ drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c | 11 +++++++---- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 13 +++++++------ drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 1 - drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 2 -- 8 files changed, 21 insertions(+), 46 deletions(-) -- 2.30.2 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel Reviewed-by: Abhinav Kumar diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 74cc11c84d71..56f5134e3933 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -461,23 +461,6 @@ int msm_dsi_dphy_timing_calc_v4(struct msm_dsi_dphy_timing *timing, return 0; } -void msm_dsi_phy_set_src_pll(struct msm_dsi_phy *phy, int pll_id, u32 reg, - u32 bit_mask) -{ - int phy_id = phy->id; - u32 val; - - if ((phy_id >= DSI_MAX) || (pll_id >= DSI_MAX)) - return; - - val = dsi_phy_read(phy->base + reg); - - if (phy->cfg->src_pll_truthtable[phy_id][pll_id]) - dsi_phy_write(phy->base + reg, val | bit_mask); - else - dsi_phy_write(phy->base + reg, val & (~bit_mask)); -} - static int dsi_phy_regulator_init(struct msm_dsi_phy *phy) { struct regulator_bulk_data *s = phy->supplies; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 8e828c5ca8f4..3b207cf9f6b4 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -33,12 +33,6 @@ struct msm_dsi_phy_cfg { unsigned long min_pll_rate; unsigned long max_pll_rate; - /* - * Each cell {phy_id, pll_id} of the truth table indicates - * if the source PLL selection bit should be set for each PHY. - * Fill default H/W values in illegal cells, eg. cell {0, 1}. - */ - bool src_pll_truthtable[DSI_MAX][DSI_MAX]; const resource_size_t io_start[DSI_MAX]; const int num_dsi_phy; const int quirks; @@ -121,7 +115,5 @@ int msm_dsi_dphy_timing_calc_v3(struct msm_dsi_dphy_timing *timing, struct msm_dsi_phy_clk_request *clk_req); int msm_dsi_dphy_timing_calc_v4(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); #endif /* __DSI_PHY_H__ */ diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 1fbb54f4df98..04535ccd11ef 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -919,7 +919,6 @@ static void dsi_10nm_phy_disable(struct msm_dsi_phy *phy) } const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = { - .src_pll_truthtable = { {false, false}, {true, false} }, .has_phy_lane = true, .reg_cfg = { .num = 1, @@ -941,7 +940,6 @@ const struct msm_dsi_phy_cfg dsi_phy_10nm_cfgs = { }; const struct msm_dsi_phy_cfg dsi_phy_10nm_8998_cfgs = { - .src_pll_truthtable = { {false, false}, {true, false} }, .has_phy_lane = true, .reg_cfg = { .num = 1, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index d08ad0c632b4..7a87bed71e36 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -947,6 +947,7 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, int ret; void __iomem *base = phy->base; void __iomem *lane_base = phy->lane_base; + u32 glbl_test_ctrl; if (msm_dsi_dphy_timing_calc_v2(timing, clk_req)) { DRM_DEV_ERROR(&phy->pdev->dev, @@ -994,10 +995,12 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, udelay(100); dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x00); - msm_dsi_phy_set_src_pll(phy, src_pll_id, - REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, - DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL); - + glbl_test_ctrl = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL); + if (phy->id == DSI_1 && src_pll_id == DSI_0) + glbl_test_ctrl |= DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL; + else + glbl_test_ctrl &= ~DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL; + dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL, glbl_test_ctrl); ret = dsi_14nm_set_usecase(phy); if (ret) { DRM_DEV_ERROR(&phy->pdev->dev, "%s: set pll usecase failed, %d\n", @@ -1021,7 +1024,6 @@ static void dsi_14nm_phy_disable(struct msm_dsi_phy *phy) } const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs = { - .src_pll_truthtable = { {false, false}, {true, false} }, .has_phy_lane = true, .reg_cfg = { .num = 1, @@ -1043,7 +1045,6 @@ const struct msm_dsi_phy_cfg dsi_phy_14nm_cfgs = { }; const struct msm_dsi_phy_cfg dsi_phy_14nm_660_cfgs = { - .src_pll_truthtable = { {false, false}, {true, false} }, .has_phy_lane = true, .reg_cfg = { .num = 1, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c index 5e73f811d645..f5b88c85a8fc 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c @@ -70,6 +70,7 @@ static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, int i; void __iomem *base = phy->base; u32 cfg_4[4] = {0x20, 0x40, 0x20, 0x00}; + u32 val; DBG(""); @@ -83,9 +84,12 @@ static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, dsi_phy_write(base + REG_DSI_20nm_PHY_STRENGTH_0, 0xff); - msm_dsi_phy_set_src_pll(phy, src_pll_id, - REG_DSI_20nm_PHY_GLBL_TEST_CTRL, - DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL); + val = dsi_phy_read(base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL); + if (src_pll_id == DSI_1) + val |= DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; + else + val &= ~DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; + dsi_phy_write(base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL, val); for (i = 0; i < 4; i++) { dsi_phy_write(base + REG_DSI_20nm_PHY_LN_CFG_3(i), @@ -125,7 +129,6 @@ static void dsi_20nm_phy_disable(struct msm_dsi_phy *phy) } const struct msm_dsi_phy_cfg dsi_phy_20nm_cfgs = { - .src_pll_truthtable = { {false, true}, {false, true} }, .has_phy_regulator = true, .reg_cfg = { .num = 2, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 0bcea3f3eca3..9f83ab90d093 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -704,6 +704,7 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, struct msm_dsi_dphy_timing *timing = &phy->timing; int i; void __iomem *base = phy->base; + u32 val; DBG(""); @@ -743,9 +744,12 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f); - msm_dsi_phy_set_src_pll(phy, src_pll_id, - REG_DSI_28nm_PHY_GLBL_TEST_CTRL, - DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL); + val = dsi_phy_read(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL); + if (phy->id == DSI_1 && src_pll_id == DSI_0) + val &= ~DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; + else + val |= DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; + dsi_phy_write(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL, val); return 0; } @@ -763,7 +767,6 @@ static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy) } const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = { - .src_pll_truthtable = { {true, true}, {false, true} }, .has_phy_regulator = true, .reg_cfg = { .num = 1, @@ -785,7 +788,6 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_cfgs = { }; const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = { - .src_pll_truthtable = { {true, true}, {false, true} }, .has_phy_regulator = true, .reg_cfg = { .num = 1, @@ -807,7 +809,6 @@ const struct msm_dsi_phy_cfg dsi_phy_28nm_hpm_famb_cfgs = { }; const struct msm_dsi_phy_cfg dsi_phy_28nm_lp_cfgs = { - .src_pll_truthtable = { {true, true}, {true, true} }, .has_phy_regulator = true, .reg_cfg = { .num = 1, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index 9ddd0adccce3..d2bfe43c9ef1 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -642,7 +642,6 @@ static void dsi_28nm_phy_disable(struct msm_dsi_phy *phy) } const struct msm_dsi_phy_cfg dsi_phy_28nm_8960_cfgs = { - .src_pll_truthtable = { {true, true}, {false, true} }, .has_phy_regulator = true, .reg_cfg = { .num = 1, diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index ce6ae2fba993..619998506b78 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -955,7 +955,6 @@ static void dsi_7nm_phy_disable(struct msm_dsi_phy *phy) } const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = { - .src_pll_truthtable = { {false, false}, {true, false} }, .has_phy_lane = true, .reg_cfg = { .num = 1, @@ -978,7 +977,6 @@ const struct msm_dsi_phy_cfg dsi_phy_7nm_cfgs = { }; const struct msm_dsi_phy_cfg dsi_phy_7nm_8150_cfgs = { - .src_pll_truthtable = { {false, false}, {true, false} }, .has_phy_lane = true, .reg_cfg = { .num = 1, From patchwork Sat Mar 27 11:03:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 410152 Delivered-To: patch@linaro.org Received: by 2002:a02:8562:0:0:0:0:0 with SMTP id g89csp2161176jai; Sat, 27 Mar 2021 04:04:07 -0700 (PDT) X-Google-Smtp-Source: ABdhPJzYZ1fV/aJCVFr8JhI4QtuGtdb+5wE5mqPKP/AtT7+kVHRFiODr/nsCPk/1Eh16JL1AyOYI X-Received: by 2002:aa7:93af:0:b029:1ef:1bb9:b1a1 with SMTP id x15-20020aa793af0000b02901ef1bb9b1a1mr17370329pff.49.1616843047182; Sat, 27 Mar 2021 04:04:07 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1616843047; cv=none; d=google.com; s=arc-20160816; b=L8CWd7bBJEMW2i5cZoKo+iqf5eJcAvBGs9ugBRXdgW+ZrwsBQ4hCxasaWiWs/dz/3F y3U2SWrFRqjXe//EcYihKWt3fBylzOWcAMdRyQebSZXpE47NLIz9q34KngG8BpVgvPdX IX14A+j/vHbgad6TnOuuDuVN/wBLiEsO+T5WSko/nOklK9LUozaghUST3Zv2/np+7QmW MUjZ8fMPGCdvxkKK7eHvQ8KpMeKfgbM3cXZsvhlhUiXIzDgvxHbw6YR+FcBZpVCIUFnL QufYODyi2Vij5oXafaCyfaNOat51KfV5BeGjNqUlMFCMARy0yk6V0EiSr20ow41RWoNx DArA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=sender:errors-to:content-transfer-encoding:cc:list-subscribe :list-help:list-post:list-archive:list-unsubscribe:list-id :precedence:mime-version:references:in-reply-to:message-id:date :subject:to:from:dkim-signature:delivered-to; bh=EE9zxZWoO9N/EGO9xL8vJuD0Y28TMpszdsbDnEA0bDE=; b=GuVYwoTFdlLc5QFsL5Cn49XjSLIdkxwuo8MIrw5vXG7XxPXlnW1v0FPy4QAI610vcQ hzT3bKrKMx6Eya89yMtuigINx/UeFSSoTDk571tFr/+w/I7YLxFFNAYtySBkuit17sGI mZl0mnr6OgHNULkx8BHIr1sIMMtl++GdMKn+h/jjShFDXq43xKH7Vv/aCPm7LpfvYCNy Lo1dWGV++vKki8cSoY9buTG2mXlx5Z6/kWLRnyrxOCbfI9aGRmNFvQAzElQloJnrVXJK OIcWK93k42f+hFw0EARauVqkZL+YUK2ml3ebvwj4nSZMI983Nm/wI/L8HVsXgoc66o+n awPQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=YCRrIdYu; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from gabe.freedesktop.org (gabe.freedesktop.org. [2610:10:20:722:a800:ff:fe36:1795]) by mx.google.com with ESMTPS id u21si4921827plj.35.2021.03.27.04.04.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:04:07 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) client-ip=2610:10:20:722:a800:ff:fe36:1795; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@linaro.org header.s=google header.b=YCRrIdYu; spf=pass (google.com: best guess record for domain of dri-devel-bounces@lists.freedesktop.org designates 2610:10:20:722:a800:ff:fe36:1795 as permitted sender) smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5E8C66F555; Sat, 27 Mar 2021 11:04:00 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-lj1-x233.google.com (mail-lj1-x233.google.com [IPv6:2a00:1450:4864:20::233]) by gabe.freedesktop.org (Postfix) with ESMTPS id F1E036F54F for ; Sat, 27 Mar 2021 11:03:32 +0000 (UTC) Received: by mail-lj1-x233.google.com with SMTP id y1so10265390ljm.10 for ; Sat, 27 Mar 2021 04:03:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=PJJjZU/dZPLTREAZ4tUVFU4MyLEu0dI478/3AFUSxGk=; b=YCRrIdYuof2G7DcvA3s032ydXQR3+rThjCmEC9+EMTSFRm2t2BdwrepUW/OMnKak0L KSH5pe7gNzlkI/8IWlwzV+0Q7pmv12DW40SqJDwX452glWWCinegD5GnoxIo2nn4Mv8x LQOa5ecVd2ejhcQTZTr6t42oA7ML9IuNoT2iAmvk9TCrZVdx/xS6sOihqIZ+XVhyBYSQ WE1S24RKGuoKxfzEKSMK019/Z9ZWkdmjHnex6/ORlgTzm2vgyGYaS9QMeVqsKAomtO5e 4968Ncbwv2Fg+sSNUamLBpVj2TUF3KMUHDP9a5gM0mAW5nW9ABOBtbG3unp9LxmlhVsJ gCDg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=PJJjZU/dZPLTREAZ4tUVFU4MyLEu0dI478/3AFUSxGk=; b=KuCI6LliUsbSXXeWcpykaOg2zBzc7t2L8HcCvtOUB13RnVWX19sX9XJE14xzsfGeRb JsxuS8Ns6QHDD6jlg8XT72e4bcfHy6PpJCtbv4hURLq1L+AyAOS+WpFCww5A9b+Kz+DG CBa1vEUEbSQNUsKd3OiobM2+OSmxxBdymEQcZ1loWxpvORuuipdna8gxNVqyOcLLqqoK 3iMchftCQ7qG/Cx36IJ3P1irqB5/oMa+NfVT5MdA+xrvqvOMwMSI2ev7KnFpQq4Ei0kj 0/aZuyP0JMiJNAAXFwLMsDTtFCaYid41KOymkieehTdOjOArivM1OcpCE83ek+uQk7Rd 6XlA== X-Gm-Message-State: AOAM530AwchsY0VJhyqA8Lf2gSuYGHIwAlL0V4NRcw6FBSvoLmFFLAJi /mKf75U+HwS3K/IcB7M4LptyDw== X-Received: by 2002:a2e:5804:: with SMTP id m4mr11582837ljb.419.1616843011397; Sat, 27 Mar 2021 04:03:31 -0700 (PDT) Received: from eriador.lan ([37.153.55.125]) by smtp.gmail.com with ESMTPSA id a8sm1513801ljn.96.2021.03.27.04.03.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sat, 27 Mar 2021 04:03:31 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Jonathan Marek , Michael Turquette Subject: [PATCH v3 25/25] drm/msm/dsi: stop passing src_pll_id to the phy_enable call Date: Sat, 27 Mar 2021 14:03:05 +0300 Message-Id: <20210327110305.3289784-26-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> References: <20210327110305.3289784-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Stephen Boyd , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, David Airlie , freedreno@lists.freedesktop.org, linux-clk@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Phy driver already knows the source PLL id basing on the set usecase and the current PLL id. Stop passing it to the phy_enable call. As a reminder, dsi manager will always use DSI 0 as a clock master in a slave mode, so PLL 0 is always a clocksource for DSI 0 and it is always a clocksource for DSI 1 too unless DSI 1 is used in the standalone mode. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/dsi/dsi.h | 2 +- drivers/gpu/drm/msm/dsi/dsi_manager.c | 11 +++++------ drivers/gpu/drm/msm/dsi/phy/dsi_phy.c | 4 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy.h | 2 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c | 2 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c | 4 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c | 4 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c | 4 ++-- drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c | 2 +- drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c | 2 +- 10 files changed, 18 insertions(+), 19 deletions(-) -- 2.30.2 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 53feea9d30c0..c8ef63bdc042 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -162,7 +162,7 @@ struct msm_dsi_phy_clk_request { void msm_dsi_phy_driver_register(void); void msm_dsi_phy_driver_unregister(void); -int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, +int msm_dsi_phy_enable(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req); void msm_dsi_phy_disable(struct msm_dsi_phy *phy); void msm_dsi_phy_get_shared_timings(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 0c47c5fb1ab3..76735cde57c6 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -114,7 +114,7 @@ static int dsi_mgr_setup_components(int id) return ret; } -static int enable_phy(struct msm_dsi *msm_dsi, int src_pll_id, +static int enable_phy(struct msm_dsi *msm_dsi, struct msm_dsi_phy_shared_timings *shared_timings) { struct msm_dsi_phy_clk_request clk_req; @@ -123,7 +123,7 @@ static int enable_phy(struct msm_dsi *msm_dsi, int src_pll_id, msm_dsi_host_get_phy_clk_req(msm_dsi->host, &clk_req, is_dual_dsi); - ret = msm_dsi_phy_enable(msm_dsi->phy, src_pll_id, &clk_req); + ret = msm_dsi_phy_enable(msm_dsi->phy, &clk_req); msm_dsi_phy_get_shared_timings(msm_dsi->phy, shared_timings); return ret; @@ -136,7 +136,6 @@ dsi_mgr_phy_enable(int id, struct msm_dsi *msm_dsi = dsi_mgr_get_dsi(id); struct msm_dsi *mdsi = dsi_mgr_get_dsi(DSI_CLOCK_MASTER); struct msm_dsi *sdsi = dsi_mgr_get_dsi(DSI_CLOCK_SLAVE); - int src_pll_id = IS_DUAL_DSI() ? DSI_CLOCK_MASTER : id; int ret; /* In case of dual DSI, some registers in PHY1 have been programmed @@ -149,11 +148,11 @@ dsi_mgr_phy_enable(int id, msm_dsi_host_reset_phy(mdsi->host); msm_dsi_host_reset_phy(sdsi->host); - ret = enable_phy(mdsi, src_pll_id, + ret = enable_phy(mdsi, &shared_timings[DSI_CLOCK_MASTER]); if (ret) return ret; - ret = enable_phy(sdsi, src_pll_id, + ret = enable_phy(sdsi, &shared_timings[DSI_CLOCK_SLAVE]); if (ret) { msm_dsi_phy_disable(mdsi->phy); @@ -162,7 +161,7 @@ dsi_mgr_phy_enable(int id, } } else { msm_dsi_host_reset_phy(msm_dsi->host); - ret = enable_phy(msm_dsi, src_pll_id, &shared_timings[id]); + ret = enable_phy(msm_dsi, &shared_timings[id]); if (ret) return ret; } diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c index 56f5134e3933..2a421fd77f2f 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.c @@ -753,7 +753,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, int src_pll_id, +int msm_dsi_phy_enable(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req) { struct device *dev = &phy->pdev->dev; @@ -776,7 +776,7 @@ int msm_dsi_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, goto reg_en_fail; } - ret = phy->cfg->ops.enable(phy, src_pll_id, clk_req); + ret = phy->cfg->ops.enable(phy, clk_req); if (ret) { DRM_DEV_ERROR(dev, "%s: phy enable failed, %d\n", __func__, ret); goto phy_en_fail; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h index 3b207cf9f6b4..74fffcae0f10 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy.h @@ -19,7 +19,7 @@ struct msm_dsi_phy_ops { int (*pll_init)(struct msm_dsi_phy *phy); - int (*enable)(struct msm_dsi_phy *phy, int src_pll_id, + int (*enable)(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req); void (*disable)(struct msm_dsi_phy *phy); void (*save_state)(struct msm_dsi_phy *phy); diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c index 04535ccd11ef..bea68154ef87 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_10nm.c @@ -786,7 +786,7 @@ static void dsi_phy_hw_v3_0_lane_settings(struct msm_dsi_phy *phy) } } -static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, +static int dsi_10nm_phy_enable(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req) { int ret; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c index 7a87bed71e36..c9afa6c461ee 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_14nm.c @@ -938,7 +938,7 @@ static void dsi_14nm_dphy_set_timing(struct msm_dsi_phy *phy, DSI_14nm_PHY_LN_TIMING_CTRL_11_TRIG3_CMD(0xa0)); } -static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, +static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req) { struct msm_dsi_dphy_timing *timing = &phy->timing; @@ -996,7 +996,7 @@ static int dsi_14nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, dsi_phy_write(base + REG_DSI_14nm_PHY_CMN_CTRL_1, 0x00); glbl_test_ctrl = dsi_phy_read(base + REG_DSI_14nm_PHY_CMN_GLBL_TEST_CTRL); - if (phy->id == DSI_1 && src_pll_id == DSI_0) + if (phy->usecase == MSM_DSI_PHY_SLAVE) glbl_test_ctrl |= DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL; else glbl_test_ctrl &= ~DSI_14nm_PHY_CMN_GLBL_TEST_CTRL_BITCLK_HS_SEL; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c index f5b88c85a8fc..e96d789aea18 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_20nm.c @@ -63,7 +63,7 @@ static void dsi_20nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) dsi_phy_write(base + REG_DSI_20nm_PHY_REGULATOR_CTRL_0, 0x03); } -static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, +static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req) { struct msm_dsi_dphy_timing *timing = &phy->timing; @@ -85,7 +85,7 @@ static int dsi_20nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, dsi_phy_write(base + REG_DSI_20nm_PHY_STRENGTH_0, 0xff); val = dsi_phy_read(base + REG_DSI_20nm_PHY_GLBL_TEST_CTRL); - if (src_pll_id == DSI_1) + if (phy->id == DSI_1 && phy->usecase == MSM_DSI_PHY_STANDALONE) val |= DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; else val &= ~DSI_20nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c index 9f83ab90d093..0e8f74ebb895 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm.c @@ -698,7 +698,7 @@ static void dsi_28nm_phy_regulator_ctrl(struct msm_dsi_phy *phy, bool enable) dsi_28nm_phy_regulator_enable_dcdc(phy); } -static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, +static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req) { struct msm_dsi_dphy_timing *timing = &phy->timing; @@ -745,7 +745,7 @@ static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, dsi_phy_write(base + REG_DSI_28nm_PHY_CTRL_0, 0x5f); val = dsi_phy_read(base + REG_DSI_28nm_PHY_GLBL_TEST_CTRL); - if (phy->id == DSI_1 && src_pll_id == DSI_0) + if (phy->usecase == MSM_DSI_PHY_SLAVE) val &= ~DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; else val |= DSI_28nm_PHY_GLBL_TEST_CTRL_BITCLK_HS_SEL; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c index d2bfe43c9ef1..104446450f7c 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_28nm_8960.c @@ -585,7 +585,7 @@ static void dsi_28nm_phy_lane_config(struct msm_dsi_phy *phy) dsi_phy_write(base + REG_DSI_28nm_8960_PHY_LNCK_TEST_STR1, 0x88); } -static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, +static int dsi_28nm_phy_enable(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req) { struct msm_dsi_dphy_timing *timing = &phy->timing; diff --git a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c index 619998506b78..badc76a8d425 100644 --- a/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c +++ b/drivers/gpu/drm/msm/dsi/phy/dsi_phy_7nm.c @@ -799,7 +799,7 @@ static void dsi_phy_hw_v4_0_lane_settings(struct msm_dsi_phy *phy) } } -static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, int src_pll_id, +static int dsi_7nm_phy_enable(struct msm_dsi_phy *phy, struct msm_dsi_phy_clk_request *clk_req) { int ret;