From patchwork Thu Sep 28 11:16:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 13402733 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 45114E732C0 for ; Thu, 28 Sep 2023 11:16:47 +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=xA5KITIl61s2Ld2erYQuyP7/K1gyfTI1VxEmPk5VZMU=; b=hT97R8eWwxC3+j ZQwY/dixUDuDTA3MbgMYe3W5k2VYeN0dK50IW42HzwwDHHsRG5e9fwxeddAutBcZr5hZy2/HehjqF krSDn4WS2/QVWUCeKGpZTRQQ6voTzCaAqodY5Q8A9SnQon8PFHDwpnS5mFV6MlBNEoJ6wRF8012sM KU3Ffpv7P15J3J3MuWvg2jXaGMZnMbkRHch4o4KSHIpjWI0HCkRlvjM0zNzjmL4ai3QjA0AGRO+PK FNTHcyaV51F7gkghL+P1SfEeB2lAtJv6Mm0qADN3i3fcpBKXcGoY/P0vLhhQ3UDQ6pyNsrsXxGtQi oRfORjioEog3nrIGlx4A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qlp0g-0038Yi-2Q; Thu, 28 Sep 2023 11:16:46 +0000 Received: from mail-lf1-x132.google.com ([2a00:1450:4864:20::132]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qlp0Z-0038R9-1H for linux-phy@lists.infradead.org; Thu, 28 Sep 2023 11:16:44 +0000 Received: by mail-lf1-x132.google.com with SMTP id 2adb3069b0e04-503056c8195so21191102e87.1 for ; Thu, 28 Sep 2023 04:16:38 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1695899797; x=1696504597; darn=lists.infradead.org; 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=WaqYa1p7vqN61Nnmz1mMsVu16pc4A060DpWFBkQ5zwA=; b=eO9Zur5H4tmuJjeOmZTzTQLTprwHvSkeIKBcaANmOoczk/MNBOOYQzP9QGkWqPkvPg mMaNi2VXG+TcIQ+lEnKe83dVrFnghpE5wNBvAB2E1Kyak0Dj1XVf//fh3+uRI0ivffG9 4bMvw++c80C6uA25Ut91B6429tDzF6aBWFy5JU8s2JPUIGTUQoQev1er1KyPeWaSd3TZ 9PR/WCg819Oyt1KqlYUFrpv5VJtUqB4vR2IrLNCVf8oZlQOw+usvAR3RF+OGVUgAon9n ZgjOwHmrSVPusFvLem03P5uiOUMYD/rPZn9OZ59FfvSE6MnkFQaIVGINO6ZFdGW/y7aV RvGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695899797; x=1696504597; 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=WaqYa1p7vqN61Nnmz1mMsVu16pc4A060DpWFBkQ5zwA=; b=GlCTmEU86H8MuPQitq5Ath4Z2TBN+Jdog+wyUnHzxN+nRk/EFW7KTuLZHONC3OjVf5 f2ZpuJU3kYThheQZWxWxueqmxWtZczyCTQl480b0NhT+mjNVODTbU+me5c3JPiMPA3ut UDBAC/vLksHEDr2pLoIg6j6/x0GzCrl1TNyvLQxuxiHsUweQHTn4pKB8DJjSG68Q5eZY hmp0v7PVvGHH98X0eJCHGnzB0NAJMv9RicDBOed8zBONWPRrjXpR3PC3HyqK4XwLhJ0j pfnOIYdm8Bi5Sz3snrDSWmg86rUPiosC7xmgc/xrHkM7PfyRNTqPMdlAWSrytvj3oJuK efAg== X-Gm-Message-State: AOJu0YwJvl3a6K5Xp2OEV6GUL3NtPXXICnPHQqIIYT62PX8AwKofHyD+ +hG0tGoQEw1oA+omnFadohb4yQ== X-Google-Smtp-Source: AGHT+IELwAXbwNWKBM1QMtP91xkOdmLsDx0Ktv/JYhcUeyUVfQBYJWS7Wq0baHGU6E4lXOEPSArOwg== X-Received: by 2002:a05:6512:3c8b:b0:502:ab7b:e480 with SMTP id h11-20020a0565123c8b00b00502ab7be480mr1068705lfv.36.1695899796850; Thu, 28 Sep 2023 04:16:36 -0700 (PDT) Received: from umbar.unikie.fi ([192.130.178.91]) by smtp.gmail.com with ESMTPSA id j18-20020ac253b2000000b004fb738796casm3086623lfh.40.2023.09.28.04.16.36 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 28 Sep 2023 04:16:36 -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 v3 07/15] phy: qualcomm: add MSM8x60 HDMI PHY support Date: Thu, 28 Sep 2023 14:16:21 +0300 Message-Id: <20230928111630.1217419-8-dmitry.baryshkov@linaro.org> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230928111630.1217419-1-dmitry.baryshkov@linaro.org> References: <20230928111630.1217419-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-20230928_041639_443553_E5E295B2 X-CRM114-Status: GOOD ( 22.53 ) X-BeenThere: linux-phy@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux Phy Mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-phy" Errors-To: linux-phy-bounces+linux-phy=archiver.kernel.org@lists.infradead.org Add support for HDMI PHY on Qualcomm MSM8x60 / APQ8060 platforms. Signed-off-by: Dmitry Baryshkov --- drivers/phy/qualcomm/Makefile | 1 + drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c | 184 ++++++++++++++++++++ drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c | 32 ++-- drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h | 1 + 4 files changed, 204 insertions(+), 14 deletions(-) create mode 100644 drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c diff --git a/drivers/phy/qualcomm/Makefile b/drivers/phy/qualcomm/Makefile index 082020af7fc1..79df2f1e9bc8 100644 --- a/drivers/phy/qualcomm/Makefile +++ b/drivers/phy/qualcomm/Makefile @@ -10,6 +10,7 @@ phy-qcom-hdmi-y := \ phy-qcom-hdmi-preqmp.o \ phy-qcom-hdmi-28hpm.o \ phy-qcom-hdmi-28lpm.o \ + phy-qcom-hdmi-45nm.o \ obj-$(CONFIG_PHY_QCOM_M31_USB) += phy-qcom-m31.o obj-$(CONFIG_PHY_QCOM_PCIE2) += phy-qcom-pcie2.o diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c b/drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c new file mode 100644 index 000000000000..31e1e9f2d037 --- /dev/null +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-45nm.c @@ -0,0 +1,184 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2013 Red Hat + * Author: Rob Clark + * Copyright (c) 2023, Linaro Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "phy-qcom-hdmi-preqmp.h" + +#define REG_HDMI_8x60_PHY_REG0 0x00000000 +#define HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__MASK 0x0000001c + +#define REG_HDMI_8x60_PHY_REG1 0x00000004 +#define HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK 0x000000f0 +#define HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK 0x0000000f + +#define REG_HDMI_8x60_PHY_REG2 0x00000008 +#define HDMI_8x60_PHY_REG2_PD_DESER 0x00000001 +#define HDMI_8x60_PHY_REG2_PD_DRIVE_1 0x00000002 +#define HDMI_8x60_PHY_REG2_PD_DRIVE_2 0x00000004 +#define HDMI_8x60_PHY_REG2_PD_DRIVE_3 0x00000008 +#define HDMI_8x60_PHY_REG2_PD_DRIVE_4 0x00000010 +#define HDMI_8x60_PHY_REG2_PD_PLL 0x00000020 +#define HDMI_8x60_PHY_REG2_PD_PWRGEN 0x00000040 +#define HDMI_8x60_PHY_REG2_RCV_SENSE_EN 0x00000080 + +#define REG_HDMI_8x60_PHY_REG3 0x0000000c +#define HDMI_8x60_PHY_REG3_PLL_ENABLE 0x00000001 + +#define REG_HDMI_8x60_PHY_REG4 0x00000010 + +#define REG_HDMI_8x60_PHY_REG5 0x00000014 + +#define REG_HDMI_8x60_PHY_REG6 0x00000018 + +#define REG_HDMI_8x60_PHY_REG7 0x0000001c + +#define REG_HDMI_8x60_PHY_REG8 0x00000020 + +#define REG_HDMI_8x60_PHY_REG9 0x00000024 + +#define REG_HDMI_8x60_PHY_REG10 0x00000028 + +#define REG_HDMI_8x60_PHY_REG11 0x0000002c + +#define REG_HDMI_8x60_PHY_REG12 0x00000030 +#define HDMI_8x60_PHY_REG12_RETIMING_EN 0x00000001 +#define HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN 0x00000002 +#define HDMI_8x60_PHY_REG12_FORCE_LOCK 0x00000010 + +static int qcom_hdmi_msm8x60_phy_power_on(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + unsigned long pixclock = hdmi_phy->hdmi_opts.pixel_clk_rate; + + /* De-serializer delay D/C for non-lbk mode: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG0, + FIELD_PREP(HDMI_8x60_PHY_REG0_DESER_DEL_CTRL__MASK, 3)); + + if (pixclock == 27000) { + /* video_format == HDMI_VFRMT_720x480p60_16_9 */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG1, + FIELD_PREP(HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK, 5) | + FIELD_PREP(HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK, 3)); + } else { + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG1, + FIELD_PREP(HDMI_8x60_PHY_REG1_DTEST_MUX_SEL__MASK, 5) | + FIELD_PREP(HDMI_8x60_PHY_REG1_OUTVOL_SWING_CTRL__MASK, 4)); + } + + /* No matter what, start from the power down mode: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_PWRGEN | + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + + /* Turn PowerGen on: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + + /* Turn PLL power on: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + + /* Write to HIGH after PLL power down de-assert: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG3, + HDMI_8x60_PHY_REG3_PLL_ENABLE); + + /* ASIC power on; PHY REG9 = 0 */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG9, 0); + + /* Enable PLL lock detect, PLL lock det will go high after lock + * Enable the re-time logic + */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG12, + HDMI_8x60_PHY_REG12_RETIMING_EN | + HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN); + + /* Drivers are on: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DESER); + + /* If the RX detector is needed: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_RCV_SENSE_EN | + HDMI_8x60_PHY_REG2_PD_DESER); + + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG4, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG5, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG6, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG7, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG8, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG9, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG10, 0); + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG11, 0); + + /* If we want to use lock enable based on counting: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG12, + HDMI_8x60_PHY_REG12_RETIMING_EN | + HDMI_8x60_PHY_REG12_PLL_LOCK_DETECT_EN | + HDMI_8x60_PHY_REG12_FORCE_LOCK); + + return 0; +} + +static int qcom_hdmi_msm8x60_phy_power_off(struct qcom_hdmi_preqmp_phy *hdmi_phy) +{ + /* Turn off Driver */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + udelay(10); + /* Disable PLL */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG3, 0); + /* Power down PHY, but keep RX-sense: */ + hdmi_phy_write(hdmi_phy, REG_HDMI_8x60_PHY_REG2, + HDMI_8x60_PHY_REG2_RCV_SENSE_EN | + HDMI_8x60_PHY_REG2_PD_PWRGEN | + HDMI_8x60_PHY_REG2_PD_PLL | + HDMI_8x60_PHY_REG2_PD_DRIVE_4 | + HDMI_8x60_PHY_REG2_PD_DRIVE_3 | + HDMI_8x60_PHY_REG2_PD_DRIVE_2 | + HDMI_8x60_PHY_REG2_PD_DRIVE_1 | + HDMI_8x60_PHY_REG2_PD_DESER); + + return 0; +} + +const struct qcom_hdmi_preqmp_cfg msm8x60_hdmi_phy_cfg = { + .clk_names = { "slave_iface" }, + .num_clks = 1, + + .reg_names = { "core-vdda" }, + .num_regs = 1, + + .power_on = qcom_hdmi_msm8x60_phy_power_on, + .power_off = qcom_hdmi_msm8x60_phy_power_off, + + /* FIXME: no PLL support */ +}; diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c index e181a45df2dc..66aa199424b8 100644 --- a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.c @@ -147,20 +147,23 @@ static int qcom_hdmi_preqmp_probe(struct platform_device *pdev) if (ret) return ret; - init.name = "hdmipll"; - init.ops = cfg->pll_ops; - init.flags = CLK_GET_RATE_NOCACHE; - init.parent_data = cfg->pll_parent; - init.num_parents = 1; - - hdmi_phy->pll_hw.init = &init; - ret = devm_clk_hw_register(hdmi_phy->dev, &hdmi_phy->pll_hw); - if (ret) - goto err; - - ret = devm_of_clk_add_hw_provider(hdmi_phy->dev, of_clk_hw_simple_get, &hdmi_phy->pll_hw); - if (ret) - goto err; + /* FIXME: msm8x60 doesn't yet have PLL ops */ + if (cfg->pll_ops) { + init.name = "hdmipll"; + init.ops = cfg->pll_ops; + init.flags = CLK_GET_RATE_NOCACHE; + init.parent_data = cfg->pll_parent; + init.num_parents = 1; + + hdmi_phy->pll_hw.init = &init; + ret = devm_clk_hw_register(hdmi_phy->dev, &hdmi_phy->pll_hw); + if (ret) + goto err; + + ret = devm_of_clk_add_hw_provider(hdmi_phy->dev, of_clk_hw_simple_get, &hdmi_phy->pll_hw); + if (ret) + goto err; + } hdmi_phy->phy = devm_phy_create(dev, pdev->dev.of_node, &qcom_hdmi_preqmp_phy_ops); if (IS_ERR(hdmi_phy->phy)) { @@ -180,6 +183,7 @@ static int qcom_hdmi_preqmp_probe(struct platform_device *pdev) } static const struct of_device_id qcom_hdmi_preqmp_of_match_table[] = { + { .compatible = "qcom,hdmi-phy-8x60", .data = &msm8x60_hdmi_phy_cfg, }, { .compatible = "qcom,hdmi-phy-8960", .data = &msm8960_hdmi_phy_cfg, }, { .compatible = "qcom,hdmi-phy-8974", .data = &msm8974_hdmi_phy_cfg, }, { }, diff --git a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h index bc81d68463ec..66fb9235520a 100644 --- a/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h +++ b/drivers/phy/qualcomm/phy-qcom-hdmi-preqmp.h @@ -74,6 +74,7 @@ static inline u32 hdmi_pll_read(struct qcom_hdmi_preqmp_phy *phy, int offset) return readl(phy->pll_reg + offset); } +extern const struct qcom_hdmi_preqmp_cfg msm8x60_hdmi_phy_cfg; extern const struct qcom_hdmi_preqmp_cfg msm8960_hdmi_phy_cfg; extern const struct qcom_hdmi_preqmp_cfg msm8974_hdmi_phy_cfg;