From patchwork Sun Jun 25 11:42:08 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291890 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4C62EC3DA40 for ; Sun, 25 Jun 2023 11:42:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=hmqiZ4PQN6oqp5vX/AdWJs34z0PWyR1F0EgHyel/q7Q=; b=BiUFLv3M9FcP+O wTf/BioAYh31FVG+4dmKtqQroTO2ubMZnjI0myR0VkblJOX1h6S7YlMgE7SHdwAylnwdcJX1gvuxO cy8KtVLNA0/PCIIswzqswp2uZZRwVunypNESZtrYu+UVzJJzYqOlLtFcyQbHU3zzgwt2k7tzdwYw2 24ngAL3MMKXn8/UmZtjqwuQeEaDCFc4m5FvJB9Ti0vJW52nkmoKLplgPg33SbHp3anbOq++3sxg43 aAV5ouk8+8UDb2CspatJeX3UAbx6gzWV3K7wxIOeZbt8Z2Wpbl5+y2Kb0FQ7fzF2eCZHZnoDiZrjK qyhtVmEtAVFwvblkchpA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8Y-007w2F-2g; Sun, 25 Jun 2023 11:42:34 +0000 Received: from mail-lj1-x22f.google.com ([2a00:1450:4864:20::22f]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8T-007vzr-0o for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:33 +0000 Received: by mail-lj1-x22f.google.com with SMTP id 38308e7fff4ca-2b45e347266so31989631fa.0 for ; Sun, 25 Jun 2023 04:42:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693344; x=1690285344; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Ee9qxsINn9dwQQTKQ6s0E4UzFdKioSthINPfeQJg8Jw=; b=EX3L88htawlQqvILyXJ3NkaBf8+4RX3uLTbwY6ggROilZVg3QNsi83qC7aea/4FwJx 1kduiYtVxYe6DDoAfb8ah6w4NKjtQ3lphfqvPdSaAAl+X0LHsHtlx4v3I/N0uMtOfXYv Jd69X7vrB5w4zgGMB6bxjz077t/mrBO8Ep0xoU3pe5AZryR2oyszzWBO+pDQm0pWl8eM QItULxfTJ88ud2/Ib1AK+fOlkUuYtv7QlG53C4FY+vtE+h7D1sBbYQPs4fRGIyFThr4a LR4H36/JFXDkiSlgSGyMZK+1B+xsfBqy4yS1Mvjc0QwjOnNV0G6wcoIL9iYDhZpV6CbJ H5CQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693344; x=1690285344; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Ee9qxsINn9dwQQTKQ6s0E4UzFdKioSthINPfeQJg8Jw=; b=d2Hbel9zy3nVILhNPaowkKYLpvnC6CeFChZWiEMoLqabh/V9ych3aKLYmTno1QhwLk 2CE+f/pa7bsBAiop4w0U3nQwUs3kyHDZYgb8fhrPrvaKV1fHB5LIunbQye2zLWkm5R0t nbihnnQ4jGnjs1BmSpTbWJ0gpFaFKMb4737atWEjJoE6rG/tljckPNZAUp9UH/8lARvp DD74xzlZERhcN/9pyxCamKwn1XuyD64bYsIJpE2JhdF3Ubpsx57lF/4sojwrJO9lYO0o HeBtncpbl6kZXNHgG5uG2hx8hDzG+pi3sBtJM25eee6S/CC4A0denbkljTo3P17x6TXF hCPQ== X-Gm-Message-State: AC+VfDym/bBXkHeE3prQ0t6lmLz29IgMvdLpGxKkHsWljI3LEfAF+psX O1KlKY0kAH5/acZU0K0sKb5jtg== X-Google-Smtp-Source: ACHHUZ555Vzkh7bREew39vbOyVZgxBDGUFOF+66ODdO4RvcbdyQSw98yjlLT7ZpaHEjp121HCoTPWQ== X-Received: by 2002:a19:5e48:0:b0:4f8:49a8:a0e2 with SMTP id z8-20020a195e48000000b004f849a8a0e2mr12908480lfi.16.1687693344498; Sun, 25 Jun 2023 04:42:24 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:24 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org, Sandor Yu Subject: [PATCH v2 01/15] phy: Add HDMI configuration options Date: Sun, 25 Jun 2023 14:42:08 +0300 Message-Id: <20230625114222.96689-2-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044229_294065_DABFC1FF X-CRM114-Status: GOOD ( 16.88 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org From: Sandor Yu Allow HDMI PHYs to be configured through the generic functions through a custom structure added to the generic union. The parameters added here are based on HDMI PHY implementation practices. The current set of parameters should cover the potential users. Signed-off-by: Sandor Yu Signed-off-by: Dmitry Baryshkov --- include/linux/phy/phy-hdmi.h | 33 +++++++++++++++++++++++++++++++++ include/linux/phy/phy.h | 7 ++++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100644 include/linux/phy/phy-hdmi.h diff --git a/include/linux/phy/phy-hdmi.h b/include/linux/phy/phy-hdmi.h new file mode 100644 index 000000000000..73a32eb535b0 --- /dev/null +++ b/include/linux/phy/phy-hdmi.h @@ -0,0 +1,33 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright 2022 NXP + */ + +#ifndef __PHY_HDMI_H_ +#define __PHY_HDMI_H_ + +enum hdmi_phy_colorspace { + HDMI_PHY_COLORSPACE_RGB, + HDMI_PHY_COLORSPACE_YUV422, + HDMI_PHY_COLORSPACE_YUV444, + HDMI_PHY_COLORSPACE_YUV420, + HDMI_PHY_COLORSPACE_RESERVED4, + HDMI_PHY_COLORSPACE_RESERVED5, + HDMI_PHY_COLORSPACE_RESERVED6, +}; + +/** + * struct phy_configure_opts_hdmi - HDMI configuration set + * @pixel_clk_rate: Pixel clock of video modes in KHz. + * @bpc: Maximum bits per color channel. + * @color_space: Colorspace in enum hdmi_phy_colorspace. + * + * This structure is used to represent the configuration state of a HDMI phy. + */ +struct phy_configure_opts_hdmi { + unsigned int pixel_clk_rate; + unsigned int bpc; + enum hdmi_phy_colorspace color_space; +}; + +#endif /* __PHY_HDMI_H_ */ diff --git a/include/linux/phy/phy.h b/include/linux/phy/phy.h index f6d607ef0e80..94d489a8a163 100644 --- a/include/linux/phy/phy.h +++ b/include/linux/phy/phy.h @@ -17,6 +17,7 @@ #include #include +#include #include #include @@ -42,7 +43,8 @@ enum phy_mode { PHY_MODE_MIPI_DPHY, PHY_MODE_SATA, PHY_MODE_LVDS, - PHY_MODE_DP + PHY_MODE_DP, + PHY_MODE_HDMI, }; enum phy_media { @@ -60,11 +62,14 @@ enum phy_media { * the DisplayPort protocol. * @lvds: Configuration set applicable for phys supporting * the LVDS phy mode. + * @hdmi: Configuration set applicable for phys supporting + * the HDMI phy mode. */ union phy_configure_opts { struct phy_configure_opts_mipi_dphy mipi_dphy; struct phy_configure_opts_dp dp; struct phy_configure_opts_lvds lvds; + struct phy_configure_opts_hdmi hdmi; }; /** From patchwork Sun Jun 25 11:42:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291892 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id EFC9EEB64DD for ; Sun, 25 Jun 2023 11:42:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=sUV/n2kBe1P0VX75XZWXUa30U3q5GDhZ6+rqq2VT1qY=; b=0T9Hws8lHIi5yr ZF3LbZQI7tD4JK+WDR5fQ8QOfLFLqbZ/WGjNeXX1sLLg2WAG5P2fZYdjVIZeKQpuqkUdqrp9PAyK7 /A8vIMD0SFbDzGqx25QtczX8q9qR71/pRUtour1YYlocEwxhdr36NV4YsZQ6KPOtJ9Gcz6xgD8zMr 5uxu3qwW0Do4NLj+H/na5m0t+8EjX8JwcMp2zk0LWGU6t9BNk5/McrrmZ9awrn1Xnhp3BitPnVhN6 ywA7JGiQUTGofmQbfqe+oJEcorgtt5ZP1rtusYUfAczD7jiHSrIOZlbLkQL74FHSUn1ZI/YRaSNnQ tFLAc5xya4CijcLTQg6w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8c-007w48-1f; Sun, 25 Jun 2023 11:42:38 +0000 Received: from mail-lf1-x136.google.com ([2a00:1450:4864:20::136]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8T-007vzv-0W for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:35 +0000 Received: by mail-lf1-x136.google.com with SMTP id 2adb3069b0e04-4f766777605so2829558e87.1 for ; Sun, 25 Jun 2023 04:42:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693345; x=1690285345; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1lbL2cnzLWBGXtey7uT89W2YDXURHiirIqN4Q9qDK+U=; b=ku9jpsDtK8kyCee2jpuYn3TywJY9eFQhGOhYJizzJGwF2RwHiJy8B1TmSdd17AkNin d8ZnFNZhM+4leZcPzwlvNS0aRne6Ia22jrhYYzJeV6jBHIyz/4IAz7LqjVHdUSoWydnz DOmX8jw90WeRXckpYC8FViC/k6y+PCzlJgGQNruBKbYWKmqG9ReU4HKd5yhCg/ODsMKz x10d7lxweUECtwl5KjjHA2nnRXQhVmf7GJPCddRn4u7/YkcKsE4pIaT/1Ca1vwmd3XpR KPux3FDDTb/WJQ7Ef8i9z/I3ll9pvcfFXcDbSI35GHv9FX7cgQDTv6edqFN/KTNDesmm NrIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693345; x=1690285345; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1lbL2cnzLWBGXtey7uT89W2YDXURHiirIqN4Q9qDK+U=; b=Him9LE+es7uUeJ0yLva1AfodgdYFfSbrSGkGhKUAiIDkI0Y7J5mpIxiAxGss6FA9Ae pUlpfM5bDlsS+a7TaXU7nF/FeZNQSYbFDmq2J2hPfq677U2aj0qXfpBqe/PjU97EhdnP LABEksu7B62IbC+c0M1CsVx7z5YjhvoSb8q63sCIVYfIIUZYxZCgGP4V8TazRa2n2cLw hr2BnMeAhTiR9HthSm74d1YhhhOgC9FIXmmNZZ2g0TlFnyjqdlUU4ol/PPMyVTIKmvTM BmgRX9Emnbt7ECsyUGeYgKdGVosh052kiShA4s5Jq7xztdoag2+7+SMY0vgOysSbOMvc ckiA== X-Gm-Message-State: AC+VfDzkVNB6vmAbJwldJdJRwmvV/mkUZIzdCPuvPxv+bf/5NMx0pWxu gRd2MKVZf1tYRpxAeu4g0oFsTA== X-Google-Smtp-Source: ACHHUZ6Su1qLKvejk6leQzHgJKQpbBQIMyRF4EKG0O2A0PYNcDYOi4f49oXqcc5XxaajmohuAqpv0A== X-Received: by 2002:ac2:4daa:0:b0:4f8:78aa:163e with SMTP id h10-20020ac24daa000000b004f878aa163emr9560228lfe.22.1687693345394; Sun, 25 Jun 2023 04:42:25 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:24 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 02/15] phy: qualcomm: add QMP HDMI PHY driver Date: Sun, 25 Jun 2023 14:42:09 +0300 Message-Id: <20230625114222.96689-3-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044229_254075_5D66DE5A X-CRM114-Status: GOOD ( 23.74 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Port Qualcomm QMP HDMI PHY to the generic PHY framework. Split the generic part and the msm8996 part. When adding support for msm8992/4 and msm8998 (which also employ QMP for HDMI PHY), one will have to provide the PLL programming part only. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Kconfig | 7 + drivers/phy/qualcomm/Makefile | 5 + drivers/phy/qualcomm/phy-qcom-qmp-hdmi-base.c | 184 ++++++++ .../phy/qualcomm/phy-qcom-qmp-hdmi-msm8996.c | 441 ++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-qmp-hdmi.h | 75 +++ 5 files changed, 712 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-hdmi-base.c create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-hdmi-msm8996.c create mode 100644 drivers/phy/qualcomm/phy-qcom-qmp-hdmi.h diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index 97ca5952e34e..4521fc9b9ced 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -68,6 +68,13 @@ config PHY_QCOM_QMP_COMBO Enable this to support the QMP Combo PHY transceiver that is used with USB3 and DisplayPort controllers on Qualcomm chips. +config PHY_QCOM_QMP_HDMI + tristate "Qualcomm QMP HDMI PHY Driver" + default PHY_QCOM_QMP && DRM_MSM_HDMI + help + Enable this to support the QMP HDMI PHY transceiver that is used + with HDMI output on Qualcomm MSM8996 chips. + config PHY_QCOM_QMP_PCIE tristate "Qualcomm QMP PCIe PHY Driver" depends on PCI || COMPILE_TEST diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index b030858e0f8d..32e27ffb7af6 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -7,11 +7,16 @@ obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o obj-$(CONFIG_PHY_QCOM_QMP_COMBO) += phy-qcom-qmp-combo.o +obj-$(CONFIG_PHY_QCOM_QMP_HDMI) += phy-qcom-qmp-hdmi.o obj-$(CONFIG_PHY_QCOM_QMP_PCIE) += phy-qcom-qmp-pcie.o obj-$(CONFIG_PHY_QCOM_QMP_PCIE_8996) += phy-qcom-qmp-pcie-msm8996.o obj-$(CONFIG_PHY_QCOM_QMP_UFS) += phy-qcom-qmp-ufs.o obj-$(CONFIG_PHY_QCOM_QMP_USB) += phy-qcom-qmp-usb.o +phy-qcom-qmp-hdmi-y := \ + phy-qcom-qmp-hdmi-base.o \ + phy-qcom-qmp-hdmi-msm8996.o \ + obj-$(CONFIG_PHY_QCOM_QUSB2) += phy-qcom-qusb2.o obj-$(CONFIG_PHY_QCOM_SNPS_EUSB2) += phy-qcom-snps-eusb2.o obj-$(CONFIG_PHY_QCOM_EUSB2_REPEATER) += phy-qcom-eusb2-repeater.o diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-hdmi-base.c b/drivers/phy/qualcomm/phy-qcom-qmp-hdmi-base.c new file mode 100644 index 000000000000..08132b3f82af --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-hdmi-base.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Ltd. + */ + +#include +#include +#include + +#include "phy-qcom-qmp-hdmi.h" + +int qmp_hdmi_phy_init(struct phy *phy) +{ + struct qmp_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); + + return pm_runtime_resume_and_get(hdmi_phy->dev); +} + +int qmp_hdmi_phy_configure(struct phy *phy, union phy_configure_opts *opts) +{ + const struct phy_configure_opts_hdmi *hdmi_opts = &opts->hdmi; + struct qmp_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); + int ret = 0; + + memcpy(&hdmi_phy->hdmi_opts, hdmi_opts, sizeof(*hdmi_opts)); + + return ret; +} + +int qmp_hdmi_phy_exit(struct phy *phy) +{ + struct qmp_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); + + pm_runtime_put_noidle(hdmi_phy->dev); + + return 0; +} + +static int __maybe_unused qmp_hdmi_runtime_resume(struct device *dev) +{ + struct qmp_hdmi_phy *hdmi_phy = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(ARRAY_SIZE(hdmi_phy->supplies), hdmi_phy->supplies); + if (ret) + return ret; + + ret = clk_bulk_prepare_enable(ARRAY_SIZE(hdmi_phy->clks), hdmi_phy->clks); + if (ret) + goto out_disable_supplies; + + return 0; + +out_disable_supplies: + regulator_bulk_disable(ARRAY_SIZE(hdmi_phy->supplies), hdmi_phy->supplies); + + return ret; +} + +static int __maybe_unused qmp_hdmi_runtime_suspend(struct device *dev) +{ + struct qmp_hdmi_phy *hdmi_phy = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(ARRAY_SIZE(hdmi_phy->clks), hdmi_phy->clks); + regulator_bulk_disable(ARRAY_SIZE(hdmi_phy->supplies), hdmi_phy->supplies); + + return 0; +} + +static int qmp_hdmi_probe(struct platform_device *pdev) +{ + struct clk_init_data init = { + .name = "hdmipll", + .parent_data = (const struct clk_parent_data[]) { + { .fw_name = "xo", .name = "xo_board" }, + }, + .flags = CLK_GET_RATE_NOCACHE, + .num_parents = 1, + }; + const struct qmp_hdmi_cfg *cfg = of_device_get_match_data(&pdev->dev); + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct qmp_hdmi_phy *hdmi_phy; + int ret, i; + + hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL); + if (!hdmi_phy) + return -ENOMEM; + + hdmi_phy->dev = dev; + + hdmi_phy->serdes = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(hdmi_phy->serdes)) + return PTR_ERR(hdmi_phy->serdes); + + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + hdmi_phy->tx[i] = devm_platform_ioremap_resource(pdev, 1 + i); + if (IS_ERR(hdmi_phy->tx[i])) + return PTR_ERR(hdmi_phy->tx[i]); + } + + hdmi_phy->phy_reg = devm_platform_ioremap_resource(pdev, 5); + if (IS_ERR(hdmi_phy->phy_reg)) + return PTR_ERR(hdmi_phy->phy_reg); + + hdmi_phy->clks[0].id = "iface"; + hdmi_phy->clks[1].id = "ref"; + ret = devm_clk_bulk_get(dev, ARRAY_SIZE(hdmi_phy->clks), hdmi_phy->clks); + if (ret) + return ret; + + hdmi_phy->supplies[0].supply = "vddio"; + hdmi_phy->supplies[0].init_load_uA = 100000; + hdmi_phy->supplies[1].supply = "vcca"; + hdmi_phy->supplies[1].init_load_uA = 10000; + ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(hdmi_phy->supplies), hdmi_phy->supplies); + if (ret) + return ret; + + platform_set_drvdata(pdev, hdmi_phy); + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + + init.ops = cfg->pll_ops; + hdmi_phy->pll_hw.init = &init; + ret = devm_clk_hw_register(hdmi_phy->dev, &hdmi_phy->pll_hw); + if (ret) + goto err; + + ret = devm_of_clk_add_hw_provider(hdmi_phy->dev, of_clk_hw_simple_get, &hdmi_phy->pll_hw); + if (ret) + goto err; + + hdmi_phy->phy = devm_phy_create(dev, pdev->dev.of_node, cfg->phy_ops); + if (IS_ERR(hdmi_phy->phy)) { + ret = PTR_ERR(hdmi_phy->phy); + goto err; + } + + phy_set_drvdata(hdmi_phy->phy, hdmi_phy); + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + pm_runtime_put_noidle(&pdev->dev); + return PTR_ERR_OR_ZERO(phy_provider); + +err: + pm_runtime_put_noidle(&pdev->dev); + return ret; +} + +static const struct of_device_id qmp_hdmi_of_match_table[] = { + { + .compatible = "qcom,hdmi-phy-8996", .data = &qmp_hdmi_8996_cfg, + }, + { }, +}; +MODULE_DEVICE_TABLE(of, qmp_hdmi_of_match_table); + +DEFINE_RUNTIME_DEV_PM_OPS(qmp_hdmi_pm_ops, + qmp_hdmi_runtime_suspend, + qmp_hdmi_runtime_resume, + NULL); + +static struct platform_driver qmp_hdmi_driver = { + .probe = qmp_hdmi_probe, + .driver = { + .name = "qcom-qmp-hdmi-phy", + .of_match_table = qmp_hdmi_of_match_table, + .pm = &qmp_hdmi_pm_ops, + }, +}; + +module_platform_driver(qmp_hdmi_driver); + +MODULE_AUTHOR("Dmitry Baryshkov "); +MODULE_DESCRIPTION("Qualcomm QMP HDMI PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-hdmi-msm8996.c b/drivers/phy/qualcomm/phy-qcom-qmp-hdmi-msm8996.c new file mode 100644 index 000000000000..27ffa70d0faa --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-hdmi-msm8996.c @@ -0,0 +1,441 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Ltd. + */ + +#include +#include +#include + +#include "phy-qcom-qmp-hdmi.h" +#include "phy-qcom-qmp-qserdes-com.h" +#include "phy-qcom-qmp-qserdes-txrx.h" + +#define HDMI_VCO_MAX_FREQ 12000000000UL +#define HDMI_VCO_MIN_FREQ 8000000000UL + +#define HDMI_PCLK_MAX_FREQ 600000000UL +#define HDMI_PCLK_MIN_FREQ 25000000UL + +#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL +#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL +#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000UL +#define HDMI_DEFAULT_REF_CLOCK 19200000 +#define HDMI_PLL_CMP_CNT 1024 + +#define HDMI_PLL_POLL_MAX_READS 100 +#define HDMI_PLL_POLL_TIMEOUT_US 150 + +#define REG_HDMI_8996_PHY_CFG 0x00000000 +#define REG_HDMI_8996_PHY_PD_CTL 0x00000004 +#define REG_HDMI_8996_PHY_MODE 0x00000008 +#define REG_HDMI_8996_PHY_MISR_CLEAR 0x0000000c +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_CFG0 0x00000010 +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_CFG1 0x00000014 +#define REG_HDMI_8996_PHY_TX0_TX1_PRBS_SEED_BYTE0 0x00000018 +#define REG_HDMI_8996_PHY_TX0_TX1_PRBS_SEED_BYTE1 0x0000001c +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_PATTERN0 0x00000020 +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_PATTERN1 0x00000024 +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_CFG0 0x00000028 +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_CFG1 0x0000002c +#define REG_HDMI_8996_PHY_TX2_TX3_PRBS_SEED_BYTE0 0x00000030 +#define REG_HDMI_8996_PHY_TX2_TX3_PRBS_SEED_BYTE1 0x00000034 +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_PATTERN0 0x00000038 +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_PATTERN1 0x0000003c +#define REG_HDMI_8996_PHY_DEBUG_BUS_SEL 0x00000040 +#define REG_HDMI_8996_PHY_TXCAL_CFG0 0x00000044 +#define REG_HDMI_8996_PHY_TXCAL_CFG1 0x00000048 +#define REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL 0x0000004c +#define REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL 0x00000050 +#define REG_HDMI_8996_PHY_LANE_BIST_CONFIG 0x00000054 +#define REG_HDMI_8996_PHY_CLOCK 0x00000058 +#define REG_HDMI_8996_PHY_MISC1 0x0000005c +#define REG_HDMI_8996_PHY_MISC2 0x00000060 +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_STATUS0 0x00000064 +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_STATUS1 0x00000068 +#define REG_HDMI_8996_PHY_TX0_TX1_BIST_STATUS2 0x0000006c +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_STATUS0 0x00000070 +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_STATUS1 0x00000074 +#define REG_HDMI_8996_PHY_TX2_TX3_BIST_STATUS2 0x00000078 +#define REG_HDMI_8996_PHY_PRE_MISR_STATUS0 0x0000007c +#define REG_HDMI_8996_PHY_PRE_MISR_STATUS1 0x00000080 +#define REG_HDMI_8996_PHY_PRE_MISR_STATUS2 0x00000084 +#define REG_HDMI_8996_PHY_PRE_MISR_STATUS3 0x00000088 +#define REG_HDMI_8996_PHY_POST_MISR_STATUS0 0x0000008c +#define REG_HDMI_8996_PHY_POST_MISR_STATUS1 0x00000090 +#define REG_HDMI_8996_PHY_POST_MISR_STATUS2 0x00000094 +#define REG_HDMI_8996_PHY_POST_MISR_STATUS3 0x00000098 +#define REG_HDMI_8996_PHY_STATUS 0x0000009c +#define REG_HDMI_8996_PHY_MISC3_STATUS 0x000000a0 +#define REG_HDMI_8996_PHY_MISC4_STATUS 0x000000a4 +#define REG_HDMI_8996_PHY_DEBUG_BUS0 0x000000a8 +#define REG_HDMI_8996_PHY_DEBUG_BUS1 0x000000ac +#define REG_HDMI_8996_PHY_DEBUG_BUS2 0x000000b0 +#define REG_HDMI_8996_PHY_DEBUG_BUS3 0x000000b4 +#define REG_HDMI_8996_PHY_PHY_REVISION_ID0 0x000000b8 +#define REG_HDMI_8996_PHY_PHY_REVISION_ID1 0x000000bc +#define REG_HDMI_8996_PHY_PHY_REVISION_ID2 0x000000c0 +#define REG_HDMI_8996_PHY_PHY_REVISION_ID3 0x000000c4 + +struct qmp_hdmi_8996_post_divider { + u64 vco_freq; + int hsclk_divsel; + int vco_ratio; + int tx_band_sel; +}; + +static inline u32 qmp_hdmi_8996_pll_get_pll_cmp(u64 fdata, unsigned long ref_clk) +{ + u64 dividend = HDMI_PLL_CMP_CNT * fdata; + u32 divisor = ref_clk * 10; + u32 rem; + + rem = do_div(dividend, divisor); + if (rem > (divisor >> 1)) + dividend++; + + return dividend - 1; +} + +static int qmp_hdmi_8996_pll_get_post_div(struct qmp_hdmi_8996_post_divider *pd, u64 bclk) +{ + int ratio[] = { 2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35 }; + int hs_divsel[] = { 0, 4, 8, 12, 1, 5, 2, 9, 3, 13, 10, 7, 14, 11, 15 }; + int tx_band_sel[] = { 0, 1, 2, 3 }; + u64 vco_freq[60]; + u64 vco, vco_optimal; + int half_rate_mode = 0; + int vco_optimal_index, vco_freq_index; + int i, j; + +retry: + vco_optimal = HDMI_VCO_MAX_FREQ; + vco_optimal_index = -1; + vco_freq_index = 0; + for (i = 0; i < 15; i++) { + for (j = 0; j < 4; j++) { + u32 ratio_mult = ratio[i] << tx_band_sel[j]; + + vco = bclk >> half_rate_mode; + vco *= ratio_mult; + vco_freq[vco_freq_index++] = vco; + } + } + + for (i = 0; i < 60; i++) { + u64 vco_tmp = vco_freq[i]; + + if ((vco_tmp >= HDMI_VCO_MIN_FREQ) && + (vco_tmp <= vco_optimal)) { + vco_optimal = vco_tmp; + vco_optimal_index = i; + } + } + + if (vco_optimal_index == -1) { + if (!half_rate_mode) { + half_rate_mode = 1; + goto retry; + } + + return -EINVAL; + } + + pd->vco_freq = vco_optimal; + pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4]; + pd->vco_ratio = ratio[vco_optimal_index / 4]; + pd->hsclk_divsel = hs_divsel[vco_optimal_index / 4]; + + return 0; +} + +static int qmp_hdmi_8996_phy_set_rate(struct qmp_hdmi_phy *hdmi_phy) +{ + unsigned long parent_rate = HDMI_DEFAULT_REF_CLOCK; + unsigned long rate = hdmi_phy->hdmi_opts.pixel_clk_rate * 1000; + struct qmp_hdmi_8996_post_divider pd; + bool gen_ssc = false; + u64 bclk; + u64 dec_start; + u64 frac_start; + u64 fdata; + u32 pll_divisor; + u32 rem; + u32 integloop_gain; + u32 pll_cmp; + int i, ret; + + bclk = ((u64)rate) * 10; + ret = qmp_hdmi_8996_pll_get_post_div(&pd, bclk); + if (ret) { + dev_err(hdmi_phy->dev, "PLL calculation failed\n"); + return ret; + } + + dec_start = pd.vco_freq; + pll_divisor = 4 * parent_rate; + do_div(dec_start, pll_divisor); + + frac_start = pd.vco_freq * (1 << 20); + + rem = do_div(frac_start, pll_divisor); + frac_start -= dec_start * (1 << 20); + if (rem > (pll_divisor >> 1)) + frac_start++; + + fdata = pd.vco_freq; + do_div(fdata, pd.vco_ratio); + + pll_cmp = qmp_hdmi_8996_pll_get_pll_cmp(fdata, parent_rate); + + /* Initially shut down PHY */ + dev_dbg(hdmi_phy->dev, "Disabling PHY"); + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_PD_CTL, 0x0); + udelay(500); + + /* Power up sequence */ + hdmi_pll_write(hdmi_phy, QSERDES_COM_BG_CTRL, 0x04); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_PD_CTL, 0x1); + hdmi_pll_write(hdmi_phy, QSERDES_COM_RESETSM_CNTRL, 0x20); + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL, 0x0f); + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL, 0x0f); + + hdmi_tx_chan_write(hdmi_phy, 0, QSERDES_TX_LANE_MODE, 0x43); + hdmi_tx_chan_write(hdmi_phy, 2, QSERDES_TX_LANE_MODE, 0x43); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1e); + hdmi_pll_write(hdmi_phy, QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07); + hdmi_pll_write(hdmi_phy, QSERDES_COM_SYSCLK_EN_SEL, 0x37); + hdmi_pll_write(hdmi_phy, QSERDES_COM_SYS_CLK_CTRL, 0x02); + hdmi_pll_write(hdmi_phy, QSERDES_COM_CLK_ENABLE1, 0x0e); + + if (frac_start != 0 || gen_ssc) { + hdmi_pll_write(hdmi_phy, QSERDES_COM_PLL_CCTRL_MODE0, 0x28); + hdmi_pll_write(hdmi_phy, QSERDES_COM_PLL_RCTRL_MODE0, 0x16); + hdmi_pll_write(hdmi_phy, QSERDES_COM_CP_CTRL_MODE0, + 11000000 / (parent_rate/ 20)); + integloop_gain = (64 * parent_rate) / HDMI_DEFAULT_REF_CLOCK; + } else { + hdmi_pll_write(hdmi_phy, QSERDES_COM_PLL_CCTRL_MODE0, 0x01); + hdmi_pll_write(hdmi_phy, QSERDES_COM_PLL_RCTRL_MODE0, 0x10); + hdmi_pll_write(hdmi_phy, QSERDES_COM_CP_CTRL_MODE0, 0x23); + integloop_gain = (1022 * parent_rate) / (100 * 1000 * 1000); + } + + /* Bypass VCO calibration */ + if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) { + hdmi_pll_write(hdmi_phy, QSERDES_COM_SVS_MODE_CLK_SEL, 1); + integloop_gain <<= 1; + } else { + hdmi_pll_write(hdmi_phy, QSERDES_COM_SVS_MODE_CLK_SEL, 2); + integloop_gain <<= 2; + } + + integloop_gain = min_t(u32, integloop_gain, 2046); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_BG_TRIM, 0x0f); + hdmi_pll_write(hdmi_phy, QSERDES_COM_PLL_IVCO, 0x0f); + hdmi_pll_write(hdmi_phy, QSERDES_COM_VCO_TUNE_CTRL, 0); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_BG_CTRL, 0x06); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_CLK_SELECT, 0x30); + hdmi_pll_write(hdmi_phy, QSERDES_COM_HSCLK_SEL, 0x20 | pd.hsclk_divsel); + hdmi_pll_write(hdmi_phy, QSERDES_COM_LOCK_CMP_EN, 0x0); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_DEC_START_MODE0, dec_start); + hdmi_pll_write(hdmi_phy, QSERDES_COM_DIV_FRAC_START1_MODE0, + frac_start & 0xff); + hdmi_pll_write(hdmi_phy, QSERDES_COM_DIV_FRAC_START2_MODE0, + (frac_start >> 8) & 0xff); + hdmi_pll_write(hdmi_phy, QSERDES_COM_DIV_FRAC_START3_MODE0, + (frac_start >> 16) & 0xf); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_INTEGLOOP_GAIN0_MODE0, + integloop_gain & 0xff); + hdmi_pll_write(hdmi_phy, QSERDES_COM_INTEGLOOP_GAIN1_MODE0, + (integloop_gain >> 8) & 0xff); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_LOCK_CMP1_MODE0, + pll_cmp & 0xff); + hdmi_pll_write(hdmi_phy, QSERDES_COM_LOCK_CMP2_MODE0, + (pll_cmp >> 8) & 0xff); + hdmi_pll_write(hdmi_phy, QSERDES_COM_LOCK_CMP3_MODE0, + (pll_cmp >> 16) & 0x3); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_VCO_TUNE_MAP, 0x00); + hdmi_pll_write(hdmi_phy, QSERDES_COM_CORE_CLK_EN, 0x2c); + hdmi_pll_write(hdmi_phy, QSERDES_COM_CORECLK_DIV, 5); + hdmi_pll_write(hdmi_phy, QSERDES_COM_CMN_CONFIG, 0x02); + + hdmi_pll_write(hdmi_phy, QSERDES_COM_RESCODE_DIV_NUM, 0x15); + + /* TX lanes setup (TX 0/1/2/3) */ + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_CLKBUF_ENABLE, 0x03); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TX_BAND, pd.tx_band_sel + 4); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_RESET_TSYNC_EN, 0x03); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_VMODE_CTRL1, 0x00); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TX_DRV_LVL_OFFSET, 0x00); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_RES_CODE_LANE_OFFSET, 0x00); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TRAN_DRVR_EMP_EN, 0x03); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_PARRATE_REC_DETECT_IDLE_EN, 0x40); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_HP_PD_ENABLES, + i != 3 ? 0xc : 0x3); + } + + if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) { + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TX_DRV_LVL, + i != 3 ? 0x25 : 0x22); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TX_EMP_POST1_LVL, + i != 3 ? 0x23 : 0x27); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_VMODE_CTRL2, + i != 3 ? 0x0d : 0x00); + } + } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) { + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TX_DRV_LVL, 0x25); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TX_EMP_POST1_LVL, 0x23); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_VMODE_CTRL2, + i != 3 ? 0x0d : 0x00); + } + } else { + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TX_DRV_LVL, 0x20); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_TX_EMP_POST1_LVL, 0x20); + hdmi_tx_chan_write(hdmi_phy, i, QSERDES_TX_VMODE_CTRL2, 0x0e); + } + } + + if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_MODE, 0x10); + else + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_MODE, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_PD_CTL, 0x1f); + + return 0; +} + +static int qmp_hdmi_8996_phy_power_on(struct phy *phy) +{ + struct qmp_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); + u32 status; + int i, ret = 0; + + ret = qmp_hdmi_8996_phy_set_rate(hdmi_phy); + if (ret) { + dev_err(hdmi_phy->dev, "Setting pixel clock rate failed\n"); + return ret; + } + + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_CFG, 0x1); + udelay(100); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_CFG, 0x19); + udelay(100); + + ret = readl_poll_timeout(hdmi_phy->serdes + QSERDES_COM_C_READY_STATUS, + status, status & BIT(0), + HDMI_PLL_POLL_TIMEOUT_US, + HDMI_PLL_POLL_MAX_READS * HDMI_PLL_POLL_TIMEOUT_US); + + if (ret) { + dev_warn(hdmi_phy->dev, "HDMI PLL is not locked\n"); + return ret; + } + + for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) + hdmi_tx_chan_write(hdmi_phy, i, + QSERDES_TX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, + 0x6f); + + /* Disable SSC */ + hdmi_pll_write(hdmi_phy, QSERDES_COM_SSC_PER1, 0x0); + hdmi_pll_write(hdmi_phy, QSERDES_COM_SSC_PER2, 0x0); + hdmi_pll_write(hdmi_phy, QSERDES_COM_SSC_STEP_SIZE1, 0x0); + hdmi_pll_write(hdmi_phy, QSERDES_COM_SSC_STEP_SIZE2, 0x0); + hdmi_pll_write(hdmi_phy, QSERDES_COM_SSC_EN_CENTER, 0x2); + + ret = readl_poll_timeout(hdmi_phy->phy_reg + REG_HDMI_8996_PHY_STATUS, + status, status & BIT(0), + HDMI_PLL_POLL_TIMEOUT_US, + HDMI_PLL_POLL_MAX_READS * HDMI_PLL_POLL_TIMEOUT_US); + if (ret) { + dev_warn(hdmi_phy->dev, "HDMI PLL is not locked\n"); + return ret; + } + + /* Restart the retiming buffer */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_CFG, 0x18); + udelay(1); + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_CFG, 0x19); + + return 0; +} + +static int qmp_hdmi_8996_phy_power_off(struct phy *phy) +{ + struct qmp_hdmi_phy *hdmi_phy = phy_get_drvdata(phy); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8996_PHY_CFG, 0x6); + usleep_range(100, 150); + + return 0; +} + +static long qmp_hdmi_8996_pll_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *parent_rate) +{ + return clamp(rate, HDMI_PCLK_MIN_FREQ, HDMI_PCLK_MAX_FREQ); +} + +static unsigned long qmp_hdmi_8996_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct qmp_hdmi_phy *phy = hw_clk_to_pll(hw); + u32 cmp1, cmp2, cmp3, pll_cmp; + + cmp1 = hdmi_pll_read(phy, QSERDES_COM_LOCK_CMP1_MODE0); + cmp2 = hdmi_pll_read(phy, QSERDES_COM_LOCK_CMP2_MODE0); + cmp3 = hdmi_pll_read(phy, QSERDES_COM_LOCK_CMP3_MODE0); + + pll_cmp = cmp1 | (cmp2 << 8) | (cmp3 << 16); + + return mult_frac(pll_cmp + 1, parent_rate, HDMI_PLL_CMP_CNT); +} + +static int qmp_hdmi_8996_pll_is_enabled(struct clk_hw *hw) +{ + struct qmp_hdmi_phy *phy = hw_clk_to_pll(hw); + u32 status; + int pll_locked; + + status = hdmi_pll_read(phy, QSERDES_COM_C_READY_STATUS); + pll_locked = status & BIT(0); + + return pll_locked; +} + +static const struct clk_ops qmp_hdmi_8996_pll_ops = { + .recalc_rate = qmp_hdmi_8996_pll_recalc_rate, + .round_rate = qmp_hdmi_8996_pll_round_rate, + .is_enabled = qmp_hdmi_8996_pll_is_enabled, +}; + +static const struct phy_ops qmp_hdmi_8996_phy_ops = { + .init = qmp_hdmi_phy_init, + .configure = qmp_hdmi_phy_configure, + .power_on = qmp_hdmi_8996_phy_power_on, + .power_off = qmp_hdmi_8996_phy_power_off, + .exit = qmp_hdmi_phy_exit, + .owner = THIS_MODULE, +}; + +const struct qmp_hdmi_cfg qmp_hdmi_8996_cfg = { + .pll_ops = &qmp_hdmi_8996_pll_ops, + .phy_ops = &qmp_hdmi_8996_phy_ops, +}; diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-hdmi.h b/drivers/phy/qualcomm/phy-qcom-qmp-hdmi.h new file mode 100644 index 000000000000..25d307a8f287 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-qmp-hdmi.h @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * Copyright (c) 2023, Linaro Ltd. + */ + +#ifndef PHY_QCOM_QMP_HDMI_H +#define PHY_QCOM_QMP_HDMI_H + +#include +#include +#include +#include + +#define MAX_CLKS 2 +#define MAX_SUPPLIES 2 + +#define HDMI_NUM_TX_CHANNEL 4 + +struct qmp_hdmi_phy { + struct device *dev; + struct phy *phy; + void __iomem *serdes; + void __iomem *tx[HDMI_NUM_TX_CHANNEL]; + void __iomem *phy_reg; + + struct phy_configure_opts_hdmi hdmi_opts; + + struct clk_hw pll_hw; + struct clk_bulk_data clks[MAX_CLKS]; + struct regulator_bulk_data supplies[MAX_SUPPLIES]; +}; + +struct qmp_hdmi_cfg { + const struct clk_ops *pll_ops; + const struct phy_ops *phy_ops; +}; + +#define hw_clk_to_pll(x) container_of(x, struct qmp_hdmi_phy, pll_hw) + +static inline void hdmi_phy_write(struct qmp_hdmi_phy *phy, int offset, + u32 data) +{ + writel(data, phy->phy_reg + offset); +} + +static inline u32 hdmi_phy_read(struct qmp_hdmi_phy *phy, int offset) +{ + return readl(phy->phy_reg + offset); +} + +static inline void hdmi_pll_write(struct qmp_hdmi_phy *phy, int offset, + u32 data) +{ + writel(data, phy->serdes + offset); +} + +static inline u32 hdmi_pll_read(struct qmp_hdmi_phy *phy, int offset) +{ + return readl(phy->serdes + offset); +} + +static inline void hdmi_tx_chan_write(struct qmp_hdmi_phy *phy, int channel, + int offset, int data) +{ + writel(data, phy->tx[channel] + offset); +} + +int qmp_hdmi_phy_init(struct phy *phy); +int qmp_hdmi_phy_configure(struct phy *phy, union phy_configure_opts *opts); +int qmp_hdmi_phy_exit(struct phy *phy); + +extern const struct qmp_hdmi_cfg qmp_hdmi_8996_cfg; + +#endif From patchwork Sun Jun 25 11:42:10 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291894 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 7283DC001B1 for ; Sun, 25 Jun 2023 11:42:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=0u6M5ltIzPhx2K7/zVXuchQdYvuEpVmHhxgWZdOdMV4=; b=giaVfrSMHG3i93 XL5roe2fZE0lESLJ02hMhdhDX36q4sI1/5KOmFu9FkIw3ziROAY1SZva7n06Lh5Xqf2FKmL/J8kXk QMGK9pBWz6Wk6ylErkuFVM5qefTY1uBu4Al4/SXjy+MjiI3GZjAtDwCWqhPD1xOQc7QiQWXiu0w35 CzTFnEEUDBcI0Gk43UeDXCnYePeqIjkoGwO0P65rSYVv6IBVkeWAqR2JefiFnENVrgtzQCXfe5jR0 p8xF5dL0zqVwvoo0SQg2pcGqe5G4Fw/V7sBj0GOtr8gxP+oW4+Gm1rLD3cz3F31kbJRCq1SX37x0l t0NJ41PpabQO0FeCviYg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8h-007w8f-2b; Sun, 25 Jun 2023 11:42:43 +0000 Received: from mail-lj1-x22d.google.com ([2a00:1450:4864:20::22d]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8c-007vzy-1S for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:41 +0000 Received: by mail-lj1-x22d.google.com with SMTP id 38308e7fff4ca-2b45c289615so32720381fa.1 for ; Sun, 25 Jun 2023 04:42:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693346; x=1690285346; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9yHEgBhCyK3jAoHxl+ZfqdHPaLpGd5hwr3inmN3SB+4=; b=FiPhR+DI+S/GPwp1mknkUY3lDzv0J0iJ+rsyoxay8vx3TdlYTTL6hoR8NkjyX0H38J b0vJroB5GviSV2aswDwYNZ2553nZs4oEtglpGS7MIqmavZ/XBO2jmyqOwrFRFpFWRK/R 413aTx5Mj4M9YQRFR7LMj8Br6sDMSwUtWSVH9w8uqV60tsBtuEWZ0vNjuHzyGy7kZIIj Um9bs824OpmbRJ6LpoHCxu5cqYqJ9ngDHxj26+h4QX97VesUqiS6fbJerPewox23ml5K USM6DQyMq7MzrXB08jn96g/QcaR+QbCHACxmeBmdQto05OHeK7n3Fw40bJunp5SpApU8 EFUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693346; x=1690285346; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9yHEgBhCyK3jAoHxl+ZfqdHPaLpGd5hwr3inmN3SB+4=; b=SCexJpBZuDE3YccBTXoKi+7tha8UMUP7oSH5ItIxta9rkVvGtLV5RGOO5EVyQVNZth tTb15jYn2bmHdac42zQet0KFREeab7k8Yr1LtrI78KNGw8i65tfK9dny0CLsStheth5J Cbpji10g3p4slIWTPj0523HTFRf1SlNJRR54frMysMap+Il80/fC5k347pCdjqk3EbdK mqEN0AyUyqU3JwGJYZBhbap8wH9t9GGv3nAzJ21KFdI9++HM29JzPhPto6wkYoJWMkJM jWBOeQVqNkYKNQOCKu9HN3KxZ0bDpA43YEgF5LETpC35KusxyVUrDTUecHiGTBSilSIi 4nhQ== X-Gm-Message-State: AC+VfDyjl9yBhKvNHNKW5QL7uH8JB8yVjvSyR8XPK31noKXutP+e4gjV GOj7CLkNNECkMFk8i7Sh3SfZRA== X-Google-Smtp-Source: ACHHUZ7NyU13Y7Q0o8BTaPFoDXDPjsUrgNaQoSEEsNiENYAbqwpuKC1VSvnZ1Kear1py+tQ3t6yqiQ== X-Received: by 2002:a05:6512:532:b0:4f8:770f:1b04 with SMTP id o18-20020a056512053200b004f8770f1b04mr10871439lfc.0.1687693346213; Sun, 25 Jun 2023 04:42:26 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.25 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:25 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 03/15] phy: qcom: apq8064-sata: extract UNI PLL register defines Date: Sun, 25 Jun 2023 14:42:10 +0300 Message-Id: <20230625114222.96689-4-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044238_546581_8673B2A4 X-CRM114-Status: GOOD ( 11.01 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org The "uni" PLL is shared between several PHYS: APQ8064's SATA, MSM8974/APQ8084 HDMI, MSM8916 DSI, MSM8974/APQ8084 DSI. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/phy-qcom-apq8064-sata.c | 23 +------------- drivers/phy/qualcomm/phy-qcom-uniphy.h | 32 ++++++++++++++++++++ 2 files changed, 33 insertions(+), 22 deletions(-) create mode 100644 drivers/phy/qualcomm/phy-qcom-uniphy.h diff --git a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c index 8814f4322adf..e9c272c1e97e 100644 --- a/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c +++ b/drivers/phy/qualcomm/phy-qcom-apq8064-sata.c @@ -15,28 +15,7 @@ #include #include -/* PHY registers */ -#define UNIPHY_PLL_REFCLK_CFG 0x000 -#define UNIPHY_PLL_PWRGEN_CFG 0x014 -#define UNIPHY_PLL_GLB_CFG 0x020 -#define UNIPHY_PLL_SDM_CFG0 0x038 -#define UNIPHY_PLL_SDM_CFG1 0x03C -#define UNIPHY_PLL_SDM_CFG2 0x040 -#define UNIPHY_PLL_SDM_CFG3 0x044 -#define UNIPHY_PLL_SDM_CFG4 0x048 -#define UNIPHY_PLL_SSC_CFG0 0x04C -#define UNIPHY_PLL_SSC_CFG1 0x050 -#define UNIPHY_PLL_SSC_CFG2 0x054 -#define UNIPHY_PLL_SSC_CFG3 0x058 -#define UNIPHY_PLL_LKDET_CFG0 0x05C -#define UNIPHY_PLL_LKDET_CFG1 0x060 -#define UNIPHY_PLL_LKDET_CFG2 0x064 -#define UNIPHY_PLL_CAL_CFG0 0x06C -#define UNIPHY_PLL_CAL_CFG8 0x08C -#define UNIPHY_PLL_CAL_CFG9 0x090 -#define UNIPHY_PLL_CAL_CFG10 0x094 -#define UNIPHY_PLL_CAL_CFG11 0x098 -#define UNIPHY_PLL_STATUS 0x0C0 +#include "phy-qcom-uniphy.h" #define SATA_PHY_SER_CTRL 0x100 #define SATA_PHY_TX_DRIV_CTRL0 0x104 diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy.h b/drivers/phy/qualcomm/phy-qcom-uniphy.h new file mode 100644 index 000000000000..d8be32b5317c --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-uniphy.h @@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2014, The Linux Foundation. All rights reserved. + */ + +#ifndef PHY_QCOM_UNIPHY_H +#define PHY_QCOM_UNIPHY_H + +/* PHY registers */ +#define UNIPHY_PLL_REFCLK_CFG 0x000 +#define UNIPHY_PLL_PWRGEN_CFG 0x014 +#define UNIPHY_PLL_GLB_CFG 0x020 +#define UNIPHY_PLL_SDM_CFG0 0x038 +#define UNIPHY_PLL_SDM_CFG1 0x03c +#define UNIPHY_PLL_SDM_CFG2 0x040 +#define UNIPHY_PLL_SDM_CFG3 0x044 +#define UNIPHY_PLL_SDM_CFG4 0x048 +#define UNIPHY_PLL_SSC_CFG0 0x04c +#define UNIPHY_PLL_SSC_CFG1 0x050 +#define UNIPHY_PLL_SSC_CFG2 0x054 +#define UNIPHY_PLL_SSC_CFG3 0x058 +#define UNIPHY_PLL_LKDET_CFG0 0x05c +#define UNIPHY_PLL_LKDET_CFG1 0x060 +#define UNIPHY_PLL_LKDET_CFG2 0x064 +#define UNIPHY_PLL_CAL_CFG0 0x06c +#define UNIPHY_PLL_CAL_CFG8 0x08c +#define UNIPHY_PLL_CAL_CFG9 0x090 +#define UNIPHY_PLL_CAL_CFG10 0x094 +#define UNIPHY_PLL_CAL_CFG11 0x098 +#define UNIPHY_PLL_STATUS 0x0c0 + +#endif From patchwork Sun Jun 25 11:42:11 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291889 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id D5738C001B1 for ; Sun, 25 Jun 2023 11:42:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=C1LIgT2jlUBcIo3/CByeaKOvmUczfFPpmVALLPQik/0=; b=HRmE0G+UeASFzz lW1UbAuVuk0fxUGvp4SmO1edKqFbG3jpHzmYHS76WRnrZMXojs08tKIU9PFVaFTcF322kRtDPuHpk 5/kHydiVIXI6ZW1wMYUhZmmZOblIl8hVzl3gGWb9QonlPHqH5/W0JK41vkivsOgM8L9oZPnuNTya+ DTRrKL7WW8OA78ghgGvZqUDFVh0taODNd7/U6p51xxLrm1WebRZavMZEMptBkoZaa41lxE8Ko7Azw 3Gxln7+uJzFrT+Z5h+XPSGCxUAhY/QJqKLTYKoBIR4jHQ1PG7XKgHdoTk2yASJpgYKPojZsVezJPS 1fuZmRaGQB2LA+alyS4g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8Y-007w20-1k; Sun, 25 Jun 2023 11:42:34 +0000 Received: from mail-lf1-x136.google.com ([2a00:1450:4864:20::136]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8T-007w0C-0W for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:33 +0000 Received: by mail-lf1-x136.google.com with SMTP id 2adb3069b0e04-4faaaa476a9so769456e87.2 for ; Sun, 25 Jun 2023 04:42:28 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693347; x=1690285347; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=S0sobRIk6tCMFCwXhjjdodtZDMDOffBV8iCIEpNnHQY=; b=OLi4x4GkdUR+Cxl3aKSon63oxzruMR2edWIzhpNwIShhXIlrrdPy0zWtXXAtXZhsLr PUUysi6UQ3QtbqZ3oCAbKCzB/SWB2/KLKuq2oL7vTmWZXMxp3esriuzM590dlnWtBqMx opewwBpX0PYFKCW6aH6AEpAvNITkYzFaNejH+IFII2/yIf2XcdiddtYzY5rRXzSzoZc/ 0oPs4D7VFlMZ2qzcqD7zNKblWGvLzhJeHOZsl/H2bzNY8tsBKv7KpUC+Ve/o4ZEa4Ab6 38unTGjS46Bf/XW8YYMpd0KHiMty+lZ8L5KfF014JM7OyKirdUiSJOVE/Z3vzlBuooAD mpmQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693347; x=1690285347; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=S0sobRIk6tCMFCwXhjjdodtZDMDOffBV8iCIEpNnHQY=; b=bz7+q7RwrjEosUoLQU8JEKSmUsl2s+fQIYTVt4j60N6cX1s5QvJFm2mUangwiUoDwP 7099SD3IaBdVMZuXPgCZaM0thcmXS0WOePb7P1ROEEX4paMProzr4pRYyJ81ya/LErD9 HtGW4JzifJqe4TiD5IUqzrUxfCwf49tzqHbCTWQP92uHH3VtXJSyYQ00ZLnFz/Znwr1/ 0R6e7/4zzznXsu2FHTHyUMdBsWcWIBdkg9GP1/BSNP7Om7j0EgmbFAsFzFcmxGwVTxb8 V3VtiykiG6ti2pBPOLpmoMqHBMtW2OD2ycwxKlB3jNKsVJK19oXaZBozFbAS2yEhdnVC yK5A== X-Gm-Message-State: AC+VfDz0boeICBqK7JQwj0f7dbKbPKXwa7TZbmJjRzU2gETocobZ5dny rpMop1IMnnhv+iI9VrpfIawPqg== X-Google-Smtp-Source: ACHHUZ73tKr2l2ETdzev4uMFqeCsXgWv4JhZjphUi7YqFNbO3jALO+Eg0LV3bds8Mw/y+uC5vo3IWQ== X-Received: by 2002:a19:f242:0:b0:4f0:223e:7916 with SMTP id d2-20020a19f242000000b004f0223e7916mr13774505lfk.62.1687693347019; Sun, 25 Jun 2023 04:42:27 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:26 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 04/15] phy: qcom-uniphy: add more registers from display PHYs Date: Sun, 25 Jun 2023 14:42:11 +0300 Message-Id: <20230625114222.96689-5-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044229_251344_34DA2A00 X-CRM114-Status: UNSURE ( 6.67 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Import register definitions from 28nm DSI and HDMI PHYs, adding more UNI PHY registers. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/phy-qcom-uniphy.h | 33 ++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-uniphy.h b/drivers/phy/qualcomm/phy-qcom-uniphy.h index d8be32b5317c..4be9bda37fa3 100644 --- a/drivers/phy/qualcomm/phy-qcom-uniphy.h +++ b/drivers/phy/qualcomm/phy-qcom-uniphy.h @@ -8,8 +8,19 @@ /* PHY registers */ #define UNIPHY_PLL_REFCLK_CFG 0x000 +#define UNIPHY_PLL_POSTDIV1_CFG 0x004 +#define UNIPHY_PLL_CHGPUMP_CFG 0x008 +#define UNIPHY_PLL_VCOLPF_CFG 0x00c +#define UNIPHY_PLL_VREG_CFG 0x010 #define UNIPHY_PLL_PWRGEN_CFG 0x014 +#define UNIPHY_PLL_DMUX_CFG 0x018 +#define UNIPHY_PLL_AMUX_CFG 0x01c #define UNIPHY_PLL_GLB_CFG 0x020 +#define UNIPHY_PLL_POSTDIV2_CFG 0x024 +#define UNIPHY_PLL_POSTDIV3_CFG 0x028 +#define UNIPHY_PLL_LPFR_CFG 0x02c +#define UNIPHY_PLL_LPFC1_CFG 0x030 +#define UNIPHY_PLL_LPFC2_CFG 0x034 #define UNIPHY_PLL_SDM_CFG0 0x038 #define UNIPHY_PLL_SDM_CFG1 0x03c #define UNIPHY_PLL_SDM_CFG2 0x040 @@ -22,11 +33,33 @@ #define UNIPHY_PLL_LKDET_CFG0 0x05c #define UNIPHY_PLL_LKDET_CFG1 0x060 #define UNIPHY_PLL_LKDET_CFG2 0x064 +#define UNIPHY_PLL_TEST_CFG 0x068 #define UNIPHY_PLL_CAL_CFG0 0x06c +#define UNIPHY_PLL_CAL_CFG1 0x070 +#define UNIPHY_PLL_CAL_CFG2 0x074 +#define UNIPHY_PLL_CAL_CFG3 0x078 +#define UNIPHY_PLL_CAL_CFG4 0x07c +#define UNIPHY_PLL_CAL_CFG5 0x080 +#define UNIPHY_PLL_CAL_CFG6 0x084 +#define UNIPHY_PLL_CAL_CFG7 0x088 #define UNIPHY_PLL_CAL_CFG8 0x08c #define UNIPHY_PLL_CAL_CFG9 0x090 #define UNIPHY_PLL_CAL_CFG10 0x094 #define UNIPHY_PLL_CAL_CFG11 0x098 +#define UNIPHY_PLL_EFUSE_CFG 0x09c +#define UNIPHY_PLL_DEBUG_BUS_SEL 0x0a0 +#define UNIPHY_PLL_CTRL_42 0x0a4 +#define UNIPHY_PLL_CTRL_43 0x0a8 +#define UNIPHY_PLL_CTRL_44 0x0ac +#define UNIPHY_PLL_CTRL_45 0x0b0 +#define UNIPHY_PLL_CTRL_46 0x0b4 +#define UNIPHY_PLL_CTRL_47 0x0b8 +#define UNIPHY_PLL_CTRL_48 0x0bc #define UNIPHY_PLL_STATUS 0x0c0 +#define UNIPHY_PLL_DEBUG_BUS0 0x0c4 +#define UNIPHY_PLL_DEBUG_BUS1 0x0c8 +#define UNIPHY_PLL_DEBUG_BUS2 0x0cc +#define UNIPHY_PLL_DEBUG_BUS3 0x0d0 +#define UNIPHY_PLL_CTRL_54 0x0d4 #endif From patchwork Sun Jun 25 11:42:12 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291896 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E61CBEB64DD for ; Sun, 25 Jun 2023 11:42:43 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Tql04QezUGZpS4DlEYd9s6TPSvaOtq9MDsvijUtldZg=; b=ijRHyZ2h/3FSAS exCLmLzv5+YgxAUxz0Wp/0KpwxFALg3y+RyedhgEfMra/FUvD8UQr/TIiqfrJ18ZMuDLAD7YSDCur RcO2cV4UZcwHt1ocvu6jF/W2ni20y+AQwxZKFPOmT8UH2BMyMCFKF2Td2Gx8ujRENIW3v6pvh0pQ0 Vn/wa6F3agDcXZh6BZ7cUtED+r7nncuDZ/8w6tV91Y/WvVi8QbsVDQMCIotGAs0wCdc8th0KOek/m DaBKEZJUhCu0Xmb639lspNaR7X0jsYcN3Zb8TNXP7cF4UG2/Ydpue2BWDzP+RDOwAjlS+fftyKmP/ w9M0uHAKqW8rUDa5OXuA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8h-007w8S-1a; Sun, 25 Jun 2023 11:42:43 +0000 Received: from mail-lj1-x234.google.com ([2a00:1450:4864:20::234]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8c-007w0D-16 for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:41 +0000 Received: by mail-lj1-x234.google.com with SMTP id 38308e7fff4ca-2b46f1256bbso40413501fa.0 for ; Sun, 25 Jun 2023 04:42:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693348; x=1690285348; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=4IDKvkLUt6w0xi4QhVDhq8WjiXJw9g5g1gbOAvslxnw=; b=UVf7sPSzkleJtCHZJ8Uny33lbL451jxqy2XrtXD9V+5kFABHrXTGgItGxN17jBjbGw NEOGg9biBcgzQOvjGZNrE06Z/GlkzdLXsVzN+AWmxWNfL/xOC0Pj85HndjK26bfYmMlO ynyqUBGmAGe+H9RPVdGUP3qGFiIC3Z/wAodzca1OIYfYtB2Osa6WqZ3McB9eyqt+k75Q LyExKPvtGO6iQM5PKZtd1tXpGbyn08cP+XgoSkfIYiyU9NnXIULKknvDGAZyV0qDemex G+eFVc5jg4ucYEXa7n2c9yqFM4qhbfDbbKyFGCIYeibrblKN9YIGmy2Y7l7eWQgGIobh qEVw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693348; x=1690285348; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=4IDKvkLUt6w0xi4QhVDhq8WjiXJw9g5g1gbOAvslxnw=; b=FzjRZTibIE/Gjren4B3QhEyk14lK4MpFnmBrtS9YDPL5rM3tqVp1SQo7Rv26L/3Kxo 2eGidwj16MdDPNiLcZYVWCqFwmenCOWOZAhzigkml0MulTD5vAvpj618liLq6BsuXdLz x+ThGryIJ/Z417uLhpF2VLFKPB3Xw2mmk6M2oVQ5QIch4Fi64zXk61NAg97xjjZl+BJm mHeic2nQ9emSXuhApQwwH6q7I8Ir45sObQZWQNWvaurW9wtnd6Ud5nd/kvXMO97jDDtU D5QLpEMbqKOmJJLYKQZZxG9K/Ub9ZEJ5nMqWGld4zrvZfLkbnxU1G8XxXkJwuGbjk+zR /DhQ== X-Gm-Message-State: AC+VfDwxazair/39rr/yRbvp7vEHSNzVALqfTBzdK/iPfj03YJPZZG+J fewcqGwEiaGfgK/3wbP7S3Hz9A== X-Google-Smtp-Source: ACHHUZ5p5N7WQBMkq/DuVdfnDmM7PcnWqfOI6YUYBTtvok8n6xoId9cW/94okdhjMx14CDDNs1zgPA== X-Received: by 2002:a05:6512:3e0c:b0:4f8:66db:eb0b with SMTP id i12-20020a0565123e0c00b004f866dbeb0bmr7426130lfv.1.1687693347822; Sun, 25 Jun 2023 04:42:27 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:27 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 05/15] phy: qualcomm: add legacy HDMI PHY driver Date: Sun, 25 Jun 2023 14:42:12 +0300 Message-Id: <20230625114222.96689-6-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044238_385474_41228FA4 X-CRM114-Status: GOOD ( 22.98 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add the driver for pre-QMP Qualcomm HDMI PHYs. Currently it suppports Qualcomm MSM8960 / APQ8064 platforms, other platforms will come later. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Kconfig | 14 + drivers/phy/qualcomm/Makefile | 6 + drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c | 439 ++++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c | 206 +++++++++ drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h | 79 ++++ 5 files changed, 744 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index 4521fc9b9ced..460ad8298f86 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -42,6 +42,20 @@ config PHY_QCOM_IPQ806X_SATA depends on OF select GENERIC_PHY +config PHY_QCOM_HDMI + tristate "Qualcomm MSM8x60/MSM8960/MSM8974 HDMI PHY driver" + depends on ARCH_QCOM || COMPILE_TEST + depends on OF + depends on COMMON_CLK + default DRM_MSM_HDMI && ARCH_QCOM && ARM + select GENERIC_PHY + help + Enable this to support the Qualcomm HDMI PHY presend on 32-bit platforms: + MSM8260, MSM8660, MSM8960, APQ8060 and APQ8064. + + Note, this driver is not used on MSM899x platforms, which use + PHY_QCOM_QMP_HDMI instead. + config PHY_QCOM_PCIE2 tristate "Qualcomm PCIe Gen2 PHY Driver" depends on OF && COMMON_CLK && (ARCH_QCOM || COMPILE_TEST) diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index 32e27ffb7af6..4c06498c709d 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -4,6 +4,12 @@ obj-$(CONFIG_PHY_QCOM_APQ8064_SATA) += phy-qcom-apq8064-sata.o obj-$(CONFIG_PHY_QCOM_EDP) += phy-qcom-edp.o obj-$(CONFIG_PHY_QCOM_IPQ4019_USB) += phy-qcom-ipq4019-usb.o obj-$(CONFIG_PHY_QCOM_IPQ806X_SATA) += phy-qcom-ipq806x-sata.o +obj-$(CONFIG_PHY_QCOM_HDMI) += phy-qcom-hdmi.o + +phy-qcom-hdmi-y := \ + phy-qcom-hdmi-preqmp.o \ + phy-qcom-hdmi-28lpm.o \ + obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o obj-$(CONFIG_PHY_QCOM_QMP_COMBO) += phy-qcom-qmp-combo.o diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c b/drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c new file mode 100644 index 000000000000..64e043f3f0e2 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-28lpm.c @@ -0,0 +1,439 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark + * Copyright (c) 2023, Linaro Ltd. + */ + +#include +#include + +#include "phy-qcom-hdmi-preqmp.h" + +#define REG_HDMI_8960_PHY_REG0 0x00000000 + +#define REG_HDMI_8960_PHY_REG1 0x00000004 + +#define REG_HDMI_8960_PHY_REG2 0x00000008 + +#define REG_HDMI_8960_PHY_REG3 0x0000000c + +#define REG_HDMI_8960_PHY_REG4 0x00000010 + +#define REG_HDMI_8960_PHY_REG5 0x00000014 + +#define REG_HDMI_8960_PHY_REG6 0x00000018 + +#define REG_HDMI_8960_PHY_REG7 0x0000001c + +#define REG_HDMI_8960_PHY_REG8 0x00000020 + +#define REG_HDMI_8960_PHY_REG9 0x00000024 + +#define REG_HDMI_8960_PHY_REG10 0x00000028 + +#define REG_HDMI_8960_PHY_REG11 0x0000002c + +#define REG_HDMI_8960_PHY_REG12 0x00000030 +#define HDMI_8960_PHY_REG12_SW_RESET 0x00000020 +#define HDMI_8960_PHY_REG12_PWRDN_B 0x00000080 + +#define REG_HDMI_8960_PHY_REG_BIST_CFG 0x00000034 + +#define REG_HDMI_8960_PHY_DEBUG_BUS_SEL 0x00000038 + +#define REG_HDMI_8960_PHY_REG_MISC0 0x0000003c + +#define REG_HDMI_8960_PHY_REG13 0x00000040 + +#define REG_HDMI_8960_PHY_REG14 0x00000044 + +#define REG_HDMI_8960_PHY_REG15 0x00000048 + +#define REG_HDMI_8960_PHY_PLL_REFCLK_CFG 0x00000000 + +#define REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG 0x00000004 + +#define REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 0x00000008 + +#define REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 0x0000000c + +#define REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG 0x00000010 + +#define REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG 0x00000014 + +#define REG_HDMI_8960_PHY_PLL_PWRDN_B 0x00000018 +#define HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL 0x00000002 +#define HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B 0x00000008 + +#define REG_HDMI_8960_PHY_PLL_SDM_CFG0 0x0000001c + +#define REG_HDMI_8960_PHY_PLL_SDM_CFG1 0x00000020 + +#define REG_HDMI_8960_PHY_PLL_SDM_CFG2 0x00000024 + +#define REG_HDMI_8960_PHY_PLL_SDM_CFG3 0x00000028 + +#define REG_HDMI_8960_PHY_PLL_SDM_CFG4 0x0000002c + +#define REG_HDMI_8960_PHY_PLL_SSC_CFG0 0x00000030 + +#define REG_HDMI_8960_PHY_PLL_SSC_CFG1 0x00000034 + +#define REG_HDMI_8960_PHY_PLL_SSC_CFG2 0x00000038 + +#define REG_HDMI_8960_PHY_PLL_SSC_CFG3 0x0000003c + +#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 0x00000040 + +#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 0x00000044 + +#define REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 0x00000048 + +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 0x0000004c + +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 0x00000050 + +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 0x00000054 + +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 0x00000058 + +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 0x0000005c + +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 0x00000060 + +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 0x00000064 + +#define REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 0x00000068 + +#define REG_HDMI_8960_PHY_PLL_DEBUG_SEL 0x0000006c + +#define REG_HDMI_8960_PHY_PLL_MISC0 0x00000070 + +#define REG_HDMI_8960_PHY_PLL_MISC1 0x00000074 + +#define REG_HDMI_8960_PHY_PLL_MISC2 0x00000078 + +#define REG_HDMI_8960_PHY_PLL_MISC3 0x0000007c + +#define REG_HDMI_8960_PHY_PLL_MISC4 0x00000080 + +#define REG_HDMI_8960_PHY_PLL_MISC5 0x00000084 + +#define REG_HDMI_8960_PHY_PLL_MISC6 0x00000088 + +#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS0 0x0000008c + +#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS1 0x00000090 + +#define REG_HDMI_8960_PHY_PLL_DEBUG_BUS2 0x00000094 + +#define REG_HDMI_8960_PHY_PLL_STATUS0 0x00000098 +#define HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK 0x00000001 + +#define REG_HDMI_8960_PHY_PLL_STATUS1 0x0000009c + +#define HDMI_8974_VCO_MAX_FREQ 1125000000UL +#define HDMI_8974_VCO_MIN_FREQ 540000000UL + +#define HDMI_8974_COMMON_DIV 5 + +static unsigned long qcom_28lpm_recalc(struct qcom_hdmi_preqmp_phy *hdmi_phy, unsigned long parent_rate) +{ + unsigned long rate; + u32 refclk_cfg; + u32 dc_offset; + u64 fraq_n; + u32 val; + + refclk_cfg = hdmi_pll_read(hdmi_phy, REG_HDMI_8960_PHY_PLL_REFCLK_CFG); + if (refclk_cfg & BIT(1)) + parent_rate /= 2; + if (refclk_cfg & BIT(3)) + parent_rate *= 2; + + val = hdmi_pll_read(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG0); + if (val & 0x40) { + dc_offset = val & 0x3f; + fraq_n = 0; + } else { + dc_offset = hdmi_pll_read(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG1) & 0x3f; + fraq_n = hdmi_pll_read(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG2) | + (hdmi_pll_read(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG3) << 8); + } + + rate = (dc_offset + 1) * parent_rate; + rate += mult_frac(fraq_n, parent_rate, 0x10000); + + return rate; +} + +static int qcom_28lpm_set_rate(struct qcom_hdmi_preqmp_phy *hdmi_phy, unsigned long parent_rate, + unsigned long vco_freq, u32 div_idx) +{ + unsigned int pixclk = hdmi_phy->hdmi_opts.pixel_clk_rate; + unsigned int int_ref_freq; + unsigned int div; + unsigned int dc_offset; + unsigned int sdm_freq_seed; + unsigned int val; + bool sdm_mode = false; + u32 refclk_cfg; + u32 lf_cfg0; + u32 lf_cfg1; + + dev_dbg(hdmi_phy->dev, "rate=%u, div = %d, vco = %lu", pixclk, div, vco_freq); + + if (vco_freq % (parent_rate / 2) == 0) { + refclk_cfg = 0x2; + int_ref_freq = parent_rate / 2; + } else { + refclk_cfg = 0x8; + int_ref_freq = parent_rate * 2; + sdm_mode = true; + } + + dc_offset = vco_freq / int_ref_freq - 1; + sdm_freq_seed = vco_freq - (dc_offset + 1) * int_ref_freq; + sdm_freq_seed = mult_frac(sdm_freq_seed, 0x10000, int_ref_freq); + + val = (div_idx << 4) | refclk_cfg; + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_REFCLK_CFG, val); + + lf_cfg0 = dc_offset >= 30 ? 0 : (dc_offset >= 16 ? 0x10 : 0x20); + lf_cfg0 += sdm_mode ? 0 : 1; + + /* XXX: 0xc3 instead of 0x33 for qcs404 */ + lf_cfg1 = dc_offset >= 30 ? 0x33 : (dc_offset >= 16 ? 0xbb : 0xf9); + + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0, lf_cfg0); + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1, lf_cfg1); + + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG0, + (sdm_mode ? 0 : 0x40) | dc_offset); + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG1, + 0x40 | dc_offset); + + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG2, + sdm_freq_seed & 0xff); + + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG3, + (sdm_freq_seed >> 8) & 0xff); + + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_SDM_CFG4, + sdm_freq_seed >> 16); + + vco_freq /= 1000; + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0, vco_freq & 0xff); + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1, vco_freq >> 8); + + hdmi_pll_write(hdmi_phy, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2, 0x3b); + + return 0; +} + +static const unsigned int qcom_hdmi_8974_divs[] = {1, 2, 4, 6}; + +static unsigned long qcom_hdmi_8960_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct qcom_hdmi_preqmp_phy *hdmi_phy = hw_clk_to_phy(hw); + u32 div_idx = hdmi_pll_read(hdmi_phy, REG_HDMI_8960_PHY_PLL_REFCLK_CFG); + unsigned long rate = qcom_28lpm_recalc(hdmi_phy, parent_rate); + + return rate / HDMI_8974_COMMON_DIV / qcom_hdmi_8974_divs[div_idx >> 4]; +} + +static long qcom_hdmi_8960_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + return clamp(rate, + HDMI_8974_VCO_MIN_FREQ / HDMI_8974_COMMON_DIV / 6, + HDMI_8974_VCO_MAX_FREQ / HDMI_8974_COMMON_DIV / 1); +} + +static const struct clk_ops qcom_hdmi_8960_pll_ops = { + .recalc_rate = qcom_hdmi_8960_pll_recalc_rate, + .round_rate = qcom_hdmi_8960_pll_round_rate, +}; + +static int qcom_hdmi_msm8960_phy_pll_enable(struct qcom_hdmi_preqmp_phy *phy) +{ + int pll_lock_retry = 10; + unsigned int val; + int ret; + + /* Assert PLL S/W reset */ + hdmi_pll_write(phy, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d); + hdmi_pll_write(phy, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0, 0x10); + hdmi_pll_write(phy, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1, 0x1a); + + /* Wait for a short time before de-asserting + * to allow the hardware to complete its job. + * This much of delay should be fine for hardware + * to assert and de-assert. + */ + udelay(10); + + /* De-assert PLL S/W reset */ + hdmi_pll_write(phy, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d); + + val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); + val |= HDMI_8960_PHY_REG12_SW_RESET; + /* Assert PHY S/W reset */ + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); + val &= ~HDMI_8960_PHY_REG12_SW_RESET; + /* + * Wait for a short time before de-asserting to allow the hardware to + * complete its job. This much of delay should be fine for hardware to + * assert and de-assert. + */ + udelay(10); + /* De-assert PHY S/W reset */ + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x3f); + + val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); + val |= HDMI_8960_PHY_REG12_PWRDN_B; + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); + /* Wait 10 us for enabling global power for PHY */ + mb(); + udelay(10); + + val = hdmi_pll_read(phy, REG_HDMI_8960_PHY_PLL_PWRDN_B); + val |= HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B; + val &= ~HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL; + hdmi_pll_write(phy, REG_HDMI_8960_PHY_PLL_PWRDN_B, val); + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x80); + + while (--pll_lock_retry > 0) { + ret = readl_poll_timeout(phy->pll_reg + REG_HDMI_8960_PHY_PLL_STATUS0, + val, val & HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK, + 1, 1000); + if (!ret) + break; + + /* + * PLL has still not locked. + * Do a software reset and try again + * Assert PLL S/W reset first + */ + hdmi_pll_write(phy, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d); + udelay(10); + hdmi_pll_write(phy, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d); + + /* + * Wait for a short duration for the PLL calibration + * before checking if the PLL gets locked + */ + udelay(350); + } + + return ret; +} + +static int qcom_hdmi_msm8974_phy_find_div(unsigned int pixclk) +{ + int i; + unsigned int min_freq = HDMI_8974_VCO_MIN_FREQ / HDMI_8974_COMMON_DIV / 1000; + + if (pixclk > HDMI_8974_VCO_MAX_FREQ / HDMI_8974_COMMON_DIV / 1000) + return -E2BIG; + + for (i = 0; i < ARRAY_SIZE(qcom_hdmi_8974_divs); i++) { + if (pixclk >= min_freq / qcom_hdmi_8974_divs[i]) + return i; + } + + return -EINVAL; +} + +static int qcom_hdmi_msm8960_phy_set_rate(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + unsigned int pixclk = hdmi_phy->hdmi_opts.pixel_clk_rate; + /* XXX: 19.2 for qcs404 */ + unsigned long parent_rate = 27000; + unsigned long vco_freq; + int div_idx; + u32 div; + + div_idx = qcom_hdmi_msm8974_phy_find_div(pixclk); + if (WARN_ON(div_idx < 0)) + return div_idx; + + div = qcom_hdmi_8974_divs[div_idx]; + vco_freq = pixclk * HDMI_8974_COMMON_DIV * div; + + return qcom_28lpm_set_rate(hdmi_phy, parent_rate, vco_freq, div_idx); +} + +static void qcom_hdmi_msm8960_phy_pll_disable(struct qcom_hdmi_preqmp_phy *phy) +{ + unsigned int val; + + val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); + val &= ~HDMI_8960_PHY_REG12_PWRDN_B; + hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); + + val = hdmi_pll_read(phy, REG_HDMI_8960_PHY_PLL_PWRDN_B); + val |= HDMI_8960_PHY_REG12_SW_RESET; + val &= ~HDMI_8960_PHY_REG12_PWRDN_B; + hdmi_pll_write(phy, REG_HDMI_8960_PHY_PLL_PWRDN_B, val); + /* Make sure HDMI PHY/PLL are powered down */ + mb(); +} + +static int qcom_hdmi_msm8960_phy_power_on(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + int ret; + + ret = qcom_hdmi_msm8960_phy_set_rate(hdmi_phy); + if (ret) + return ret; + + ret = qcom_hdmi_msm8960_phy_pll_enable(hdmi_phy); + if (ret) + return ret; + + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG2, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG0, 0x1b); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG1, 0xf2); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG4, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG5, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG6, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG7, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG8, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG9, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG10, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG11, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG3, 0x20); + + return 0; +} + +static int qcom_hdmi_msm8960_phy_power_off(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG2, 0x7f); + + qcom_hdmi_msm8960_phy_pll_disable(hdmi_phy); + + return 0; +} + +const struct clk_parent_data msm8960_hdmi_pll_parent = { + .fw_name = "pxo", .name = "pxo_board", +}; + +const struct qcom_hdmi_preqmp_cfg msm8960_hdmi_phy_cfg = { + .clk_names = { "slave_iface" }, + .num_clks = 1, + + .reg_names = { "core-vdda" }, + .num_regs = 1, + + .power_on = qcom_hdmi_msm8960_phy_power_on, + .power_off = qcom_hdmi_msm8960_phy_power_off, + + .pll_ops = &qcom_hdmi_8960_pll_ops, + .pll_parent = &msm8960_hdmi_pll_parent, +}; diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c new file mode 100644 index 000000000000..6885f587d7b4 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark + * Copyright (c) 2023, Linaro Ltd. + */ + +#include +#include + +#include "phy-qcom-hdmi-preqmp.h" + +static int qcom_hdmi_preqmp_phy_init(struct phy *phy) +{ + struct qcom_hdmi_preqmp_phy *hdmi_phy = phy_get_drvdata(phy); + + return pm_runtime_resume_and_get(hdmi_phy->dev); +} + +static int qcom_hdmi_preqmp_phy_exit(struct phy *phy) +{ + struct qcom_hdmi_preqmp_phy *hdmi_phy = phy_get_drvdata(phy); + + pm_runtime_put_noidle(hdmi_phy->dev); + + return 0; +} + +static int qcom_hdmi_preqmp_phy_power_on(struct phy *phy) +{ + struct qcom_hdmi_preqmp_phy *hdmi_phy = phy_get_drvdata(phy); + + return hdmi_phy->power_on(hdmi_phy); +}; + +static int qcom_hdmi_preqmp_phy_power_off(struct phy *phy) +{ + struct qcom_hdmi_preqmp_phy *hdmi_phy = phy_get_drvdata(phy); + + return hdmi_phy->power_off(hdmi_phy); +}; + +static int qcom_hdmi_preqmp_phy_configure(struct phy *phy, union phy_configure_opts *opts) +{ + const struct phy_configure_opts_hdmi *hdmi_opts = &opts->hdmi; + struct qcom_hdmi_preqmp_phy *hdmi_phy = phy_get_drvdata(phy); + int ret = 0; + + memcpy(&hdmi_phy->hdmi_opts, hdmi_opts, sizeof(*hdmi_opts)); + + return ret; +} + +static int __maybe_unused qcom_hdmi_preqmp_runtime_resume(struct device *dev) +{ + struct qcom_hdmi_preqmp_phy *hdmi_phy = dev_get_drvdata(dev); + int ret; + + ret = regulator_bulk_enable(hdmi_phy->num_regs, hdmi_phy->regs); + if (ret) + return ret; + + ret = clk_bulk_prepare_enable(hdmi_phy->num_clks, hdmi_phy->clks); + if (ret) + goto out_disable_supplies; + + return 0; + +out_disable_supplies: + regulator_bulk_disable(hdmi_phy->num_regs, hdmi_phy->regs); + + return ret; +} + +static int __maybe_unused qcom_hdmi_preqmp_runtime_suspend(struct device *dev) +{ + struct qcom_hdmi_preqmp_phy *hdmi_phy = dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(hdmi_phy->num_clks, hdmi_phy->clks); + regulator_bulk_disable(hdmi_phy->num_regs, hdmi_phy->regs); + + return 0; +} + +static const struct phy_ops qcom_hdmi_preqmp_phy_ops = { + .init = qcom_hdmi_preqmp_phy_init, + .configure = qcom_hdmi_preqmp_phy_configure, + .power_on = qcom_hdmi_preqmp_phy_power_on, + .power_off = qcom_hdmi_preqmp_phy_power_off, + .exit = qcom_hdmi_preqmp_phy_exit, + .owner = THIS_MODULE, +}; + +static int qcom_hdmi_preqmp_probe(struct platform_device *pdev) +{ + struct clk_init_data init; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct qcom_hdmi_preqmp_phy *hdmi_phy; + const struct qcom_hdmi_preqmp_cfg *cfg; + int i, ret; + + cfg = of_device_get_match_data(dev); + if (!cfg) + return -EINVAL; + + hdmi_phy = devm_kzalloc(dev, sizeof(*hdmi_phy), GFP_KERNEL); + if (!hdmi_phy) + return -ENOMEM; + + hdmi_phy->dev = dev; + + hdmi_phy->phy_reg = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(hdmi_phy->phy_reg)) + return PTR_ERR(hdmi_phy->phy_reg); + + hdmi_phy->pll_reg = devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(hdmi_phy->pll_reg)) + return PTR_ERR(hdmi_phy->pll_reg); + + hdmi_phy->num_clks = cfg->num_clks; + for (i = 0; i < cfg->num_clks; i++) + hdmi_phy->clks[i].id = cfg->clk_names[i]; + ret = devm_clk_bulk_get(dev, hdmi_phy->num_clks, hdmi_phy->clks); + if (ret) + return ret; + + hdmi_phy->num_regs = cfg->num_regs; + for (i = 0; i < cfg->num_regs; i++) { + hdmi_phy->regs[i].supply = cfg->reg_names[i]; + hdmi_phy->regs[i].init_load_uA = cfg->reg_init_load[i]; + } + ret = devm_regulator_bulk_get(dev, hdmi_phy->num_regs, hdmi_phy->regs); + if (ret) + return ret; + + hdmi_phy->power_on = cfg->power_on; + hdmi_phy->power_off = cfg->power_off; + + platform_set_drvdata(pdev, hdmi_phy); + + ret = devm_pm_runtime_enable(&pdev->dev); + if (ret) + return ret; + + ret = pm_runtime_resume_and_get(&pdev->dev); + if (ret) + return ret; + + init.name = "hdmipll"; + init.ops = cfg->pll_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_data = cfg->pll_parent; + init.num_parents = 1; + + hdmi_phy->pll_hw.init = &init; + ret = devm_clk_hw_register(hdmi_phy->dev, &hdmi_phy->pll_hw); + if (ret) + goto err; + + ret = devm_of_clk_add_hw_provider(hdmi_phy->dev, of_clk_hw_simple_get, &hdmi_phy->pll_hw); + if (ret) + goto err; + + hdmi_phy->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_hdmi_preqmp_phy_ops); + if (IS_ERR(hdmi_phy->phy)) { + ret = PTR_ERR(hdmi_phy->phy); + goto err; + } + + phy_set_drvdata(hdmi_phy->phy, hdmi_phy); + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + pm_runtime_put_noidle(&pdev->dev); + return PTR_ERR_OR_ZERO(phy_provider); + +err: + pm_runtime_put_noidle(&pdev->dev); + return ret; +} + +static const struct of_device_id qcom_hdmi_preqmp_of_match_table[] = { + { .compatible = "qcom,hdmi-phy-8960", .data = &msm8960_hdmi_phy_cfg, }, + { }, +}; +MODULE_DEVICE_TABLE(of, qcom_hdmi_preqmp_of_match_table); + +DEFINE_RUNTIME_DEV_PM_OPS(qcom_hdmi_preqmp_pm_ops, + qcom_hdmi_preqmp_runtime_suspend, + qcom_hdmi_preqmp_runtime_resume, + NULL); + +static struct platform_driver qcom_hdmi_preqmp_driver = { + .probe = qcom_hdmi_preqmp_probe, + .driver = { + .name = "qcom-preqmp-hdmi-phy", + .of_match_table = qcom_hdmi_preqmp_of_match_table, + .pm = &qcom_hdmi_preqmp_pm_ops, + }, +}; + +module_platform_driver(qcom_hdmi_preqmp_driver); + +MODULE_AUTHOR("Dmitry Baryshkov "); +MODULE_DESCRIPTION("Qualcomm MSMpreqmp HDMI PHY driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h new file mode 100644 index 000000000000..dca9be78d8fc --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark + * Copyright (c) 2023, Linaro Ltd. + */ + +#ifndef PHY_QCOM_HDMI_PREQMP_H +#define PHY_QCOM_HDMI_PREQMP_H + +#include +#include +#include +#include + +#define MAX_CLKS 2 +#define MAX_SUPPLIES 2 + +struct qcom_hdmi_preqmp_phy { + struct device *dev; + struct phy *phy; + void __iomem *pll_reg; + void __iomem *phy_reg; + + struct phy_configure_opts_hdmi hdmi_opts; + + struct clk_hw pll_hw; + struct clk_bulk_data clks[MAX_CLKS]; + int num_clks; + + struct regulator_bulk_data regs[MAX_SUPPLIES]; + int num_regs; + + int (*power_on)(struct qcom_hdmi_preqmp_phy *phy); + int (*power_off)(struct qcom_hdmi_preqmp_phy *phy); +}; + +#define hw_clk_to_phy(x) container_of(x, struct qcom_hdmi_preqmp_phy, pll_hw) + +struct qcom_hdmi_preqmp_cfg { + const char * const clk_names[MAX_CLKS]; + int num_clks; + + const char * const reg_names[MAX_SUPPLIES]; + int reg_init_load[MAX_SUPPLIES]; + int num_regs; + + int (*power_on)(struct qcom_hdmi_preqmp_phy *phy); + int (*power_off)(struct qcom_hdmi_preqmp_phy *phy); + + const struct clk_ops *pll_ops; + const struct clk_parent_data *pll_parent; +}; + +static inline void hdmi_phy_write(struct qcom_hdmi_preqmp_phy *phy, int offset, + u32 data) +{ + writel(data, phy->phy_reg + offset); +} + +static inline u32 hdmi_phy_read(struct qcom_hdmi_preqmp_phy *phy, int offset) +{ + return readl(phy->phy_reg + offset); +} + +static inline void hdmi_pll_write(struct qcom_hdmi_preqmp_phy *phy, int offset, + u32 data) +{ + writel(data, phy->pll_reg + offset); +} + +static inline u32 hdmi_pll_read(struct qcom_hdmi_preqmp_phy *phy, int offset) +{ + return readl(phy->pll_reg + offset); +} + +extern const struct qcom_hdmi_preqmp_cfg msm8960_hdmi_phy_cfg; + +#endif From patchwork Sun Jun 25 11:42:13 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291903 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 98E37C001DC for ; Sun, 25 Jun 2023 11:42:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=o+eON+YyLj9wJZrEunglen29Z2eFNy9Zkb9BklTkhQM=; b=uLHeL7+JfBhGAv Xv1htHV3DY24JZI2Fx3S4WUY8bL9RmMDFg5+NyWi2oIMKQb8eqdrXWb8kZI3cnTnf/bu6Wp1boRZG o23U7fh8EyeIROO5CUvp6jMn0oSWVyeTC0TyDrTAUuX1i4Qv5pqWn/Qdbg9eowGJFTnKFQPNhcOsA EAqQnXvDF6kdOhFVp2H7gD7dIsxRrzWZVbzbPsMkxJx/t0NoASlZIzgCQhqBusg95mBgoINd9tiBe poi0kdUZTezP5ngmcUPUQn0/3QTQJxghnfDqdLbnULcXVplc/FUsEp1d8VSqSO5pE7OK1KOhUGaJA akh1keAbVSoPJh4ll7kA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8m-007wBg-0e; Sun, 25 Jun 2023 11:42:48 +0000 Received: from mail-lj1-x22e.google.com ([2a00:1450:4864:20::22e]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8d-007w0I-06 for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:44 +0000 Received: by mail-lj1-x22e.google.com with SMTP id 38308e7fff4ca-2b5e7dba43cso11103601fa.1 for ; Sun, 25 Jun 2023 04:42:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693348; x=1690285348; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=NYVV5hJVC84dRN3HiXzBvDfdG/XbHXbUqhWRqpc73+U=; b=GYFwV+1P31PrgxNy+ApRe56VBRh1zwOEfCAGI4/X6C1MZAZuTNyPtPjxe1UwCwrEA8 qCTxu4Oayt/M+dVY9UwNMX2BD4Ywu4vkH1uWMiN3N9Ov5RxfV7GHtZXIRrUcxiS6R1uI Gduwj4h6y+elnSFs4NfdkYlUZY5m8kbWJaSdr3NaXNoJBFuIp07Ks0BR8e2bOrdsGEYx 3vkEvHB+r2lXMyC0bzgi9WfwRGLxDVgykURTyZZ0X3DrydCkCojZAnnIL3CwGsoFhzqj w92mcJsgV5gYfLM4ttkts+wFkMnqdr1PA+O+72CebcQeOSD01vES+BOuYplfRB3Yx6sP ZpWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693348; x=1690285348; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=NYVV5hJVC84dRN3HiXzBvDfdG/XbHXbUqhWRqpc73+U=; b=lSoALH4cAp7DJ5HqUtbJEQc7hwv58tJl0lKp4dE0Q9GmBzVVnImIoLSSSYy/Gheciw yaLVe0Jy0B4dbR4zdrBO+xGD6q+fCEnfMqUbj/0xE313bq6zvel8KA8EhmX4GDoP6/w/ HK7KQkuJuEhiSNwaCcT8ofCMPYDanwUpGOJbcg9K+osw23yx7W0fMJJfwM9HXTzwkq5z 9zxvZiHsp9DJJMaersdagy9ivYYKVHlS47MK8VAqV020aCjYu4XpSbE+ikxpSNGzIpGE gkmWL7GbcTcUHKLaMaxH5xObLnTeOswoZgc1oV00lgCD6JZq+RHN+U9VdUeJP0zWcQ+5 P1BQ== X-Gm-Message-State: AC+VfDxqpPaebYWvRp3TZYECOtczxZuG6Co9yCaIgYeCyvtnhEpfTGab 9RBbVT42Y+XSOgBLAxSxIql8cw== X-Google-Smtp-Source: ACHHUZ6LHwCS/JFs6atAA6flCCjf/fOLJSRU35XdOZ0SGfBQg9k2swJcE9aFXIsHwGB4eklQUaaN0g== X-Received: by 2002:a19:7714:0:b0:4f8:5717:f771 with SMTP id s20-20020a197714000000b004f85717f771mr14595904lfc.21.1687693348708; Sun, 25 Jun 2023 04:42:28 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:28 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 06/15] phy: qualcomm: add MSM8974 HDMI PHY support Date: Sun, 25 Jun 2023 14:42:13 +0300 Message-Id: <20230625114222.96689-7-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044239_084434_A0AD5703 X-CRM114-Status: GOOD ( 24.52 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add support for HDMI PHY on Qualcomm MSM8974 / APQ8074 platforms. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Kconfig | 2 +- drivers/phy/qualcomm/Makefile | 1 + drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c | 327 ++++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c | 1 + drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h | 1 + 5 files changed, 331 insertions(+), 1 deletion(-) create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index 460ad8298f86..f6e48cc58bad 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -51,7 +51,7 @@ config PHY_QCOM_HDMI select GENERIC_PHY help Enable this to support the Qualcomm HDMI PHY presend on 32-bit platforms: - MSM8260, MSM8660, MSM8960, APQ8060 and APQ8064. + MSM8260, MSM8660, MSM8960, MSM8974, APQ8060, APQ8064, APQ8074 and APQ8084. Note, this driver is not used on MSM899x platforms, which use PHY_QCOM_QMP_HDMI instead. diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index 4c06498c709d..e331323b954b 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -8,6 +8,7 @@ obj-$(CONFIG_PHY_QCOM_HDMI) += phy-qcom-hdmi.o phy-qcom-hdmi-y := \ phy-qcom-hdmi-preqmp.o \ + phy-qcom-hdmi-28hpm.o \ phy-qcom-hdmi-28lpm.o \ obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c b/drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c new file mode 100644 index 000000000000..d3bf67e743aa --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-28hpm.c @@ -0,0 +1,327 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark + * Copyright (c) 2023, Linaro Ltd. + */ + +#include +#include + +#include "phy-qcom-hdmi-preqmp.h" +#include "phy-qcom-uniphy.h" + +#define REG_HDMI_8x74_ANA_CFG0 0x00000000 +#define REG_HDMI_8x74_ANA_CFG1 0x00000004 +#define REG_HDMI_8x74_ANA_CFG2 0x00000008 +#define REG_HDMI_8x74_ANA_CFG3 0x0000000c +#define REG_HDMI_8x74_PD_CTRL0 0x00000010 +#define REG_HDMI_8x74_PD_CTRL1 0x00000014 +#define REG_HDMI_8x74_GLB_CFG 0x00000018 +#define REG_HDMI_8x74_DCC_CFG0 0x0000001c +#define REG_HDMI_8x74_DCC_CFG1 0x00000020 +#define REG_HDMI_8x74_TXCAL_CFG0 0x00000024 +#define REG_HDMI_8x74_TXCAL_CFG1 0x00000028 +#define REG_HDMI_8x74_TXCAL_CFG2 0x0000002c +#define REG_HDMI_8x74_TXCAL_CFG3 0x00000030 +#define REG_HDMI_8x74_BIST_CFG0 0x00000034 +#define REG_HDMI_8x74_BIST_PATN0 0x0000003c +#define REG_HDMI_8x74_BIST_PATN1 0x00000040 +#define REG_HDMI_8x74_BIST_PATN2 0x00000044 +#define REG_HDMI_8x74_BIST_PATN3 0x00000048 +#define REG_HDMI_8x74_STATUS 0x0000005c + +#define HDMI_8974_VCO_MAX_FREQ 1800000000UL +#define HDMI_8974_VCO_MIN_FREQ 600000000UL + +#define HDMI_8974_COMMON_DIV 5 + +static void qcom_uniphy_setup(void __iomem *base, unsigned int ref_freq, + bool sdm_mode, + bool ref_freq_mult_2, + bool dither, + unsigned int refclk_div, + unsigned int vco_freq) +{ + unsigned int int_ref_freq = ref_freq * (ref_freq_mult_2 ? 2 : 1); + unsigned int div_in_freq = vco_freq / refclk_div; + unsigned int dc_offset = div_in_freq / int_ref_freq - 1; + unsigned int sdm_freq_seed; + unsigned int val; + unsigned int remain = div_in_freq - (dc_offset + 1) * int_ref_freq; + sdm_freq_seed = mult_frac(remain, 0x10000, int_ref_freq); + + val = (ref_freq_mult_2 ? BIT(0) : 0) | + ((refclk_div - 1) << 2); + writel(val, base + UNIPHY_PLL_REFCLK_CFG); + + writel(sdm_mode ? 0 : 0x40 + dc_offset, base + UNIPHY_PLL_SDM_CFG0); + + writel(dither ? 0x40 + dc_offset: 0, base + UNIPHY_PLL_SDM_CFG1); + + writel(sdm_freq_seed & 0xff, base + UNIPHY_PLL_SDM_CFG2); + + writel((sdm_freq_seed >> 8) & 0xff, base + UNIPHY_PLL_SDM_CFG3); + + writel(sdm_freq_seed >> 16, base + UNIPHY_PLL_SDM_CFG4); + + ref_freq = ref_freq * 5 / 1000; + writel(ref_freq & 0xff, base + UNIPHY_PLL_CAL_CFG8); + + writel(ref_freq >> 8, base + UNIPHY_PLL_CAL_CFG9); + + vco_freq /= 1000; + writel(vco_freq & 0xff, base + UNIPHY_PLL_CAL_CFG10); + + writel(vco_freq >> 8, base + UNIPHY_PLL_CAL_CFG11); +} + +static unsigned long qcom_uniphy_recalc(void __iomem *base, unsigned long parent_rate) +{ + unsigned long rate; + u32 refclk_cfg; + u32 dc_offset; + u64 fraq_n; + u32 val; + + refclk_cfg = readl(base + UNIPHY_PLL_REFCLK_CFG); + if (refclk_cfg & BIT(0)) + parent_rate *= 2; + + val = readl(base + UNIPHY_PLL_SDM_CFG0); + if (val & 0x40) { + dc_offset = val & 0x3f; + fraq_n = 0; + } else { + dc_offset = readl(base + UNIPHY_PLL_SDM_CFG1) & 0x3f; + fraq_n = readl(base + UNIPHY_PLL_SDM_CFG2) | + (readl(base + UNIPHY_PLL_SDM_CFG3) << 8); + } + + rate = (dc_offset + 1) * parent_rate; + rate += mult_frac(fraq_n, parent_rate, 0x10000); + + rate *= (refclk_cfg >> 2) * 0x3 + 1; + + return rate; +} + +static const unsigned int qcom_hdmi_8974_divs[] = {1, 2, 4, 6}; + +static unsigned long qcom_hdmi_8974_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct qcom_hdmi_preqmp_phy *hdmi_phy = hw_clk_to_phy(hw); + u32 div_idx = hdmi_pll_read(hdmi_phy, UNIPHY_PLL_POSTDIV1_CFG); + unsigned long rate = qcom_uniphy_recalc(hdmi_phy->pll_reg, parent_rate); + + return rate / HDMI_8974_COMMON_DIV / qcom_hdmi_8974_divs[div_idx & 0x3]; +} + +static long qcom_hdmi_8974_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + return clamp(rate, + HDMI_8974_VCO_MIN_FREQ / HDMI_8974_COMMON_DIV / 6, + HDMI_8974_VCO_MAX_FREQ / HDMI_8974_COMMON_DIV / 1); +} + +static const struct clk_ops qcom_hdmi_8974_pll_ops = { + .recalc_rate = qcom_hdmi_8974_pll_recalc_rate, + .round_rate = qcom_hdmi_8974_pll_round_rate, +}; + +static int qcom_hdmi_msm8974_phy_find_div(unsigned int pixclk) +{ + int i; + unsigned int min_freq = HDMI_8974_VCO_MIN_FREQ / HDMI_8974_COMMON_DIV / 1000; + + if (pixclk > HDMI_8974_VCO_MAX_FREQ / HDMI_8974_COMMON_DIV / 1000) + return -E2BIG; + + for (i = 0; i < ARRAY_SIZE(qcom_hdmi_8974_divs); i++) { + if (pixclk >= min_freq / qcom_hdmi_8974_divs[i]) + return i; + } + + return -EINVAL; +} + +static int qcom_hdmi_msm8974_phy_pll_set_rate(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + unsigned int pixclk = hdmi_phy->hdmi_opts.pixel_clk_rate; + unsigned long vco_rate; + unsigned int div; + int div_idx = 0; + + div_idx = qcom_hdmi_msm8974_phy_find_div(pixclk); + if (WARN_ON(div_idx < 0)) + return div_idx; + + div = qcom_hdmi_8974_divs[div_idx]; + vco_rate = pixclk * HDMI_8974_COMMON_DIV * div; + + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_GLB_CFG, 0x81); + + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_GLB_CFG, 0x01); + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_VCOLPF_CFG, 0x19); + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_LPFR_CFG, 0x0e); + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_LPFC1_CFG, 0x20); + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_LPFC2_CFG, 0x0d); + + qcom_uniphy_setup(hdmi_phy->pll_reg, 19200, true, true, true, 1, vco_rate); + + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_LKDET_CFG0, 0x10); + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_LKDET_CFG1, 0x1a); + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_LKDET_CFG2, 0x05); + + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_POSTDIV1_CFG, div_idx); + + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_POSTDIV2_CFG, 0x00); + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_POSTDIV3_CFG, 0x00); + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_CAL_CFG2, 0x01); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_PD_CTRL0, 0x1f); + udelay(50); + + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_GLB_CFG, 0x0f); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_PD_CTRL1, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG2, 0x10); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG0, 0xdb); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG1, 0x43); + if (pixclk == 297000) { + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG2, 0x06); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG3, 0x03); + } else if (pixclk == 268500) { + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG2, 0x05); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG3, 0x00); + } else { + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG2, 0x02); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG3, 0x00); + } + + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_VREG_CFG, 0x04); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_DCC_CFG0, 0xd0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_DCC_CFG1, 0x1a); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_TXCAL_CFG0, 0x00); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_TXCAL_CFG1, 0x00); + if (pixclk == 268500) { + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_TXCAL_CFG2, 0x11); + } else { + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_TXCAL_CFG2, 0x02); + } + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_TXCAL_CFG3, 0x05); + udelay(200); + + return 0; +} + +static int qcom_hdmi_msm8974_phy_pll_enable(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + int ret; + unsigned long status; + + /* Global enable */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_GLB_CFG, 0x81); + + /* Power up power gen */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_PD_CTRL0, 0x00); + udelay(350); + + /* PLL power up */ + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_GLB_CFG, 0x01); + udelay(5); + + /* Power up PLL LDO */ + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_GLB_CFG, 0x03); + udelay(350); + + /* PLL power up */ + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_GLB_CFG, 0x0f); + udelay(350); + + /* Poll for PLL ready status */ + ret = readl_poll_timeout(hdmi_phy->pll_reg + UNIPHY_PLL_STATUS, + status, status & BIT(0), + 100, 2000); + if (ret) { + dev_warn(hdmi_phy->dev, "HDMI PLL not ready\n"); + goto err; + } + + udelay(350); + + /* Poll for PHY ready status */ + ret = readl_poll_timeout(hdmi_phy->phy_reg + REG_HDMI_8x74_STATUS, + status, status & BIT(0), + 100, 2000); + if (ret) { + dev_warn(hdmi_phy->dev, "HDMI PHY not ready\n"); + goto err; + } + + return 0; + +err: + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_GLB_CFG, 0); + udelay(5); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_GLB_CFG, 0); + + return ret; +} + +static int qcom_hdmi_msm8974_phy_power_on(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + int ret; + + ret = qcom_hdmi_msm8974_phy_pll_set_rate(hdmi_phy); + if (ret) + return ret; + + ret = qcom_hdmi_msm8974_phy_pll_enable(hdmi_phy); + if (ret) + return ret; + + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG0, 0x1b); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_ANA_CFG1, 0xf2); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_BIST_CFG0, 0x0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_BIST_PATN0, 0x0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_BIST_PATN1, 0x0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_BIST_PATN2, 0x0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_BIST_PATN3, 0x0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_PD_CTRL1, 0x20); + + return 0; +} + +static int qcom_hdmi_msm8974_phy_power_off(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_PD_CTRL0, 0x7f); + + hdmi_pll_write(hdmi_phy, UNIPHY_PLL_GLB_CFG, 0); + udelay(5); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x74_GLB_CFG, 0); + + return 0; +} + +const struct clk_parent_data msm8974_hdmi_pll_parent = { + .fw_name = "xo", .name = "xo_board", +}; + +const struct qcom_hdmi_preqmp_cfg msm8974_hdmi_phy_cfg = { + .clk_names = { "iface", "alt_iface" }, + .num_clks = 2, + + .reg_names = { "vddio", "core-vdda" }, + .reg_init_load = { 100000, 10000 }, + .num_regs = 2, + + .power_on = qcom_hdmi_msm8974_phy_power_on, + .power_off = qcom_hdmi_msm8974_phy_power_off, + + .pll_ops = &qcom_hdmi_8974_pll_ops, + .pll_parent = &msm8974_hdmi_pll_parent, +}; diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c index 6885f587d7b4..e181a45df2dc 100644 --- a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c @@ -181,6 +181,7 @@ static int qcom_hdmi_preqmp_probe(struct platform_device *pdev) static const struct of_device_id qcom_hdmi_preqmp_of_match_table[] = { { .compatible = "qcom,hdmi-phy-8960", .data = &msm8960_hdmi_phy_cfg, }, + { .compatible = "qcom,hdmi-phy-8974", .data = &msm8974_hdmi_phy_cfg, }, { }, }; MODULE_DEVICE_TABLE(of, qcom_hdmi_preqmp_of_match_table); diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h index dca9be78d8fc..bc81d68463ec 100644 --- a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h @@ -75,5 +75,6 @@ static inline u32 hdmi_pll_read(struct qcom_hdmi_preqmp_phy *phy, int offset) } extern const struct qcom_hdmi_preqmp_cfg msm8960_hdmi_phy_cfg; +extern const struct qcom_hdmi_preqmp_cfg msm8974_hdmi_phy_cfg; #endif From patchwork Sun Jun 25 11:42:14 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291893 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9E55DC001B0 for ; Sun, 25 Jun 2023 11:42:42 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=oZl+BYRpXR0z8l6BDyr+6jqFuNV3yJ6CT2+lbPQeD4c=; b=p3/EOLUAXrRL/g hXg0wJv1InRpryybwfV0Uh61ar1KbXYODFJK8GDM2REITOl+RP12NyxcxVFnOHW/0qLfxaHYFkNgk tK5ZQEYda/ozZOf8ju0XbTCwEJW75R4HUPHxRuKTaUMA8N98Ozcdxz/m2TqORGPuHPlGEXjv2B93B Y7K/Z8ugmibkhHzYDtPFLryW55dllCAtLjArQ94it9j2DMgB1hSU9QLLwqoIhXFTcthDPTh2j+FQH cERtz5htHKNC0BWTdpGETJeJDpAR/Ue1XjaQGgXObSXFCwVwYgXWVh9EIS4oNMBZypFRm73A1QwA5 rQvlzMc5tkbCCDOcQ8cA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8g-007w7F-0B; Sun, 25 Jun 2023 11:42:42 +0000 Received: from mail-lj1-x234.google.com ([2a00:1450:4864:20::234]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8c-007w1A-16 for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:40 +0000 Received: by mail-lj1-x234.google.com with SMTP id 38308e7fff4ca-2b69a48368fso7100791fa.0 for ; Sun, 25 Jun 2023 04:42:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693349; x=1690285349; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JwknVKkBmWHuFpmkhtaTA1a3VKhqXsJ2KbK3Od2bgoQ=; b=QylqeAaY1tYDPd3sxugMl5fHUtTlb9lKb8HvhunSAaeAZuHg5BX5sJTb8Oo8uT5PlB xJZeaGm2J/gCOH+vCj97AhNLsWLdOM7hvmkKkmsXKvFinKT2ZpDyDHurJXukKYIBnLYH xT1AqodeKPWrZIUQwHyRNmmN7l338UfRnTNO4ElbFIQKFtvB9I29GrknaTU6WtZ4q6nH mr5A3/hQkg7twB8UenGDI04APtEtXQI1DybuTpxFIXaB9xRdg2/Domky+CBMpEmCNLH6 cGC46jgrxIMo3EtrvoHw7y48BFux96tHr81gsSJmwxHPM+/5wln+qF5f02LdFoPTb3Ba nPww== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693349; x=1690285349; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JwknVKkBmWHuFpmkhtaTA1a3VKhqXsJ2KbK3Od2bgoQ=; b=lS40YcMy/yzoD/AagCDK7MsBrYpJY9krwssF9Aor1jC7K3tyEL1HrXCvB2Q3wVpx+c 8dACuE7FsZr78YAZ4yJg91nd3i7pBhPSzotaSCF9GeBYcZtes3qEpPneAb2oZiNMXHD0 6BUjKbvJ/qEmVOC7QN3dyLdDgmgvgIrIvRyqzFfIWTzE5fRyYNbcL4gkEdYq4E/iWlEc 6cieQ8L2+phGG/LZeW7CB3p7uDNfDya/xMFo1GKV++AhhEOw3ee03QXrbejbuCiz1Bwo xIToN2kb5H09t21r+qzsESF9lTEWOOxftzdOvHl9E3y7f/vmj+MFnd6YJ0+I9D0II9QU gQEw== X-Gm-Message-State: AC+VfDzwHafUDlkd9u4blJ78lP1gpA8iK5Incgfephq8m2Zhmn1gaebj lFCuHir2oWg+jCHdB534VLD9vQ== X-Google-Smtp-Source: ACHHUZ5KJxKQTpGxP5PzwhZv/pSQJnliAItqcafWineei7VPYegGypUKIezliFbStJxtz9SaN5ZOiw== X-Received: by 2002:a05:6512:3d23:b0:4fa:79da:ca8a with SMTP id d35-20020a0565123d2300b004fa79daca8amr1393970lfv.7.1687693349710; Sun, 25 Jun 2023 04:42:29 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:29 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 07/15] phy: qualcomm: add MSM8x60 HDMI PHY support Date: Sun, 25 Jun 2023 14:42:14 +0300 Message-Id: <20230625114222.96689-8-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044238_384434_5852DE25 X-CRM114-Status: GOOD ( 21.96 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add support for HDMI PHY on Qualcomm MSM8x60 / APQ8060 platforms. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Makefile | 1 + drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c | 184 ++++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c | 32 ++-- drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h | 1 + 4 files changed, 204 insertions(+), 14 deletions(-) create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index e331323b954b..a02f2b499d84 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -10,6 +10,7 @@ phy-qcom-hdmi-y := \ phy-qcom-hdmi-preqmp.o \ phy-qcom-hdmi-28hpm.o \ phy-qcom-hdmi-28lpm.o \ + phy-qcom-hdmi-45nm.o \ obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c b/drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c new file mode 100644 index 000000000000..31e1e9f2d037 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark + * Copyright (c) 2023, Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-qcom-hdmi-preqmp.h" + +#define REG_HDMI_8x60_PHY_REG0 0x00000000 +#define HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__MASK 0x0000001c + +#define REG_HDMI_8x60_PHY_REG1 0x00000004 +#define HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK 0x000000f0 +#define HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK 0x0000000f + +#define REG_HDMI_8x60_PHY_REG2 0x00000008 +#define HDMI_8x60_PHY_REG2_PD_DESER 0x00000001 +#define HDMI_8x60_PHY_REG2_PD_DRIVE_1 0x00000002 +#define HDMI_8x60_PHY_REG2_PD_DRIVE_2 0x00000004 +#define HDMI_8x60_PHY_REG2_PD_DRIVE_3 0x00000008 +#define HDMI_8x60_PHY_REG2_PD_DRIVE_4 0x00000010 +#define HDMI_8x60_PHY_REG2_PD_PLL 0x00000020 +#define HDMI_8x60_PHY_REG2_PD_PWRGEN 0x00000040 +#define HDMI_8x60_PHY_REG2_RCV_SENSE_EN 0x00000080 + +#define REG_HDMI_8x60_PHY_REG3 0x0000000c +#define HDMI_8x60_PHY_REG3_PLL_ENABLE 0x00000001 + +#define REG_HDMI_8x60_PHY_REG4 0x00000010 + +#define REG_HDMI_8x60_PHY_REG5 0x00000014 + +#define REG_HDMI_8x60_PHY_REG6 0x00000018 + +#define REG_HDMI_8x60_PHY_REG7 0x0000001c + +#define REG_HDMI_8x60_PHY_REG8 0x00000020 + +#define REG_HDMI_8x60_PHY_REG9 0x00000024 + +#define REG_HDMI_8x60_PHY_REG10 0x00000028 + +#define REG_HDMI_8x60_PHY_REG11 0x0000002c + +#define REG_HDMI_8x60_PHY_REG12 0x00000030 +#define HDMI_8x60_PHY_REG12_RETIMING_EN 0x00000001 +#define HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN 0x00000002 +#define HDMI_8x60_PHY_REG12_FORCE_LOCK 0x00000010 + +static int qcom_hdmi_msm8x60_phy_power_on(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + unsigned long pixclock = hdmi_phy->hdmi_opts.pixel_clk_rate; + + /* De-serializer delay D/C for non-lbk mode: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG0, + FIELD_PREP(HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__MASK, 3)); + + if (pixclock == 27000) { + /* video_format == HDMI_VFRMT_720x480p60_16_9 */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG1, + FIELD_PREP(HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK, 5) | + FIELD_PREP(HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK, 3)); + } else { + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG1, + FIELD_PREP(HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK, 5) | + FIELD_PREP(HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK, 4)); + } + + /* No matter what, start from the power down mode: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_PWRGEN | + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + + /* Turn PowerGen on: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + + /* Turn PLL power on: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + + /* Write to HIGH after PLL power down de-assert: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG3, + HDMI_8x60_PHY_REG3_PLL_ENABLE); + + /* ASIC power on; PHY REG9 = 0 */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG9, 0); + + /* Enable PLL lock detect, PLL lock det will go high after lock + * Enable the re-time logic + */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG12, + HDMI_8x60_PHY_REG12_RETIMING_EN | + HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN); + + /* Drivers are on: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DESER); + + /* If the RX detector is needed: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_RCV_SENSE_EN | + HDMI_8x60_PHY_REG2_PD_DESER); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG4, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG5, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG6, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG7, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG8, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG9, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG10, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG11, 0); + + /* If we want to use lock enable based on counting: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG12, + HDMI_8x60_PHY_REG12_RETIMING_EN | + HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN | + HDMI_8x60_PHY_REG12_FORCE_LOCK); + + return 0; +} + +static int qcom_hdmi_msm8x60_phy_power_off(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + /* Turn off Driver */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + udelay(10); + /* Disable PLL */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG3, 0); + /* Power down PHY, but keep RX-sense: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_RCV_SENSE_EN | + HDMI_8x60_PHY_REG2_PD_PWRGEN | + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + + return 0; +} + +const struct qcom_hdmi_preqmp_cfg msm8x60_hdmi_phy_cfg = { + .clk_names = { "slave_iface" }, + .num_clks = 1, + + .reg_names = { "core-vdda" }, + .num_regs = 1, + + .power_on = qcom_hdmi_msm8x60_phy_power_on, + .power_off = qcom_hdmi_msm8x60_phy_power_off, + + /* FIXME: no PLL support */ +}; diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c index e181a45df2dc..66aa199424b8 100644 --- a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c @@ -147,20 +147,23 @@ static int qcom_hdmi_preqmp_probe(struct platform_device *pdev) if (ret) return ret; - init.name = "hdmipll"; - init.ops = cfg->pll_ops; - init.flags = CLK_GET_RATE_NOCACHE; - init.parent_data = cfg->pll_parent; - init.num_parents = 1; - - hdmi_phy->pll_hw.init = &init; - ret = devm_clk_hw_register(hdmi_phy->dev, &hdmi_phy->pll_hw); - if (ret) - goto err; - - ret = devm_of_clk_add_hw_provider(hdmi_phy->dev, of_clk_hw_simple_get, &hdmi_phy->pll_hw); - if (ret) - goto err; + /* FIXME: msm8x60 doesn't yet have PLL ops */ + if (cfg->pll_ops) { + init.name = "hdmipll"; + init.ops = cfg->pll_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_data = cfg->pll_parent; + init.num_parents = 1; + + hdmi_phy->pll_hw.init = &init; + ret = devm_clk_hw_register(hdmi_phy->dev, &hdmi_phy->pll_hw); + if (ret) + goto err; + + ret = devm_of_clk_add_hw_provider(hdmi_phy->dev, of_clk_hw_simple_get, &hdmi_phy->pll_hw); + if (ret) + goto err; + } hdmi_phy->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_hdmi_preqmp_phy_ops); if (IS_ERR(hdmi_phy->phy)) { @@ -180,6 +183,7 @@ static int qcom_hdmi_preqmp_probe(struct platform_device *pdev) } static const struct of_device_id qcom_hdmi_preqmp_of_match_table[] = { + { .compatible = "qcom,hdmi-phy-8x60", .data = &msm8x60_hdmi_phy_cfg, }, { .compatible = "qcom,hdmi-phy-8960", .data = &msm8960_hdmi_phy_cfg, }, { .compatible = "qcom,hdmi-phy-8974", .data = &msm8974_hdmi_phy_cfg, }, { }, diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h index bc81d68463ec..66fb9235520a 100644 --- a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h @@ -74,6 +74,7 @@ static inline u32 hdmi_pll_read(struct qcom_hdmi_preqmp_phy *phy, int offset) return readl(phy->pll_reg + offset); } +extern const struct qcom_hdmi_preqmp_cfg msm8x60_hdmi_phy_cfg; extern const struct qcom_hdmi_preqmp_cfg msm8960_hdmi_phy_cfg; extern const struct qcom_hdmi_preqmp_cfg msm8974_hdmi_phy_cfg; From patchwork Sun Jun 25 11:42:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291897 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8594AC001DE for ; Sun, 25 Jun 2023 11:42:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=nIhWsyDw1QzbOy1eTge9aTgj5lDrkXtTQJzZup/QlXk=; b=LheVszG7wlPWVF HTUncWt32rjf11KvfxQmdPreLq1ih6Q/4PigfSxYsbAMCl5h9QY/sb9dH1XYX4i/hL4wIgR+ddilf T5VB7V8Ard4vMsqAqlYGzfwHh28tjkRLPMLIYNDt5NNKY9yj44g+xCv97VZbhYY5a0pUzoWb3S3AV czjvTjOCSc05utsaIUTveasjTdoid041fRISJ1OkxcMWHXEC4bwFbXN8i9MVS8u+qm7/fpi6NRDBn ceC5s6Iv4SmOwLGobNPvEvZguVHWuxQoGKojDfpm30WiCAfEx1Dv07umsrHGMoMS2elPTs+v85/Uf 1RTnZkSdk55BlyaYLw1w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8j-007w9v-00; Sun, 25 Jun 2023 11:42:45 +0000 Received: from mail-lf1-x134.google.com ([2a00:1450:4864:20::134]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8c-007w1J-1s for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:42 +0000 Received: by mail-lf1-x134.google.com with SMTP id 2adb3069b0e04-4f875b267d9so3028828e87.1 for ; Sun, 25 Jun 2023 04:42:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693350; x=1690285350; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lwdtqkDXqK7iZxcIX1bEzs8baolumoX7/30733m/ZW8=; b=csRNaQVYcN5FlY1KPPmbQ3DhS2yDIluczA9prBJjlEis0hj9zyLOJ92+3vWSG3wDPH aJXwYnwBhB7nfZ4ZU/BkYzjQow5FL+ttw7WQzRVTWRsWovgYQMYPWJNsEFH1shm9DxEM MRw6m6BbZlxeDAAkVWzXRx1B7TtkNNicfCrLeAjQFowxLo1TM0o/L6IUFsH668ogcEcf aaKuM1FSW1r5X+W9WZNu7KY0FB/zb4yo/pEvgO00Rvrt/C0Ne7l4AjlelDBp7hA97/c7 1/LSkEId65dBAiGKPtDbLGQZ3rVH/fWZDpYriqPbjBCZNoKJ1rwoB+GNFbMT4msiXzFo x9xA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693350; x=1690285350; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lwdtqkDXqK7iZxcIX1bEzs8baolumoX7/30733m/ZW8=; b=KyP8T06CVaBpKAY4lBPHeYzV9jrvKjf70q/gEP7TMq7uBw9z1YtqtNbJ8TxkKE+cuD bT9VQxFHAvijQI2GoYQ9LnTMz7YEAO0tbVVpL8ly2LsO/XADj1mZcDzPeperJv+9twBX HyGEnqAMCrrKFZR4MUhRW6MHFfQf4cupaZZWq3pbOLfG6v6HdbrmD3cl2Q6StE7MHZh2 VH1PaknoG2j3th4M/BjKOLIv+FL1rEb0ATjWew17jvTL5b1YRq/LVUaFudz7y1XAjXJH lJ384r5nGMdZfzj1r0mcZuB6Q81avF4pL0CPv3SLO+WDvb7llNA1rZS/tB9oHMwUB4s/ xT7w== X-Gm-Message-State: AC+VfDzU+fdCDaAxpfVB4Wi7Dg3QFuhTZvObGK1mSKWWFa7/xmx6QptD dnW9rTRl0YZ3/p/J5Y2w1rD0/g== X-Google-Smtp-Source: ACHHUZ6JBYjRhM3xUtGku0UohCxWUXppP0M1khuC54BjHXVyboGxygUTxDaw7zl/dBjjx5nQpMp90Q== X-Received: by 2002:a19:e348:0:b0:4f8:48f3:f06 with SMTP id c8-20020a19e348000000b004f848f30f06mr14544063lfk.48.1687693350508; Sun, 25 Jun 2023 04:42:30 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:30 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 08/15] drm/msm/hdmi: move the alt_iface clock to the hpd list Date: Sun, 25 Jun 2023 14:42:15 +0300 Message-Id: <20230625114222.96689-9-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044238_663467_0DEE906C X-CRM114-Status: GOOD ( 10.35 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org According to the vendor kernel [1] , the alt_iface clock should be enabled together with the rest of HPD clocks, to make HPD to work properly. [1] https://git.codelinaro.org/clo/la/kernel/msm-3.18/-/commit/e07a5487e521e57f76083c0a6e2f995414ac6d03 Signed-off-by: Dmitry Baryshkov Reviewed-by: Konrad Dybcio --- drivers/gpu/drm/msm/hdmi/hdmi.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 3132105a2a43..0fc3df43aa70 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -248,9 +248,9 @@ static const struct hdmi_platform_config hdmi_tx_8960_config = { }; static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"}; -static const char *pwr_clk_names_8x74[] = {"extp", "alt_iface"}; -static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core"}; -static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0}; +static const char *pwr_clk_names_8x74[] = {"extp"}; +static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core", "alt_iface"}; +static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0, 0}; static const struct hdmi_platform_config hdmi_tx_8974_config = { HDMI_CFG(pwr_reg, 8x74), From patchwork Sun Jun 25 11:42:16 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291902 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C8836C001DD for ; Sun, 25 Jun 2023 11:42:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=4g9yUlj3C9CZlxcf+ttR4X1jbBauNio1XAmvfws7/jE=; b=vF0WWmjl76/yIE 5F3IjIqq9jfq7I/5VfrjsOp6fmP4uSNbeLd2Z7oWAIkEkx/jN6BEIXrJbaHC6VwspGfjHMR7QlgQN mDWpqVRVYOdMmvRkWH4tMHr7na4F2lnnYtnpOkX9b+lNNvV1wwlY56oXAJPe5mKJ9CG4goRelI6yz wCjOFlqW1ij7S2Iuv4KtT2tcckgIZ+5MnbgXv2sG/ONrDkeF+UsYyzI8Ik/5kYwMo2lvr0OOumu9+ LCccJ76HqzMBlGSo4WEDjtr7mNeBYs5kFSPsVovpz8wZf2CvXJ4s79wjA0pShzFziPQvRHwBbvusy cbw+EopSSLIl87VYnvsQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8m-007wBs-1W; Sun, 25 Jun 2023 11:42:48 +0000 Received: from mail-lf1-x12e.google.com ([2a00:1450:4864:20::12e]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8g-007w1O-3B for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:44 +0000 Received: by mail-lf1-x12e.google.com with SMTP id 2adb3069b0e04-4f973035d60so2656187e87.3 for ; Sun, 25 Jun 2023 04:42:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693351; x=1690285351; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8sn8z574aHDaIUAuI0kB4BeZ8f9+C4yT5HRFlvneark=; b=N4i8hbKp9JLJ7Hcn5m0dC+xMh8Petmn5eegQ1/6yt8GKKAQ8iTYfVKIQX7i/p1hZhO B1OgHjyfFzsmDZtUgO1wINs2xE+2KB9pH5JxmHz6eF+mw4OK+Xymp+jJMrltjcCmoPob yRmekZ2ZzUo0x0sAoPICZrcNFfh3VQa7AatW01uq7AzJM+vgXo35kAqM7N6U4LyfOsfz jwKpTxvoB8rKJB60H3GZqakAev5xiRrEbatzO5MtZXsItftL26ZlcSvBgFQtNEDH8yJk KfiVvrP9L+ntHTqXnHE179n+56wKUMogFcNBBvMhLL9A/rL9I7yZxtpLn3fN1DuLj+jY K/GA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693351; x=1690285351; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=8sn8z574aHDaIUAuI0kB4BeZ8f9+C4yT5HRFlvneark=; b=Sgs3gRTNWyXaqLCIumEVP/4klqNauqQTBoWm3aaPe6N6GK7iPi+xMbz6fM/VLMyNCA gDc7lbwnxUR3Lj3JBfvP1v6kizX5GN7i3xjGccsblM5uErY/LSnxrChZL02618wqOZAc h+U5D8Pzc7XpRZjs03tFBuKvUNf/UYdtYRYDW1yMzbLAz/a/CpXU2P3eqWOp699i1I3i Rjl5kLtIfD79H9cAQSudfKlKSrPjV4A5KgtggsAOHkY9Q79FnG2+PiJ7+xYOtf1oG2xG et3WHSW5vlwhOhOqxlghSv7nMpkiCGJNCbothbhpv7nObgXEXIK+L1uNLM0RkG9XfAVJ 1qag== X-Gm-Message-State: AC+VfDyGxohkLnoe3xi3qJ6oX5fYaZC193le33TPl2XUrG/+J/dm72LY YbDyluif+QjZjri3M8tmQ3Du/Q== X-Google-Smtp-Source: ACHHUZ5uSrg00k+4Jeoniqdq+eKmv5SMkKvGBXZUIVFY2Z0vMlR3S+2poEP5u2Y66tfSof0mcBqGaA== X-Received: by 2002:a19:2d43:0:b0:4f8:5e49:c610 with SMTP id t3-20020a192d43000000b004f85e49c610mr12389972lft.35.1687693351436; Sun, 25 Jun 2023 04:42:31 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:30 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 09/15] drm/msm/hdmi: simplify extp clock handling Date: Sun, 25 Jun 2023 14:42:16 +0300 Message-Id: <20230625114222.96689-10-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044243_056099_3E3C4C43 X-CRM114-Status: GOOD ( 18.60 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org With the extp being the only "power" clock left, remove the surrounding loops and handle the extp clock directly. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/hdmi/hdmi.c | 24 ++++--------------- drivers/gpu/drm/msm/hdmi/hdmi.h | 6 +---- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 33 ++++++++++---------------- 3 files changed, 18 insertions(+), 45 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index 0fc3df43aa70..a2780aba6d3c 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -248,13 +248,11 @@ static const struct hdmi_platform_config hdmi_tx_8960_config = { }; static const char *pwr_reg_names_8x74[] = {"core-vdda", "core-vcc"}; -static const char *pwr_clk_names_8x74[] = {"extp"}; static const char *hpd_clk_names_8x74[] = {"iface", "core", "mdp_core", "alt_iface"}; static unsigned long hpd_clk_freq_8x74[] = {0, 19200000, 0, 0}; static const struct hdmi_platform_config hdmi_tx_8974_config = { HDMI_CFG(pwr_reg, 8x74), - HDMI_CFG(pwr_clk, 8x74), HDMI_CFG(hpd_clk, 8x74), .hpd_freq = hpd_clk_freq_8x74, }; @@ -495,24 +493,10 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev) hdmi->hpd_clks[i] = clk; } - hdmi->pwr_clks = devm_kcalloc(&pdev->dev, - config->pwr_clk_cnt, - sizeof(hdmi->pwr_clks[0]), - GFP_KERNEL); - if (!hdmi->pwr_clks) - return -ENOMEM; - - for (i = 0; i < config->pwr_clk_cnt; i++) { - struct clk *clk; - - clk = msm_clk_get(pdev, config->pwr_clk_names[i]); - if (IS_ERR(clk)) - return dev_err_probe(dev, PTR_ERR(clk), - "failed to get pwr clk: %s\n", - config->pwr_clk_names[i]); - - hdmi->pwr_clks[i] = clk; - } + hdmi->extp_clk = devm_clk_get_optional(&pdev->dev, "extp"); + if (IS_ERR(hdmi->extp_clk)) + return dev_err_probe(dev, PTR_ERR(hdmi->extp_clk), + "failed to get extp clock\n"); hdmi->hpd_gpiod = devm_gpiod_get_optional(&pdev->dev, "hpd", GPIOD_IN); /* This will catch e.g. -EPROBE_DEFER */ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index e8dbee50637f..2d405da63bd0 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -51,7 +51,7 @@ struct hdmi { struct regulator_bulk_data *hpd_regs; struct regulator_bulk_data *pwr_regs; struct clk **hpd_clks; - struct clk **pwr_clks; + struct clk *extp_clk; struct gpio_desc *hpd_gpiod; @@ -98,10 +98,6 @@ struct hdmi_platform_config { const char **hpd_clk_names; const long unsigned *hpd_freq; int hpd_clk_cnt; - - /* clks that need to be on for screen pwr (ie pixel clk): */ - const char **pwr_clk_names; - int pwr_clk_cnt; }; struct hdmi_bridge { diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 9b1391d27ed3..62ce1455f974 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -25,7 +25,7 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge) struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; const struct hdmi_platform_config *config = hdmi->config; - int i, ret; + int ret; pm_runtime_get_sync(&hdmi->pdev->dev); @@ -33,21 +33,15 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge) if (ret) DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %d\n", ret); - if (config->pwr_clk_cnt > 0) { + if (hdmi->extp_clk) { DBG("pixclock: %lu", hdmi->pixclock); - ret = clk_set_rate(hdmi->pwr_clks[0], hdmi->pixclock); - if (ret) { - DRM_DEV_ERROR(dev->dev, "failed to set pixel clk: %s (%d)\n", - config->pwr_clk_names[0], ret); - } - } + ret = clk_set_rate(hdmi->extp_clk, hdmi->pixclock); + if (ret) + DRM_DEV_ERROR(dev->dev, "failed to set extp clk rate: %d\n", ret); - for (i = 0; i < config->pwr_clk_cnt; i++) { - ret = clk_prepare_enable(hdmi->pwr_clks[i]); - if (ret) { - DRM_DEV_ERROR(dev->dev, "failed to enable pwr clk: %s (%d)\n", - config->pwr_clk_names[i], ret); - } + ret = clk_prepare_enable(hdmi->extp_clk); + if (ret) + DRM_DEV_ERROR(dev->dev, "failed to enable extp clk: %d\n", ret); } } @@ -57,15 +51,15 @@ static void power_off(struct drm_bridge *bridge) struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; const struct hdmi_platform_config *config = hdmi->config; - int i, ret; + int ret; /* TODO do we need to wait for final vblank somewhere before * cutting the clocks? */ mdelay(16 + 4); - for (i = 0; i < config->pwr_clk_cnt; i++) - clk_disable_unprepare(hdmi->pwr_clks[i]); + if (hdmi->extp_clk) + clk_disable_unprepare(hdmi->extp_clk); ret = regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs); if (ret) @@ -270,7 +264,6 @@ static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; - const struct hdmi_platform_config *config = hdmi->config; struct msm_drm_private *priv = bridge->dev->dev_private; struct msm_kms *kms = priv->kms; long actual, requested; @@ -284,8 +277,8 @@ static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge if (kms->funcs->round_pixclk) actual = kms->funcs->round_pixclk(kms, requested, hdmi_bridge->hdmi->encoder); - else if (config->pwr_clk_cnt > 0) - actual = clk_round_rate(hdmi->pwr_clks[0], requested); + else if (hdmi->extp_clk) + actual = clk_round_rate(hdmi->extp_clk, requested); else actual = requested; From patchwork Sun Jun 25 11:42:17 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291895 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A8A1DEB64DC for ; Sun, 25 Jun 2023 11:42:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=x55nIozV0vkbZw8lsWujFoEbB2BXcoDaa+bKUpIq1m8=; b=pLgiOlSwk0ZZzu ztOk+NIfqJr2iQy96JgeSjcCdLkk6a/o14wFRkIE6fRMlXkAYfEqootkEHYCnbKlwR0CFXYEtE8vK VPDRnaOH13taR0t3z+SFxZdKCKSXlTzTnmuGkApBxDPUB0JIgDjxdGW8PvGm+iM/Qw5YPJnisPrFV kOJbR7oK6Uv41DkSf9AdrkZf2vh4JH3xpvSxFnkJZS5J8rqTD6u6V5hNf8C0PDUtWSy3Wm9Ao9Dm6 ZCt9oLVoNd+BeRfB4wQGPl5yk+OWdvhgpwC28Hb+FRt1rPcBdGLb3C0uDzJL6YfbxuOmeNe+j5f2F AWiLmaiHxpqik7knvNgg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8i-007w95-0h; Sun, 25 Jun 2023 11:42:44 +0000 Received: from mail-lf1-x134.google.com ([2a00:1450:4864:20::134]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8c-007w1S-1r for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:41 +0000 Received: by mail-lf1-x134.google.com with SMTP id 2adb3069b0e04-4f86a7a5499so3005377e87.2 for ; Sun, 25 Jun 2023 04:42:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693352; x=1690285352; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=HlnLygFYYtSxoKEaC5DFXDBhNuXumh16hVtzEXEvSec=; b=bJDzcJXCkAPD5zeUzpoqy0kG3q005OtGeLsMf6/8V95IZdLI0J9FwWFQzM7I0TviaG 7R72ljXh4KrImRig/whnSLpd6D+vlRxOUdDwWuupvCQS7qyud0wY7+GK+uT+kqTl9Tqu spKdhblRSZ/3kfTR4niN2Mbd10wb19O3UehlWtub8FJ/kOPQglGSe7XF9bIKwtfryB6G ApTzotjKQMX3+GMHDaU1t8gp+wa2hLP4pmo8Lqu+fEOwu1kpacrne/Ttr6H/9T0X90dE u1Lujt97vZeMsX1ApXMYlC9jczbq0/FkcAzNk0PxtqsRa8rOqSFB3L+HD3ABtublF8Qd PTaw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693352; x=1690285352; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=HlnLygFYYtSxoKEaC5DFXDBhNuXumh16hVtzEXEvSec=; b=VDZ8PqcjA4RxwZRK1Uki4bFBy/Klyp6xX1cKXpvFD4/E4bxucJ/tdjRcsB34fYGVJI dzWvBWI3zdj4BuA+wDvva6ixFh4MP8oUU31/fGcLUIY/tWYN/g3jHhbVBV064Nnc5OoJ J2esqf+TvxNFzpGaqcVpVqYEVFvHDCkyk1KL10YLT9BLMC2CKjE9XoouZiXnLey0yBeL g8euxzr2KjB8O3G9bY7GxGsKU+3at1ta77vLmNupoLVI9RKnOK/4IkeLKV9kGA2nN+Ts Hoy6vVOSIskG+N6QCGu7IqFHf8z+XOQy5EmtUg9x/jGyTZGefRt9CfZzo/pN2hlGslC2 /zLA== X-Gm-Message-State: AC+VfDySHR8NmXiXErBcEoSczvm8MZEFLyEpTwKcmMZkZWAVeWoAAkSs Sdcg46kMpZrN0IkUY1X6E9DZXA== X-Google-Smtp-Source: ACHHUZ7uaGIlPGOJp+0nRUkLMEV41kt31Ga6/kU/1+uK8JUDcsenYErcV7bYVaZlQb/IfK6J5BBR0A== X-Received: by 2002:a19:9156:0:b0:4f8:58af:ebd7 with SMTP id y22-20020a199156000000b004f858afebd7mr14228099lfj.39.1687693352116; Sun, 25 Jun 2023 04:42:32 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:31 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 10/15] drm/msm/hdmi: correct indentation of HDMI bridge functions Date: Sun, 25 Jun 2023 14:42:17 +0300 Message-Id: <20230625114222.96689-11-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044238_666139_32082646 X-CRM114-Status: UNSURE ( 8.70 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 62ce1455f974..fbcf4dd91cd9 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -291,12 +291,12 @@ static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge } static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = { - .pre_enable = msm_hdmi_bridge_pre_enable, - .post_disable = msm_hdmi_bridge_post_disable, - .mode_set = msm_hdmi_bridge_mode_set, - .mode_valid = msm_hdmi_bridge_mode_valid, - .get_edid = msm_hdmi_bridge_get_edid, - .detect = msm_hdmi_bridge_detect, + .pre_enable = msm_hdmi_bridge_pre_enable, + .post_disable = msm_hdmi_bridge_post_disable, + .mode_set = msm_hdmi_bridge_mode_set, + .mode_valid = msm_hdmi_bridge_mode_valid, + .get_edid = msm_hdmi_bridge_get_edid, + .detect = msm_hdmi_bridge_detect, }; static void From patchwork Sun Jun 25 11:42:18 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291899 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A69CDC001DD for ; Sun, 25 Jun 2023 11:42:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=l1ZLetIh5bOjJtC0J/BEcRB0V86+iPTLH+xQoSlECZ4=; b=qh5CC4JoONxn/R cglRe9/85cdP++/p9FD+OQl0vZwfJhz/t8VfMyDi6LbQnJqzurBNxWSjRSAUJ/vSuaXZ47W9LUPm4 t2nxrxjvADZ0ea85LURoD2KW75yXgbUI5uvJKAgSBJ6CMtgf/VN2FBamH/0q9ScWf75DWHKeLS1AG dVo63dZq0Zx/3aXam4zgrsthPVeT6LiuGPhQxIDtKjlUZ0iUTcCQRN5CTRRwJh/gAflCfUGxOWIJ1 L8+0mJPSBKzF9i/bgIWJ51yyO3txIuJxIkoD+EE4UpqyH9SL+TanqND+3a5a3Tf01ao4F7vbOny1J au20aLuj6nRI51xROCIw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8j-007wAC-0x; Sun, 25 Jun 2023 11:42:45 +0000 Received: from mail-lf1-x132.google.com ([2a00:1450:4864:20::132]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8c-007w1r-2K for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:42 +0000 Received: by mail-lf1-x132.google.com with SMTP id 2adb3069b0e04-4f871c93a5fso2827925e87.2 for ; Sun, 25 Jun 2023 04:42:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693353; x=1690285353; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=JRCcVx5yqkWjx+j8HRIisuUziAvNRbEhBQXvfMXuZd8=; b=l03zKow5647+l5uNvEOvclkTiqWG965H4wqbDIqh2y8vH8NEUWgZwEv7r6IlcabhTF BoTk1ggbF/1vLmC1qFPlhuDc1FAoVGdAYTgW9JJ6dAdCQiuFRo5X3KXBQ/nlv20OvGSx 6jEFE9ppAu0hGi4si53AZrSdZOej/zMrh0zhyjBdUeFJc4vyXFCjay6o286oo0kINLy/ FIxMtHJmVgbdAV/yuVtaMORxNjOcEwpRDVal+J+boSCp+L8XnMmE2LEAR+nLN9p1horC RrNCUfyjM2kR7v5rYAXqeAl0ofxT3gluVN7t0zMbuj5SP16YQqRBvOt/WPkwEWwT9KYT J/mA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693353; x=1690285353; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=JRCcVx5yqkWjx+j8HRIisuUziAvNRbEhBQXvfMXuZd8=; b=lww+t+/vSv5D229uIRbHltFeJIJ30kUw+x9OatwT8hBdTu7a3d1rzEaxvqip7jknxj K50HTkRgmCjCahBz8jBBwKco2OdW4ddkyjTYIIfBV3bGooMTV2iwWqd46ocSqYgtzDbt KuhzZ3ZyNsFkIioiigrYjg+/ozP2tvhZS9+DxFM94/ON9rfV0TdvGlr7nQdyHfCg/6Tf P3aZPUMhKiNvba3x212OxbrOest9accd4+I7xbiJyaLjaSywwXTbsjoUXkSU3VWtMRn7 qqRCHhw5C1jPTAmYau3vlaYIYWNPThzLM0qNY4KrnC2Y60c8zuFNI0+mFTRq5r2rBIoK Nw6w== X-Gm-Message-State: AC+VfDww+rN8WhrQ9FSXlVWdOe5JJ4ouRywgY58cnmzf+kHCkRor0I2Q hiXBDpxHijFP3PygymVbY5QtNw== X-Google-Smtp-Source: ACHHUZ7docs3bpHHggTQnwRK9vZD9G6BzpVgE1c++x/CDmK3D6Xsv/RdHy9EgpRd+K39O/pVejaPOw== X-Received: by 2002:ac2:498f:0:b0:4f8:6cf1:8163 with SMTP id f15-20020ac2498f000000b004f86cf18163mr12237375lfl.18.1687693353048; Sun, 25 Jun 2023 04:42:33 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:32 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 11/15] drm/msm/hdmi: switch to atomic_pre_enable/post_disable Date: Sun, 25 Jun 2023 14:42:18 +0300 Message-Id: <20230625114222.96689-12-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044238_771625_74BAEB1A X-CRM114-Status: UNSURE ( 9.66 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org In preparation of reworking the HDMI mode setting, switch pre_enable and post_disable callbacks to their atomic variants. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index fbcf4dd91cd9..f9293f7d8f34 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -128,7 +128,8 @@ static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi) hdmi_write(hdmi, REG_HDMI_INFOFRAME_CTRL1, val); } -static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge) +static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; @@ -154,7 +155,8 @@ static void msm_hdmi_bridge_pre_enable(struct drm_bridge *bridge) msm_hdmi_hdcp_on(hdmi->hdcp_ctrl); } -static void msm_hdmi_bridge_post_disable(struct drm_bridge *bridge) +static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge, + struct drm_bridge_state *old_bridge_state) { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; @@ -291,8 +293,13 @@ static enum drm_mode_status msm_hdmi_bridge_mode_valid(struct drm_bridge *bridge } static const struct drm_bridge_funcs msm_hdmi_bridge_funcs = { - .pre_enable = msm_hdmi_bridge_pre_enable, - .post_disable = msm_hdmi_bridge_post_disable, + .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, + .atomic_reset = drm_atomic_helper_bridge_reset, + + .atomic_pre_enable = msm_hdmi_bridge_atomic_pre_enable, + .atomic_post_disable = msm_hdmi_bridge_atomic_post_disable, + .mode_set = msm_hdmi_bridge_mode_set, .mode_valid = msm_hdmi_bridge_mode_valid, .get_edid = msm_hdmi_bridge_get_edid, From patchwork Sun Jun 25 11:42:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291898 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 18311C001DC for ; Sun, 25 Jun 2023 11:42:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=HHWNOUx9jKAQQUhD8gdmNidl4tOASa9uVzHeepvKGGg=; b=bhXpwJDcQ860Fu B8djGhpG/Qk3MI/tG0Ri3NIf3gFzgcEhTUthIt1KqYbo43N3CJwmIPfN0IVHCvX1Rj4R0Tfc1Wq4a U5uZTYJjV/kJmM/3J2hF8N1iL6U36tn7YROohUSLXqvJMFtfnZwqR833erI5fIs0uMyJLomcyUVfV dsv8FxcwKzxGrPmLSFiyeJrNJG9YGcs4ssCRPXQ8VMYtDdc5AkB9toIRIaVugAoiKXe5Yc9/a+qEP lMiN+Z/GSl8TLdcQPrNdv1eAiZ7czci7og2dvpao4pPr22/0eynI8hwLfV2bzKgru+wBmj+q3x9zM /zp2mnseLloDUiIIVMTw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8i-007w9J-1r; Sun, 25 Jun 2023 11:42:44 +0000 Received: from mail-lf1-x12b.google.com ([2a00:1450:4864:20::12b]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8c-007w1z-1r for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:42 +0000 Received: by mail-lf1-x12b.google.com with SMTP id 2adb3069b0e04-4f8735ac3e3so3006874e87.2 for ; Sun, 25 Jun 2023 04:42:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693354; x=1690285354; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kMftiAUxeR8BPoZkZvXeNvb1WLgqdhL6DsPjfLjpExg=; b=nE9hwWDfWngVy/rJ1ATloHL2acbnwoqhkXi38nYNFRf1kqZvB71Smf9bY+b/qkrxRP MXwB9J5C9ItoBwkkMGNCcn4lpjlZqKXZYOy7ojITBqpz+YA0ayUBiGBnq9HlMmAGb12O 6u3q0MrT4vlbNvIjFcH+4UMvFq3OVM9Dvw3BRFepnAVB9fEDbqIAit6SifKg1vx1xKzW P63sX/0OItKDxNlXzDmh7X/E/fLaWYYPXDddddvAK4XUNeaXVOLEYi+MNbGoqxV7RVQS zw6oboCfNTyAoJeHJ9c6K/PvkFU0vbURW6HoODLyIT5IOHXAxdyu2IgUUWmSYxKc133c /Z5g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693354; x=1690285354; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=kMftiAUxeR8BPoZkZvXeNvb1WLgqdhL6DsPjfLjpExg=; b=Q9/SWB32ms5EfkY6V+iHeOdQdZh6OAhEReulk+0GHHn/FNGLsnpiFX2Jm4QN4uw0LL 02bweqS3A/kgs/mQTi4txMXIsfsaXGXrzfJuPvGBqPYR4t+3+S/JhBdrooi1k6jb+wEj ymM5SA0EdaZR7FkZceMSw7MZmjZw/FhuCccdXDxJXUJx2PJBLwRSOE1MMitkzVNQBcjZ qQcmWG1fQmYct8V8/PG9H0JLb+UflQlEw8KaE97KTcKAqBGJciD2GI9C3iMT6nw4ORri y21+I03L7M+RXMDNJb/yf/piuWRFFaNS3d6L+7gDqmUkq1+bjgPVpGwEu8oNVJuEYCjr ruVg== X-Gm-Message-State: AC+VfDzavf+clXNU2+czTA+qGdFy0w3lkviW87jyrmnFuUClCiTR/Tub VfgxcKi8sDLc713/n+e6D+poDA== X-Google-Smtp-Source: ACHHUZ42a3rY1LXrItHqP+/HoHNQ4DRPF+yUblDDgmlM5wyJNaabrKnL1yHAUQYVToD3/xWvmBDNxQ== X-Received: by 2002:a19:5018:0:b0:4f8:75b0:2297 with SMTP id e24-20020a195018000000b004f875b02297mr11187764lfb.43.1687693353834; Sun, 25 Jun 2023 04:42:33 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:33 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 12/15] drm/msm/hdmi: set infoframes on all pre_enable calls Date: Sun, 25 Jun 2023 14:42:19 +0300 Message-Id: <20230625114222.96689-13-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044238_664333_9DFD5CD2 X-CRM114-Status: UNSURE ( 9.22 ) X-CRM114-Notice: Please train this message. X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org In consequent modeset calls, the atomic_pre_enable() will be called several times without calling atomic_post_disable() inbetween. Thus iframes will not be updated for the next mode. Fix this by setting the iframe outside of the !power_on check. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index f9293f7d8f34..bb10b35194ff 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -141,10 +141,11 @@ static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge, msm_hdmi_phy_resource_enable(phy); msm_hdmi_power_on(bridge); hdmi->power_on = true; - if (hdmi->hdmi_mode) { - msm_hdmi_config_avi_infoframe(hdmi); - msm_hdmi_audio_update(hdmi); - } + } + + if (hdmi->hdmi_mode) { + msm_hdmi_config_avi_infoframe(hdmi); + msm_hdmi_audio_update(hdmi); } msm_hdmi_phy_powerup(phy, hdmi->pixclock); From patchwork Sun Jun 25 11:42:20 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291900 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0261BEB64DC for ; Sun, 25 Jun 2023 11:42:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=CKa3rZivwuxZNTfSQ7rDLjrPHtigV+JAX96xT51/Y+k=; b=lCFqC9zI1KGIHk SL5uiYxGs8/GHWIgSP//A+1FSMHOelGbRs2hbo8toXHUHfWnuCx8TRw3gnKyZcwj/vQ9wsZbooHIy wvaqR6/A+SqGuNW7bfbwDbqfyrZSr2a+BztSElfTRYjlxUuCAWnFLqz20Xl+0XllVqQpDKrU/uSQt U3R/Di0SuaAeB/dpLPwyES74RerjFInzLohilnO/MF5FXPpmN08Iaf42l5uVoEEjBf1RcVexjQb2i aBmMBjBFa9CbS1hsVV/orKnIclxy+jnWzqhYNdWWaBDiqZ1UR6JIckA6Mfg+Wg/vUoh6oKZcMBOhx P/hww7FBNEzGXifhMvGA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8l-007wB3-28; Sun, 25 Jun 2023 11:42:47 +0000 Received: from mail-lf1-x12c.google.com ([2a00:1450:4864:20::12c]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8d-007w2S-0l for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:43 +0000 Received: by mail-lf1-x12c.google.com with SMTP id 2adb3069b0e04-4faaaa476a9so769513e87.2 for ; Sun, 25 Jun 2023 04:42:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693354; x=1690285354; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=enSUc5wVEHF7eZy9e0DAWbElAzfosEhYHkkqQR9evEU=; b=GpwaJlGXYuG3Z4vYv+wgR1y2wSg6nEIFTwhWxzjR8tWukr9O16cDD9VF+YnnlCjaJb 9P+vI/dv1+JB09f0n/C9kVydtIyLLSbVaC7drfvLGjsIrjRdsjgnY9y+OQxAf4jMayEn hhGSh+40bZWK785rOVrHPcEVEac9RpB2HOCfce4XDRh8b5mBgF7ee0u5PkJMxYcLcCTu afZ/9K18wwJFf6mdgQTTlTxs3inKzkdEK3QIv8Sren5kiPdEDhQk5vqYTDtlde2xYLH5 QcoGxFiQwaEn/muwpiiGzEDnREKrol504vdRN3gMtj0DVLlYhdcq365Gif76dx6QF8zr 9D9g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693354; x=1690285354; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=enSUc5wVEHF7eZy9e0DAWbElAzfosEhYHkkqQR9evEU=; b=IQ66VsZqvkEVQlN4RBNGHH1pdvt4/v7f+xQwaxujZAal33FliIO9CIxqnfXGkcAR6I ID06a32dkqoGDKTE9e1sHXewpwr19hcTEF1Tr8dPlK+h7xDYZ6SyJePOpxQj7qwePUDG N8NLGCTKHmq0IVoInHUXWGjCgLv7tcr3hIH2+LhlIjArea7ZG88RTk+HJWYutpHpEP8e BPbi/VNKumfOk2cH3VEZD7YwX3c2JYTBmGc0vSdUNc6O10TyJ3nNYMGbGoMXZTREa47H 0qVZrfFl9j9CnDOlsf6EeYwI67TsmuQbUYWajsIYuzO52IICGObMc+EvmeV7lv3RYun+ 2bXw== X-Gm-Message-State: AC+VfDygiVH3WaZCJuJQA7Z0wXoBAAvHXDOhSWocxbRrolC0gm3WSFOo Ps4hxn8xoLjA63mJZXME0BTew/AmyzGvFz2ucLU= X-Google-Smtp-Source: ACHHUZ7u+Sgj815uM7U4pf8to+2Ka6ErMJBQSl4tNszqEw9fDmnsKqiRTL0HxBnsCbazmmHgMzIq7g== X-Received: by 2002:a05:6512:3d8e:b0:4fb:73d1:58e5 with SMTP id k14-20020a0565123d8e00b004fb73d158e5mr253539lfv.53.1687693354615; Sun, 25 Jun 2023 04:42:34 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.33 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:34 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 13/15] drm/msm/hdmi: pair msm_hdmi_phy_powerup with msm_hdmi_phy_powerdown Date: Sun, 25 Jun 2023 14:42:20 +0300 Message-Id: <20230625114222.96689-14-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044239_286685_237D9849 X-CRM114-Status: GOOD ( 10.35 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org In preparation to converting MSM HDMI driver to use PHY framework, which requires phy_power_on() calls to be paired with phy_power_off(), add a conditional call to msm_hdmi_phy_powerdown() before the call to msm_hdmi_phy_powerup(). Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/hdmi/hdmi.h | 1 + drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 2d405da63bd0..46ae7ef9bc98 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -42,6 +42,7 @@ struct hdmi { /* video state: */ bool power_on; + bool phy_power_on; unsigned long int pixclock; void __iomem *mmio; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index bb10b35194ff..1bbd76e595af 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -148,7 +148,11 @@ static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge, msm_hdmi_audio_update(hdmi); } + if (hdmi->phy_power_on) + msm_hdmi_phy_powerdown(phy); + msm_hdmi_phy_powerup(phy, hdmi->pixclock); + hdmi->phy_power_on = true; msm_hdmi_set_mode(hdmi, true); @@ -170,6 +174,7 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge, msm_hdmi_set_mode(hdmi, false); msm_hdmi_phy_powerdown(phy); + hdmi->phy_power_on = false; if (hdmi->power_on) { power_off(bridge); From patchwork Sun Jun 25 11:42:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 447E7C001B1 for ; Sun, 25 Jun 2023 11:42:48 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=suDmroSYJnGkJmNQyyhYK0jhN7alwIYIVV6aMw9tfdM=; b=cqeO5Ftsgi9vco q4tjVCH6LDyklYyEaB2jOEx6ETH83oiyGxO4fQCDahCOb//0O9ZKwX3kRc84R68ZDzkiNzCVDHnTa ZGzcTh3J4wsiS0XlvJCYve9T0xqdzFyk0/ZezoKD1nqn9hnhB5bv43iuJFeTJEGFNnVhLS6wIwKbb lBlPylANelJfhNgD8Dn+q56ONmuR5b5izCODrXctlGzGg8MyFBwzpD/4SbyAZ1MATbdtJSX1pj1xd bks11XiOBEqYre+nSWbQ/miEshOVeDgdkv9o5PbkFdtlOAbagaLCzVBr5lRegDCYy5zZIdXB/Q158 RteLdxI4iAUBoB8BZsjA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8l-007wBM-30; Sun, 25 Jun 2023 11:42:47 +0000 Received: from mail-lj1-x22a.google.com ([2a00:1450:4864:20::22a]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8d-007w2o-0l for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:44 +0000 Received: by mail-lj1-x22a.google.com with SMTP id 38308e7fff4ca-2b69e6cce7dso2940311fa.2 for ; Sun, 25 Jun 2023 04:42:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693355; x=1690285355; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=932oaPt6ojnBPy1wAaag4ZZtb2XDeptEQhNEoOdPrqw=; b=H+ELCcN6A7C+cu4Gz+vqMW9K7rBpvzmK5ul5JS7ht9DpmHK7C+mto5e8wqo5kJtOiQ GeGIZyDWj+btrMC88k67C6AegNdOjLXRDjq9SEjRTXwR960n2R8Z5FIZuo40uwsza4AE 3RqsMwuZTTgmmXwACUn0x7H0/UOYIz+y8wcGcecg4HGnwLvgGSeH7tcacEhMUoPxlkAb 8+ax9O2qk2TMTaJwXq8O3W3wcV/qtQLcwOvTzzo7rejGmd4QFErJW2zE/bc4toiHHsGc QwrkaGE6Fhev1cBcL/RMA8wjwEmSri2u/b4pNu5dLvQJPguAxfEMGTUPONE2Uk9mv4hu Xxzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693355; x=1690285355; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=932oaPt6ojnBPy1wAaag4ZZtb2XDeptEQhNEoOdPrqw=; b=d/qJYMENi1N9h6R5U7YqU0P/mNHhXdercFjuWTwfswj4jeT5L/LO1OgqFdGX9+nr3V plZABv4RQNQBh/RoxW3mRPt5rFAMa1InxI0KkmCE/rD5n33kAlPV4zb2ZI+wcDJOAS8n HPv1xbvIxa3EoYvyDWwIyGYN7QNuruudrjKcMlHuRx5FH/xfCqzNbLW5i5pQiGBizsvy aZLQwAUS3brO/2BI+anEfuQ+jZn+UI4qiWrmnL8xScxKvAS3wRPI+ykDNbNIRtfBE5lg F6EAQnjoYb3z3x9zH5bJLNm9uNTPrktA4x5o1RYsFm+rcNFW0pkGk5RukYFxfZuWIhkU eOTA== X-Gm-Message-State: AC+VfDzWecd4kA2xkyBSqX6VfDuK1OV0B+UcSb+iCMnqXtDpoLRiITK4 nt7YCifd1ar16QDZ2Mi1l1W52Q== X-Google-Smtp-Source: ACHHUZ66VO3vu75MCGaSX6TG8BtoxYP+CJ4ISP2ve/ajONihYsP2NhV3L51wwDQmpF1JegHTbD084Q== X-Received: by 2002:a05:6512:554:b0:4f8:66db:8235 with SMTP id h20-20020a056512055400b004f866db8235mr12421534lfl.39.1687693355445; Sun, 25 Jun 2023 04:42:35 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:35 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 14/15] drm/msm/hdmi: switch to generic PHY subsystem Date: Sun, 25 Jun 2023 14:42:21 +0300 Message-Id: <20230625114222.96689-15-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044239_288319_25416206 X-CRM114-Status: GOOD ( 20.76 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Change the MSM HDMI driver to use generic PHY subsystem. Moving PHY drivers allows better code sharing with the rest of the PHY system. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 6 --- drivers/gpu/drm/msm/hdmi/hdmi.c | 58 +++------------------ drivers/gpu/drm/msm/hdmi/hdmi.h | 72 +------------------------- drivers/gpu/drm/msm/hdmi/hdmi_bridge.c | 58 +++++++++++++-------- 4 files changed, 45 insertions(+), 149 deletions(-) diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index 8d02d8c33069..908c79702864 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -23,12 +23,6 @@ msm-$(CONFIG_DRM_MSM_HDMI) += \ hdmi/hdmi_bridge.o \ hdmi/hdmi_hpd.o \ hdmi/hdmi_i2c.o \ - hdmi/hdmi_phy.o \ - hdmi/hdmi_phy_8960.o \ - hdmi/hdmi_phy_8996.o \ - hdmi/hdmi_phy_8x60.o \ - hdmi/hdmi_phy_8x74.o \ - hdmi/hdmi_pll_8960.o \ msm-$(CONFIG_DRM_MSM_MDP4) += \ disp/mdp4/mdp4_crtc.o \ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.c b/drivers/gpu/drm/msm/hdmi/hdmi.c index a2780aba6d3c..5c50ae57f107 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi.c @@ -7,6 +7,7 @@ #include #include +#include #include #include @@ -72,44 +73,6 @@ static void msm_hdmi_destroy(struct hdmi *hdmi) msm_hdmi_i2c_destroy(hdmi->i2c); } -static void msm_hdmi_put_phy(struct hdmi *hdmi) -{ - if (hdmi->phy_dev) { - put_device(hdmi->phy_dev); - hdmi->phy = NULL; - hdmi->phy_dev = NULL; - } -} - -static int msm_hdmi_get_phy(struct hdmi *hdmi) -{ - struct platform_device *pdev = hdmi->pdev; - struct platform_device *phy_pdev; - struct device_node *phy_node; - - phy_node = of_parse_phandle(pdev->dev.of_node, "phys", 0); - if (!phy_node) { - DRM_DEV_ERROR(&pdev->dev, "cannot find phy device\n"); - return -ENXIO; - } - - phy_pdev = of_find_device_by_node(phy_node); - of_node_put(phy_node); - - if (!phy_pdev) - return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "phy driver is not ready\n"); - - hdmi->phy = platform_get_drvdata(phy_pdev); - if (!hdmi->phy) { - put_device(&phy_pdev->dev); - return dev_err_probe(&pdev->dev, -EPROBE_DEFER, "phy driver is not ready\n"); - } - - hdmi->phy_dev = &phy_pdev->dev; - - return 0; -} - /* construct hdmi at bind/probe time, grab all the resources. If * we are to EPROBE_DEFER we want to do it here, rather than later * at modeset_init() time @@ -510,37 +473,32 @@ static int msm_hdmi_dev_probe(struct platform_device *pdev) if (hdmi->hpd_gpiod) gpiod_set_consumer_name(hdmi->hpd_gpiod, "HDMI_HPD"); - ret = msm_hdmi_get_phy(hdmi); - if (ret) { + hdmi->phy = devm_phy_get(&pdev->dev, NULL); + if (IS_ERR(hdmi->phy)) { DRM_DEV_ERROR(&pdev->dev, "failed to get phy\n"); - return ret; + return PTR_ERR(hdmi->phy); } ret = devm_pm_runtime_enable(&pdev->dev); if (ret) - goto err_put_phy; + goto err; platform_set_drvdata(pdev, hdmi); ret = component_add(&pdev->dev, &msm_hdmi_ops); if (ret) - goto err_put_phy; + goto err; return 0; -err_put_phy: - msm_hdmi_put_phy(hdmi); +err: return ret; } static int msm_hdmi_dev_remove(struct platform_device *pdev) { - struct hdmi *hdmi = dev_get_drvdata(&pdev->dev); - component_del(&pdev->dev, &msm_hdmi_ops); - msm_hdmi_put_phy(hdmi); - return 0; } @@ -565,12 +523,10 @@ static struct platform_driver msm_hdmi_driver = { void __init msm_hdmi_register(void) { - msm_hdmi_phy_driver_register(); platform_driver_register(&msm_hdmi_driver); } void __exit msm_hdmi_unregister(void) { platform_driver_unregister(&msm_hdmi_driver); - msm_hdmi_phy_driver_unregister(); } diff --git a/drivers/gpu/drm/msm/hdmi/hdmi.h b/drivers/gpu/drm/msm/hdmi/hdmi.h index 46ae7ef9bc98..d68ac7aaf1f2 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi.h +++ b/drivers/gpu/drm/msm/hdmi/hdmi.h @@ -19,7 +19,6 @@ #include "msm_drv.h" #include "hdmi.xml.h" -struct hdmi_phy; struct hdmi_platform_config; struct hdmi_audio { @@ -56,8 +55,7 @@ struct hdmi { struct gpio_desc *hpd_gpiod; - struct hdmi_phy *phy; - struct device *phy_dev; + struct phy *phy; struct i2c_adapter *i2c; struct drm_connector *connector; @@ -125,74 +123,6 @@ static inline u32 hdmi_qfprom_read(struct hdmi *hdmi, u32 reg) return msm_readl(hdmi->qfprom_mmio + reg); } -/* - * hdmi phy: - */ - -enum hdmi_phy_type { - MSM_HDMI_PHY_8x60, - MSM_HDMI_PHY_8960, - MSM_HDMI_PHY_8x74, - MSM_HDMI_PHY_8996, - MSM_HDMI_PHY_MAX, -}; - -struct hdmi_phy_cfg { - enum hdmi_phy_type type; - void (*powerup)(struct hdmi_phy *phy, unsigned long int pixclock); - void (*powerdown)(struct hdmi_phy *phy); - const char * const *reg_names; - int num_regs; - const char * const *clk_names; - int num_clks; -}; - -extern const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg; -extern const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg; -extern const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg; -extern const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg; - -struct hdmi_phy { - struct platform_device *pdev; - void __iomem *mmio; - struct hdmi_phy_cfg *cfg; - const struct hdmi_phy_funcs *funcs; - struct regulator_bulk_data *regs; - struct clk **clks; -}; - -static inline void hdmi_phy_write(struct hdmi_phy *phy, u32 reg, u32 data) -{ - msm_writel(data, phy->mmio + reg); -} - -static inline u32 hdmi_phy_read(struct hdmi_phy *phy, u32 reg) -{ - return msm_readl(phy->mmio + reg); -} - -int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy); -void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy); -void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock); -void msm_hdmi_phy_powerdown(struct hdmi_phy *phy); -void __init msm_hdmi_phy_driver_register(void); -void __exit msm_hdmi_phy_driver_unregister(void); - -#ifdef CONFIG_COMMON_CLK -int msm_hdmi_pll_8960_init(struct platform_device *pdev); -int msm_hdmi_pll_8996_init(struct platform_device *pdev); -#else -static inline int msm_hdmi_pll_8960_init(struct platform_device *pdev) -{ - return -ENODEV; -} - -static inline int msm_hdmi_pll_8996_init(struct platform_device *pdev) -{ - return -ENODEV; -} -#endif - /* * audio: */ diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c index 1bbd76e595af..42aaaebbce00 100644 --- a/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +++ b/drivers/gpu/drm/msm/hdmi/hdmi_bridge.c @@ -5,6 +5,7 @@ */ #include +#include #include #include @@ -32,17 +33,6 @@ static void msm_hdmi_power_on(struct drm_bridge *bridge) ret = regulator_bulk_enable(config->pwr_reg_cnt, hdmi->pwr_regs); if (ret) DRM_DEV_ERROR(dev->dev, "failed to enable pwr regulator: %d\n", ret); - - if (hdmi->extp_clk) { - DBG("pixclock: %lu", hdmi->pixclock); - ret = clk_set_rate(hdmi->extp_clk, hdmi->pixclock); - if (ret) - DRM_DEV_ERROR(dev->dev, "failed to set extp clk rate: %d\n", ret); - - ret = clk_prepare_enable(hdmi->extp_clk); - if (ret) - DRM_DEV_ERROR(dev->dev, "failed to enable extp clk: %d\n", ret); - } } static void power_off(struct drm_bridge *bridge) @@ -58,9 +48,6 @@ static void power_off(struct drm_bridge *bridge) */ mdelay(16 + 4); - if (hdmi->extp_clk) - clk_disable_unprepare(hdmi->extp_clk); - ret = regulator_bulk_disable(config->pwr_reg_cnt, hdmi->pwr_regs); if (ret) DRM_DEV_ERROR(dev->dev, "failed to disable pwr regulator: %d\n", ret); @@ -131,14 +118,21 @@ static void msm_hdmi_config_avi_infoframe(struct hdmi *hdmi) static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge, struct drm_bridge_state *old_bridge_state) { + struct drm_atomic_state *state = old_bridge_state->base.state; struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; - struct hdmi_phy *phy = hdmi->phy; + struct drm_connector *connector; + union phy_configure_opts phy_opts; + int ret; DBG("power up"); + connector = drm_atomic_get_new_connector_for_encoder(state, bridge->encoder); + if (WARN_ON(!connector)) + return; + if (!hdmi->power_on) { - msm_hdmi_phy_resource_enable(phy); + phy_init(hdmi->phy); msm_hdmi_power_on(bridge); hdmi->power_on = true; } @@ -149,9 +143,27 @@ static void msm_hdmi_bridge_atomic_pre_enable(struct drm_bridge *bridge, } if (hdmi->phy_power_on) - msm_hdmi_phy_powerdown(phy); + phy_power_off(hdmi->phy); + + phy_opts.hdmi.pixel_clk_rate = hdmi->pixclock / 1000; + phy_opts.hdmi.bpc = connector->display_info.bpc; + phy_opts.hdmi.color_space = HDMI_PHY_COLORSPACE_RGB; + phy_configure(hdmi->phy, &phy_opts); + + ret = phy_power_on(hdmi->phy); + if (WARN_ON(ret)) + return; + + if (hdmi->extp_clk) { + ret = clk_set_rate(hdmi->extp_clk, hdmi->pixclock); + if (ret) + DRM_DEV_ERROR(bridge->dev->dev, "failed to set extp clk rate: %d\n", ret); + + ret = clk_prepare_enable(hdmi->extp_clk); + if (ret) + DRM_DEV_ERROR(bridge->dev->dev, "failed to enable extp clk: %d\n", ret); + } - msm_hdmi_phy_powerup(phy, hdmi->pixclock); hdmi->phy_power_on = true; msm_hdmi_set_mode(hdmi, true); @@ -165,7 +177,6 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge, { struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge); struct hdmi *hdmi = hdmi_bridge->hdmi; - struct hdmi_phy *phy = hdmi->phy; if (hdmi->hdcp_ctrl) msm_hdmi_hdcp_off(hdmi->hdcp_ctrl); @@ -173,7 +184,12 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge, DBG("power down"); msm_hdmi_set_mode(hdmi, false); - msm_hdmi_phy_powerdown(phy); + if (hdmi->phy_power_on) { + if (hdmi->extp_clk) + clk_disable_unprepare(hdmi->extp_clk); + + phy_power_off(hdmi->phy); + } hdmi->phy_power_on = false; if (hdmi->power_on) { @@ -181,7 +197,7 @@ static void msm_hdmi_bridge_atomic_post_disable(struct drm_bridge *bridge, hdmi->power_on = false; if (hdmi->hdmi_mode) msm_hdmi_audio_update(hdmi); - msm_hdmi_phy_resource_disable(phy); + phy_exit(hdmi->phy); } } From patchwork Sun Jun 25 11:42:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13291904 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 34313EB64DC for ; Sun, 25 Jun 2023 11:42:52 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=OZdimNtvLpBlPTF2Cjp3cX2L27BIv/ZAQTVKwtczHPM=; b=R6Ha03FSQLJjOz QeV2ZKTWf+MMWSWt1lzbX7kAKGM+VljmSQXIjX+Sd5rIK6aIFz+aW71fUOobAwGF5Gc/XFtBOoAoQ SEeyGjc/3zNHmNXiuSnKFhr50OZf+7uOPCOzNSzWMMBAHtXELblUfVLwF6hvHbR77tS3313emYEfl FFoGTlgcUB2IwDjTOT81hjLFvhaDn91bz1H5jw30OOpAbK+R0Pd8mj2Ksw1ZdrvB30qF3cRU9msyB N2fXbot0FNhy56n8bES4S7xdbOoBxjOtbp433yt2ieJSfvqTsQuBLvFKYVdC5EADc86jOg5Xab7H2 RaMjTPlT12idb8t8kyOw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8p-007wD3-2m; Sun, 25 Jun 2023 11:42:51 +0000 Received: from mail-lf1-x133.google.com ([2a00:1450:4864:20::133]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qDO8d-007w37-1G for linux-phy@lists.infradead.org; Sun, 25 Jun 2023 11:42:47 +0000 Received: by mail-lf1-x133.google.com with SMTP id 2adb3069b0e04-4f973035d60so2656230e87.3 for ; Sun, 25 Jun 2023 04:42:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1687693356; x=1690285356; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=XP9B90BXE/1rxd7cjE/PsULeD4GojoYmATkXjbj/K4I=; b=ySen9sB9ao7F0ov+tLSeBVeYuAvZ1EgabA+VHcAAXgriZjVfIGSA5LkYzAQcq6xfFw yTRBA6jYVs1j/Hl2/1NbvSiKTMwzl6/u1OM6MUnE1PDs86PxFveYvURYV9Z3qwFCgIg2 aQsrlUJyhTye0MuiEBIc29iwBBEWFgnc5sGxSdf2uIEjzIpZo4BfeNePtqGbqjRY1AtG 52coCA/a/ZmDsc66frc6khgXMwsUrkpmZ9WQpwnp3MljjuKL0VQ+BDhIDZZye8LzluNu v1OusMpMOM63b83dgfE6E1LEyqZcuvSdDAcWrTwcaNrScixniRkLc6djZheCdL2UoOm8 ocHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1687693356; x=1690285356; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=XP9B90BXE/1rxd7cjE/PsULeD4GojoYmATkXjbj/K4I=; b=Ua3NoGu4o/00VA1/JRRjtxi0q4re14LfGJ1Bu+omXKw2eQVmqCke9KX49Tu/ftNW6A zQYV55uND+wTZJrJ/JC6YWI7FAJqg52cZxARE/3XbjmnrrxudUtEmLs81zcxxKUX5UgM zeEqqA6m9UsfKY3quz2fKtLnSzkTtRxlQ5DVN4WmN2u5xUGJlsQ+4SeqFEq+6Jx0WXxq LD6r36gmF6knHdj0ZaxjQ8I8tptwg2WSAgzuvTwZCuHqpMtFjFXOz1gnukCV7JjCq7Ne NhC0xw1n7/peiobDNl4GjnPg3APjqmV6jyEocVHtYt4z2GuOGmVIGs2V1QA8J/G4jGTn IiHQ== X-Gm-Message-State: AC+VfDxYVghWiz3bcVj/IF8qpBm6pZaS55XgHPhHZ68ZTbyhg3NRGnOD dLA0Bpp39q6YQa95C2x4w/AFlg== X-Google-Smtp-Source: ACHHUZ4MiwoObYwQ1+61NWp6Rdls7lKFKe4/rAS+Ba9kIvghDFrfBkgsCFXXtVtoyZ7ljlh6qvbsPw== X-Received: by 2002:a05:6512:29e:b0:4f8:76a9:dc4d with SMTP id j30-20020a056512029e00b004f876a9dc4dmr11124417lfp.23.1687693356217; Sun, 25 Jun 2023 04:42:36 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id b23-20020ac25637000000b004f87893ce21sm637323lff.3.2023.06.25.04.42.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 25 Jun 2023 04:42:35 -0700 (PDT) From: Dmitry Baryshkov To: Rob Clark , Sean Paul , Abhinav Kumar , Marijn Suijten , Vinod Koul , Kishon Vijay Abraham I Cc: Philipp Zabel , Stephen Boyd , David Airlie , Daniel Vetter , Bjorn Andersson , Konrad Dybcio , linux-arm-msm@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, linux-phy@lists.infradead.org Subject: [PATCH v2 15/15] drm/msm/hdmi: drop old HDMI PHY code Date: Sun, 25 Jun 2023 14:42:22 +0300 Message-Id: <20230625114222.96689-16-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> References: <20230625114222.96689-1-dmitry.baryshkov@linaro.org> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230625_044239_440247_804952DD X-CRM114-Status: GOOD ( 17.52 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Drop source files used by old HDMI PHY and HDMI PLL drivers. Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/hdmi/hdmi_phy.c | 217 ------- drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c | 51 -- drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c | 765 ----------------------- drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c | 141 ----- drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c | 44 -- drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c | 458 -------------- 6 files changed, 1676 deletions(-) delete mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_phy.c delete mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c delete mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c delete mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c delete mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c delete mode 100644 drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy.c deleted file mode 100644 index 9780107e1cc9..000000000000 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy.c +++ /dev/null @@ -1,217 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. - */ - -#include - -#include "hdmi.h" - -static int msm_hdmi_phy_resource_init(struct hdmi_phy *phy) -{ - struct hdmi_phy_cfg *cfg = phy->cfg; - struct device *dev = &phy->pdev->dev; - int i, ret; - - phy->regs = devm_kcalloc(dev, cfg->num_regs, sizeof(phy->regs[0]), - GFP_KERNEL); - if (!phy->regs) - return -ENOMEM; - - phy->clks = devm_kcalloc(dev, cfg->num_clks, sizeof(phy->clks[0]), - GFP_KERNEL); - if (!phy->clks) - return -ENOMEM; - - for (i = 0; i < cfg->num_regs; i++) - phy->regs[i].supply = cfg->reg_names[i]; - - ret = devm_regulator_bulk_get(dev, cfg->num_regs, phy->regs); - if (ret) { - if (ret != -EPROBE_DEFER) - DRM_DEV_ERROR(dev, "failed to get phy regulators: %d\n", ret); - - return ret; - } - - for (i = 0; i < cfg->num_clks; i++) { - struct clk *clk; - - clk = msm_clk_get(phy->pdev, cfg->clk_names[i]); - if (IS_ERR(clk)) { - ret = PTR_ERR(clk); - DRM_DEV_ERROR(dev, "failed to get phy clock: %s (%d)\n", - cfg->clk_names[i], ret); - return ret; - } - - phy->clks[i] = clk; - } - - return 0; -} - -int msm_hdmi_phy_resource_enable(struct hdmi_phy *phy) -{ - struct hdmi_phy_cfg *cfg = phy->cfg; - struct device *dev = &phy->pdev->dev; - int i, ret = 0; - - pm_runtime_get_sync(dev); - - ret = regulator_bulk_enable(cfg->num_regs, phy->regs); - if (ret) { - DRM_DEV_ERROR(dev, "failed to enable regulators: (%d)\n", ret); - return ret; - } - - for (i = 0; i < cfg->num_clks; i++) { - ret = clk_prepare_enable(phy->clks[i]); - if (ret) - DRM_DEV_ERROR(dev, "failed to enable clock: %s (%d)\n", - cfg->clk_names[i], ret); - } - - return ret; -} - -void msm_hdmi_phy_resource_disable(struct hdmi_phy *phy) -{ - struct hdmi_phy_cfg *cfg = phy->cfg; - struct device *dev = &phy->pdev->dev; - int i; - - for (i = cfg->num_clks - 1; i >= 0; i--) - clk_disable_unprepare(phy->clks[i]); - - regulator_bulk_disable(cfg->num_regs, phy->regs); - - pm_runtime_put_sync(dev); -} - -void msm_hdmi_phy_powerup(struct hdmi_phy *phy, unsigned long int pixclock) -{ - if (!phy || !phy->cfg->powerup) - return; - - phy->cfg->powerup(phy, pixclock); -} - -void msm_hdmi_phy_powerdown(struct hdmi_phy *phy) -{ - if (!phy || !phy->cfg->powerdown) - return; - - phy->cfg->powerdown(phy); -} - -static int msm_hdmi_phy_pll_init(struct platform_device *pdev, - enum hdmi_phy_type type) -{ - int ret; - - switch (type) { - case MSM_HDMI_PHY_8960: - ret = msm_hdmi_pll_8960_init(pdev); - break; - case MSM_HDMI_PHY_8996: - ret = msm_hdmi_pll_8996_init(pdev); - break; - /* - * we don't have PLL support for these, don't report an error for now - */ - case MSM_HDMI_PHY_8x60: - case MSM_HDMI_PHY_8x74: - default: - ret = 0; - break; - } - - return ret; -} - -static int msm_hdmi_phy_probe(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct hdmi_phy *phy; - int ret; - - phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); - if (!phy) - return -ENODEV; - - phy->cfg = (struct hdmi_phy_cfg *)of_device_get_match_data(dev); - if (!phy->cfg) - return -ENODEV; - - phy->mmio = msm_ioremap(pdev, "hdmi_phy"); - if (IS_ERR(phy->mmio)) { - DRM_DEV_ERROR(dev, "%s: failed to map phy base\n", __func__); - return -ENOMEM; - } - - phy->pdev = pdev; - - ret = msm_hdmi_phy_resource_init(phy); - if (ret) - return ret; - - pm_runtime_enable(&pdev->dev); - - ret = msm_hdmi_phy_resource_enable(phy); - if (ret) - return ret; - - ret = msm_hdmi_phy_pll_init(pdev, phy->cfg->type); - if (ret) { - DRM_DEV_ERROR(dev, "couldn't init PLL\n"); - msm_hdmi_phy_resource_disable(phy); - return ret; - } - - msm_hdmi_phy_resource_disable(phy); - - platform_set_drvdata(pdev, phy); - - return 0; -} - -static int msm_hdmi_phy_remove(struct platform_device *pdev) -{ - pm_runtime_disable(&pdev->dev); - - return 0; -} - -static const struct of_device_id msm_hdmi_phy_dt_match[] = { - { .compatible = "qcom,hdmi-phy-8660", - .data = &msm_hdmi_phy_8x60_cfg }, - { .compatible = "qcom,hdmi-phy-8960", - .data = &msm_hdmi_phy_8960_cfg }, - { .compatible = "qcom,hdmi-phy-8974", - .data = &msm_hdmi_phy_8x74_cfg }, - { .compatible = "qcom,hdmi-phy-8084", - .data = &msm_hdmi_phy_8x74_cfg }, - { .compatible = "qcom,hdmi-phy-8996", - .data = &msm_hdmi_phy_8996_cfg }, - {} -}; - -static struct platform_driver msm_hdmi_phy_platform_driver = { - .probe = msm_hdmi_phy_probe, - .remove = msm_hdmi_phy_remove, - .driver = { - .name = "msm_hdmi_phy", - .of_match_table = msm_hdmi_phy_dt_match, - }, -}; - -void __init msm_hdmi_phy_driver_register(void) -{ - platform_driver_register(&msm_hdmi_phy_platform_driver); -} - -void __exit msm_hdmi_phy_driver_unregister(void) -{ - platform_driver_unregister(&msm_hdmi_phy_platform_driver); -} diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c deleted file mode 100644 index cf90a0c1f822..000000000000 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c +++ /dev/null @@ -1,51 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2013 Red Hat - * Author: Rob Clark - */ - -#include "hdmi.h" - -static void hdmi_phy_8960_powerup(struct hdmi_phy *phy, - unsigned long int pixclock) -{ - DBG("pixclock: %lu", pixclock); - - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG0, 0x1b); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG1, 0xf2); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG4, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG5, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG6, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG7, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG8, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG9, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG10, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG11, 0x00); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG3, 0x20); -} - -static void hdmi_phy_8960_powerdown(struct hdmi_phy *phy) -{ - DBG(""); - - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x7f); -} - -static const char * const hdmi_phy_8960_reg_names[] = { - "core-vdda", -}; - -static const char * const hdmi_phy_8960_clk_names[] = { - "slave_iface", -}; - -const struct hdmi_phy_cfg msm_hdmi_phy_8960_cfg = { - .type = MSM_HDMI_PHY_8960, - .powerup = hdmi_phy_8960_powerup, - .powerdown = hdmi_phy_8960_powerdown, - .reg_names = hdmi_phy_8960_reg_names, - .num_regs = ARRAY_SIZE(hdmi_phy_8960_reg_names), - .clk_names = hdmi_phy_8960_clk_names, - .num_clks = ARRAY_SIZE(hdmi_phy_8960_clk_names), -}; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c deleted file mode 100644 index 4dd055416620..000000000000 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8996.c +++ /dev/null @@ -1,765 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. - */ - -#include -#include - -#include "hdmi.h" - -#define HDMI_VCO_MAX_FREQ 12000000000UL -#define HDMI_VCO_MIN_FREQ 8000000000UL - -#define HDMI_PCLK_MAX_FREQ 600000000 -#define HDMI_PCLK_MIN_FREQ 25000000 - -#define HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD 3400000000UL -#define HDMI_DIG_FREQ_BIT_CLK_THRESHOLD 1500000000UL -#define HDMI_MID_FREQ_BIT_CLK_THRESHOLD 750000000UL -#define HDMI_CORECLK_DIV 5 -#define HDMI_DEFAULT_REF_CLOCK 19200000 -#define HDMI_PLL_CMP_CNT 1024 - -#define HDMI_PLL_POLL_MAX_READS 100 -#define HDMI_PLL_POLL_TIMEOUT_US 150 - -#define HDMI_NUM_TX_CHANNEL 4 - -struct hdmi_pll_8996 { - struct platform_device *pdev; - struct clk_hw clk_hw; - - /* pll mmio base */ - void __iomem *mmio_qserdes_com; - /* tx channel base */ - void __iomem *mmio_qserdes_tx[HDMI_NUM_TX_CHANNEL]; -}; - -#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8996, clk_hw) - -struct hdmi_8996_phy_pll_reg_cfg { - u32 tx_lx_lane_mode[HDMI_NUM_TX_CHANNEL]; - u32 tx_lx_tx_band[HDMI_NUM_TX_CHANNEL]; - u32 com_svs_mode_clk_sel; - u32 com_hsclk_sel; - u32 com_pll_cctrl_mode0; - u32 com_pll_rctrl_mode0; - u32 com_cp_ctrl_mode0; - u32 com_dec_start_mode0; - u32 com_div_frac_start1_mode0; - u32 com_div_frac_start2_mode0; - u32 com_div_frac_start3_mode0; - u32 com_integloop_gain0_mode0; - u32 com_integloop_gain1_mode0; - u32 com_lock_cmp_en; - u32 com_lock_cmp1_mode0; - u32 com_lock_cmp2_mode0; - u32 com_lock_cmp3_mode0; - u32 com_core_clk_en; - u32 com_coreclk_div; - u32 com_vco_tune_ctrl; - - u32 tx_lx_tx_drv_lvl[HDMI_NUM_TX_CHANNEL]; - u32 tx_lx_tx_emp_post1_lvl[HDMI_NUM_TX_CHANNEL]; - u32 tx_lx_vmode_ctrl1[HDMI_NUM_TX_CHANNEL]; - u32 tx_lx_vmode_ctrl2[HDMI_NUM_TX_CHANNEL]; - u32 tx_lx_res_code_lane_tx[HDMI_NUM_TX_CHANNEL]; - u32 tx_lx_hp_pd_enables[HDMI_NUM_TX_CHANNEL]; - - u32 phy_mode; -}; - -struct hdmi_8996_post_divider { - u64 vco_freq; - int hsclk_divsel; - int vco_ratio; - int tx_band_sel; - int half_rate_mode; -}; - -static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8996 *pll) -{ - return platform_get_drvdata(pll->pdev); -} - -static inline void hdmi_pll_write(struct hdmi_pll_8996 *pll, int offset, - u32 data) -{ - msm_writel(data, pll->mmio_qserdes_com + offset); -} - -static inline u32 hdmi_pll_read(struct hdmi_pll_8996 *pll, int offset) -{ - return msm_readl(pll->mmio_qserdes_com + offset); -} - -static inline void hdmi_tx_chan_write(struct hdmi_pll_8996 *pll, int channel, - int offset, int data) -{ - msm_writel(data, pll->mmio_qserdes_tx[channel] + offset); -} - -static inline u32 pll_get_cpctrl(u64 frac_start, unsigned long ref_clk, - bool gen_ssc) -{ - if ((frac_start != 0) || gen_ssc) - return (11000000 / (ref_clk / 20)); - - return 0x23; -} - -static inline u32 pll_get_rctrl(u64 frac_start, bool gen_ssc) -{ - if ((frac_start != 0) || gen_ssc) - return 0x16; - - return 0x10; -} - -static inline u32 pll_get_cctrl(u64 frac_start, bool gen_ssc) -{ - if ((frac_start != 0) || gen_ssc) - return 0x28; - - return 0x1; -} - -static inline u32 pll_get_integloop_gain(u64 frac_start, u64 bclk, u32 ref_clk, - bool gen_ssc) -{ - int digclk_divsel = bclk >= HDMI_DIG_FREQ_BIT_CLK_THRESHOLD ? 1 : 2; - u64 base; - - if ((frac_start != 0) || gen_ssc) - base = (64 * ref_clk) / HDMI_DEFAULT_REF_CLOCK; - else - base = (1022 * ref_clk) / 100; - - base <<= digclk_divsel; - - return (base <= 2046 ? base : 2046); -} - -static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk) -{ - u64 dividend = HDMI_PLL_CMP_CNT * fdata; - u32 divisor = ref_clk * 10; - u32 rem; - - rem = do_div(dividend, divisor); - if (rem > (divisor >> 1)) - dividend++; - - return dividend - 1; -} - -static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk) -{ - u64 fdata = ((u64)pll_cmp) * ref_clk * 10; - - do_div(fdata, HDMI_PLL_CMP_CNT); - - return fdata; -} - -static int pll_get_post_div(struct hdmi_8996_post_divider *pd, u64 bclk) -{ - int ratio[] = { 2, 3, 4, 5, 6, 9, 10, 12, 14, 15, 20, 21, 25, 28, 35 }; - int hs_divsel[] = { 0, 4, 8, 12, 1, 5, 2, 9, 3, 13, 10, 7, 14, 11, 15 }; - int tx_band_sel[] = { 0, 1, 2, 3 }; - u64 vco_freq[60]; - u64 vco, vco_optimal; - int half_rate_mode = 0; - int vco_optimal_index, vco_freq_index; - int i, j; - -retry: - vco_optimal = HDMI_VCO_MAX_FREQ; - vco_optimal_index = -1; - vco_freq_index = 0; - for (i = 0; i < 15; i++) { - for (j = 0; j < 4; j++) { - u32 ratio_mult = ratio[i] << tx_band_sel[j]; - - vco = bclk >> half_rate_mode; - vco *= ratio_mult; - vco_freq[vco_freq_index++] = vco; - } - } - - for (i = 0; i < 60; i++) { - u64 vco_tmp = vco_freq[i]; - - if ((vco_tmp >= HDMI_VCO_MIN_FREQ) && - (vco_tmp <= vco_optimal)) { - vco_optimal = vco_tmp; - vco_optimal_index = i; - } - } - - if (vco_optimal_index == -1) { - if (!half_rate_mode) { - half_rate_mode = 1; - goto retry; - } - } else { - pd->vco_freq = vco_optimal; - pd->tx_band_sel = tx_band_sel[vco_optimal_index % 4]; - pd->vco_ratio = ratio[vco_optimal_index / 4]; - pd->hsclk_divsel = hs_divsel[vco_optimal_index / 4]; - - return 0; - } - - return -EINVAL; -} - -static int pll_calculate(unsigned long pix_clk, unsigned long ref_clk, - struct hdmi_8996_phy_pll_reg_cfg *cfg) -{ - struct hdmi_8996_post_divider pd; - u64 bclk; - u64 tmds_clk; - u64 dec_start; - u64 frac_start; - u64 fdata; - u32 pll_divisor; - u32 rem; - u32 cpctrl; - u32 rctrl; - u32 cctrl; - u32 integloop_gain; - u32 pll_cmp; - int i, ret; - - /* bit clk = 10 * pix_clk */ - bclk = ((u64)pix_clk) * 10; - - if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) - tmds_clk = pix_clk >> 2; - else - tmds_clk = pix_clk; - - ret = pll_get_post_div(&pd, bclk); - if (ret) - return ret; - - dec_start = pd.vco_freq; - pll_divisor = 4 * ref_clk; - do_div(dec_start, pll_divisor); - - frac_start = pd.vco_freq * (1 << 20); - - rem = do_div(frac_start, pll_divisor); - frac_start -= dec_start * (1 << 20); - if (rem > (pll_divisor >> 1)) - frac_start++; - - cpctrl = pll_get_cpctrl(frac_start, ref_clk, false); - rctrl = pll_get_rctrl(frac_start, false); - cctrl = pll_get_cctrl(frac_start, false); - integloop_gain = pll_get_integloop_gain(frac_start, bclk, - ref_clk, false); - - fdata = pd.vco_freq; - do_div(fdata, pd.vco_ratio); - - pll_cmp = pll_get_pll_cmp(fdata, ref_clk); - - DBG("VCO freq: %llu", pd.vco_freq); - DBG("fdata: %llu", fdata); - DBG("pix_clk: %lu", pix_clk); - DBG("tmds clk: %llu", tmds_clk); - DBG("HSCLK_SEL: %d", pd.hsclk_divsel); - DBG("DEC_START: %llu", dec_start); - DBG("DIV_FRAC_START: %llu", frac_start); - DBG("PLL_CPCTRL: %u", cpctrl); - DBG("PLL_RCTRL: %u", rctrl); - DBG("PLL_CCTRL: %u", cctrl); - DBG("INTEGLOOP_GAIN: %u", integloop_gain); - DBG("TX_BAND: %d", pd.tx_band_sel); - DBG("PLL_CMP: %u", pll_cmp); - - /* Convert these values to register specific values */ - if (bclk > HDMI_DIG_FREQ_BIT_CLK_THRESHOLD) - cfg->com_svs_mode_clk_sel = 1; - else - cfg->com_svs_mode_clk_sel = 2; - - cfg->com_hsclk_sel = (0x20 | pd.hsclk_divsel); - cfg->com_pll_cctrl_mode0 = cctrl; - cfg->com_pll_rctrl_mode0 = rctrl; - cfg->com_cp_ctrl_mode0 = cpctrl; - cfg->com_dec_start_mode0 = dec_start; - cfg->com_div_frac_start1_mode0 = (frac_start & 0xff); - cfg->com_div_frac_start2_mode0 = ((frac_start & 0xff00) >> 8); - cfg->com_div_frac_start3_mode0 = ((frac_start & 0xf0000) >> 16); - cfg->com_integloop_gain0_mode0 = (integloop_gain & 0xff); - cfg->com_integloop_gain1_mode0 = ((integloop_gain & 0xf00) >> 8); - cfg->com_lock_cmp1_mode0 = (pll_cmp & 0xff); - cfg->com_lock_cmp2_mode0 = ((pll_cmp & 0xff00) >> 8); - cfg->com_lock_cmp3_mode0 = ((pll_cmp & 0x30000) >> 16); - cfg->com_lock_cmp_en = 0x0; - cfg->com_core_clk_en = 0x2c; - cfg->com_coreclk_div = HDMI_CORECLK_DIV; - cfg->phy_mode = (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) ? 0x10 : 0x0; - cfg->com_vco_tune_ctrl = 0x0; - - cfg->tx_lx_lane_mode[0] = - cfg->tx_lx_lane_mode[2] = 0x43; - - cfg->tx_lx_hp_pd_enables[0] = - cfg->tx_lx_hp_pd_enables[1] = - cfg->tx_lx_hp_pd_enables[2] = 0x0c; - cfg->tx_lx_hp_pd_enables[3] = 0x3; - - for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) - cfg->tx_lx_tx_band[i] = pd.tx_band_sel + 4; - - if (bclk > HDMI_HIGH_FREQ_BIT_CLK_THRESHOLD) { - cfg->tx_lx_tx_drv_lvl[0] = - cfg->tx_lx_tx_drv_lvl[1] = - cfg->tx_lx_tx_drv_lvl[2] = 0x25; - cfg->tx_lx_tx_drv_lvl[3] = 0x22; - - cfg->tx_lx_tx_emp_post1_lvl[0] = - cfg->tx_lx_tx_emp_post1_lvl[1] = - cfg->tx_lx_tx_emp_post1_lvl[2] = 0x23; - cfg->tx_lx_tx_emp_post1_lvl[3] = 0x27; - - cfg->tx_lx_vmode_ctrl1[0] = - cfg->tx_lx_vmode_ctrl1[1] = - cfg->tx_lx_vmode_ctrl1[2] = - cfg->tx_lx_vmode_ctrl1[3] = 0x00; - - cfg->tx_lx_vmode_ctrl2[0] = - cfg->tx_lx_vmode_ctrl2[1] = - cfg->tx_lx_vmode_ctrl2[2] = 0x0D; - - cfg->tx_lx_vmode_ctrl2[3] = 0x00; - } else if (bclk > HDMI_MID_FREQ_BIT_CLK_THRESHOLD) { - for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { - cfg->tx_lx_tx_drv_lvl[i] = 0x25; - cfg->tx_lx_tx_emp_post1_lvl[i] = 0x23; - cfg->tx_lx_vmode_ctrl1[i] = 0x00; - } - - cfg->tx_lx_vmode_ctrl2[0] = - cfg->tx_lx_vmode_ctrl2[1] = - cfg->tx_lx_vmode_ctrl2[2] = 0x0D; - cfg->tx_lx_vmode_ctrl2[3] = 0x00; - } else { - for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { - cfg->tx_lx_tx_drv_lvl[i] = 0x20; - cfg->tx_lx_tx_emp_post1_lvl[i] = 0x20; - cfg->tx_lx_vmode_ctrl1[i] = 0x00; - cfg->tx_lx_vmode_ctrl2[i] = 0x0E; - } - } - - DBG("com_svs_mode_clk_sel = 0x%x", cfg->com_svs_mode_clk_sel); - DBG("com_hsclk_sel = 0x%x", cfg->com_hsclk_sel); - DBG("com_lock_cmp_en = 0x%x", cfg->com_lock_cmp_en); - DBG("com_pll_cctrl_mode0 = 0x%x", cfg->com_pll_cctrl_mode0); - DBG("com_pll_rctrl_mode0 = 0x%x", cfg->com_pll_rctrl_mode0); - DBG("com_cp_ctrl_mode0 = 0x%x", cfg->com_cp_ctrl_mode0); - DBG("com_dec_start_mode0 = 0x%x", cfg->com_dec_start_mode0); - DBG("com_div_frac_start1_mode0 = 0x%x", cfg->com_div_frac_start1_mode0); - DBG("com_div_frac_start2_mode0 = 0x%x", cfg->com_div_frac_start2_mode0); - DBG("com_div_frac_start3_mode0 = 0x%x", cfg->com_div_frac_start3_mode0); - DBG("com_integloop_gain0_mode0 = 0x%x", cfg->com_integloop_gain0_mode0); - DBG("com_integloop_gain1_mode0 = 0x%x", cfg->com_integloop_gain1_mode0); - DBG("com_lock_cmp1_mode0 = 0x%x", cfg->com_lock_cmp1_mode0); - DBG("com_lock_cmp2_mode0 = 0x%x", cfg->com_lock_cmp2_mode0); - DBG("com_lock_cmp3_mode0 = 0x%x", cfg->com_lock_cmp3_mode0); - DBG("com_core_clk_en = 0x%x", cfg->com_core_clk_en); - DBG("com_coreclk_div = 0x%x", cfg->com_coreclk_div); - DBG("phy_mode = 0x%x", cfg->phy_mode); - - DBG("tx_l0_lane_mode = 0x%x", cfg->tx_lx_lane_mode[0]); - DBG("tx_l2_lane_mode = 0x%x", cfg->tx_lx_lane_mode[2]); - - for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { - DBG("tx_l%d_tx_band = 0x%x", i, cfg->tx_lx_tx_band[i]); - DBG("tx_l%d_tx_drv_lvl = 0x%x", i, cfg->tx_lx_tx_drv_lvl[i]); - DBG("tx_l%d_tx_emp_post1_lvl = 0x%x", i, - cfg->tx_lx_tx_emp_post1_lvl[i]); - DBG("tx_l%d_vmode_ctrl1 = 0x%x", i, cfg->tx_lx_vmode_ctrl1[i]); - DBG("tx_l%d_vmode_ctrl2 = 0x%x", i, cfg->tx_lx_vmode_ctrl2[i]); - } - - return 0; -} - -static int hdmi_8996_pll_set_clk_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); - struct hdmi_phy *phy = pll_get_phy(pll); - struct hdmi_8996_phy_pll_reg_cfg cfg; - int i, ret; - - memset(&cfg, 0x00, sizeof(cfg)); - - ret = pll_calculate(rate, parent_rate, &cfg); - if (ret) { - DRM_ERROR("PLL calculation failed\n"); - return ret; - } - - /* Initially shut down PHY */ - DBG("Disabling PHY"); - hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x0); - udelay(500); - - /* Power up sequence */ - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x04); - - hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESETSM_CNTRL, 0x20); - hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX0_TX1_LANE_CTL, 0x0F); - hdmi_phy_write(phy, REG_HDMI_8996_PHY_TX2_TX3_LANE_CTL, 0x0F); - - for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_CLKBUF_ENABLE, - 0x03); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_TX_BAND, - cfg.tx_lx_tx_band[i]); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_RESET_TSYNC_EN, - 0x03); - } - - hdmi_tx_chan_write(pll, 0, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE, - cfg.tx_lx_lane_mode[0]); - hdmi_tx_chan_write(pll, 2, REG_HDMI_PHY_QSERDES_TX_LX_LANE_MODE, - cfg.tx_lx_lane_mode[2]); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_BUF_ENABLE, 0x1E); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BIAS_EN_CLKBUFLR_EN, 0x07); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYSCLK_EN_SEL, 0x37); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SYS_CLK_CTRL, 0x02); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_ENABLE1, 0x0E); - - /* Bypass VCO calibration */ - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SVS_MODE_CLK_SEL, - cfg.com_svs_mode_clk_sel); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_TRIM, 0x0F); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_IVCO, 0x0F); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_CTRL, - cfg.com_vco_tune_ctrl); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_BG_CTRL, 0x06); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CLK_SELECT, 0x30); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_HSCLK_SEL, - cfg.com_hsclk_sel); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP_EN, - cfg.com_lock_cmp_en); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_CCTRL_MODE0, - cfg.com_pll_cctrl_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_PLL_RCTRL_MODE0, - cfg.com_pll_rctrl_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CP_CTRL_MODE0, - cfg.com_cp_ctrl_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DEC_START_MODE0, - cfg.com_dec_start_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START1_MODE0, - cfg.com_div_frac_start1_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START2_MODE0, - cfg.com_div_frac_start2_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_DIV_FRAC_START3_MODE0, - cfg.com_div_frac_start3_mode0); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN0_MODE0, - cfg.com_integloop_gain0_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_INTEGLOOP_GAIN1_MODE0, - cfg.com_integloop_gain1_mode0); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0, - cfg.com_lock_cmp1_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0, - cfg.com_lock_cmp2_mode0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0, - cfg.com_lock_cmp3_mode0); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_VCO_TUNE_MAP, 0x00); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORE_CLK_EN, - cfg.com_core_clk_en); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CORECLK_DIV, - cfg.com_coreclk_div); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_CMN_CONFIG, 0x02); - - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_RESCODE_DIV_NUM, 0x15); - - /* TX lanes setup (TX 0/1/2/3) */ - for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL, - cfg.tx_lx_tx_drv_lvl[i]); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_TX_EMP_POST1_LVL, - cfg.tx_lx_tx_emp_post1_lvl[i]); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL1, - cfg.tx_lx_vmode_ctrl1[i]); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_VMODE_CTRL2, - cfg.tx_lx_vmode_ctrl2[i]); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_TX_DRV_LVL_OFFSET, - 0x00); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_RES_CODE_LANE_OFFSET, - 0x00); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_TRAN_DRVR_EMP_EN, - 0x03); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_PARRATE_REC_DETECT_IDLE_EN, - 0x40); - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_HP_PD_ENABLES, - cfg.tx_lx_hp_pd_enables[i]); - } - - hdmi_phy_write(phy, REG_HDMI_8996_PHY_MODE, cfg.phy_mode); - hdmi_phy_write(phy, REG_HDMI_8996_PHY_PD_CTL, 0x1F); - - /* - * Ensure that vco configuration gets flushed to hardware before - * enabling the PLL - */ - wmb(); - - return 0; -} - -static int hdmi_8996_phy_ready_status(struct hdmi_phy *phy) -{ - u32 nb_tries = HDMI_PLL_POLL_MAX_READS; - unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US; - u32 status; - int phy_ready = 0; - - DBG("Waiting for PHY ready"); - - while (nb_tries--) { - status = hdmi_phy_read(phy, REG_HDMI_8996_PHY_STATUS); - phy_ready = status & BIT(0); - - if (phy_ready) - break; - - udelay(timeout); - } - - DBG("PHY is %sready", phy_ready ? "" : "*not* "); - - return phy_ready; -} - -static int hdmi_8996_pll_lock_status(struct hdmi_pll_8996 *pll) -{ - u32 status; - int nb_tries = HDMI_PLL_POLL_MAX_READS; - unsigned long timeout = HDMI_PLL_POLL_TIMEOUT_US; - int pll_locked = 0; - - DBG("Waiting for PLL lock"); - - while (nb_tries--) { - status = hdmi_pll_read(pll, - REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS); - pll_locked = status & BIT(0); - - if (pll_locked) - break; - - udelay(timeout); - } - - DBG("HDMI PLL is %slocked", pll_locked ? "" : "*not* "); - - return pll_locked; -} - -static int hdmi_8996_pll_prepare(struct clk_hw *hw) -{ - struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); - struct hdmi_phy *phy = pll_get_phy(pll); - int i, ret = 0; - - hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x1); - udelay(100); - - hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19); - udelay(100); - - ret = hdmi_8996_pll_lock_status(pll); - if (!ret) - return ret; - - for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) - hdmi_tx_chan_write(pll, i, - REG_HDMI_PHY_QSERDES_TX_LX_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN, - 0x6F); - - /* Disable SSC */ - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER1, 0x0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_PER2, 0x0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE1, 0x0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_STEP_SIZE2, 0x0); - hdmi_pll_write(pll, REG_HDMI_PHY_QSERDES_COM_SSC_EN_CENTER, 0x2); - - ret = hdmi_8996_phy_ready_status(phy); - if (!ret) - return ret; - - /* Restart the retiming buffer */ - hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x18); - udelay(1); - hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x19); - - return 0; -} - -static long hdmi_8996_pll_round_rate(struct clk_hw *hw, - unsigned long rate, - unsigned long *parent_rate) -{ - if (rate < HDMI_PCLK_MIN_FREQ) - return HDMI_PCLK_MIN_FREQ; - else if (rate > HDMI_PCLK_MAX_FREQ) - return HDMI_PCLK_MAX_FREQ; - else - return rate; -} - -static unsigned long hdmi_8996_pll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); - u64 fdata; - u32 cmp1, cmp2, cmp3, pll_cmp; - - cmp1 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP1_MODE0); - cmp2 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP2_MODE0); - cmp3 = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_LOCK_CMP3_MODE0); - - pll_cmp = cmp1 | (cmp2 << 8) | (cmp3 << 16); - - fdata = pll_cmp_to_fdata(pll_cmp + 1, parent_rate); - - do_div(fdata, 10); - - return fdata; -} - -static void hdmi_8996_pll_unprepare(struct clk_hw *hw) -{ - struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); - struct hdmi_phy *phy = pll_get_phy(pll); - - hdmi_phy_write(phy, REG_HDMI_8996_PHY_CFG, 0x6); - usleep_range(100, 150); -} - -static int hdmi_8996_pll_is_enabled(struct clk_hw *hw) -{ - struct hdmi_pll_8996 *pll = hw_clk_to_pll(hw); - u32 status; - int pll_locked; - - status = hdmi_pll_read(pll, REG_HDMI_PHY_QSERDES_COM_C_READY_STATUS); - pll_locked = status & BIT(0); - - return pll_locked; -} - -static const struct clk_ops hdmi_8996_pll_ops = { - .set_rate = hdmi_8996_pll_set_clk_rate, - .round_rate = hdmi_8996_pll_round_rate, - .recalc_rate = hdmi_8996_pll_recalc_rate, - .prepare = hdmi_8996_pll_prepare, - .unprepare = hdmi_8996_pll_unprepare, - .is_enabled = hdmi_8996_pll_is_enabled, -}; - -static const struct clk_init_data pll_init = { - .name = "hdmipll", - .ops = &hdmi_8996_pll_ops, - .parent_data = (const struct clk_parent_data[]){ - { .fw_name = "xo", .name = "xo_board" }, - }, - .num_parents = 1, - .flags = CLK_IGNORE_UNUSED, -}; - -int msm_hdmi_pll_8996_init(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct hdmi_pll_8996 *pll; - int i, ret; - - pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); - if (!pll) - return -ENOMEM; - - pll->pdev = pdev; - - pll->mmio_qserdes_com = msm_ioremap(pdev, "hdmi_pll"); - if (IS_ERR(pll->mmio_qserdes_com)) { - DRM_DEV_ERROR(dev, "failed to map pll base\n"); - return -ENOMEM; - } - - for (i = 0; i < HDMI_NUM_TX_CHANNEL; i++) { - char name[32]; - - snprintf(name, sizeof(name), "hdmi_tx_l%d", i); - - pll->mmio_qserdes_tx[i] = msm_ioremap(pdev, name); - if (IS_ERR(pll->mmio_qserdes_tx[i])) { - DRM_DEV_ERROR(dev, "failed to map pll base\n"); - return -ENOMEM; - } - } - pll->clk_hw.init = &pll_init; - - ret = devm_clk_hw_register(dev, &pll->clk_hw); - if (ret) { - DRM_DEV_ERROR(dev, "failed to register pll clock\n"); - return ret; - } - - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw); - if (ret) { - DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret); - return ret; - } - - return 0; -} - -static const char * const hdmi_phy_8996_reg_names[] = { - "vddio", - "vcca", -}; - -static const char * const hdmi_phy_8996_clk_names[] = { - "iface", "ref", -}; - -const struct hdmi_phy_cfg msm_hdmi_phy_8996_cfg = { - .type = MSM_HDMI_PHY_8996, - .reg_names = hdmi_phy_8996_reg_names, - .num_regs = ARRAY_SIZE(hdmi_phy_8996_reg_names), - .clk_names = hdmi_phy_8996_clk_names, - .num_clks = ARRAY_SIZE(hdmi_phy_8996_clk_names), -}; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c deleted file mode 100644 index 1d97640d8c24..000000000000 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x60.c +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2013 Red Hat - * Author: Rob Clark - */ - -#include - -#include "hdmi.h" - -static void hdmi_phy_8x60_powerup(struct hdmi_phy *phy, - unsigned long int pixclock) -{ - /* De-serializer delay D/C for non-lbk mode: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG0, - HDMI_8x60_PHY_REG0_DESER_DEL_CTRL(3)); - - if (pixclock == 27000000) { - /* video_format == HDMI_VFRMT_720x480p60_16_9 */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1, - HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | - HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(3)); - } else { - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG1, - HDMI_8x60_PHY_REG1_DTEST_MUX_SEL(5) | - HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL(4)); - } - - /* No matter what, start from the power down mode: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_PWRGEN | - HDMI_8x60_PHY_REG2_PD_PLL | - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); - - /* Turn PowerGen on: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_PLL | - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); - - /* Turn PLL power on: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); - - /* Write to HIGH after PLL power down de-assert: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, - HDMI_8x60_PHY_REG3_PLL_ENABLE); - - /* ASIC power on; PHY REG9 = 0 */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0); - - /* Enable PLL lock detect, PLL lock det will go high after lock - * Enable the re-time logic - */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12, - HDMI_8x60_PHY_REG12_RETIMING_EN | - HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN); - - /* Drivers are on: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_DESER); - - /* If the RX detector is needed: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_RCV_SENSE_EN | - HDMI_8x60_PHY_REG2_PD_DESER); - - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG4, 0); - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG5, 0); - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG6, 0); - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG7, 0); - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG8, 0); - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG9, 0); - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG10, 0); - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG11, 0); - - /* If we want to use lock enable based on counting: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG12, - HDMI_8x60_PHY_REG12_RETIMING_EN | - HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN | - HDMI_8x60_PHY_REG12_FORCE_LOCK); -} - -static void hdmi_phy_8x60_powerdown(struct hdmi_phy *phy) -{ - /* Assert RESET PHY from controller */ - hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, - HDMI_PHY_CTRL_SW_RESET); - udelay(10); - /* De-assert RESET PHY from controller */ - hdmi_phy_write(phy, REG_HDMI_PHY_CTRL, 0); - /* Turn off Driver */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); - udelay(10); - /* Disable PLL */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG3, 0); - /* Power down PHY, but keep RX-sense: */ - hdmi_phy_write(phy, REG_HDMI_8x60_PHY_REG2, - HDMI_8x60_PHY_REG2_RCV_SENSE_EN | - HDMI_8x60_PHY_REG2_PD_PWRGEN | - HDMI_8x60_PHY_REG2_PD_PLL | - HDMI_8x60_PHY_REG2_PD_DRIVE_4 | - HDMI_8x60_PHY_REG2_PD_DRIVE_3 | - HDMI_8x60_PHY_REG2_PD_DRIVE_2 | - HDMI_8x60_PHY_REG2_PD_DRIVE_1 | - HDMI_8x60_PHY_REG2_PD_DESER); -} - -static const char * const hdmi_phy_8x60_reg_names[] = { - "core-vdda", -}; - -static const char * const hdmi_phy_8x60_clk_names[] = { - "slave_iface", -}; - -const struct hdmi_phy_cfg msm_hdmi_phy_8x60_cfg = { - .type = MSM_HDMI_PHY_8x60, - .powerup = hdmi_phy_8x60_powerup, - .powerdown = hdmi_phy_8x60_powerdown, - .reg_names = hdmi_phy_8x60_reg_names, - .num_regs = ARRAY_SIZE(hdmi_phy_8x60_reg_names), - .clk_names = hdmi_phy_8x60_clk_names, - .num_clks = ARRAY_SIZE(hdmi_phy_8x60_clk_names), -}; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c b/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c deleted file mode 100644 index a2a6940e195a..000000000000 --- a/drivers/gpu/drm/msm/hdmi/hdmi_phy_8x74.c +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (C) 2013 Red Hat - * Author: Rob Clark - */ - -#include "hdmi.h" - -static void hdmi_phy_8x74_powerup(struct hdmi_phy *phy, - unsigned long int pixclock) -{ - hdmi_phy_write(phy, REG_HDMI_8x74_ANA_CFG0, 0x1b); - hdmi_phy_write(phy, REG_HDMI_8x74_ANA_CFG1, 0xf2); - hdmi_phy_write(phy, REG_HDMI_8x74_BIST_CFG0, 0x0); - hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN0, 0x0); - hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN1, 0x0); - hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN2, 0x0); - hdmi_phy_write(phy, REG_HDMI_8x74_BIST_PATN3, 0x0); - hdmi_phy_write(phy, REG_HDMI_8x74_PD_CTRL1, 0x20); -} - -static void hdmi_phy_8x74_powerdown(struct hdmi_phy *phy) -{ - hdmi_phy_write(phy, REG_HDMI_8x74_PD_CTRL0, 0x7f); -} - -static const char * const hdmi_phy_8x74_reg_names[] = { - "core-vdda", - "vddio", -}; - -static const char * const hdmi_phy_8x74_clk_names[] = { - "iface", "alt_iface" -}; - -const struct hdmi_phy_cfg msm_hdmi_phy_8x74_cfg = { - .type = MSM_HDMI_PHY_8x74, - .powerup = hdmi_phy_8x74_powerup, - .powerdown = hdmi_phy_8x74_powerdown, - .reg_names = hdmi_phy_8x74_reg_names, - .num_regs = ARRAY_SIZE(hdmi_phy_8x74_reg_names), - .clk_names = hdmi_phy_8x74_clk_names, - .num_clks = ARRAY_SIZE(hdmi_phy_8x74_clk_names), -}; diff --git a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c b/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c deleted file mode 100644 index cb35a297afbd..000000000000 --- a/drivers/gpu/drm/msm/hdmi/hdmi_pll_8960.c +++ /dev/null @@ -1,458 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Copyright (c) 2016, The Linux Foundation. All rights reserved. - * Copyright (C) 2013 Red Hat - * Author: Rob Clark - */ - -#include -#include - -#include "hdmi.h" - -struct hdmi_pll_8960 { - struct platform_device *pdev; - struct clk_hw clk_hw; - void __iomem *mmio; - - unsigned long pixclk; -}; - -#define hw_clk_to_pll(x) container_of(x, struct hdmi_pll_8960, clk_hw) - -/* - * HDMI PLL: - * - * To get the parent clock setup properly, we need to plug in hdmi pll - * configuration into common-clock-framework. - */ - -struct pll_rate { - unsigned long rate; - int num_reg; - struct { - u32 val; - u32 reg; - } conf[32]; -}; - -/* NOTE: keep sorted highest freq to lowest: */ -static const struct pll_rate freqtbl[] = { - { 154000000, 14, { - { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x0d, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4d, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x5e, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0x42, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - } - }, - /* 1080p60/1080p50 case */ - { 148500000, 27, { - { 0x02, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, - { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, - { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, - { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, - { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, - { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, - { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, - } - }, - { 108000000, 13, { - { 0x08, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x21, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x1c, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x49, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - } - }, - /* 720p60/720p50/1080i60/1080i50/1080p24/1080p30/1080p25 */ - { 74250000, 8, { - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x12, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x76, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0xe6, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - } - }, - { 74176000, 14, { - { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0xe5, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x0c, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x7d, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0xbc, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - } - }, - { 65000000, 14, { - { 0x18, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xf9, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x8a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x0b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4b, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0x09, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - } - }, - /* 480p60/480i60 */ - { 27030000, 18, { - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x38, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, - { 0x20, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0xff, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4e, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0xd7, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0x03, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, - } - }, - /* 576p50/576i50 */ - { 27000000, 27, { - { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, - { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, - { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x7b, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x01, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, - { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, - { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, - { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, - { 0x2a, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x03, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, - } - }, - /* 640x480p60 */ - { 25200000, 27, { - { 0x32, REG_HDMI_8960_PHY_PLL_REFCLK_CFG }, - { 0x02, REG_HDMI_8960_PHY_PLL_CHRG_PUMP_CFG }, - { 0x01, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG0 }, - { 0x33, REG_HDMI_8960_PHY_PLL_LOOP_FLT_CFG1 }, - { 0x2c, REG_HDMI_8960_PHY_PLL_IDAC_ADJ_CFG }, - { 0x06, REG_HDMI_8960_PHY_PLL_I_VI_KVCO_CFG }, - { 0x0a, REG_HDMI_8960_PHY_PLL_PWRDN_B }, - { 0x77, REG_HDMI_8960_PHY_PLL_SDM_CFG0 }, - { 0x4c, REG_HDMI_8960_PHY_PLL_SDM_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG2 }, - { 0xc0, REG_HDMI_8960_PHY_PLL_SDM_CFG3 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SDM_CFG4 }, - { 0x9a, REG_HDMI_8960_PHY_PLL_SSC_CFG0 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG1 }, - { 0x00, REG_HDMI_8960_PHY_PLL_SSC_CFG2 }, - { 0x20, REG_HDMI_8960_PHY_PLL_SSC_CFG3 }, - { 0x10, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0 }, - { 0x1a, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1 }, - { 0x0d, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2 }, - { 0xf4, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG0 }, - { 0x02, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG1 }, - { 0x3b, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG2 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG3 }, - { 0x86, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG4 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG5 }, - { 0x33, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG6 }, - { 0x00, REG_HDMI_8960_PHY_PLL_VCOCAL_CFG7 }, - } - }, -}; - -static inline void pll_write(struct hdmi_pll_8960 *pll, u32 reg, u32 data) -{ - msm_writel(data, pll->mmio + reg); -} - -static inline u32 pll_read(struct hdmi_pll_8960 *pll, u32 reg) -{ - return msm_readl(pll->mmio + reg); -} - -static inline struct hdmi_phy *pll_get_phy(struct hdmi_pll_8960 *pll) -{ - return platform_get_drvdata(pll->pdev); -} - -static int hdmi_pll_enable(struct clk_hw *hw) -{ - struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw); - struct hdmi_phy *phy = pll_get_phy(pll); - int timeout_count, pll_lock_retry = 10; - unsigned int val; - - DBG(""); - - /* Assert PLL S/W reset */ - pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d); - pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG0, 0x10); - pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG1, 0x1a); - - /* Wait for a short time before de-asserting - * to allow the hardware to complete its job. - * This much of delay should be fine for hardware - * to assert and de-assert. - */ - udelay(10); - - /* De-assert PLL S/W reset */ - pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d); - - val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); - val |= HDMI_8960_PHY_REG12_SW_RESET; - /* Assert PHY S/W reset */ - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); - val &= ~HDMI_8960_PHY_REG12_SW_RESET; - /* - * Wait for a short time before de-asserting to allow the hardware to - * complete its job. This much of delay should be fine for hardware to - * assert and de-assert. - */ - udelay(10); - /* De-assert PHY S/W reset */ - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x3f); - - val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); - val |= HDMI_8960_PHY_REG12_PWRDN_B; - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); - /* Wait 10 us for enabling global power for PHY */ - mb(); - udelay(10); - - val = pll_read(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B); - val |= HDMI_8960_PHY_PLL_PWRDN_B_PLL_PWRDN_B; - val &= ~HDMI_8960_PHY_PLL_PWRDN_B_PD_PLL; - pll_write(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B, val); - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG2, 0x80); - - timeout_count = 1000; - while (--pll_lock_retry > 0) { - /* are we there yet? */ - val = pll_read(pll, REG_HDMI_8960_PHY_PLL_STATUS0); - if (val & HDMI_8960_PHY_PLL_STATUS0_PLL_LOCK) - break; - - udelay(1); - - if (--timeout_count > 0) - continue; - - /* - * PLL has still not locked. - * Do a software reset and try again - * Assert PLL S/W reset first - */ - pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x8d); - udelay(10); - pll_write(pll, REG_HDMI_8960_PHY_PLL_LOCKDET_CFG2, 0x0d); - - /* - * Wait for a short duration for the PLL calibration - * before checking if the PLL gets locked - */ - udelay(350); - - timeout_count = 1000; - } - - return 0; -} - -static void hdmi_pll_disable(struct clk_hw *hw) -{ - struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw); - struct hdmi_phy *phy = pll_get_phy(pll); - unsigned int val; - - DBG(""); - - val = hdmi_phy_read(phy, REG_HDMI_8960_PHY_REG12); - val &= ~HDMI_8960_PHY_REG12_PWRDN_B; - hdmi_phy_write(phy, REG_HDMI_8960_PHY_REG12, val); - - val = pll_read(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B); - val |= HDMI_8960_PHY_REG12_SW_RESET; - val &= ~HDMI_8960_PHY_REG12_PWRDN_B; - pll_write(pll, REG_HDMI_8960_PHY_PLL_PWRDN_B, val); - /* Make sure HDMI PHY/PLL are powered down */ - mb(); -} - -static const struct pll_rate *find_rate(unsigned long rate) -{ - int i; - - for (i = 1; i < ARRAY_SIZE(freqtbl); i++) - if (rate > freqtbl[i].rate) - return &freqtbl[i - 1]; - - return &freqtbl[i - 1]; -} - -static unsigned long hdmi_pll_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw); - - return pll->pixclk; -} - -static long hdmi_pll_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *parent_rate) -{ - const struct pll_rate *pll_rate = find_rate(rate); - - return pll_rate->rate; -} - -static int hdmi_pll_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct hdmi_pll_8960 *pll = hw_clk_to_pll(hw); - const struct pll_rate *pll_rate = find_rate(rate); - int i; - - DBG("rate=%lu", rate); - - for (i = 0; i < pll_rate->num_reg; i++) - pll_write(pll, pll_rate->conf[i].reg, pll_rate->conf[i].val); - - pll->pixclk = rate; - - return 0; -} - -static const struct clk_ops hdmi_pll_ops = { - .enable = hdmi_pll_enable, - .disable = hdmi_pll_disable, - .recalc_rate = hdmi_pll_recalc_rate, - .round_rate = hdmi_pll_round_rate, - .set_rate = hdmi_pll_set_rate, -}; - -static const struct clk_parent_data hdmi_pll_parents[] = { - { .fw_name = "pxo", .name = "pxo_board" }, -}; - -static struct clk_init_data pll_init = { - .name = "hdmi_pll", - .ops = &hdmi_pll_ops, - .parent_data = hdmi_pll_parents, - .num_parents = ARRAY_SIZE(hdmi_pll_parents), - .flags = CLK_IGNORE_UNUSED, -}; - -int msm_hdmi_pll_8960_init(struct platform_device *pdev) -{ - struct device *dev = &pdev->dev; - struct hdmi_pll_8960 *pll; - int i, ret; - - /* sanity check: */ - for (i = 0; i < (ARRAY_SIZE(freqtbl) - 1); i++) - if (WARN_ON(freqtbl[i].rate < freqtbl[i + 1].rate)) - return -EINVAL; - - pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL); - if (!pll) - return -ENOMEM; - - pll->mmio = msm_ioremap(pdev, "hdmi_pll"); - if (IS_ERR(pll->mmio)) { - DRM_DEV_ERROR(dev, "failed to map pll base\n"); - return -ENOMEM; - } - - pll->pdev = pdev; - pll->clk_hw.init = &pll_init; - - ret = devm_clk_hw_register(dev, &pll->clk_hw); - if (ret < 0) { - DRM_DEV_ERROR(dev, "failed to register pll clock\n"); - return ret; - } - - ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_simple_get, &pll->clk_hw); - if (ret) { - DRM_DEV_ERROR(dev, "%s: failed to register clk provider: %d\n", __func__, ret); - return ret; - } - - return 0; -}