From patchwork Mon Jun 21 07:24:19 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jagan Teki X-Patchwork-Id: 12333997 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-17.1 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4FCEC49EA2 for ; Mon, 21 Jun 2021 07:28:13 +0000 (UTC) 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 mail.kernel.org (Postfix) with ESMTPS id B024560E08 for ; Mon, 21 Jun 2021 07:28:13 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org B024560E08 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amarulasolutions.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org 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=9aTjib7hok7K93ZILUgmUFfznh+42Ot0Qr/YeVsCneM=; b=1GAoQ52PPEkvWF hgtPv5lVdPvsoGGfnROwKE+QAD6fc1mgYbCVPcAfjXHTij3bxdadMfSAd1J3b4QUJFPGmHSpz1x9P 3ca5CzFR/22w2+SBkITr3cBZkXQNIR0V55bdQuss1rNfkNj3vxxcSCiiE/aONf/pFHPwmEJGaNBe9 UJ47hRyR+GA6yNjvEk/ZitxNPPpstmH/E/8r+5tnvyQM5dctyAbFDiNlWXTJoygHVBmHXjIhmsFcu h3LWfRAoA+A/HCS/lb/hxNdVusdYsYWBtU34kW4WkjYcTLOlJl60c4ubAqm7+5AZHz7U/TN3lNbbE cE0ExFW2S6TJo5ILZ9sQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.94.2 #2 (Red Hat Linux)) id 1lvEKJ-002UVT-9s; Mon, 21 Jun 2021 07:26:35 +0000 Received: from mail-pl1-x631.google.com ([2607:f8b0:4864:20::631]) by bombadil.infradead.org with esmtps (Exim 4.94.2 #2 (Red Hat Linux)) id 1lvEIu-002Tsg-Jm for linux-arm-kernel@lists.infradead.org; Mon, 21 Jun 2021 07:25:13 +0000 Received: by mail-pl1-x631.google.com with SMTP id 69so8047974plc.5 for ; Mon, 21 Jun 2021 00:25:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amarulasolutions.com; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Lup727rZLbGr3vyVlbClHGUKHLX9fxH8BjtfQEfB8/4=; b=aMmsv68lVfYZR82zX+vhWtVfOZjjn/TBWHf4EnveoeT12AUEmHOzYzB/QM6hBDz/FN QFCga/+I7XcFJXk8TxJgqeD7DUKO93LTm6xuMyHjfojLMXoZQhvEmGeCVmUTEj09PZzk BN4kGoNiKB8ivLG5XzJfJB+xZ52aIAR4AMD/8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Lup727rZLbGr3vyVlbClHGUKHLX9fxH8BjtfQEfB8/4=; b=qASIUa7BTVuzklh9LrZhU15HjObc9tRB7OnILA0DbI/CkGUbftZmWmwA4qqf28Rt1g CXw/TvkPO8KmS7PD+bHSXZhC3AJx2KaZToxbWVj1eunIyCfUnIoBExicM6bZKgVgWNoI medHUj651yOG1g+IlyNEs5Bv6HRa71E/0Vce7a9u/hyZ3XeL3//VKPKiB12c5E7TyJX1 hqt0e4et4ag52BcYESMfX01b7ZywWdkkxQGvy3eqf0nyKdC2DFJj0Fa2tYsFmmlIZ5Tg eqMEqGkBdSoTssTm7ENJ4yCbB1LXlqwXoPFqp7fofoG+UjeJY+zzCTBTSM5FXZtdl+fI ervA== X-Gm-Message-State: AOAM530LoyUaeurOOkCd+cW6oCZgN045GCVA9oktP4DO6zqaGZH9nIFW iZV2XR0pPJu6o3epqxeGZMx72w== X-Google-Smtp-Source: ABdhPJzifgqvkvEs04pUMLDheJAy9L6rtD13FLwnanqcAZd8AIuPsznijFvjfR+DvvUqFmz+nLFIbg== X-Received: by 2002:a17:902:d48b:b029:122:d1b9:7e5a with SMTP id c11-20020a170902d48bb0290122d1b97e5amr9985842plg.47.1624260307627; Mon, 21 Jun 2021 00:25:07 -0700 (PDT) Received: from localhost.localdomain ([2405:201:c00a:a884:139:e97f:a55d:7f66]) by smtp.gmail.com with ESMTPSA id 21sm13951294pfh.103.2021.06.21.00.25.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 21 Jun 2021 00:25:07 -0700 (PDT) From: Jagan Teki To: Peng Fan , Shawn Guo , Sascha Hauer , Tomasz Figa , Fancy Fang Cc: devicetree@vger.kernel.org, linux-arm-kernel@lists.infradead.org, dri-devel@lists.freedesktop.org, linux-phy@lists.infradead.org, linux-kernel@vger.kernel.org, NXP Linux Team , linux-amarula@amarulasolutions.com, Anthony Brandon , Francis Laniel , Matteo Lisi , Milco Pratesi , Jagan Teki , Kishon Vijay Abraham I , Vinod Koul Subject: [RFC PATCH 4/9] phy: samsung: Add SEC DSIM DPHY driver Date: Mon, 21 Jun 2021 12:54:19 +0530 Message-Id: <20210621072424.111733-5-jagan@amarulasolutions.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210621072424.111733-1-jagan@amarulasolutions.com> References: <20210621072424.111733-1-jagan@amarulasolutions.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210621_002508_759369_7DD5F545 X-CRM114-Status: GOOD ( 24.33 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Samsung SEC MIPI DSIM DPHY controller is part of registers available in SEC MIPI DSIM bridge for NXP's i.MX8M Mini and Nano Processors. Add phy driver for it. Cc: Kishon Vijay Abraham I Cc: Vinod Koul Signed-off-by: Jagan Teki --- drivers/phy/samsung/Kconfig | 9 + drivers/phy/samsung/Makefile | 1 + drivers/phy/samsung/phy-sec-dsim-dphy.c | 236 ++++++++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 drivers/phy/samsung/phy-sec-dsim-dphy.c diff --git a/drivers/phy/samsung/Kconfig b/drivers/phy/samsung/Kconfig index e20d2fcc9fe7..e80d40d1278c 100644 --- a/drivers/phy/samsung/Kconfig +++ b/drivers/phy/samsung/Kconfig @@ -103,3 +103,12 @@ config PHY_EXYNOS5250_SATA Exynos5250 based SoCs.This SerDes/Phy supports SATA 1.5 Gb/s, SATA 3.0 Gb/s, SATA 6.0 Gb/s speeds. It supports one SATA host port to accept one SATA device. + +config PHY_SEC_DSIM_DPHY + tristate "Samsung SEC MIPI DSIM DPHY driver" + depends on OF && HAS_IOMEM + select GENERIC_PHY + select REGMAP_MMIO + help + Enable this to add support for the SEC MIPI DSIM DPHY as found + on NXP's i.MX8M Mini and Nano family of SOCs. diff --git a/drivers/phy/samsung/Makefile b/drivers/phy/samsung/Makefile index 3959100fe8a2..4d46c7ec0072 100644 --- a/drivers/phy/samsung/Makefile +++ b/drivers/phy/samsung/Makefile @@ -11,3 +11,4 @@ phy-exynos-usb2-$(CONFIG_PHY_EXYNOS5250_USB2) += phy-exynos5250-usb2.o phy-exynos-usb2-$(CONFIG_PHY_S5PV210_USB2) += phy-s5pv210-usb2.o obj-$(CONFIG_PHY_EXYNOS5_USBDRD) += phy-exynos5-usbdrd.o obj-$(CONFIG_PHY_EXYNOS5250_SATA) += phy-exynos5250-sata.o +obj-$(CONFIG_PHY_SEC_DSIM_DPHY) += phy-sec-dsim-dphy.o diff --git a/drivers/phy/samsung/phy-sec-dsim-dphy.c b/drivers/phy/samsung/phy-sec-dsim-dphy.c new file mode 100644 index 000000000000..31de4a774b5f --- /dev/null +++ b/drivers/phy/samsung/phy-sec-dsim-dphy.c @@ -0,0 +1,236 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2018 NXP + * Copyright (C) 2021 Amarula Solutions(India) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DSI_PHYCTRL_B1 0x00 +#define DSI_PHYCTRL_B2 0x04 +#define DSI_PHYCTRL_M1 0x08 +#define DSI_PHYCTRL_M2 0x0c +#define DSI_PHYTIMING 0x10 +#define DSI_PHYTIMING1 0x14 +#define DSI_PHYTIMING2 0x18 + +/* phytiming */ +#define M_TLPXCTL_MASK GENMASK(15, 8) +#define M_TLPXCTL(x) FIELD_PREP(M_TLPXCTL_MASK, (x)) +#define M_THSEXITCTL_MASK GENMASK(7, 0) +#define M_THSEXITCTL(x) FIELD_PREP(M_THSEXITCTL_MASK, (x)) + +/* phytiming1 */ +#define M_TCLKPRPRCTL_MASK GENMASK(31, 24) +#define M_TCLKPRPRCTL(x) FIELD_PREP(M_TCLKPRPRCTL_MASK, (x)) +#define M_TCLKZEROCTL_MASK GENMASK(23, 16) +#define M_TCLKZEROCTL(x) FIELD_PREP(M_TCLKZEROCTL_MASK, (x)) +#define M_TCLKPOSTCTL_MASK GENMASK(15, 8) +#define M_TCLKPOSTCTL(x) FIELD_PREP(M_TCLKPOSTCTL_MASK, (x)) +#define M_TCLKTRAILCTL_MASK GENMASK(7, 0) +#define M_TCLKTRAILCTL(x) FIELD_PREP(M_TCLKTRAILCTL_MASK, (x)) + +/* phytiming2 */ +#define M_THSPRPRCTL_MASK GENMASK(23, 16) +#define M_THSPRPRCTL(x) FIELD_PREP(M_THSPRPRCTL_MASK, (x)) +#define M_THSZEROCTL_MASK GENMASK(15, 8) +#define M_THSZEROCTL(x) FIELD_PREP(M_THSZEROCTL_MASK, (x)) +#define M_THSTRAILCTL_MASK GENMASK(7, 0) +#define M_THSTRAILCTL(x) FIELD_PREP(M_THSTRAILCTL_MASK, (x)) + +struct dsim_dphy_plat_data { + unsigned int m_tlpxctl; + unsigned int m_thsexitctl; + unsigned int m_tclkprprctl; + unsigned int m_tclkzeroctl; + unsigned int m_tclkpostctl; + unsigned int m_tclktrailctl; + unsigned int m_thsprprctl; + unsigned int m_thszeroctl; + unsigned int m_thstrailctl; +}; + +struct dsim_dphy { + struct regmap *regmap; + struct clk *phy_ref_clk; + const struct dsim_dphy_plat_data *pdata; +}; + +static const struct regmap_config dsim_dphy_regmap_config = { + .reg_bits = 8, + .val_bits = 32, + .reg_stride = 4, + .max_register = DSI_PHYTIMING2, + .name = "mipi-dphy", +}; + +static int dsim_dphy_init(struct phy *phy) +{ + struct dsim_dphy *dphy = phy_get_drvdata(phy); + const struct dsim_dphy_plat_data *pdata = dphy->pdata; + u32 reg; + + /* phytiming */ + regmap_read(dphy->regmap, DSI_PHYTIMING, ®); + + reg &= ~M_TLPXCTL_MASK; + reg |= M_TLPXCTL(pdata->m_tlpxctl); + reg &= ~M_THSEXITCTL_MASK; + reg |= M_THSEXITCTL(pdata->m_thsexitctl); + regmap_write(dphy->regmap, DSI_PHYTIMING, reg); + + /* phytiming1 */ + regmap_read(dphy->regmap, DSI_PHYTIMING1, ®); + + reg &= ~M_TCLKPRPRCTL_MASK; + reg |= M_TCLKPRPRCTL(pdata->m_tclkprprctl); + reg &= ~M_TCLKZEROCTL_MASK; + reg |= M_TCLKZEROCTL(pdata->m_tclkzeroctl); + reg &= ~M_TCLKPOSTCTL_MASK; + reg |= M_TCLKPOSTCTL(pdata->m_tclkpostctl); + reg &= ~M_TCLKTRAILCTL_MASK; + reg |= M_TCLKTRAILCTL(pdata->m_tclktrailctl); + regmap_write(dphy->regmap, DSI_PHYTIMING1, reg); + + /* phytiming2 */ + regmap_read(dphy->regmap, DSI_PHYTIMING2, ®); + + reg &= ~M_THSPRPRCTL_MASK; + reg |= M_THSPRPRCTL(pdata->m_thsprprctl); + reg &= ~M_THSZEROCTL_MASK; + reg |= M_THSZEROCTL(pdata->m_thszeroctl); + reg &= ~M_THSTRAILCTL_MASK; + reg |= M_THSTRAILCTL(pdata->m_thstrailctl); + regmap_write(dphy->regmap, DSI_PHYTIMING2, reg); + + return 0; +} + +static int dsim_dphy_exit(struct phy *phy) +{ + return 0; +} + +static int dsim_dphy_power_on(struct phy *phy) +{ + struct dsim_dphy *dphy = phy_get_drvdata(phy); + int ret; + + ret = clk_prepare_enable(dphy->phy_ref_clk); + if (ret < 0) + return ret; + + return ret; +} + +static int dsim_dphy_power_off(struct phy *phy) +{ + struct dsim_dphy *dphy = phy_get_drvdata(phy); + + clk_disable_unprepare(dphy->phy_ref_clk); + + return 0; +} + +static const struct phy_ops dsim_dphy_phy_ops = { + .init = dsim_dphy_init, + .exit = dsim_dphy_exit, + .power_on = dsim_dphy_power_on, + .power_off = dsim_dphy_power_off, + .owner = THIS_MODULE, +}; + +static const struct dsim_dphy_plat_data imx8mm_dphy_plat_data = { + /* phytiming */ + .m_tlpxctl = 0x06, + .m_thsexitctl = 0x0b, + /* phytiming1 */ + .m_tclkprprctl = 0x07, + .m_tclkzeroctl = 0x26, + .m_tclkpostctl = 0x0d, + .m_tclktrailctl = 0x08, + /* phytimings2 */ + .m_thsprprctl = 0x08, + .m_thszeroctl = 0x0d, + .m_thstrailctl = 0x0b, +}; + +static const struct of_device_id dsim_dphy_of_match[] = { + { + .compatible = "fsl,imx8mm-sec-dsim-dphy", + .data = &imx8mm_dphy_plat_data, + }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, dsim_dphy_of_match); + +static int dsim_dphy_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct phy_provider *phy_provider; + struct dsim_dphy *dphy; + struct phy *phy; + void __iomem *base; + + if (!np) + return -ENODEV; + + dphy = devm_kzalloc(dev, sizeof(*dphy), GFP_KERNEL); + if (!dphy) + return -ENOMEM; + + dphy->pdata = of_device_get_match_data(&pdev->dev); + if (!dphy->pdata) + return -EINVAL; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + dphy->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &dsim_dphy_regmap_config); + if (IS_ERR(dphy->regmap)) { + dev_err(dev, "failed create the DPHY regmap\n"); + return PTR_ERR(dphy->regmap); + } + + dphy->phy_ref_clk = devm_clk_get(&pdev->dev, "phy_ref"); + if (IS_ERR(dphy->phy_ref_clk)) { + dev_err(dev, "failed to get phy_ref clock\n"); + return PTR_ERR(dphy->phy_ref_clk); + } + + dev_set_drvdata(dev, dphy); + + phy = devm_phy_create(dev, np, &dsim_dphy_phy_ops); + if (IS_ERR(phy)) { + dev_err(dev, "failed to create phy %ld\n", PTR_ERR(phy)); + return PTR_ERR(phy); + } + phy_set_drvdata(phy, dphy); + + phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); + + return PTR_ERR_OR_ZERO(phy_provider); +} + +static struct platform_driver dsim_dphy_driver = { + .probe = dsim_dphy_probe, + .driver = { + .name = "sec-dsim-dphy", + .of_match_table = dsim_dphy_of_match, + } +}; +module_platform_driver(dsim_dphy_driver); + +MODULE_AUTHOR("Jagan Teki "); +MODULE_DESCRIPTION("Samsung SEC MIPI DSIM DPHY driver"); +MODULE_LICENSE("GPL");