From patchwork Tue May 23 12:14:40 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252138 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 A3F6AC7EE26 for ; Tue, 23 May 2023 12:16:03 +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=KSBN21y6MwpjrWAmTKJJ+eUeEqrsJn+hwUNu8RGqzSU=; b=1hkhET393+zEFn MlFwSWuTxUwDfQQ9a9cyUd9XrCqEP2Yi7H94rpGjWSPXeZ000RMQ9WTnBMvKI87Lqn2X31a1DrZ4w D3gDVktY327xO8y2k746zzAc3Vb4HttnuB06wGFx1LBlTkI0Orcm7Ayx6AANBP2BtsVLRnUKdUifm wZOsO/k+JkHZhpsxLgh22HV8Mg8eN/XxiAL/SnZqbE6pvsWj2VpXHnWv/Erpd3AtUZWi3QMF3Z6uj xTlIcQEUrSMBT2ztNiz6qV4xiLW9VrtxF8tMejMHMMI4viyt+E1QKqQqnN1v8K1a9m+pyOvQg4Pmt D2mIICZkhiQQWbWKYhiA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvr-00ACcE-0w; Tue, 23 May 2023 12:16:03 +0000 Received: from mail-lf1-f49.google.com ([209.85.167.49]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvn-00ACYC-0m for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:00 +0000 Received: by mail-lf1-f49.google.com with SMTP id 2adb3069b0e04-4f122ff663eso7898230e87.2 for ; Tue, 23 May 2023 05:15:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844097; x=1687436097; 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=enXMayXRzHH3oByKOYNfSsDWlN3ph9R0cvur3PtJ7ms=; b=GgOuR/mBHkSar7s0Nq/XxGnf14MrxbwcDNTCNamb0kCxl6mw7on0TwmCUUcd5yvDEZ xkdovIonZ6mLa8iqAurAuOdW3v6I00EoT0PP0HuqTGCJ1oEMsEwzZxnhUv5gX0gsoZoq nN5cUlV5NpjXrVg3HaTQthzV9XPF/h+gGjspwMbRcW03qPEajJg1BygcKK+Q9VdYVgPI k7k4wRunYgMWFD+h0OjzE1pRerv3SSAGrHur2dbQzGlD2k5+MGI/RUuRDiEKse1YEn0g pRoMum/gT2lrfjOuAs3i+ZRguXVD2TzbLbLv6bVvuKi/sOvsE3zqQI6xXGr5msLsuSbF cXvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844097; x=1687436097; 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=enXMayXRzHH3oByKOYNfSsDWlN3ph9R0cvur3PtJ7ms=; b=Pn3hGZo3aP4Xtc00gKjxhTwVIOYH44Sf7RZGA0L+khyFHgj1FxWnNPgQmPaGb1ao8U s6Wc1jY4jbU+ob9bgZnh2JIgbLKUaY6D6Z1GS06e9beQTVcNCHMeM6JLhn6iPLwBxJui PdCkO68xXblRlrfllN/Il5pyM5jQJQdhcDEAPpcf6JKxSEH9qMww5q0FvJrgJSbp4kAV X3gCHwYdNYJVh2zzAiQeqv+5mxi2UjTRPUhyOcCdz1aLRT7fKyNX/Xs6GJE0gjj6hv/I fxFrO+LQh+vP/9hC7WYt479nrsJAXIDJ1KinuN1a70L3+xLewgMz2T86Flxv+FWM023X A2rA== X-Gm-Message-State: AC+VfDw7SgJFFEZy9Xcfb7oNhTQBhw2G61BwSlO6AW5xUEMIEJBwrjL5 l99wGb81gVGs7HoT+9ITR+g3jC9fF14oxh9MTp8= X-Google-Smtp-Source: ACHHUZ4vMMeapHmDZhf0XR9q/6ZhAQ2GX3q8enToq80E9pn+2TNU+/BW9JtkjjWBEAiAkysxIU6lHQ== X-Received: by 2002:ac2:5925:0:b0:4f3:7a01:f0d6 with SMTP id v5-20020ac25925000000b004f37a01f0d6mr3942481lfi.67.1684844097087; Tue, 23 May 2023 05:14:57 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.14.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:14:56 -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 01/15] phy: Add HDMI configuration options Date: Tue, 23 May 2023 15:14:40 +0300 Message-Id: <20230523121454.3460634-2-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_051559_275589_AC19E3A1 X-CRM114-Status: GOOD ( 17.30 ) 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 3a570bc59fc7..93d77d45b1d4 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 Tue May 23 12:14:41 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252237 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 86B47C77B75 for ; Tue, 23 May 2023 13:20:00 +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=bWuurS4qh764yo376R8IQosKbfLdZ6AjX+kk2Mkqfv8=; b=jw+bApwCdPhdTs ZTPeHlnnPzjfQXZEXOQEeLga20EO6h6pjtV1RKqk1vKLxFeQ8zBtUlCZq/8UCLAjn87aRZOZhaefv 7PR4DMrKKjao+k9FuxNK2+oKUXWMrV2yYiAZBK9tNxPumFcHRaIwQA8uDfMfBUkweCj0q07zRrf9m gZBPDhlIkQtLp9q7sUJjxu6+AD36jFm1QeKsHvHMcE5PP5FLraIOs2COAqW6m0rYHN7jYdY3KbxKo fbxYt4yBnYm/2xRyOm9l2JqRfdtaZ8mXt6GzkWN+h5mESJGeUj2hgne2ICT4BlMwwpRz6vSb/S5BB Z2AW0rSXzAOSh+YeY0wQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1Rvk-00AMQb-0Y; Tue, 23 May 2023 13:20:00 +0000 Received: from mail-lf1-f43.google.com ([209.85.167.43]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvo-00ACZL-1Y for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:03 +0000 Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-4f3baf04f0cso3287235e87.1 for ; Tue, 23 May 2023 05:15:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844098; x=1687436098; 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=rgm/XtzngAHmwGZTfcJ2+YPJWTpV3jmA/kZ9iH9BoTY=; b=yA1cVxFO2O8n5NIbIYXp91JXoGotPcUhT4h09ZeBEc5LDn8/FE81WyHEE/QpjEiDq4 uer021n+5y4XopCMoLDDpBiXxU4n+FD72NCMUykpCYBcnyYJq43H8tmi1SZKOZEUniVk S7qHkafxPytQBDuTVcdeepkNgUTLupsYKy8r1WWhWbwWPfIhjlXNurJ1OcsE+251ntYw PW4jd0onRh6MEA42iSYEVDgdYTmGSzy72xHAuFryQ6gbNILWgFyx/wUBN2+IMMIMXP46 j0rMO6uXaoJ0+ufTeP1bUfHXJG5saYWBJS2E6kIE3AbjAnAFqLC/UO+W3wK1O7WO2ZVW K6ZQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844098; x=1687436098; 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=rgm/XtzngAHmwGZTfcJ2+YPJWTpV3jmA/kZ9iH9BoTY=; b=VfH3OCvS91LwEE6WyhcaNQd6XjaVTH5lfVII9Z4EL9jNBD3tEmc3KQIDWHUQM91csA TS6kQl25uNNEsAg4kjd6xY8T8udR6z5Q2XvnXqEMOvfWn0Od7boYfMjMI3IwbOrdXru5 jvnPt2cZvyYPN+KNkv2lTdY9g/5huxBMADyhuDsefi3iQvwpjUpVQjWoPNcdnZH2NqQa nW61JfP8svmxQKQHx+PDLquLRBBTLF7d1QKm8/CNjHSg6SBPibpqxL8m4GEMrBpH79Zo 78IXiXOt+9zdnLtUmWKWquzjUiFoXjhDhwFZrcC2qAM0hqVq6cyLEhNAsWWMzNy49+Ix KtfQ== X-Gm-Message-State: AC+VfDzBcsKvNcah1qsGkifNL9Jh0AO7qzZL2V3cGZcoeFeqEz6RfWLs Z77RgRV1wHPvAYMUxi2LQEwwcw== X-Google-Smtp-Source: ACHHUZ7eoev2KX+OibISW6WzPEusz0pvwugrVCRTeStvCtRl7yIAz+ecdsYWqoPEPFHagXASzi3rJA== X-Received: by 2002:ac2:5ec2:0:b0:4f3:94b5:3272 with SMTP id d2-20020ac25ec2000000b004f394b53272mr4372100lfq.11.1684844098239; Tue, 23 May 2023 05:14:58 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.14.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:14:57 -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 02/15] phy: qualcomm: add QMP HDMI PHY driver Date: Tue, 23 May 2023 15:14:41 +0300 Message-Id: <20230523121454.3460634-3-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_051600_524233_6776ABAD X-CRM114-Status: GOOD ( 24.26 ) 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 4850d48f31fa..94fb5679df4a 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -65,6 +65,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 de3dc9ccf067..b877d86ea0b1 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -6,7 +6,12 @@ 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_PCIE2) += phy-qcom-pcie2.o +phy-qcom-qmp-hdmi-y := \ + phy-qcom-qmp-hdmi-base.o \ + phy-qcom-qmp-hdmi-msm8996.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 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 Tue May 23 12:14:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252240 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 15C15C7EE2A for ; Tue, 23 May 2023 13:20:01 +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=EcUt1KgJ9V1Y49tci2rfQQa/4WpuylwGgVadvG002ws=; b=K5rs0GqTkWt0Ln H63mxkufok/V9EfpMjGx6hP7wUSajD7ZhAhormCceKoRU7VXH547I81f37fcMiWiGnQYF6qwoGgRP U3M4vpoyFmWSMtCOM4xBMSsxA7UtBJv9p+8VLqP9tWAo/E2huRSvA2CV9408Yg/0Ra4kmDnV174+7 4uVl4Mt7zJb/sZTgONhVz2MdlGptufsfD+nk/vXpr+WHFlLLS7zqDuzIThVn2BriSRxZplHZGmWSY RoTgd0vLfAD9bJFjgPDZ+zrtr6ws8kWTtakaIsBezS2FiWr8+uqFI1Yy5rnTcYENOHV7gTQobfAQQ pLI+xsnDkQD5S+bKHbcA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1Rvk-00AMQx-2I; Tue, 23 May 2023 13:20:00 +0000 Received: from mail-lf1-f53.google.com ([209.85.167.53]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvp-00ACZv-0W for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:04 +0000 Received: by mail-lf1-f53.google.com with SMTP id 2adb3069b0e04-4f00c33c3d6so8528019e87.2 for ; Tue, 23 May 2023 05:16:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844099; x=1687436099; 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=luYkfguOMuGP5SycDO6aZL2kqBCqNqXT6dUGNjFwDrI=; b=efRJLVptrDY8EDmyxpSSCSpG63wmsHbw6YIajCMRkug/5/4uEA96TwhlAvquawMH/q M1WGUQrzrKsvw5D1+M33kOHrmIz6fiak3rVwmK6cXd0E9DJfLUN/fd+JX/IUvvAc5ENZ lso42E+KfGlPYy0cRIqx6Fz1OyG1JXMqTtI0Cv01nAqCRbjRy9w6uq9aQWvAp4ElQop+ +s3ZGXsaQIbWS0pwdxAaWq/1NDJsiqBqd6Sfk7lvw/VmJk7Ag0Be3T5IRNSTTuZBdWrD HGEHxlELKl0O2Go2boqo55z8AiSQ51Rb7Gdt6rB4Bh0nUqYWYVkGtg4V9+EHfWPlcK1L Yykg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844099; x=1687436099; 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=luYkfguOMuGP5SycDO6aZL2kqBCqNqXT6dUGNjFwDrI=; b=IMzHunM1vw7tQtDyYXxr/+tGble55tDeTsCwJRiWoRP83acTXZBoTYHMV1cKXXpPnZ 0yuWTiFBErfr8OO6MdJDMLgkhoSxcajijHHpxWkHMAEDNxP/K1tQFgRQF3x8MsS/JaTt XL8KKbJiYOwjS6o6zN/b8Hiu7VOvlCO8JN7KcpIa8Ok1CKxfiE3c2Tk7p+k77F2/uzln Hy5ui8rtr9P16tdJedtyxppdEYKt9BINJIJFAlsPnoRz4/HUTZdDLhbyxSlEGj9N2fSn WCJ1F9Ehn/Dc12NhYduWcnP1GB8XEN0M+8TZAAFi97o2cjg/10oO0hrm73kY9xx702aq XpIA== X-Gm-Message-State: AC+VfDxglnswOvYiGHBAu4Af3+8wg0tdW7yfcDv2riROirF3ieMfS9r+ 2JauiexN2kM8vcaODs+0GK9X+g== X-Google-Smtp-Source: ACHHUZ4LzcC2bCAAaHwEefgNRISItdKvzWc0Vo3TUg1ofzKxIGp0uPpONKilAkkXutxeDWTlOcOJ+Q== X-Received: by 2002:ac2:539a:0:b0:4f3:8244:95e2 with SMTP id g26-20020ac2539a000000b004f3824495e2mr4225547lfh.50.1684844099145; Tue, 23 May 2023 05:14:59 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.14.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:14:58 -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 03/15] phy: qualcomm: add MSM8960 HDMI PHY driver Date: Tue, 23 May 2023 15:14:42 +0300 Message-Id: <20230523121454.3460634-4-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_051601_203791_A6B0C0E5 X-CRM114-Status: GOOD ( 15.70 ) 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 the HDMI PHY driver for Qualcomm MSM8960 / APQ8064 platforms. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Kconfig | 11 + drivers/phy/qualcomm/Makefile | 1 + drivers/phy/qualcomm/phy-qcom-hdmi-msm8960.c | 744 +++++++++++++++++++ 3 files changed, 756 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-msm8960.c diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index 94fb5679df4a..838f93ad1168 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -42,6 +42,17 @@ config PHY_QCOM_IPQ806X_SATA depends on OF select GENERIC_PHY +config PHY_QCOM_HDMI_MSM8960 + tristate "Qualcomm MSM8960 HDMI PHY driver" + depends on ARCH_QCOM || COMPILE_TEST + depends on OF + depends on COMMON_CLK + default DRM_MSM_HDMI && ARCH_MSM8960 + select GENERIC_PHY + help + Enable this to support the Qualcomm HDMI PHY presend on MSM8960 and + APQ8064 platforms. + 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 b877d86ea0b1..6d7d76c7fee0 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -4,6 +4,7 @@ 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_MSM8960) += phy-qcom-hdmi-msm8960.o obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o phy-qcom-qmp-hdmi-y := \ diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-msm8960.c b/drivers/phy/qualcomm/phy-qcom-hdmi-msm8960.c new file mode 100644 index 000000000000..338d132dc8c8 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-msm8960.c @@ -0,0 +1,744 @@ +// 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 + +#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 + +struct qcom_hdmi_8960_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 *iface_clk; + struct regulator *vdda; +}; + +#define hw_clk_to_phy(x) container_of(x, struct qcom_hdmi_8960_phy, pll_hw) + +static inline void hdmi_phy_write(struct qcom_hdmi_8960_phy *phy, int offset, + u32 data) +{ + writel(data, phy->phy_reg + offset); +} + +static inline u32 hdmi_phy_read(struct qcom_hdmi_8960_phy *phy, int offset) +{ + return readl(phy->phy_reg + offset); +} + +static inline void hdmi_pll_write(struct qcom_hdmi_8960_phy *phy, int offset, + u32 data) +{ + writel(data, phy->pll_reg + offset); +} + +static inline u32 hdmi_pll_read(struct qcom_hdmi_8960_phy *phy, int offset) +{ + return readl(phy->pll_reg + offset); +} + +struct pll_conf { + u32 val; + u32 reg; +}; + +struct pll_rate { + unsigned long rate; + size_t num_reg; + const struct pll_conf *conf; +}; + +static const struct pll_conf pll_conf_154M[] = { + { 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 }, +}; + +static const struct pll_conf pll_conf_148M5[] = { + { 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 }, +}; + +static const struct pll_conf pll_conf_108M[] = { + { 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 }, +}; + +static const struct pll_conf pll_conf_74M25[] = { + { 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 }, +}; + +static const struct pll_conf pll_conf_74M176[] = { + { 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 }, +}; + +static const struct pll_conf pll_conf_65M[] = { + { 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 }, +}; + +static const struct pll_conf pll_conf_27M03[] = { + { 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 }, +}; + +static const struct pll_conf pll_conf_27M[] = { + { 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 }, +}; + +static const struct pll_conf pll_conf_25M2[] = { + { 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 }, +}; + + +/* NOTE: keep sorted highest freq to lowest: */ +static const struct pll_rate freqtbl[] = { + { 154000, ARRAY_SIZE(pll_conf_154M), pll_conf_154M }, + /* 1080p60/1080p50 case */ + { 148500, ARRAY_SIZE(pll_conf_148M5), pll_conf_148M5 }, + { 108000, ARRAY_SIZE(pll_conf_108M), pll_conf_108M }, + /* 720p60/720p50/1080i60/1080i50/1080p24/1080p30/1080p25 */ + { 74250, ARRAY_SIZE(pll_conf_74M25), pll_conf_74M25 }, + { 74176, ARRAY_SIZE(pll_conf_74M176), pll_conf_74M176 }, + { 65000, ARRAY_SIZE(pll_conf_65M), pll_conf_65M }, + /* 480p60/480i60 */ + { 27030, ARRAY_SIZE(pll_conf_27M03), pll_conf_27M03 }, + /* 576p50/576i50 */ + { 27000, ARRAY_SIZE(pll_conf_27M), pll_conf_27M }, + /* 640x480p60 */ + { 25200, ARRAY_SIZE(pll_conf_25M2), pll_conf_25M2 }, +}; + +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 qcom_hdmi_8960_pll_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct qcom_hdmi_8960_phy *hdmi_phy = hw_clk_to_phy(hw); + + return hdmi_phy->hdmi_opts.pixel_clk_rate * 1000UL; +} + +static long qcom_hdmi_8960_pll_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *parent_rate) +{ + const struct pll_rate *pll_rate = find_rate(rate / 1000); + + return pll_rate->rate * 1000UL; +} + +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_8960_phy_pll_enable(struct qcom_hdmi_8960_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_8960_phy_set_rate(struct qcom_hdmi_8960_phy *phy) +{ + unsigned int pixclk = phy->hdmi_opts.pixel_clk_rate; + const struct pll_rate *pll_rate = find_rate(pixclk); + int i; + + dev_dbg(phy->dev, "rate=%u", pixclk); + + for (i = 0; i < pll_rate->num_reg; i++) + hdmi_pll_write(phy, pll_rate->conf[i].reg, pll_rate->conf[i].val); + + return 0; +} + +static void qcom_hdmi_8960_phy_pll_disable(struct qcom_hdmi_8960_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_8960_phy_power_on(struct phy *phy) +{ + struct qcom_hdmi_8960_phy *hdmi_phy = phy_get_drvdata(phy); + int ret; + + ret = qcom_hdmi_8960_phy_pll_enable(hdmi_phy); + if (ret) + return ret; + + ret = qcom_hdmi_8960_phy_set_rate(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_8960_phy_power_off(struct phy *phy) +{ + struct qcom_hdmi_8960_phy *hdmi_phy = phy_get_drvdata(phy); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8960_PHY_REG2, 0x7f); + + qcom_hdmi_8960_phy_pll_disable(hdmi_phy); + + return 0; +} + +static int qcom_hdmi_8960_phy_init(struct phy *phy) +{ + struct qcom_hdmi_8960_phy *hdmi_phy = phy_get_drvdata(phy); + + return pm_runtime_resume_and_get(hdmi_phy->dev); +} + +static int qcom_hdmi_8960_phy_exit(struct phy *phy) +{ + struct qcom_hdmi_8960_phy *hdmi_phy = phy_get_drvdata(phy); + + pm_runtime_put_noidle(hdmi_phy->dev); + + return 0; +} + +static int qcom_hdmi_8960_phy_configure(struct phy *phy, union phy_configure_opts *opts) +{ + const struct phy_configure_opts_hdmi *hdmi_opts = &opts->hdmi; + struct qcom_hdmi_8960_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_8960_runtime_resume(struct device *dev) +{ + struct qcom_hdmi_8960_phy *hdmi_phy = dev_get_drvdata(dev); + int ret; + + ret = regulator_enable(hdmi_phy->vdda); + if (ret) + return ret; + + ret = clk_prepare_enable(hdmi_phy->iface_clk); + if (ret) + goto out_disable_supplies; + + return 0; + +out_disable_supplies: + regulator_disable(hdmi_phy->vdda); + + return ret; +} + +static int __maybe_unused qcom_hdmi_8960_runtime_suspend(struct device *dev) +{ + struct qcom_hdmi_8960_phy *hdmi_phy = dev_get_drvdata(dev); + + clk_disable_unprepare(hdmi_phy->iface_clk); + regulator_disable(hdmi_phy->vdda); + + return 0; +} + +static const struct phy_ops qcom_hdmi_8960_phy_ops = { + .init = qcom_hdmi_8960_phy_init, + .configure = qcom_hdmi_8960_phy_configure, + .power_on = qcom_hdmi_8960_phy_power_on, + .power_off = qcom_hdmi_8960_phy_power_off, + .exit = qcom_hdmi_8960_phy_exit, + .owner = THIS_MODULE, +}; + +static int qcom_hdmi_8960_probe(struct platform_device *pdev) +{ + struct clk_init_data init = { + .name = "hdmipll", + .ops = &qcom_hdmi_8960_pll_ops, + .parent_data = (const struct clk_parent_data[]) { + { .fw_name = "pxo", .name = "pxo_board" }, + }, + .flags = CLK_GET_RATE_NOCACHE, + .num_parents = 1, + }; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct qcom_hdmi_8960_phy *hdmi_phy; + int ret; + + 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->iface_clk = devm_clk_get(dev, "slave_iface"); + if (IS_ERR(hdmi_phy->iface_clk)) { + ret = PTR_ERR(hdmi_phy->iface_clk); + return ret; + } + + hdmi_phy->vdda = devm_regulator_get(dev, "core-vdda"); + if (IS_ERR(hdmi_phy->vdda)) { + ret = PTR_ERR(hdmi_phy->vdda); + 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; + + 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_8960_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_8960_of_match_table[] = { + { + .compatible = "qcom,hdmi-phy-8960", + }, + { }, +}; +MODULE_DEVICE_TABLE(of, qcom_hdmi_8960_of_match_table); + +DEFINE_RUNTIME_DEV_PM_OPS(qcom_hdmi_8960_pm_ops, + qcom_hdmi_8960_runtime_suspend, + qcom_hdmi_8960_runtime_resume, + NULL); + +static struct platform_driver qcom_hdmi_8960_driver = { + .probe = qcom_hdmi_8960_probe, + .driver = { + .name = "qcom-8960-hdmi-phy", + .of_match_table = qcom_hdmi_8960_of_match_table, + .pm = &qcom_hdmi_8960_pm_ops, + }, +}; + +module_platform_driver(qcom_hdmi_8960_driver); + +MODULE_AUTHOR("Dmitry Baryshkov "); +MODULE_DESCRIPTION("Qualcomm MSM8960 HDMI PHY driver"); +MODULE_LICENSE("GPL"); From patchwork Tue May 23 12:14:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252239 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 BB5A1C7EE26 for ; Tue, 23 May 2023 13:20:00 +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=H3TkPDtIxw/SQH3Mlj38F/qnU1kOA2CuDizu+pNtAAA=; b=23WdavBiZzk74y ueHPe3RXCs5yB+f5EFZXyLN5rE8k51eZSd4bOU5WUcb4kxPNWpiQGnlQIqlDNOfHaJ5L/oxIivwyQ 6IlUX0kipltnm6YX0m3VJBGre3GznTmCMyygnBsvYC/QeGO6x3vc0rLQfQSmKqrmrZTawi+FB5s9D 1sc/FX9aiX+euTg8fqAT6v1nEsuMvEjLX/rT7qaQpbpsE2OPf7DACvczO7D/raOH2HYPF5B1P3YtH QfvFk9vZNDgY4l7Ks9OSbyyu8eyUfYkaDifPpTHxqrWuzlWaOZL8AbErTUEf4nUD55Fy8hfMHLVB+ W4b2zeGwvfsbDGO5YxkQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1Rvk-00AMQo-1R; Tue, 23 May 2023 13:20:00 +0000 Received: from mail-lf1-f51.google.com ([209.85.167.51]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvp-00ACaL-2t for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:03 +0000 Received: by mail-lf1-f51.google.com with SMTP id 2adb3069b0e04-4ec8eca56cfso8037213e87.0 for ; Tue, 23 May 2023 05:16:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844100; x=1687436100; 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=2XJbQtrgiFrkjr0gRTcBYqYCtImHLEqMB5lmknqfspg=; b=n7WDTUIUx8uYcUJBfRArsRz+juVsm4mTxtdATqMDLiqji6iPHp+K28FkBnQe+AMw8q O+xEGKqcC2p7aP+jSEACzCJqsQcvSIPMAckFFrO7xE0i42J8x/9c5JXkTMKv+U85pBTn +Z4CyBfalnal5Io6DWZB8em0Atz/bJWyTuhy853v9Y20w0oW2OGUnLn4of/7CK7OF8V5 Yc3d3L4C40nqo+XZpCMXdD3RrxO6pH4G3c9fvXmUjaCzYnScn2hzsHrP8VNqoglZWMyp uJjIXbnUub3zUwTgi+OBFujoU4zo9M6RGa0A8ADwwFsfeyXiTRUUTxrIrk/nmcPQls++ tdtg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844100; x=1687436100; 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=2XJbQtrgiFrkjr0gRTcBYqYCtImHLEqMB5lmknqfspg=; b=Si/iq2Ch+FYzweQ9GT9/uqheUxgYu/DLI+qIiwdnuekAPUxMCNSKLbsWIoJ1DRr3Su 5/zzzuTPxdRnAtixNpE52zSQZdLy3GtGrJyA16uZOwhtwwEusldSFWg+BOArcOnLhuWl wvxVnEndni8EfzGnKaZf0AnPsxl3PLhnbDrGm1dA1onDwMDkSANoHWyXKqcMplCL31Xx GBpBmd9kFeagPsXlp479QLwu5JAyCFIatgKmZhvHOO8zgJHfoyCX3TW9NAeAtwll2VAq 6lhieYOldL+kYk5wnQ6UuUagxqS9joEpqKp5YKKoBHVsJDfkSg3CkK7L9xUw/pBqIvOQ DQ6Q== X-Gm-Message-State: AC+VfDwh21TBl1HtfWo8MfwP8cMo38b+1JopWrkg0C3ktHgEwk/cvz2m MgXqxg7imIGHR1fJIhfh6CsbNQ== X-Google-Smtp-Source: ACHHUZ6qJxwQ9GLDem0UXt4kJ6yZsQnCT/eWjJ4qWFQNjiJxNfLH5wiNwedepVWU2KMUPpGMQ48Gng== X-Received: by 2002:ac2:596a:0:b0:4f3:7cf8:b348 with SMTP id h10-20020ac2596a000000b004f37cf8b348mr4670060lfp.5.1684844100063; Tue, 23 May 2023 05:15:00 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.14.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:14:59 -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 04/15] phy: qualcomm: add MSM8x60 HDMI PHY driver Date: Tue, 23 May 2023 15:14:43 +0300 Message-Id: <20230523121454.3460634-5-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_051601_936896_7ADEA81D X-CRM114-Status: GOOD ( 22.64 ) 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 the HDMI PHY driver for Qualcomm MSM8260 / MSM8660 / APQ8060 platforms. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Kconfig | 11 + drivers/phy/qualcomm/Makefile | 1 + drivers/phy/qualcomm/phy-qcom-hdmi-msm8x60.c | 353 +++++++++++++++++++ 3 files changed, 365 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-msm8x60.c diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index 838f93ad1168..a603d4777a02 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -42,6 +42,17 @@ config PHY_QCOM_IPQ806X_SATA depends on OF select GENERIC_PHY +config PHY_QCOM_HDMI_MSM8X60 + tristate "Qualcomm MSM8x60 HDMI PHY driver" + depends on ARCH_QCOM || COMPILE_TEST + depends on OF + depends on COMMON_CLK + default DRM_MSM_HDMI && ARCH_MSM8X60 + select GENERIC_PHY + help + Enable this to support the Qualcomm HDMI PHY presend on MSM8260, + MSM8660 and APQ8060 platforms. + config PHY_QCOM_HDMI_MSM8960 tristate "Qualcomm MSM8960 HDMI PHY driver" depends on ARCH_QCOM || COMPILE_TEST diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index 6d7d76c7fee0..cbc730c074ad 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -4,6 +4,7 @@ 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_MSM8X60) += phy-qcom-hdmi-msm8x60.o obj-$(CONFIG_PHY_QCOM_HDMI_MSM8960) += phy-qcom-hdmi-msm8960.o obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-msm8x60.c b/drivers/phy/qualcomm/phy-qcom-hdmi-msm8x60.c new file mode 100644 index 000000000000..a5bacab80909 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-msm8x60.c @@ -0,0 +1,353 @@ +// 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 + +#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 + +struct qcom_hdmi_8x60_phy { + struct device *dev; + struct phy *phy; + void __iomem *phy_reg; + + struct phy_configure_opts_hdmi hdmi_opts; + + struct clk *iface_clk; + struct regulator *vdda; +}; + +static inline void hdmi_phy_write(struct qcom_hdmi_8x60_phy *phy, int offset, + u32 data) +{ + writel(data, phy->phy_reg + offset); +} + +static inline u32 hdmi_phy_read(struct qcom_hdmi_8x60_phy *phy, int offset) +{ + return readl(phy->phy_reg + offset); +} + +static int qcom_hdmi_8x60_phy_power_on(struct phy *phy) +{ + struct qcom_hdmi_8x60_phy *hdmi_phy = phy_get_drvdata(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_8x60_phy_power_off(struct phy *phy) +{ + struct qcom_hdmi_8x60_phy *hdmi_phy = phy_get_drvdata(phy); + + /* Assert RESET PHY from controller */ +#if 0 + hdmi_phy_write(hdmi_phy, REG_HDMI_PHY_CTRL, + HDMI_PHY_CTRL_SW_RESET); + udelay(10); + /* De-assert RESET PHY from controller */ + hdmi_phy_write(hdmi_phy, REG_HDMI_PHY_CTRL, 0); +#endif + /* 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; +} + +static int qcom_hdmi_8x60_phy_init(struct phy *phy) +{ + struct qcom_hdmi_8x60_phy *hdmi_phy = phy_get_drvdata(phy); + + return pm_runtime_resume_and_get(hdmi_phy->dev); +} + +static int qcom_hdmi_8x60_phy_exit(struct phy *phy) +{ + struct qcom_hdmi_8x60_phy *hdmi_phy = phy_get_drvdata(phy); + + pm_runtime_put_noidle(hdmi_phy->dev); + + return 0; +} + +static int qcom_hdmi_8x60_phy_configure(struct phy *phy, union phy_configure_opts *opts) +{ + const struct phy_configure_opts_hdmi *hdmi_opts = &opts->hdmi; + struct qcom_hdmi_8x60_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_8x60_runtime_resume(struct device *dev) +{ + struct qcom_hdmi_8x60_phy *hdmi_phy = dev_get_drvdata(dev); + int ret; + + ret = regulator_enable(hdmi_phy->vdda); + if (ret) + return ret; + + ret = clk_prepare_enable(hdmi_phy->iface_clk); + if (ret) + goto out_disable_supplies; + + return 0; + +out_disable_supplies: + regulator_disable(hdmi_phy->vdda); + + return ret; +} + +static int __maybe_unused qcom_hdmi_8x60_runtime_suspend(struct device *dev) +{ + struct qcom_hdmi_8x60_phy *hdmi_phy = dev_get_drvdata(dev); + + clk_disable_unprepare(hdmi_phy->iface_clk); + regulator_disable(hdmi_phy->vdda); + + return 0; +} + +static const struct phy_ops qcom_hdmi_8x60_phy_ops = { + .init = qcom_hdmi_8x60_phy_init, + .configure = qcom_hdmi_8x60_phy_configure, + .power_on = qcom_hdmi_8x60_phy_power_on, + .power_off = qcom_hdmi_8x60_phy_power_off, + .exit = qcom_hdmi_8x60_phy_exit, + .owner = THIS_MODULE, +}; + +static int qcom_hdmi_8x60_probe(struct platform_device *pdev) +{ + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct qcom_hdmi_8x60_phy *hdmi_phy; + int ret; + + 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->iface_clk = devm_clk_get(dev, "slave_iface"); + if (IS_ERR(hdmi_phy->iface_clk)) { + ret = PTR_ERR(hdmi_phy->iface_clk); + return ret; + } + + hdmi_phy->vdda = devm_regulator_get(dev, "core-vdda"); + if (IS_ERR(hdmi_phy->vdda)) { + ret = PTR_ERR(hdmi_phy->vdda); + 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; + + hdmi_phy->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_hdmi_8x60_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_8x60_of_match_table[] = { + { + .compatible = "qcom,hdmi-phy-8x60", + }, + { }, +}; +MODULE_DEVICE_TABLE(of, qcom_hdmi_8x60_of_match_table); + +DEFINE_RUNTIME_DEV_PM_OPS(qcom_hdmi_8x60_pm_ops, + qcom_hdmi_8x60_runtime_suspend, + qcom_hdmi_8x60_runtime_resume, + NULL); + +static struct platform_driver qcom_hdmi_8x60_driver = { + .probe = qcom_hdmi_8x60_probe, + .driver = { + .name = "qcom-8x60-hdmi-phy", + .of_match_table = qcom_hdmi_8x60_of_match_table, + .pm = &qcom_hdmi_8x60_pm_ops, + }, +}; + +module_platform_driver(qcom_hdmi_8x60_driver); + +MODULE_AUTHOR("Dmitry Baryshkov "); +MODULE_DESCRIPTION("Qualcomm MSM8x60 HDMI PHY driver"); +MODULE_LICENSE("GPL"); From patchwork Tue May 23 12:14:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252253 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 36A59C7EE26 for ; Tue, 23 May 2023 13:42:56 +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=oU0d2/HsT9SaHh+qccLdG1cmbp/a2fb96TlkTzbsIt8=; b=zLBCv5g+40Co/9 yUwb1yKcI7/3Q5na99IJEHhamVLKR/pOB6LS0GwZZKuwuhIxoHbQP7/RZq5OfAn+yhVnsoy1WQBcC aXJKd9xeEInIDk+4enDm1tvf7hQq1ko6A/0FX1Ji4uLVNcjGzOlR1USgl4Kw+z82axJdqXO1+XUEd 4EyvVlMKxz47x9P1Y6meU3MM5fAleWDLCPHxIdOAdXSqkSNZI/UGYkHzF6Sl2sxtwpb/hUbtbo9ag fWq4wyL+3bzeywV9WiOVnW06LV7+Ykh8dsIDl+SVsGOv/Hc3fsXN9V2+NJ73R24DssDAJWbBn7wXF TcmABjAV0kJo/hcvB3OQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHv-00AOlf-2m; Tue, 23 May 2023 13:42:55 +0000 Received: from desiato.infradead.org ([90.155.92.199]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHu-00AOkw-1e for linux-phy@bombadil.infradead.org; Tue, 23 May 2023 13:42:54 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=oekQjRFBIrAygoTditdy5x9KkvJ1geHU7IHNMEp5myg=; b=JmeppnNCAKtRn/NAZ3xTsVbznV +ga08NBEdGn6JITrOZanQlDIrwpjYEhqKYRAvR9YKUJ/jVVbgLAPExehsQtjn6rCizVZWF8K1E9II PUk5aCBPEvg0C6X0ovGHvEdud28w9cWH9n9gCdCKqQYLrTOe0l1kDGB5HozxpWQ/f54HL1AIErjZf 7hxVWNiuHaDzWh/FdBz7uiJHrevXTN84qBwaAIR59mIHpNxDjXOd674v29SRG5bpgpjjFrtsFDPel nLvZXyfXiqpFek/FmlFaSmk+ULVpzLnlC+48Y99fLtbroHEOvMpMwbJ4y7PX/W8sr/BfG7Aoo0f5f ZxydY5DA==; Received: from mail-lf1-x129.google.com ([2a00:1450:4864:20::129]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvu-003VxJ-0c for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:08 +0000 Received: by mail-lf1-x129.google.com with SMTP id 2adb3069b0e04-4f3a611b3ddso5847147e87.0 for ; Tue, 23 May 2023 05:16:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844101; x=1687436101; 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=oekQjRFBIrAygoTditdy5x9KkvJ1geHU7IHNMEp5myg=; b=pER6DvtBYvZcUs9mr3h/rYIfKF+AF+ERIBYWqsz6nI0gS+92VC8E1OPK6wBpmdffpK qXuQJu3cfeUBwxNE4szc71laSxqNr67vTf7hruSgG60yHyaBCebJtoCCunLjOfTMfdU4 B+Ux9+q9H8JBz7NR+0n2nQi92GTamyLIjaLkZLE6S+Vc6Qgc6OmTnU/00l4g8w0DvEtg 8ABQPtHJX7XRhelM/TroNxr9hwxl76o+1DVW6o0UzwGYnwPh7pOv3NvjQGszUOLr3AyH 8wsxw162gIPalyc0EE3JyG3VLlDfOQGpndDi3mfxvBiGN7A9KZXC1NoJ73FUVGmLQE9r sMGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844101; x=1687436101; 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=oekQjRFBIrAygoTditdy5x9KkvJ1geHU7IHNMEp5myg=; b=Z1virvf/67c1RAygrn8klISDE7LLQGbNedJTmD+RqeWLYRReBZHp7R4blwlUJKfkrp yhLl+Dd9Xt2E+fspBajfX9Aof+nDsVpG95K9j1TryijfrskLeL6CPwzjnpLCxl668oAo 9ofYvkVS3zD5rIhb7/pdQlkwO1E3/MOe9jubub66hPgC5x+54MOhVcX5E4+EmT7lbZTS o6dNAcKubz9RQp9qeZo1D2PlW9QzoBGrTkroOp6lEJdwmDIAamvm7Hdn2UUHT+UBclRM CRbWsJoKd4WhHfKCrPHnUw64MrevYiVxuaCc6kcJhTew2tT71V5JIfYR6TFdqG4oZY3h FHEw== X-Gm-Message-State: AC+VfDyXKTSczcs7U6HQP4+bbhcOOs6D43Z5CrzNRTWiPiXmg07AGD98 06NjAekUdms2zL20gUhUsrIExw== X-Google-Smtp-Source: ACHHUZ5QKmn14LzKukoTWcZuPZoMzzO6QtSUJ9uk65D6dYNPL8VebCPjC+8oLciKQFXnMuHXWqd+Aw== X-Received: by 2002:a05:6512:1086:b0:4dc:8049:6f36 with SMTP id j6-20020a056512108600b004dc80496f36mr4982158lfg.1.1684844100968; Tue, 23 May 2023 05:15:00 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:00 -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 05/15] phy: qcom: apq8064-sata: extract UNI PLL register defines Date: Tue, 23 May 2023 15:14:44 +0300 Message-Id: <20230523121454.3460634-6-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_131606_410218_CD9C3B89 X-CRM114-Status: GOOD ( 11.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 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 d437a249cd73..caabce5214b7 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 Tue May 23 12:14:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252238 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 5367DC7EE2E for ; Tue, 23 May 2023 13:20:01 +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=Vm3yy7htEzxIt2 wtbH0yZSM0j4OPe26qHASKwMtYgPa7VTx7Do+bcny0wIDWd8JdHUv/9jG7aK2LMcTMIKHlyRl5zFW 9BSIrh5itRuAVq06I9gsueSc37fZC7TT1VdkJMD7yhIt1kwPWQxp12DSSxIAFpw5jLnlpDoKbr2RK 1yJwdXTqanip6mX+MGXX+OSR3Uvn63SLotivezgseT1LyHsapqVrVlXjTOAJ14xejrXGfxpVqZKDS Mq6QqKjI9AeiWeUKNjkg8ioBGqt3V0LjqtDj2KMSqZL5s2YPX/LS3zkkOroHCTmwF/NbTpqjjgH0n 5I5y8I5lOXw5ig7PyXdA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1Rvk-00AMRE-3A; Tue, 23 May 2023 13:20:00 +0000 Received: from mail-lf1-f51.google.com ([209.85.167.51]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvr-00ACbo-0q for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:04 +0000 Received: by mail-lf1-f51.google.com with SMTP id 2adb3069b0e04-4f004cc54f4so8530936e87.3 for ; Tue, 23 May 2023 05:16:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844102; x=1687436102; 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=TfvFAcphjN90FHE/qU53hgzZzrbHHOgAGSBcP/AapZqKZdHWIztfbDSK8/EvTVpEB6 5PIcz0ijsAqKp9g0i9gxxIY6yu4LRc67tW+tBbLmv3EkYdr16usT78ZUxqUgIdmOZ0+J npsh6nW73/Yd1VcP2G8Sft7abdmOTULOmHxwkuIT3BTr0Dz80oN17o7QUogbwQmJTu4/ 8UG55Qm+pb3APF2P/4riyKRDZz4ARhSgVGN3QSQT7wSzdpHkg0S+hRJsTRQ/Toyx8jd+ Y9EhGi1i79ilK+d8QmEikQD1z6xnQhL1RXKqp/lO1wDiyha98rEGryOHbCD9u7GY7TR/ t59g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844102; x=1687436102; 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=iE3nxCLiFlpAqR4NH1w2pq7pZiggRjiiBIDZFk2lvKSxtN+54iyTApcJhYlJVqF3/J Y/IsGGwDnktEdvGMa1B/qHzOM/tm9o3YBRq4YiyL3UGN9AB4hoalEnmB6/ys1C36T82H Q5W/BMvms3NHh/FwO5NU18nSsBSAKbU9bZh6GAFNfaW2j5vun6PqqqjoIPWUoj/BMH2w 1RVq1C115E4hmCcCfHXNcNkc4onXMULKF8Lw4Q69KnRaGqgu1eRsUvJAMHLmkw8C53+6 IU1glA5Jdgj7kUZ4RSrIPDe4ZT7C3/pEnamaXNSbPMtAQC/W4YOIJjsdpuszjW53RZzK eb0w== X-Gm-Message-State: AC+VfDxQgaG7U3BYOy8LCZPDmJrIdkbpIb5JqZsGT3EbCWFwX+7PXZkE DRefJVpLHAgywEsvD/055BBoqQ== X-Google-Smtp-Source: ACHHUZ6qJzzoeKD4BIbsi2hhZzRfGK1ZyDtu9HGwi2v+ywlMux+3ZZ28AH6kH9qZw4r2MLZNcIW1nQ== X-Received: by 2002:a05:6512:972:b0:4eb:3b4c:50ac with SMTP id v18-20020a056512097200b004eb3b4c50acmr3717597lft.65.1684844102085; Tue, 23 May 2023 05:15:02 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:01 -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 06/15] phy: qcom-uniphy: add more registers from display PHYs Date: Tue, 23 May 2023 15:14:45 +0300 Message-Id: <20230523121454.3460634-7-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_051603_302578_D2FBCF37 X-CRM114-Status: UNSURE ( 6.98 ) 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 Tue May 23 12:14:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252241 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 8A023C7EE2F for ; Tue, 23 May 2023 13:20:01 +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=SdTnMCy9yVBZAfPrOlyGWANIdth0QPXxrhlW6Jli3pE=; b=MVYissNfqEQ2Kb w9ekDF6/1rL1b87aQgn7P1DWdv+kHyq6K2EZtivzzYfyDvY3hevjbRucBiCaEv3+bGVoFUK9NnCxd biRRfI9+oaV/4wp2HSkEFyy+6gV1/zcb9azU//nkj27HEI/7Tp8231tQAxqeDfxJTP4hPylbRkTWk GIrZNo/nbsV7E0qWntknkpLMksTWGkgtSh4i1sCF5IX92cXpU2qpv3aQXVDGOyRAAczIi7nbMP1iW +DQOpUxYDd/+GnNvh4P7BxnlgsvvokQVl4JbWkhBgPZf5wTvx+1wNChd9idRnYQ5nuzpKpkgloJxC NyOIJvsHVv90hpGZqkzg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1Rvl-00AMRU-0q; Tue, 23 May 2023 13:20:01 +0000 Received: from mail-lf1-f43.google.com ([209.85.167.43]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvs-00ACcU-0v for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:06 +0000 Received: by mail-lf1-f43.google.com with SMTP id 2adb3069b0e04-4f4b80bf93aso1213341e87.0 for ; Tue, 23 May 2023 05:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844103; x=1687436103; 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=lXESD2KrVm3U7h3EGxyXap+xEb/teM8AqZZ0TCrr8q0=; b=ZTjM6o2Jnhepsdd5nebQiT8er5eFmxzPk2xWWh+3yVBwfi4RHl58/7o4Yw023nF3Gy B0azNyzg31jDyD8Y8QnUl8HZ8ZYt4dT5ahle5ZXyM1NHpgySzKWFT9IWuttVd7qT7Y37 +wyLW/mLO2P1u7nMnQgi14apSEjsBhE3KD9X91b/UOBDL52kjqmxEK5yyLS3EJBt9oo3 K2zvNLiBNPk7tYP73e18jyzqaGs++cBHE1foMjDgRicagxtAY/GF5i4HCAfHzbeWx5tR fPoGfbxH1CgIlUxWp90KI35yLXmllZmhWWDdyIwuGzmHvcxgWVod5/H41NKcmXU2xCn/ hqwg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844103; x=1687436103; 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=lXESD2KrVm3U7h3EGxyXap+xEb/teM8AqZZ0TCrr8q0=; b=hYZK+zWlbIlJ/1d4kxLOs5hVdPMaKPiuURgT0GFd4Xg/FxehjQ++fxf9woXtm+1nFH gvh1Nok32GRvfq6yzfK41Svblr93CeBlt5+F5X+qGCmjWk4KDG+FN8VnH377cflpuKM0 cq61tErJjObcF8tf44l7f+hEGj4op4Ak2ker24cIgBdnVkEkB1HPw7BzDztBoXmd8dYQ oMLu7buLpy2DZsCM4zE1thjCtmEFJnKXkSk84nJRwJGP/pgi3sUT0QCNyFGR/sWJ6cUP njwLQYD8Xij7EyqqHLh728ENoMHbfGI3k/e/+bLwjMG9ryFKpkPmTUqnKNSUFxCC/RVe j2Lw== X-Gm-Message-State: AC+VfDyz7W646++120q7C8oZXeJrgPnUl7g9MRhSEAj6N5f+VKyA4jG6 ynkRJOrJ4X3X9PXWw6zK79/kXQ== X-Google-Smtp-Source: ACHHUZ5LI9RATEt2bX+ORMcay3S+a3qMx9r9gOraB4eYwNbUwVzC/XeaBcCmBmoW4imGHiqgouWTiQ== X-Received: by 2002:ac2:5dd0:0:b0:4f3:a9d3:4893 with SMTP id x16-20020ac25dd0000000b004f3a9d34893mr4618433lfq.35.1684844102952; Tue, 23 May 2023 05:15:02 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:02 -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 07/15] phy: qualcomm: add MSM8974 HDMI PHY driver Date: Tue, 23 May 2023 15:14:46 +0300 Message-Id: <20230523121454.3460634-8-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_051604_498516_F540B605 X-CRM114-Status: GOOD ( 22.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 Port the HDMI PHY driver for Qualcomm MSM8974 / APQ8074 platforms. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Kconfig | 11 + drivers/phy/qualcomm/Makefile | 1 + drivers/phy/qualcomm/phy-qcom-hdmi-msm8974.c | 531 +++++++++++++++++++ 3 files changed, 543 insertions(+) create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-msm8974.c diff --git a/drivers/phy/qualcomm/Kconfig b/drivers/phy/qualcomm/Kconfig index a603d4777a02..812e54390ad8 100644 --- a/drivers/phy/qualcomm/Kconfig +++ b/drivers/phy/qualcomm/Kconfig @@ -64,6 +64,17 @@ config PHY_QCOM_HDMI_MSM8960 Enable this to support the Qualcomm HDMI PHY presend on MSM8960 and APQ8064 platforms. +config PHY_QCOM_HDMI_MSM8974 + tristate "Qualcomm MSM8974 HDMI PHY driver" + depends on ARCH_QCOM || COMPILE_TEST + depends on OF + depends on COMMON_CLK + default DRM_MSM_HDMI && ARCH_MSM8974 + select GENERIC_PHY + help + Enable this to support the Qualcomm HDMI PHY presend on MSM8974 and + APQ8074 platforms. + 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 cbc730c074ad..6e73b1ff4692 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -6,6 +6,7 @@ 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_MSM8X60) += phy-qcom-hdmi-msm8x60.o obj-$(CONFIG_PHY_QCOM_HDMI_MSM8960) += phy-qcom-hdmi-msm8960.o +obj-$(CONFIG_PHY_QCOM_HDMI_MSM8974) += phy-qcom-hdmi-msm8974.o obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o phy-qcom-qmp-hdmi-y := \ diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-msm8974.c b/drivers/phy/qualcomm/phy-qcom-hdmi-msm8974.c new file mode 100644 index 000000000000..d61aaea9eae6 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-msm8974.c @@ -0,0 +1,531 @@ +// 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-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 + +#define MAX_CLKS 2 +#define MAX_SUPPLIES 2 + +struct qcom_hdmi_8974_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]; + struct regulator_bulk_data supplies[MAX_SUPPLIES]; +}; + +#define hw_clk_to_phy(x) container_of(x, struct qcom_hdmi_8974_phy, pll_hw) + +static inline void hdmi_phy_write(struct qcom_hdmi_8974_phy *phy, int offset, + u32 data) +{ + writel(data, phy->phy_reg + offset); +} + +static inline u32 hdmi_phy_read(struct qcom_hdmi_8974_phy *phy, int offset) +{ + return readl(phy->phy_reg + offset); +} + +static inline void hdmi_pll_write(struct qcom_hdmi_8974_phy *phy, int offset, + u32 data) +{ + writel(data, phy->pll_reg + offset); +} + +static inline u32 hdmi_pll_read(struct qcom_hdmi_8974_phy *phy, int offset) +{ + return readl(phy->pll_reg + offset); +} + +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_8974_phy *hdmi_phy = hw_clk_to_phy(hw); + u32 div_idx = hdmi_pll_read(hdmi_phy, UNIPHY_PLL_POSTDIV1_CFG); + + return qcom_uniphy_recalc(hdmi_phy->pll_reg, parent_rate) / 5 / 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_8974_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_8974_phy_pll_set_rate(struct qcom_hdmi_8974_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_8974_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); + qcom_uniphy_recalc(hdmi_phy->pll_reg, 19200); + + 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_8974_phy_pll_enable(struct qcom_hdmi_8974_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_8974_phy_power_on(struct phy *phy) +{ + struct qcom_hdmi_8974_phy *hdmi_phy = phy_get_drvdata(phy); + int ret; + + ret = qcom_hdmi_8974_phy_pll_set_rate(hdmi_phy); + if (ret) + return ret; + + ret = qcom_hdmi_8974_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_8974_phy_power_off(struct phy *phy) +{ + struct qcom_hdmi_8974_phy *hdmi_phy = phy_get_drvdata(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; +} + +static int qcom_hdmi_8974_phy_init(struct phy *phy) +{ + struct qcom_hdmi_8974_phy *hdmi_phy = phy_get_drvdata(phy); + + return pm_runtime_resume_and_get(hdmi_phy->dev); +} + +static int qcom_hdmi_8974_phy_exit(struct phy *phy) +{ + struct qcom_hdmi_8974_phy *hdmi_phy = phy_get_drvdata(phy); + + pm_runtime_put_noidle(hdmi_phy->dev); + + return 0; +} + +static int qcom_hdmi_8974_phy_configure(struct phy *phy, union phy_configure_opts *opts) +{ + const struct phy_configure_opts_hdmi *hdmi_opts = &opts->hdmi; + struct qcom_hdmi_8974_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_8974_runtime_resume(struct device *dev) +{ + struct qcom_hdmi_8974_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 qcom_hdmi_8974_runtime_suspend(struct device *dev) +{ + struct qcom_hdmi_8974_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 const struct phy_ops qcom_hdmi_8974_phy_ops = { + .init = qcom_hdmi_8974_phy_init, + .configure = qcom_hdmi_8974_phy_configure, + .power_on = qcom_hdmi_8974_phy_power_on, + .power_off = qcom_hdmi_8974_phy_power_off, + .exit = qcom_hdmi_8974_phy_exit, + .owner = THIS_MODULE, +}; + +static int qcom_hdmi_8974_probe(struct platform_device *pdev) +{ + struct clk_init_data init = { + .name = "hdmipll", + .ops = &qcom_hdmi_8974_pll_ops, + .parent_data = (const struct clk_parent_data[]) { + { .fw_name = "xo", .name = "xo_board" }, + }, + .flags = CLK_GET_RATE_NOCACHE, + .num_parents = 1, + }; + struct phy_provider *phy_provider; + struct device *dev = &pdev->dev; + struct qcom_hdmi_8974_phy *hdmi_phy; + int ret; + + 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->clks[0].id = "iface"; + hdmi_phy->clks[1].id = "alt_iface"; + 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 = "core-vdda"; + 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; + + 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_8974_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_8974_of_match_table[] = { + { + .compatible = "qcom,hdmi-phy-8974", + }, + { }, +}; +MODULE_DEVICE_TABLE(of, qcom_hdmi_8974_of_match_table); + +DEFINE_RUNTIME_DEV_PM_OPS(qcom_hdmi_8974_pm_ops, + qcom_hdmi_8974_runtime_suspend, + qcom_hdmi_8974_runtime_resume, + NULL); + +static struct platform_driver qcom_hdmi_8974_driver = { + .probe = qcom_hdmi_8974_probe, + .driver = { + .name = "qcom-8974-hdmi-phy", + .of_match_table = qcom_hdmi_8974_of_match_table, + .pm = &qcom_hdmi_8974_pm_ops, + }, +}; + +module_platform_driver(qcom_hdmi_8974_driver); + +MODULE_AUTHOR("Dmitry Baryshkov "); +MODULE_DESCRIPTION("Qualcomm MSM8974 HDMI PHY driver"); +MODULE_LICENSE("GPL"); From patchwork Tue May 23 12:14:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252242 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 D1C61C7EE30 for ; Tue, 23 May 2023 13:20:01 +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=ajaz5qberObTqW TAjNSSt8kj82H4Txh3Nw0zxT75bWo8F6mwP2LH2wdyz9X90ArYYz+4PysPG28KIqam8uVIcuOx3oD 5f00fYKoNjsncDgWiihPtDSTf2vBXqakMkE24D/50D7oSTDPHHX9A7ew+IqdR+Fw/N3giwJOMIqCu HVdLfX/lb6TWe8DyJkC2Uuhl9fQjzepD41UutLbMXb2ODckohDmJwxcyzdy3aJjkbN9Aiu+MwHfrN bmJedv9pwGmlQKspGfO2F2C71R2gJCXKkLj0HOdxt1feMsglZ4xI46EaooaetYKdY86ZjaZXwFTGX SH2bl04ojGGeW1i+I9pQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1Rvl-00AMRi-1i; Tue, 23 May 2023 13:20:01 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvy-00ACeS-0Y for linux-phy@bombadil.infradead.org; Tue, 23 May 2023 12:16:10 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=lwdtqkDXqK7iZxcIX1bEzs8baolumoX7/30733m/ZW8=; b=p/ijDyivtX8PS4VEiNgRTeLoXd 3yLRqWYN2yrC8WlVhI9QMS3jzrifphMcFrIx6V85KmU5uBLwDjN57KGLBC2DVS/SAajqF9FP+1OXH 81RVm8I0MFXqphlSrKgsnarvXk8PF3nUpL4Z1rfOP2kxK6ATrBlgYqkgfnl/9062YjomCb2mZ7nmz GZ2DEaXiJjefNpbUmrhjZ2cyt1D90ikYCDTzzSnhGU6o45o9RhUg2bIuwn0PsstZNItOmAqkHQmFF LIv2a2xI6lpOEZ/zGnnuKb1VZlNwTlfP+VSoIHGpNSrcEnevQ4wou1H0jBlBxXvS8qn9HTVetkAW6 jbO7MkPA==; Received: from mail-lf1-x129.google.com ([2a00:1450:4864:20::129]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvu-003VxN-0P for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:08 +0000 Received: by mail-lf1-x129.google.com with SMTP id 2adb3069b0e04-4f1411e8111so8023296e87.1 for ; Tue, 23 May 2023 05:16:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844103; x=1687436103; 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=xovt4aEyTZfHLuBgY7Lj6XlCpNIET84LYBDk+/oVzP755lUBkUTXz+H6yWz2r2Cw2U IB+r1bJB7dhEFU49rbl4eAsdZr98efw8Tfpn6MGdjG/QIcKYEViZoQL8G2YfISYdPR1S Pwxw+0/cK9OIcRrEA1vKeANcP8A+BaNRoTwJtIB+F5Ez8S26oOYFLFZOJJojsY88BbeM GNS5nvvM6ccaALPTO6+4ZuCu7UkWC0G3TDPFiXp6UMGrw/mXkJMa8rxWmKnR2xYYsTv3 uYQqAGNkgWno9cyaOslg7BQvNJK/cVw83NRJd59NVf7QGygEkyoXuI719WVBPTwyIptU Kd8g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844103; x=1687436103; 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=a4fiZE92cwW3UbRmIrnie41VVnNAJecUP0y9h0vh+ZMaMsn5XcTltDzmicAmVBjEZj zFqM0qLYHIqOZM4aPcoektpa+Mg9TqO2N8yNkzpMqZs369g784VPNjTotHIk5J3G5hZj tW2cqMQOm0bX7UJqa9sWibbPQrh6ag3vrJynGYXJaLrt+EUYEdnb5QiZfM5uRGD3Bt7t mD2iE7BcAd2htVYVaZW/3Xv+PKZ19hM/e11187nhI2peJLjz/dgJH3FwRGzr9NkfqLv8 x+Yw4GazZykSPs7W196WGBNDeD6eXMgd521GITyJfYsW36pM8ge1N7VuVgzuCZfqYjfc ib9w== X-Gm-Message-State: AC+VfDwrH/pwMAx3RlTjwR3Lipt6M4ARnLLw7hjRfXRNNc+RHpC3onyb A1fur/hy969fXuimUaaJbJY39w== X-Google-Smtp-Source: ACHHUZ50IH3a8pjiP+UBa8g9txbuBk/wEdojWdQ3Zvz9henvUls4QHCr5OhPT8MEUkJo4Z565Npxlw== X-Received: by 2002:ac2:46fc:0:b0:4f3:9a2c:589e with SMTP id q28-20020ac246fc000000b004f39a2c589emr4109700lfo.24.1684844103714; Tue, 23 May 2023 05:15:03 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:03 -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 08/15] drm/msm/hdmi: move the alt_iface clock to the hpd list Date: Tue, 23 May 2023 15:14:47 +0300 Message-Id: <20230523121454.3460634-9-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_131606_333655_2B925C13 X-CRM114-Status: GOOD ( 10.72 ) 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 --- 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 Tue May 23 12:14:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252251 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 4A42BC7EE29 for ; Tue, 23 May 2023 13: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=4g9yUlj3C9CZlxcf+ttR4X1jbBauNio1XAmvfws7/jE=; b=onqyvT3NifNlM7 cM2cLyR5QNvP/rI7vskBtLyZ5KlMw5aOLCXaz/L5qOQYB9YFbQEEa4r+BIlJkyKmGTiIIOkdVugUp iL/S20J0Lo70cqCZPv01gTaRuU7L1ksEVCrH1yn9ouo/5fw7dXsOVEbGJWQlWfzuOlwLrvZkauvvQ HxvDufwY7vrLMScCOvD4iM9qkc5Elo8+n0UTciLC3Wozg8Px46wIyz1wOolpryrw235L6eckuq+jN CD1j12AiBlloQ83IVosYVeNwZQHtmPfbKp7Gt2qR38VO7AfOK8Zw9LHDwYzDbJWlb0+CJKpK1I3KH Rh2Zzu7Jwul/ZC6We1QQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHr-00AOk3-2x; Tue, 23 May 2023 13:42:51 +0000 Received: from desiato.infradead.org ([90.155.92.199]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHq-00AOjN-1i for linux-phy@bombadil.infradead.org; Tue, 23 May 2023 13:42:50 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=8sn8z574aHDaIUAuI0kB4BeZ8f9+C4yT5HRFlvneark=; b=SE5wcTCUAvf9ETSXJT21tfBCef G2GIXBffnT6TGRLPKBD9ahTEgIXbTndTBPyOQ2vDZXSLyga9UL8K2ct1IGG+Q1scffQwbpXsbrDNK t98vaz/goYIXjxfeyvs3/yKk23N1mqBqTtY6e0OB+14VE9jzga8nt3lZTSh5EqVoWWFVoIscCxq07 ZSG0NbaZGpxNiFm63IP/LQjKQ3Rp9bmxzvCurn+nOqqB3PS/nr/4R0ln+ZO2ojZC2yv0e4tbjlFzc oH+P7eaq7O9g/hbJwn6Nj6eJsYCeh0YwTP4/O8RaVawZ4WHIsURCi5qQnYjAu97PDQpNsvC/84/OA bPtTZsfQ==; Received: from mail-lf1-x12d.google.com ([2a00:1450:4864:20::12d]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvw-003VxO-1A for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:19 +0000 Received: by mail-lf1-x12d.google.com with SMTP id 2adb3069b0e04-4ec8eca56cfso8037340e87.0 for ; Tue, 23 May 2023 05:16:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844104; x=1687436104; 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=NABmMvAZ5FpgPwHmApWhTM1W/+iMUkp+1qkO+tUHvEzrRYB0ZAEGnjRApYTtkLuBVE OxD0HQTsHG9G5jAxEL29oWUJwbPeB8rokvXtuc8d/AemolRtQA2MoR9KjzUC2eY4Bp+7 borkfxo88r013TLydToJoVCZnQjj2LQxaN9VahzMYF98QerMOpm6In4PKaQB9AiPcDpg mrxpsk8Hz0f7lLb+ZLroeYSY9mA3yZT8rCHIAudb5lruDAuwVgGIe6hC6bsQHVIP6+RA ADMvhRxtaJf8iGxaUU3PDO61rLJP9xGDaC4JF1ferMxze25QZ3XlVi08AtWVruT298Ib Qa/g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844104; x=1687436104; 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=l272RbqrOkFWb69X8MCK4vO9a21zECe5hL/T6JtSUGvIKibz5K+bNOTkbxDMbR/t3B zdOAzVdMoURogYv4mdh5irGkpoLU65zZL2nxAePPgP8MxfmoqwJsdNXnUP1bC4uoQp2H Lufx3tdHsKlAW9L5QRHGBbl8czLO5HAU2TFI8CsASdi54pdOHWGjIDO1zgyeTQrx0c/g qw+HSDtalL5sF8v3JsuJM/seZ6U35Jhhcg+neVmlrHIRaHZtX2PBVHCJ5uzl/52rt+TA hW+tcbShpCR/8Hf9uchGOVdFRcJXHDPtPY5X/DgpUzo12nYHM4Pj5E+/eIyZGM/l8X4V yNkQ== X-Gm-Message-State: AC+VfDxW2gestUmPBlXqfeoa1FlXyJi5GuiltXNOGrsBUC8/cZesMi4M r9tZGQfRDE5vI4J0CSSiPvdj4w== X-Google-Smtp-Source: ACHHUZ7OUViKj9nWvPtND4JYYFWZ9ax9Hta1Ce9OP9c7+jgaorTGGMrTsHMFswURqp7Tt0PaOAIY+Q== X-Received: by 2002:ac2:5599:0:b0:4f4:1959:b729 with SMTP id v25-20020ac25599000000b004f41959b729mr2263490lfg.68.1684844104771; Tue, 23 May 2023 05:15:04 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:04 -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 09/15] drm/msm/hdmi: simplify extp clock handling Date: Tue, 23 May 2023 15:14:48 +0300 Message-Id: <20230523121454.3460634-10-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_131608_770297_86B7F3F9 X-CRM114-Status: GOOD ( 18.86 ) 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 Tue May 23 12:14:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252252 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 D2FC6C77B75 for ; Tue, 23 May 2023 13:42:54 +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=bX7kbUgDj6rnRE 7wdARFqAWGJqqnKdyrDElcRDGwiLeTiEFAslcMRgvKQkEClEik7YttQHoNJBoHzvms3H/g0uuomTi oAwV61UFXcQmF2sFq8zZLliga3U7OVrfA5n7aK76NbBjaORPsPerad2z58cWRbFhOh5Cl/mZ+nMBK gnUtpT28tmizdufDJb34OJYT1ENIYqzObWf/R5S5eqD7Li6c8JYY32v0cCUe/t3W16OXc6xwqhHN1 DTCwL81Lr5pGkLuu7JPBnelQK7iA8fqgcI14vNtyF2M5HxfiOcTtY75xOHne7h6cXf3IaWLRNWuoL ksIwuVXN4DPqL2ySMjIQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHu-00AOlE-1k; Tue, 23 May 2023 13:42:54 +0000 Received: from desiato.infradead.org ([90.155.92.199]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHt-00AOkw-2i for linux-phy@bombadil.infradead.org; Tue, 23 May 2023 13:42:53 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=HlnLygFYYtSxoKEaC5DFXDBhNuXumh16hVtzEXEvSec=; b=RdDaGOni8cRNYXdUp/hB8Elq9k FQVwkRCt/vc4GPAYk7ZuuYjnGrgEM3n2AdCrHlTpc50YgfOslGo45nhz6axNr8XNAePU6b1CEuOVY eE/hbluOJXbs/t4+Ar25JMN8z+PUgKxX84Q2yx6lpImM6zb9XV+KNKxaBRjFCUkEFYXhCeLQLteyu mOl+q1z9DZIUl0Lx9Yt6sVXaN5z0it59bl5oOAxcVEVliBct6LdWe00KihEPzf5Ye6DHbqMOKDyrM 6c38STs1l4V2TutBAEJLCN6bJbu1NjvRxYyyIQHHrL8uDzt/fWBPNZ2hR1lxIlPBXmITWuAk6bVBX qLbFVvSQ==; Received: from mail-lf1-x129.google.com ([2a00:1450:4864:20::129]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvu-003VxQ-1n for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:09 +0000 Received: by mail-lf1-x129.google.com with SMTP id 2adb3069b0e04-4f3ba703b67so3470045e87.1 for ; Tue, 23 May 2023 05:16:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844105; x=1687436105; 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=SL/WVHABS704+8O+JkeKaXTNIjTPa6bMNxe4CV7AGXBoUs/Jdt4ceFX7jQwNDAyN1+ BJOdBVhocMwX+gbdjC8AlbYXA9mlNGWCdJM+iikUuY1fcz4I/dmwnnMiBgAXlV1S7tXL jfviyHrP2KDMfy76e8Lg1peoMrw1hq/5Ocuk0nQ3vXbGRwtzQf8YiTGt0icIpgU0fNWQ iRUecbmN3nbJywrZahJkGoXLhrzzXS8TR5ngxOFwOZcBG1P36g9r3irNgFshMUr9qw7x xL47QOII4bg1JQ5vU0zlR9msEyIZfYCj9nDGwfhp4y1OYpJtNIXrATNNec4qpF2HkvxP JrJA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844105; x=1687436105; 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=JThhqTOMvmhRmvZwW0gZImfhqTtSe9p8Mg5o9VuirgRurLpQTct+HmVe5S0Eu+DjOg V+ooIX0gsGnEF5eLEA9I/i+JIm3xlcHVFOqQRBGcxFkRJsuWLTQ7xvKj8NY/0lvU1Qh1 R9LYKQtZ9HWVxyCuYR/yeGJTuyt6UKA7MCFKDZ302XNU79vp1EyWOQX6nbWnnUxkIP0f +y1D7U+IJ/5Ws0nrWDiTmTNcEeNHeV3vReWZ5a7699F6CIpl1BZmnoCi0pJRC+p2FAnI 5YpRPjKxqkmeBPDfeYAfeFsaW+UjVAQ7GKME3cw/bAhkdnVX4zx9GvCzdPDNLrzRCW+k SZzg== X-Gm-Message-State: AC+VfDwwuABbQXWo0pwxoS0wyFdieP1b4/s+KX10i0h4U9rHj+tyEozg lYX98jswD9pL0xjcmdTWfVoMcw== X-Google-Smtp-Source: ACHHUZ7RIvGjdINojHjJ65ERgUVxZ9JLqK/cT+DIqTF6C4Xu/7dDxF+Uml9xZ924hzI/Ju9SUi5sYw== X-Received: by 2002:a19:5213:0:b0:4f3:a0f5:92e5 with SMTP id m19-20020a195213000000b004f3a0f592e5mr3853326lfb.31.1684844105762; Tue, 23 May 2023 05:15:05 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:05 -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 10/15] drm/msm/hdmi: correct indentation of HDMI bridge functions Date: Tue, 23 May 2023 15:14:49 +0300 Message-Id: <20230523121454.3460634-11-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_131606_683491_DA8760CB X-CRM114-Status: UNSURE ( 8.96 ) 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 Tue May 23 12:14:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252254 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 83F6EC7EE23 for ; Tue, 23 May 2023 13:42:57 +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=Nawf5VJXLgQrbs HPPKItpyetcJR3jYAm61ZTHUG4F6iFbkWBY3VdVOnynNSyJ98lyCFOdt7iQfjZ2AjiBPJK1RCo9O3 1C1LXW7LBijCl5c3q8OYoDyZCjY2tQ3xYCpx9bvFMyn2oaGRj8sLdDVgEOyKZRz0akTo7gOd4XXoT 5xk4OxfcHMKxpB2PnKRYgywvsBp6tAXgT5bXsUlZAf9e8NR28T7RWxOvst9oEjjrcrIV6srU5plq9 4PZsxgC7RAisU+2cfMhI8CpPOzB/SwHZlMLBZQCNIlLRUkAqaIuQlH83U8zWMbdl5eHH/koL6CE60 69r3JOyWn9/ZzAZj6ySA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHx-00AOm6-0b; Tue, 23 May 2023 13:42:57 +0000 Received: from desiato.infradead.org ([90.155.92.199]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHw-00AOla-01 for linux-phy@bombadil.infradead.org; Tue, 23 May 2023 13:42:56 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=JRCcVx5yqkWjx+j8HRIisuUziAvNRbEhBQXvfMXuZd8=; b=A4e2vcHGmeuwyjj+kNDatSUmxK RyWTPYoywRMwI8WKT6QdTk1FQOXas8TjMNs6vB/fQwruuxAT9osA3Mg3un3P3J7YFgy9FS7FWm+Zs 1h/52+YDwmM6ol2xbvtze+QVCKxwgDHs/KiFyXgSShq3wkARZ1u1GRnOIv5MLDNVT8qz3ASF6RUNg Ch2VOKIAxLQhzZCs2A0Zx5hBzb/tR4TyjCidcSS/a046YVkA5mcPy3RioRxMM3/qykmgr47frWDYL tQNvWcIk8bpvF4vATSDbaKM5jcCMU5ABymswMOdY1Gj50tGA1GEEAS7ZBExza5kUKgPTG4OxKBtsi BTWIEelQ==; Received: from mail-lf1-x136.google.com ([2a00:1450:4864:20::136]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvx-003Vy2-02 for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:11 +0000 Received: by mail-lf1-x136.google.com with SMTP id 2adb3069b0e04-4f37b860173so8028151e87.2 for ; Tue, 23 May 2023 05:16:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844106; x=1687436106; 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=iJC8cOHW0X4kvVER7XhLHnQWxkC+jbzri8i0MSx1FWzm1j3TgBoKJEus10S6ncpEAK DZHgtbe5CSmiS1kT64zbTG4hR6qrLUvhfvpstMG0lUjREEOQbg6NnSHZLHPM+cx/8VZa 0k5wf8cRNQEmr3gnjDbgqS9mV0/+AU8YkvOYxkQShYze+C455NHKiS3vFFgyBRYjzUp2 ETvYqSNmMRncJhyLTNm3pI2nWj3zzRDQaFijvBKyBZQtynIE90HbTb4jtKT9xCF54p3G ReLH6SmJ7a/4A2aOI4UaYI4RKs4PLNkiEM0lc3Q8NK/pVbL4EegKUnYepXO+PObstRho BVzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844106; x=1687436106; 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=HPUBLCkzF9DAILQqbhH5dpScTvVcvvRx2Waa3jBN2hVpq40ZcMtML2ENIGIKnnoiJc Mb1L4NHwOUbHRI+Qd9Xsx2qNJ2pMCLocp+G0s+yfx+GacRf+h012UULQLahdLgGKnpVe h5JDVavQYJUfyWaTMoDdbkLItBhwlhDHpqrYXSrDNEcXnyZ3s42cPRSphxsssCT3oGF3 Z8nHgQQmPGOGA/vXW9ObrBZIPfG5whSRM/t0/EGVXnY0LIr5YkP98M5d2TG4IShY8QxO ayBOdCXk1hl7rPKKr0DQHvQ0iNbG92gKa/mcI9obR3Qv9sSzwbcnWFy4Q8intt7lRK74 ShSg== X-Gm-Message-State: AC+VfDwO37gyCsdey6aYYr2WnTkv9ttVU82XZKqSybYfbZ3DTmKJQH3b 2O+M25KweEOtxajih7r/WvQjBA== X-Google-Smtp-Source: ACHHUZ5vlFenZbIB+tk6w5Wm9JFARuGQkoC34ibzwpD/wshwINCjNKESlnZMABksaf1XUycVFfSF6w== X-Received: by 2002:ac2:5a0a:0:b0:4ec:a18e:f985 with SMTP id q10-20020ac25a0a000000b004eca18ef985mr3960269lfn.13.1684844106606; Tue, 23 May 2023 05:15:06 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.05 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:06 -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 11/15] drm/msm/hdmi: switch to atomic_pre_enable/post_disable Date: Tue, 23 May 2023 15:14:50 +0300 Message-Id: <20230523121454.3460634-12-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_131609_382387_0691FDE9 X-CRM114-Status: GOOD ( 10.03 ) 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 Tue May 23 12:14:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252250 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 80BC9C7EE2E for ; Tue, 23 May 2023 13: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=HHWNOUx9jKAQQUhD8gdmNidl4tOASa9uVzHeepvKGGg=; b=j+D0Stc8swBAeN hPC1VwjLxTdgpyLahQBtU6DN0JoEkikq3nBlrUbq3fA8dv4wuxeUnHvG9zZg2C12AAlpdbHjqjyGK ByiG+0gA2A9yQMJ43tH77uKLdhtnIx+ORyTahsKgUegQUGGRHbkjRSEX4EahJkNUkSGRg/C5jjM+v vjvZrgPpW9+bfJV5RSg+s0xzP3KuTJHBO9QMMLeTvMkL18xvoHCynsxgLnrvGQYtgnDsq8q4rTZpe EoGsV7Nve66RLIcLWHys8uGMgdew2CI9zh/ximT/wlRAXJlQqANOrEhuS9Q6YCDQBwOsjDhytD1nt 5CH03jDhqqLnM6mIFVog==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHs-00AOkF-0b; Tue, 23 May 2023 13:42:52 +0000 Received: from desiato.infradead.org ([90.155.92.199]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHr-00AOjN-0I for linux-phy@bombadil.infradead.org; Tue, 23 May 2023 13:42:51 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=kMftiAUxeR8BPoZkZvXeNvb1WLgqdhL6DsPjfLjpExg=; b=bixzUOGXX8NJ9Z31bfl2etglB9 Gi1QB6rd8hRlGPCzhLxF6tS0etwnAvCMirV3d2Hfb/X6YqFXuq5bksS+uFiemoAr0BBQFc6LifMbA qZmrZCwwuur/2B5TWMqO4pavH0ZyJNADYZ3JcGktGBQ184yJ9MUhxXdve9HHcVunAcP8uVlWRw2zp UUuU5cMOO3FHorrN8mkZgB0/83H8ByFXSilXLmlXIbAcxd3SnQmf8KbxEk+Uu7xApnarB1Vgjg1fU mXMEIWWQsBpswv7lWVMqtmUiZbMyQkxyKr6FlfWj5LDzS14cEAYqfh+Ilq3Sgk+nJipRqPSI4ZL7Z WoQ7Jo+g==; Received: from mail-lf1-x12d.google.com ([2a00:1450:4864:20::12d]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvw-003Vy3-1A for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:13 +0000 Received: by mail-lf1-x12d.google.com with SMTP id 2adb3069b0e04-4f3b314b1d7so4353578e87.1 for ; Tue, 23 May 2023 05:16:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844107; x=1687436107; 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=ETX+jpQh1MkS/oEmbkm1RFkjIuPTjVkoKZKMQyqb44Ujy6MPxqvuFFRR5Ozv1N0fPL IyRB8EvrCQUBDzkstsPROcFAYQ7O6UofNHKb4BgRFu8BpUTjlKD5eVx0dhx3mVAHQr+e ozCd+EVp6H33iBFNoDaAnD5i2WIfckcUzBL91i4FYMXFEn7vvogAnsjs9zn53E/hJkK3 LElwG+XWm/cAFZrLhqcdOPkbMVV/f7Z65RHR/MDV4Mm2ULcy2ilkir4TjCbvjfiTc8iB BnpqO61RlUfjK6tn/iGB7tqivbti3PaXHqJ4yeetkBiZ9/Exc43+iHe9sV9rqRdhlFe8 Px/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844107; x=1687436107; 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=Se6yo/3aDGeZmV42SarTWHhnsCeZA8ZGroHzpDTY4wKbJ44N1RfGs0kILUN2ta22vc rf1E4vF8rpG4nk20E8B8s/eVEkRbSYNVxf03IDDQ0vAc/Yt8c12lvXUYN3XbMSOeS2e7 mlq2uKw7Z+n3ACcjjKHuxztY6g1YaNjF1bKe+Nk9Fu6eKHY3AkTG5nvPNBS4/JOuX+zX 7UlXE6d6K4jkylFhBiN/qIHoUemLQE2Bh+zW75MeeiOJzoqbhkoddG9JnuzXrB2lugid 30xDdM5xxRU6yC+BSLbq0jtRZJBrc58Hypt4DstzYAvhY6OfYq/SojSWVfICm6Feun9h bJUg== X-Gm-Message-State: AC+VfDxlgTl9/2NBah5Ej4UuUrUzF518bfWZaWG/nlTu6TM9Viau1zbl DIqco63L6IZKCqoQOtIkd4DpMg== X-Google-Smtp-Source: ACHHUZ43GR6mi7FCfEihpvwLYVmk40w1hC6t0c87laL1uoecXBbBd/pseUpVwOps9C9xtYnTi/b2Gw== X-Received: by 2002:ac2:5fae:0:b0:4ed:b4f9:28c7 with SMTP id s14-20020ac25fae000000b004edb4f928c7mr4155100lfe.6.1684844107381; Tue, 23 May 2023 05:15:07 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:07 -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 12/15] drm/msm/hdmi: set infoframes on all pre_enable calls Date: Tue, 23 May 2023 15:14:51 +0300 Message-Id: <20230523121454.3460634-13-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_131608_723083_6E562451 X-CRM114-Status: UNSURE ( 9.48 ) 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 Tue May 23 12:14:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252139 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 B3656C7EE2E for ; Tue, 23 May 2023 12:16:13 +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=gukc9rEloLY5qF XRb3c1xymnxTLANBg31Gk28pYhX9SIuDGl+UMDYWAmLvfMjfAPynlLHMoJK1eWdEeRCfYJe1wSZxV 9La1GmyKXlao5jiWSq1FJL6XHVFdcscn1hPGsjSQcTfHxYtB4tm4h9w8Q+sF9B0e3j7wAwn54iCbR 9ZquMTopmF16CZMkcE3Nhd1EQoJvbekoHkpHdWmRaXjBLLMc7bzettLSG9K2mWascZS7Iq7meHcAg /gosv/membs5qK/V47SyYkG5F1BeFeVGsNXhnOwt1m7AXlwBDYpN7HvUXjBe9KH/iq5OBjgkFRb5g Kz32QccuVuLtlAMMPxzQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qw1-00ACfp-0V; Tue, 23 May 2023 12:16:13 +0000 Received: from mail-lf1-f51.google.com ([209.85.167.51]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvx-00ACeN-1Z for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:10 +0000 Received: by mail-lf1-f51.google.com with SMTP id 2adb3069b0e04-4f4ba3e0b98so1061616e87.2 for ; Tue, 23 May 2023 05:16:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844108; x=1687436108; 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=cLSxKqmrFivha60kjqdkAq/2GXt9zXw+KGWMkRMtnGfSoqc+rEbGIY9SPFp3raR+tL Fvve4+1DQYi2PZ2Uk+JYU1ZJHEpz7EtzCFXCqQ4nutMAoROslrRjO/0UMoGpS3F3PoLF b66oDK+O3wB+Kad+4bZv7mmK5nHfbLakmzppjNLiji1FtxYNYvhmsFa41D5FrKjbmdOp rGkgZ1zXw6baayCE5w1FciCQFkd3PAedqX2dE/XVUQBO6CdcCCjqBs+KpHQtjGAiY/44 fX8XjppzEo8N+XyYR0YxjjNW/xd/cvw3Ha1RuV9t1+FNXekSLqTGUystJEhzUatiIUt+ HICw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844108; x=1687436108; 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=h5U9V51aZN2ySQ+aJVvjSHVl2sU9iliD3yzGAdlZ1JydjJGsidQsYV8ugt9zcwj8fu QQ2n43Y/PQ0iewI8WDhuh8o/7dfUd3MIFBpZcaK8wXh1AYvtXdrdQcY23IlzYv9wR9pH JuXsORwtjGctw8rDcknVvan2Pzrr3skNWSRooympbvEp8BRJfox5m3mLlcg7eWTPTioQ 1CoMgFixClQmxaFSnW9UwVaiwo890QkvNC/Ty/tbre7r2liXLJwnfjh2sMVGoqQzDYnn 5aeHgaHRG0atC8lwwnpjOKkUGWgX7jQP9y+EKeprTONOu+yC/OTTqf3Fsgd3JXQiMLcq 0I/g== X-Gm-Message-State: AC+VfDycfVU0ZOEwZEZLBUI70ma7ujJmtZv7uyUdUM6+wKSH1v4G6dos +vFisruPMF3RN29Ky8PVs7ibwg== X-Google-Smtp-Source: ACHHUZ5WxYFiA0x3xgvZXvUWQdi/r/0i5DuVqgDFMuE7nU4AygQeYTf069U5/4/emwtjx39IRyOE/A== X-Received: by 2002:a19:7003:0:b0:4f3:a99f:1ea3 with SMTP id h3-20020a197003000000b004f3a99f1ea3mr4008960lfc.32.1684844108297; Tue, 23 May 2023 05:15:08 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:07 -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 13/15] drm/msm/hdmi: pair msm_hdmi_phy_powerup with msm_hdmi_phy_powerdown Date: Tue, 23 May 2023 15:14:52 +0300 Message-Id: <20230523121454.3460634-14-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_051609_525402_782ABC65 X-CRM114-Status: GOOD ( 10.71 ) 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 Tue May 23 12:14:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252249 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 EBAC1C77B75 for ; Tue, 23 May 2023 13:42:49 +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=DOXmsZEN3RVgZ+d8ESFWaHlSOLw2NrbEt/Ua1vuabdQ=; b=Q8m+tncaOFyyto RXG2MfJjYmYWbUntRBZbRuHzXZe9qE6Li231GKhHdhIEEywWpgXiF3V7S3QShbdrowD5bVWn/YEjr w22m3+CKbq63Yuh0pAmPxpng6GhwEhmCaeoNR141zkS74OmH1TsmBA7ZWG8ffDuBIkljaFDF68lex bdz9Y/EMTydsAStk+PHE7vL0u6NDGV1lmJVfYwDa8IvqLxJDsQFHuoc+gFMe1zV3XjVnXngB8o5DU Xu380rmXlaCtQ+1YgTx/8nyBolMejnT//5YRQCF77AEYovxp/vIz1JzVt7UIfQyT6LEGJuhyz2gDZ W+5OnubpuEWNTm27bujA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHp-00AOjF-1q; Tue, 23 May 2023 13:42:49 +0000 Received: from desiato.infradead.org ([90.155.92.199]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1SHo-00AOit-1e for linux-phy@bombadil.infradead.org; Tue, 23 May 2023 13:42:48 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=ViKI4t0SKXO4iiwXWVymsba+N4lBXVYHQrPxEsEaJls=; b=jTelHnG1LSuG6wOuhwgJpzK06j sp8UneIACYfF7QaH2q+C8VmAt6NbjEMyLh2XYDlB9Kn08M5B20nTWm8uBcpYs4DnJOHRtinb+aXp2 PWiqejYHhQWJvXbV/FBucsmsH4BowaVsXSj69vrYOzgWBs1rKN+vS2GwYYU89aIKx2z1Rk3gJXMUP xIIC/MNiUV7LwpTgtZAyTMU7mO8iWbFHa5B2EDTBUAZ2/zrt7yAVx1BtYu8ybZLZZe42wPVL6v4d1 ea/0b1Wi6N8ZxPC63oteZDTV2piJwiV3zl4EmUFOeO59iZoJZ6FHox3huSKYJiZXIv4ionz+OCnjj Y626OFfw==; Received: from mail-lf1-x133.google.com ([2a00:1450:4864:20::133]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qvz-003Vyn-2E for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:19 +0000 Received: by mail-lf1-x133.google.com with SMTP id 2adb3069b0e04-4f3a9ad31dbso6015658e87.0 for ; Tue, 23 May 2023 05:16:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844109; x=1687436109; 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=ViKI4t0SKXO4iiwXWVymsba+N4lBXVYHQrPxEsEaJls=; b=Hsl2Dv5K8URQJgGAlVolkrPOvDuRpqL62TFPVlDB53+F9WE9D/drEKfl2r+9GqNnGN ee1EtSbURM8gEiE/RN+3ewBCdGRj9ZA3Y1O1ksHKphi8etJTG7h25CFhqajrItm2oGsS XkMmgPfgEWB1tbPjUUdPQCHY42xnpuYymN1y3YgFLRCfsL55qiqoPmSw686bz+hSPsz1 pWM4PB+EPqBtp4/bS5yEy+musakvDq3LFX7cItLOOVKYOzTBocKTu1meCTFUuArSsnXA +dF3Zs5Ug623PxyQ/w2ReDUSIFAHJE+QYV3gUjzrv6nYYBObTOVNspa09eUIz2Nqx/xV Ibog== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844109; x=1687436109; 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=ViKI4t0SKXO4iiwXWVymsba+N4lBXVYHQrPxEsEaJls=; b=LdP/pqEZWbuqKq11LnPql6nElVuh2orv2iTnpKy4hSFpunbgX5juy/zc39HJuz5i2q ag0cnXf6QSbbd6UzJyw/AP7LwyimoFJ9ehesvMRcplbH0ZKZ/BvawQb5ZbjxVGesDOw1 C9T3+Qrxp+wWlK1JjDxaQ92VkoetLbfA9Wq56jhdie0pUqQc1eMYPBTtUb6G3EzXlGS0 Dwk5DbbmuF4ajmnyRt8BQDKAMTT0nnSOOiLkPRQNDtRc5Cx4EvVzjjNAh+VV1uMpuIRL JVnTht3b4bc8Pu3QZp50jEhlnlmD9aYItwLE1MyaHnC23LHYmjL1oTgYXiKx8Gwrd3tI mosg== X-Gm-Message-State: AC+VfDwyLzyg60sus4rKn3FKEj9syJpjKINkQz2Aa/Ak4Q5oBnDoSlYh hxh+rT1cTYClr/FURPBLIijJpFQUIEX8dmXplvA= X-Google-Smtp-Source: ACHHUZ72bYMSRyQRFv584+HjvWOMYcMAfV250O04MsDehMJj5/+bBjE0hTMbWWYeWlTn2BUzHRDjDA== X-Received: by 2002:ac2:4299:0:b0:4d8:75f8:6963 with SMTP id m25-20020ac24299000000b004d875f86963mr3607315lfh.38.1684844109428; Tue, 23 May 2023 05:15:09 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.08 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:08 -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 14/15] drm/msm/hdmi: switch to generic PHY subsystem Date: Tue, 23 May 2023 15:14:53 +0300 Message-Id: <20230523121454.3460634-15-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_131617_478249_175F044A X-CRM114-Status: GOOD ( 21.13 ) 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 7274c41228ed..7be487002816 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 Tue May 23 12:14:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13252211 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 50D93C7EE23 for ; Tue, 23 May 2023 12:40:13 +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=UmfFI1YaV7D9RB ORptHBHG4ro3EfWaqAi8Th6iw8gc//GNwBNliLLIgr6+ZdLkyTb0wCGWxVVAq2M0Ug1DZPG0GtZ4m AGmCZI2mPc4LpRrrNz/mYZ23nbjLhA629uHLv+9dyu3Tbh0lwgVpEDgjnFuRqKLlW+3+bkzU3Df3J OM74RfO1Dmcc+cbw74TyAKadN0CtuSKKlbvCFRBvavpcSZJkfXK0GZFcaIxgECLvEFWFy1hs/Wm1K b4Mn4fGsZMqmf5GhRcdhoX9aUdxMuFMAVtU0xkozErrN3bdsfWUsVOiawSh+MNstUk36+bQYtX7Fg DAbErhCQHv7tvX3Dd19w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1q1RJE-00AGjY-37; Tue, 23 May 2023 12:40:12 +0000 Received: from desiato.infradead.org ([2001:8b0:10b:1:d65d:64ff:fe57:4e05]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1RJD-00AGjA-0E for linux-phy@bombadil.infradead.org; Tue, 23 May 2023 12:40:11 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=desiato.20200630; h=Content-Transfer-Encoding:MIME-Version :References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender:Reply-To: Content-Type:Content-ID:Content-Description; bh=XP9B90BXE/1rxd7cjE/PsULeD4GojoYmATkXjbj/K4I=; b=HlyE9MmtA6qNPphk7+/IV41AeL btlZ2J20cvqhVSBNN3ONbbAXtDFNN+Tl1K06Yg7zw83HfXbtnPTLPHVit80HUAyqD7Dfvuu1XE8kI IuwnuMfdFOEnR5p+BtUW67tLkA0uZTLpNklg9xE+AJSqQxN12xF3jWdaokge47GrDHwHT00ngk6z9 SNmGZ32E4QrRxLt8AbTp2Hsiw++7JFHUH2e8h21JY1W8UeNQJM661uHthNSAP/ig8/uo45UvR8fNp PZAg8FdRj094iHLw51vkbfIHzU0UsmzpO9xzyr5kZpHXsukj8VW64egA38Yn4jDbtuJ3Am0lt1yQ2 xF+HnLJA==; Received: from mail-lf1-x134.google.com ([2a00:1450:4864:20::134]) by desiato.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1q1Qw2-003Vyo-1n for linux-phy@lists.infradead.org; Tue, 23 May 2023 12:16:23 +0000 Received: by mail-lf1-x134.google.com with SMTP id 2adb3069b0e04-4f1411e8111so8023497e87.1 for ; Tue, 23 May 2023 05:16:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1684844110; x=1687436110; 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=lBqO9D4h7iVEAt5lPK5iUp2J9qJGJILxZhuPMKY7VCqwrIVV8GWuMDPe016yubim2l 4fhE3NiHZiDkQsylasOwzNoal2f/7GCDkXa103xjVS3yTR2Zq5OhCwl5klEgMeWv2bzF RsD+wLmqNlFR0OMwZ6rudOB3009HbnA1+U3KsrKuq/WbNjvFfMHn/quDY+WSi2eLLHhr 68kThda9D+s1IDnuFGosQ2Do+tiGq9rBzOLBMbVpFRqR6NjAj2dxW4pzyYyXKl/YAlGc vLXuK4uq2iLrfHX3b5f/vHJrGD+llfVQG024R8VhN6l9WSkcVWz5CTd+2NPe5bYA4rmz MwWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1684844110; x=1687436110; 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=KKxgpF4nrBlsYsnrcW++lQ93JwJXlT1oiCYFdT0kxYErDmAWj6pHIZFEF69d7i0m9c 35Qrw8z0pTGv1GO53jqLxa7JLP3vI7mE31oJpDzC/hAvw/Jgz+AHfgMH7nPWwpam7Z7R ZfeJGgB7oc3okWXGP51d+8DaELotau+qkMvqJVoO/vAMJbbaJ7EeUNOsKkbewncZeecj YzFCjfAyFDPPBVC7hVfN0b5rdNL8z5jouXE9MyiaSfZmvZ0XBEg/czx2IWjF6Kd1Xbjo Wmmz/UhtfdixrqK9YlxHi38GiDR+J1mYoisJZd+fG4JJqcd6WuW+8wE8i/1txKAIrKV5 ok9A== X-Gm-Message-State: AC+VfDwXH5sw5nuzKrsDaJwrmrHz8jJZC58LTQ5aRcNowOUO7tAVrMqP 4+906fvyKJxk8Yd9p0cnqKzACA== X-Google-Smtp-Source: ACHHUZ47UGwssKwfmocME2dkzwwDLG3d1DVLr++zsbLo/zCWz32HHwvKaReGmAN61haa2bn5sKvh8w== X-Received: by 2002:ac2:4c18:0:b0:4dd:9fd8:3a36 with SMTP id t24-20020ac24c18000000b004dd9fd83a36mr4279249lfq.1.1684844110343; Tue, 23 May 2023 05:15:10 -0700 (PDT) Received: from eriador.lan ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id c26-20020ac2531a000000b004f160559d4asm1319616lfh.183.2023.05.23.05.15.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 May 2023 05:15:09 -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 15/15] drm/msm/hdmi: drop old HDMI PHY code Date: Tue, 23 May 2023 15:14:54 +0300 Message-Id: <20230523121454.3460634-16-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230523121454.3460634-1-dmitry.baryshkov@linaro.org> References: <20230523121454.3460634-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-20230523_131617_687363_2ECD0ED4 X-CRM114-Status: GOOD ( 17.78 ) 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; -}