aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/memory
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2022-03-01 10:52:27 +0100
committerArnd Bergmann <arnd@arndb.de>2022-03-01 10:52:27 +0100
commit88c7385290ed9e08fb051997a26113e412396611 (patch)
tree28ab8dd4aa2a0db21ab8cf54d59c3f4f63d90ddd /drivers/memory
parentb903f9c55ea4a2af9a627268becc1e5f48ffbeec (diff)
parent12fbfd665fc473800d25d0f3ca4617c82cff42dd (diff)
downloadlinux-88c7385290ed9e08fb051997a26113e412396611.tar.gz
Merge tag 'memory-controller-drv-mediatek-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl into arm/drivers
Memory controller drivers for v5.18 - Mediatek SoC 1. Several updates in the MTK SMI bindings. 2. Add support for MT8186 MTK SMI and improvements in support for MT8195. * tag 'memory-controller-drv-mediatek-5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/krzk/linux-mem-ctrl: memory: mtk-smi: Enable sleep ctrl safety function for MT8195 memory: mtk-smi: mt8186: Add smi support memory: mtk-smi: Add sleep ctrl function memory: mtk-smi: handle positive return value for clk_bulk_prepare_enable dt-bindings: memory: mediatek: Add mt8186 support dt-bindings: memory: mtk-smi: Correct minItems to 2 for the gals clocks dt-bindings: memory: mtk-smi: No need mediatek,larb-id for mt8167 dt-bindings: memory: mtk-smi: Rename clock to clocks Link: https://lore.kernel.org/r/20220228164313.52931-2-krzysztof.kozlowski@canonical.com Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/memory')
-rw-r--r--drivers/memory/mtk-smi.c54
1 files changed, 52 insertions, 2 deletions
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c
index a0d50ce71e9ce2..7d8a083df44a82 100644
--- a/drivers/memory/mtk-smi.c
+++ b/drivers/memory/mtk-smi.c
@@ -8,6 +8,7 @@
#include <linux/device.h>
#include <linux/err.h>
#include <linux/io.h>
+#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
@@ -32,6 +33,10 @@
#define SMI_DUMMY 0x444
/* SMI LARB */
+#define SMI_LARB_SLP_CON 0xc
+#define SLP_PROT_EN BIT(0)
+#define SLP_PROT_RDY BIT(16)
+
#define SMI_LARB_CMD_THRT_CON 0x24
#define SMI_LARB_THRT_RD_NU_LMT_MSK GENMASK(7, 4)
#define SMI_LARB_THRT_RD_NU_LMT (5 << 4)
@@ -81,6 +86,7 @@
#define MTK_SMI_FLAG_THRT_UPDATE BIT(0)
#define MTK_SMI_FLAG_SW_FLAG BIT(1)
+#define MTK_SMI_FLAG_SLEEP_CTL BIT(2)
#define MTK_SMI_CAPS(flags, _x) (!!((flags) & (_x)))
struct mtk_smi_reg_pair {
@@ -348,13 +354,19 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8183 = {
/* IPU0 | IPU1 | CCU */
};
+static const struct mtk_smi_larb_gen mtk_smi_larb_mt8186 = {
+ .config_port = mtk_smi_larb_config_port_gen2_general,
+ .flags_general = MTK_SMI_FLAG_SLEEP_CTL,
+};
+
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = {
.config_port = mtk_smi_larb_config_port_gen2_general,
};
static const struct mtk_smi_larb_gen mtk_smi_larb_mt8195 = {
.config_port = mtk_smi_larb_config_port_gen2_general,
- .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG,
+ .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG |
+ MTK_SMI_FLAG_SLEEP_CTL,
.ostd = mtk_smi_larb_mt8195_ostd,
};
@@ -365,11 +377,32 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = {
{.compatible = "mediatek,mt8167-smi-larb", .data = &mtk_smi_larb_mt8167},
{.compatible = "mediatek,mt8173-smi-larb", .data = &mtk_smi_larb_mt8173},
{.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183},
+ {.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186},
{.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192},
{.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195},
{}
};
+static int mtk_smi_larb_sleep_ctrl_enable(struct mtk_smi_larb *larb)
+{
+ int ret;
+ u32 tmp;
+
+ writel_relaxed(SLP_PROT_EN, larb->base + SMI_LARB_SLP_CON);
+ ret = readl_poll_timeout_atomic(larb->base + SMI_LARB_SLP_CON,
+ tmp, !!(tmp & SLP_PROT_RDY), 10, 1000);
+ if (ret) {
+ /* TODO: Reset this larb if it fails here. */
+ dev_err(larb->smi.dev, "sleep ctrl is not ready(0x%x).\n", tmp);
+ }
+ return ret;
+}
+
+static void mtk_smi_larb_sleep_ctrl_disable(struct mtk_smi_larb *larb)
+{
+ writel_relaxed(0, larb->base + SMI_LARB_SLP_CON);
+}
+
static int mtk_smi_device_link_common(struct device *dev, struct device **com_dev)
{
struct platform_device *smi_com_pdev;
@@ -479,9 +512,12 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
int ret;
ret = clk_bulk_prepare_enable(larb->smi.clk_num, larb->smi.clks);
- if (ret < 0)
+ if (ret)
return ret;
+ if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL))
+ mtk_smi_larb_sleep_ctrl_disable(larb);
+
/* Configure the basic setting for this larb */
larb_gen->config_port(dev);
@@ -491,6 +527,13 @@ static int __maybe_unused mtk_smi_larb_resume(struct device *dev)
static int __maybe_unused mtk_smi_larb_suspend(struct device *dev)
{
struct mtk_smi_larb *larb = dev_get_drvdata(dev);
+ int ret;
+
+ if (MTK_SMI_CAPS(larb->larb_gen->flags_general, MTK_SMI_FLAG_SLEEP_CTL)) {
+ ret = mtk_smi_larb_sleep_ctrl_enable(larb);
+ if (ret)
+ return ret;
+ }
clk_bulk_disable_unprepare(larb->smi.clk_num, larb->smi.clks);
return 0;
@@ -543,6 +586,12 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8183 = {
F_MMU1_LARB(7),
};
+static const struct mtk_smi_common_plat mtk_smi_common_mt8186 = {
+ .type = MTK_SMI_GEN2,
+ .has_gals = true,
+ .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(4) | F_MMU1_LARB(7),
+};
+
static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = {
.type = MTK_SMI_GEN2,
.has_gals = true,
@@ -577,6 +626,7 @@ static const struct of_device_id mtk_smi_common_of_ids[] = {
{.compatible = "mediatek,mt8167-smi-common", .data = &mtk_smi_common_gen2},
{.compatible = "mediatek,mt8173-smi-common", .data = &mtk_smi_common_gen2},
{.compatible = "mediatek,mt8183-smi-common", .data = &mtk_smi_common_mt8183},
+ {.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186},
{.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192},
{.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo},
{.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},