From nobody Sun Feb 8 09:12:09 2026 Received: from mailgw01.mediatek.com (unknown [60.244.123.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id ECDFC1FC0E3; Thu, 3 Apr 2025 06:50:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=60.244.123.138 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743663043; cv=none; b=ucHI5tVoINZPOra5A5xeUI7zLjWOFJ6Ux+ew1tj7dplIZ2bY+6qe01SnhDloopJld5IFddL9wRG6Gc2XuADXvfWVzFUKtvT8J0Kxq3xtTirpcLuc2T38tYcTfdT9mCMrqw22LXdp988dRH9bQ9EA03u2Uf5nj0Y4hhpd2aTaXxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743663043; c=relaxed/simple; bh=dISGsuvWoy4nucKXb3vajiwE8lGz6a1qQN6HyAeEtiE=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=bG4Odf6Cot4JO8j/O5rGXpSk3F3rVykB/WkFsfkR/CGlUL5Sr4WkvilNrmEdnJ1DAtUr8eCiAaLqjw9gjIAym9dqC65+FdK4nYZcOde070zskYzupvhVvx/IpbHeY/Iyqu8eQ94GJlK0Ax6PKDyDJpzD7EDZpSgYbb1Qo4PqAHA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com; spf=pass smtp.mailfrom=mediatek.com; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b=eR+RL3yi; arc=none smtp.client-ip=60.244.123.138 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mediatek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="eR+RL3yi" X-UUID: f1feef66105711f0aae1fd9735fae912-20250403 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=LTZofUX6Jv/8yJIenVhAoWh1nNKDtqpvFcNBJxTaRao=; b=eR+RL3yi5DShQCFKQr80qgSyh3xBnrE0D04BOawx8nuVQS+iq54xn7sMfDKUKbBnRzA778wmeeVyA60YnNY1BahcFXTwXhF9Bbj7GwOZPH4Kj5zWzRC77rxnFZeHIWExMSgQXl/cXz0j32WvmvP8tjGf37hwjtzY+jVPEAuF1UY=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.2.1,REQID:f1543aa0-2593-4c8f-899e-6f81ce786d56,IP:0,UR L:25,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION: release,TS:25 X-CID-META: VersionHash:0ef645f,CLOUDID:217024c7-16da-468a-87f7-8ca8d6b3b9f7,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:81|82|102,TC:nil,Content:0|50,EDM:-3 ,IP:nil,URL:11|83|1,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OS A:0,AV:0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULN X-UUID: f1feef66105711f0aae1fd9735fae912-20250403 Received: from mtkmbs13n1.mediatek.inc [(172.21.101.193)] by mailgw01.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1888648647; Thu, 03 Apr 2025 14:50:35 +0800 Received: from mtkmbs11n1.mediatek.inc (172.21.101.185) by mtkmbs10n1.mediatek.inc (172.21.101.34) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.39; Thu, 3 Apr 2025 14:50:34 +0800 Received: from mhfsdcap04.gcn.mediatek.inc (10.17.3.154) by mtkmbs11n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1258.39 via Frontend Transport; Thu, 3 Apr 2025 14:50:33 +0800 From: Crystal Guo To: Krzysztof Kozlowski , Rob Herring , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Crystal Guo CC: , , , , Subject: [PATCH v4 1/2] dt-bindings: memory-controllers: Add MediaTek DRAM controller interface Date: Thu, 3 Apr 2025 14:48:47 +0800 Message-ID: <20250403065030.22761-2-crystal.guo@mediatek.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20250403065030.22761-1-crystal.guo@mediatek.com> References: <20250403065030.22761-1-crystal.guo@mediatek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-MTK: N Content-Type: text/plain; charset="utf-8" A MediaTek DRAM controller interface to provide the current DDR data rate. Signed-off-by: Crystal Guo Reviewed-by: AngeloGioacchino Del Regno --- .../mediatek,mt8196-dramc.yaml | 44 +++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 Documentation/devicetree/bindings/memory-controllers/me= diatek,mt8196-dramc.yaml diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,= mt8196-dramc.yaml b/Documentation/devicetree/bindings/memory-controllers/me= diatek,mt8196-dramc.yaml new file mode 100644 index 000000000000..c0b3e7166a87 --- /dev/null +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,mt8196-= dramc.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +# Copyright (c) 2025 MediaTek Inc. +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/memory-controllers/mediatek,mt8196-dram= c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek DRAM Controller (DRAMC) + +maintainers: + - Crystal Guo + +description: + A MediaTek DRAM controller interface to provide the current data rate of= DRAM. + +properties: + compatible: + items: + - enum: + - mediatek,mt8196-dramc + + reg: + items: + - description: anaphy registers + - description: ddrphy registers + +additionalProperties: false + +required: + - compatible + - reg + +examples: + - | + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + memory-controller@10236000 { + compatible =3D "mediatek,mt8196-dramc"; + reg =3D <0 0x10236000 0 0x2000>, + <0 0x10238000 0 0x2000>; + }; + }; --=20 2.18.0 From nobody Sun Feb 8 09:12:09 2026 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 00638206F05; Thu, 3 Apr 2025 06:50:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=210.61.82.184 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743663051; cv=none; b=kioUvL6AGUfwmDmWqsqPXLaaLz9T6xcCfJoWYsDGad1iNy7PR9o1eLugJRYtTPg/3HvAUwwkh8ZowaBDAF7lktCD7E8x8Fyhp7LURrRQVmI4cG2kZ7F+K7uuw5UOanI89Od/h/jx13Y5Kr1PDA2Vxl3DkboNmUJ7IQXqxQ6bwRk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1743663051; c=relaxed/simple; bh=8hWKitp77IDck8hoCKIBJO+3gKob/Lpbkk2OG4er9Ao=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CfIxtA1KnWW4FJs6qEYBQp0bL8kGSB8ONAx3hkbXbkRNA5/7L6xq9A1rjyBEkJMcDcy+HoOEDFZL4K99qRIqNVc9rBLdrvmgjOjezbfGtvJ5aRqP8+ESA6H0JF7fvpHAWM53MGXnyqJIGJrAgHgywTkJr0hys8lkip7wncfIkmI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com; spf=pass smtp.mailfrom=mediatek.com; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b=IW7yjui6; arc=none smtp.client-ip=210.61.82.184 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=mediatek.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=mediatek.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="IW7yjui6" X-UUID: f27977ea105711f08eb9c36241bbb6fb-20250403 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:CC:To:From; bh=6gJRfFUgDxR3NJcSHCZBqNa83odaYPcFqinYa0FxqG0=; b=IW7yjui6l8QqvY8icZFhUroJ2atkcg4vnKQmTHmNLD90ZSysJg9JISQjfbKZTgUSeS4bGmjx/FhMKVymRiO5D7m1SVDuyiBvIM2OymViDLfO4W0WOferYKPhkCA+hFGGeqJjp/3acTcNpljFf8UMjKwI3ixRDkolcXhNnLJkONs=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.2.1,REQID:cb43f136-9bb6-4d0c-88eb-b1cc71423e4a,IP:0,UR L:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:-25 X-CID-META: VersionHash:0ef645f,CLOUDID:89162d8d-f5b8-47d5-8cf3-b68fe7530c9a,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:81|82|102,TC:nil,Content:0|50,EDM:-3 ,IP:nil,URL:0,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV :0,LES:1,SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR X-UUID: f27977ea105711f08eb9c36241bbb6fb-20250403 Received: from mtkmbs11n2.mediatek.inc [(172.21.101.187)] by mailgw02.mediatek.com (envelope-from ) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1900332356; Thu, 03 Apr 2025 14:50:36 +0800 Received: from mtkmbs11n1.mediatek.inc (172.21.101.185) by mtkmbs11n1.mediatek.inc (172.21.101.185) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.39; Thu, 3 Apr 2025 14:50:35 +0800 Received: from mhfsdcap04.gcn.mediatek.inc (10.17.3.154) by mtkmbs11n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1258.39 via Frontend Transport; Thu, 3 Apr 2025 14:50:34 +0800 From: Crystal Guo To: Krzysztof Kozlowski , Rob Herring , Conor Dooley , Matthias Brugger , AngeloGioacchino Del Regno , Crystal Guo CC: , , , , Subject: [PATCH v4 2/2] memory/mediatek: Add an interface to get current DDR data rate Date: Thu, 3 Apr 2025 14:48:48 +0800 Message-ID: <20250403065030.22761-3-crystal.guo@mediatek.com> X-Mailer: git-send-email 2.46.0 In-Reply-To: <20250403065030.22761-1-crystal.guo@mediatek.com> References: <20250403065030.22761-1-crystal.guo@mediatek.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-MTK: N Content-Type: text/plain; charset="utf-8" Add MediaTek DRAMC driver to provide an interface that can obtain current DDR data rate. Signed-off-by: Crystal Guo Reviewed-by: AngeloGioacchino Del Regno --- drivers/memory/Kconfig | 1 + drivers/memory/Makefile | 1 + drivers/memory/mediatek/Kconfig | 20 +++ drivers/memory/mediatek/Makefile | 2 + drivers/memory/mediatek/mtk-dramc.c | 223 ++++++++++++++++++++++++++++ 5 files changed, 247 insertions(+) create mode 100644 drivers/memory/mediatek/Kconfig create mode 100644 drivers/memory/mediatek/Makefile create mode 100644 drivers/memory/mediatek/mtk-dramc.c diff --git a/drivers/memory/Kconfig b/drivers/memory/Kconfig index c82d8d8a16ea..b1698549ff81 100644 --- a/drivers/memory/Kconfig +++ b/drivers/memory/Kconfig @@ -227,5 +227,6 @@ config STM32_FMC2_EBI =20 source "drivers/memory/samsung/Kconfig" source "drivers/memory/tegra/Kconfig" +source "drivers/memory/mediatek/Kconfig" =20 endif diff --git a/drivers/memory/Makefile b/drivers/memory/Makefile index d2e6ca9abbe0..c0facf529803 100644 --- a/drivers/memory/Makefile +++ b/drivers/memory/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_STM32_FMC2_EBI) +=3D stm32-fmc2-ebi.o =20 obj-$(CONFIG_SAMSUNG_MC) +=3D samsung/ obj-$(CONFIG_TEGRA_MC) +=3D tegra/ +obj-$(CONFIG_MEDIATEK_MC) +=3D mediatek/ obj-$(CONFIG_TI_EMIF_SRAM) +=3D ti-emif-sram.o obj-$(CONFIG_FPGA_DFL_EMIF) +=3D dfl-emif.o =20 diff --git a/drivers/memory/mediatek/Kconfig b/drivers/memory/mediatek/Kcon= fig new file mode 100644 index 000000000000..eadc11ec0f1c --- /dev/null +++ b/drivers/memory/mediatek/Kconfig @@ -0,0 +1,20 @@ +# SPDX-License-Identifier: GPL-2.0-only +config MEDIATEK_MC + bool "MediaTek Memory Controller support" + default y + depends on ARCH_MEDIATEK || COMPILE_TEST + help + This option allows to enable MediaTek memory controller drivers, + which may include controllers for DRAM or others. + +if MEDIATEK_MC + +config MTK_DRAMC + tristate "MediaTek DRAMC driver" + default y + help + This driver is for the DRAM Controller found in MediaTek SoCs + and provides a sysfs interface for reporting the current DRAM + data rate. + +endif diff --git a/drivers/memory/mediatek/Makefile b/drivers/memory/mediatek/Mak= efile new file mode 100644 index 000000000000..a1395fc55b41 --- /dev/null +++ b/drivers/memory/mediatek/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_MTK_DRAMC) +=3D mtk-dramc.o diff --git a/drivers/memory/mediatek/mtk-dramc.c b/drivers/memory/mediatek/= mtk-dramc.c new file mode 100644 index 000000000000..d54c8e00d4ee --- /dev/null +++ b/drivers/memory/mediatek/mtk-dramc.c @@ -0,0 +1,223 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 MediaTek Inc. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct mtk_dramc_pdata { + u8 fmeter_version; + u8 ref_freq_mhz; + const u16 *regs; + const u32 *masks; + u32 posdiv_purify; + u8 prediv; + u16 shuffle_offset; +}; + +struct mtk_dramc { + void __iomem *anaphy_base; + void __iomem *ddrphy_base; + const struct mtk_dramc_pdata *pdata; +}; + +enum mtk_dramc_reg_index { + DRAMC_DPHY_DVFS_STA, + DRAMC_APHY_SHU_PHYPLL2, + DRAMC_APHY_SHU_CLRPLL2, + DRAMC_APHY_SHU_PHYPLL3, + DRAMC_APHY_SHU_CLRPLL3, + DRAMC_APHY_SHU_PHYPLL4, + DRAMC_APHY_ARPI0, + DRAMC_APHY_CA_ARDLL1, + DRAMC_APHY_B0_TX0, +}; + +enum mtk_dramc_mask_index { + DRAMC_DPHY_DVFS_SHU_LV, + DRAMC_DPHY_DVFS_PLL_SEL, + DRAMC_APHY_PLL2_SDMPCW, + DRAMC_APHY_PLL3_POSDIV, + DRAMC_APHY_PLL4_FBKSEL, + DRAMC_APHY_ARPI0_SOPEN, + DRAMC_APHY_ARDLL1_CK_EN, + DRAMC_APHY_B0_TX0_SER_MODE, +}; + +static const u16 mtk_dramc_regs_mt8196[] =3D { + [DRAMC_DPHY_DVFS_STA] =3D 0xe98, + [DRAMC_APHY_SHU_PHYPLL2] =3D 0x908, + [DRAMC_APHY_SHU_CLRPLL2] =3D 0x928, + [DRAMC_APHY_SHU_PHYPLL3] =3D 0x90c, + [DRAMC_APHY_SHU_CLRPLL3] =3D 0x92c, + [DRAMC_APHY_SHU_PHYPLL4] =3D 0x910, + [DRAMC_APHY_ARPI0] =3D 0x0d94, + [DRAMC_APHY_CA_ARDLL1] =3D 0x0d08, + [DRAMC_APHY_B0_TX0] =3D 0x0dc4, +}; + +static const u32 mtk_dramc_masks_mt8196[] =3D { + [DRAMC_DPHY_DVFS_SHU_LV] =3D GENMASK(15, 14), + [DRAMC_DPHY_DVFS_PLL_SEL] =3D GENMASK(25, 25), + [DRAMC_APHY_PLL2_SDMPCW] =3D GENMASK(18, 3), + [DRAMC_APHY_PLL3_POSDIV] =3D GENMASK(13, 11), + [DRAMC_APHY_PLL4_FBKSEL] =3D GENMASK(6, 6), + [DRAMC_APHY_ARPI0_SOPEN] =3D GENMASK(26, 26), + [DRAMC_APHY_ARDLL1_CK_EN] =3D GENMASK(0, 0), + [DRAMC_APHY_B0_TX0_SER_MODE] =3D GENMASK(4, 3), +}; + +static unsigned int read_reg_field(void __iomem *base, unsigned int offset= , unsigned int mask) +{ + unsigned int val =3D readl(base + offset); + unsigned int shift =3D __ffs(mask); + + return (val & mask) >> shift; +} + +static int mtk_dramc_probe(struct platform_device *pdev) +{ + struct mtk_dramc *dramc; + const struct mtk_dramc_pdata *pdata; + + dramc =3D devm_kzalloc(&pdev->dev, sizeof(struct mtk_dramc), GFP_KERNEL); + if (!dramc) + return dev_err_probe(&pdev->dev, -ENOMEM, "Failed to allocate memory\n"); + + pdata =3D of_device_get_match_data(&pdev->dev); + if (!pdata) + return dev_err_probe(&pdev->dev, -EINVAL, "No platform data available\n"= ); + + dramc->pdata =3D pdata; + + dramc->anaphy_base =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(dramc->anaphy_base)) + return dev_err_probe(&pdev->dev, PTR_ERR(dramc->anaphy_base), + "Unable to map ANAPHY base\n"); + + dramc->ddrphy_base =3D devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(dramc->ddrphy_base)) + return dev_err_probe(&pdev->dev, PTR_ERR(dramc->ddrphy_base), + "Unable to map DDRPHY base\n"); + + platform_set_drvdata(pdev, dramc); + return 0; +} + +static unsigned int mtk_fmeter_v1(struct mtk_dramc *dramc) +{ + const struct mtk_dramc_pdata *pdata =3D dramc->pdata; + unsigned int shu_level, pll_sel, offset; + unsigned int sdmpcw, posdiv, clkdiv, fbksel, sopen, async_ca, ser_mode; + unsigned int prediv_freq, posdiv_freq, vco_freq; + unsigned int final_rate; + + shu_level =3D read_reg_field(dramc->ddrphy_base, pdata->regs[DRAMC_DPHY_D= VFS_STA], + pdata->masks[DRAMC_DPHY_DVFS_SHU_LV]); + pll_sel =3D read_reg_field(dramc->ddrphy_base, pdata->regs[DRAMC_DPHY_DVF= S_STA], + pdata->masks[DRAMC_DPHY_DVFS_PLL_SEL]); + offset =3D pdata->shuffle_offset * shu_level; + + sdmpcw =3D read_reg_field(dramc->anaphy_base, + ((pll_sel =3D=3D 0) ? + pdata->regs[DRAMC_APHY_SHU_PHYPLL2] : + pdata->regs[DRAMC_APHY_SHU_CLRPLL2]) + offset, + pdata->masks[DRAMC_APHY_PLL2_SDMPCW]); + posdiv =3D read_reg_field(dramc->anaphy_base, + ((pll_sel =3D=3D 0) ? + pdata->regs[DRAMC_APHY_SHU_PHYPLL3] : + pdata->regs[DRAMC_APHY_SHU_CLRPLL3]) + offset, + pdata->masks[DRAMC_APHY_PLL3_POSDIV]); + fbksel =3D read_reg_field(dramc->anaphy_base, pdata->regs[DRAMC_APHY_SHU_= PHYPLL4] + offset, + pdata->masks[DRAMC_APHY_PLL4_FBKSEL]); + sopen =3D read_reg_field(dramc->anaphy_base, pdata->regs[DRAMC_APHY_ARPI0= ] + offset, + pdata->masks[DRAMC_APHY_ARPI0_SOPEN]); + async_ca =3D read_reg_field(dramc->anaphy_base, pdata->regs[DRAMC_APHY_CA= _ARDLL1] + offset, + pdata->masks[DRAMC_APHY_ARDLL1_CK_EN]); + ser_mode =3D read_reg_field(dramc->anaphy_base, pdata->regs[DRAMC_APHY_B0= _TX0] + offset, + pdata->masks[DRAMC_APHY_B0_TX0_SER_MODE]); + + clkdiv =3D (ser_mode =3D=3D 1) ? 1 : 0; + posdiv &=3D ~(pdata->posdiv_purify); + + prediv_freq =3D pdata->ref_freq_mhz * (sdmpcw >> pdata->prediv); + posdiv_freq =3D (prediv_freq >> posdiv) >> 1; + vco_freq =3D posdiv_freq << fbksel; + final_rate =3D vco_freq >> clkdiv; + + if (sopen =3D=3D 1 && async_ca =3D=3D 1) + final_rate >>=3D 1; + + return final_rate; +} + +/** + * mtk_dramc_get_data_rate - Calculate the current DRAM data rate + * @dev: Device pointer + * + * Return: DRAM Data Rate in Mbps or negative number for error + */ +static unsigned int mtk_dramc_get_data_rate(struct device *dev) +{ + struct mtk_dramc *dramc =3D dev_get_drvdata(dev); + + if (dramc->pdata->fmeter_version =3D=3D 1) + return mtk_fmeter_v1(dramc); + + dev_err(dev, "Frequency meter version %u not supported\n", dramc->pdata->= fmeter_version); + return -EINVAL; +} + +static ssize_t dram_data_rate_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + return snprintf(buf, PAGE_SIZE, "DRAM data rate =3D %u\n", + mtk_dramc_get_data_rate(dev)); +} + +static DEVICE_ATTR_RO(dram_data_rate); + +static struct attribute *mtk_dramc_attrs[] =3D { + &dev_attr_dram_data_rate.attr, + NULL +}; +ATTRIBUTE_GROUPS(mtk_dramc); + +static const struct mtk_dramc_pdata dramc_pdata_mt8196 =3D { + .fmeter_version =3D 1, + .ref_freq_mhz =3D 26, + .regs =3D mtk_dramc_regs_mt8196, + .masks =3D mtk_dramc_masks_mt8196, + .posdiv_purify =3D BIT(2), + .prediv =3D 7, + .shuffle_offset =3D 0x700, +}; + +static const struct of_device_id mtk_dramc_of_ids[] =3D { + { .compatible =3D "mediatek,mt8196-dramc", .data =3D &dramc_pdata_mt8196 = }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, mtk_dramc_of_ids); + +static struct platform_driver mtk_dramc_driver =3D { + .probe =3D mtk_dramc_probe, + .driver =3D { + .name =3D "mtk-dramc", + .of_match_table =3D mtk_dramc_of_ids, + .dev_groups =3D mtk_dramc_groups, + }, +}; +module_platform_driver(mtk_dramc_driver); + +MODULE_AUTHOR("Crystal Guo "); +MODULE_DESCRIPTION("MediaTek DRAM Controller Driver"); +MODULE_LICENSE("GPL"); --=20 2.18.0