blob: 089e92b23db933c7caeb527a2f698fa8a486f2e0 [file]
// SPDX-License-Identifier: GPL-2.0
//
// Copyright (c) 2021 MediaTek Inc.
#include <linux/device.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
struct pmif_mpu_data {
const u32 *regs;
};
struct pmif_mpu {
void __iomem *base;
const struct pmif_mpu_data *data;
};
enum pmif_mpu_regs {
PMIF_MPU_CTRL,
PMIF_PMIC_ALL_RGN_EN,
};
static const u32 mt6983_pmif_mpu_regs[] = {
[PMIF_MPU_CTRL] = 0x000,
[PMIF_PMIC_ALL_RGN_EN] = 0x0B0,
};
static u32 pmif_mpu_readl(struct pmif_mpu *arb, enum pmif_mpu_regs reg)
{
return readl(arb->base + arb->data->regs[reg]);
}
static void pmif_mpu_writel(struct pmif_mpu *arb, u32 val, enum pmif_mpu_regs reg)
{
writel(val, arb->base + arb->data->regs[reg]);
}
static const struct pmif_mpu_data mt6983_pmif_mpu_arb = {
.regs = mt6983_pmif_mpu_regs,
};
static int mtk_spmi_pmif_mpu_probe(struct platform_device *pdev)
{
struct pmif_mpu *arb = NULL;
int err = 0;
u32 pmic_all_rgn_en = 0, rgn_en = 0;
u32 disable_pmif_mpu = 0;
arb = devm_kzalloc(&pdev->dev, sizeof(*arb), GFP_KERNEL);
if (!arb)
return -ENOMEM;
arb->data = of_device_get_match_data(&pdev->dev);
if (!arb->data) {
dev_info(&pdev->dev, "cannot get drv_data\n");
return -EINVAL;
}
arb->base = devm_platform_ioremap_resource_byname(pdev, "pmif_mpu");
if (IS_ERR(arb->base)) {
err = PTR_ERR(arb->base);
dev_info(&pdev->dev, "failed to get remapped address\n");
return PTR_ERR(arb->base);
}
platform_set_drvdata(pdev, arb);
if (!of_property_read_u32(pdev->dev.of_node, "disable", &disable_pmif_mpu)) {
if (disable_pmif_mpu) {
pmif_mpu_writel(arb, 0, PMIF_PMIC_ALL_RGN_EN);
dev_info(&pdev->dev, "Disable PMIF MPU\n");
return 0;
}
}
rgn_en = pmif_mpu_readl(arb, PMIF_PMIC_ALL_RGN_EN);
dev_info(&pdev->dev, "PMIC_ALL_RGN_EN=0x%x\n", rgn_en);
if (!of_property_read_u32(pdev->dev.of_node, "mediatek,pmic_all_rgn_en",
&pmic_all_rgn_en)) {
rgn_en |= pmic_all_rgn_en;
pmif_mpu_writel(arb, rgn_en, PMIF_PMIC_ALL_RGN_EN);
}
pmif_mpu_writel(arb, 1, PMIF_MPU_CTRL);
rgn_en = pmif_mpu_readl(arb, PMIF_PMIC_ALL_RGN_EN);
dev_info(&pdev->dev, "PMIC_ALL_RGN_EN=0x%x, setting:0x%x\n",
rgn_en, pmic_all_rgn_en);
return 0;
}
static int mtk_spmi_pmif_mpu_remove(struct platform_device *pdev)
{
return 0;
}
static const struct of_device_id mtk_spmi_pmif_mpu_match_table[] = {
{
.compatible = "mediatek,mt6886-spmi_pmif_mpu",
.data = &mt6983_pmif_mpu_arb,
}, {
.compatible = "mediatek,mt6895-spmi_pmif_mpu",
.data = &mt6983_pmif_mpu_arb,
}, {
.compatible = "mediatek,mt6983-spmi_pmif_mpu",
.data = &mt6983_pmif_mpu_arb,
}, {
.compatible = "mediatek,mt6985-spmi_pmif_mpu",
.data = &mt6983_pmif_mpu_arb,
}, {
/* sentinel */
},
};
MODULE_DEVICE_TABLE(of, mtk_spmi_pmif_mpu_match_table);
static struct platform_driver mtk_spmi_pmif_mpu_driver = {
.driver = {
.name = "spmi-mtk-mpu",
.of_match_table = of_match_ptr(mtk_spmi_pmif_mpu_match_table),
},
.probe = mtk_spmi_pmif_mpu_probe,
.remove = mtk_spmi_pmif_mpu_remove,
};
module_platform_driver(mtk_spmi_pmif_mpu_driver);
MODULE_DESCRIPTION("MediaTek SPMI PMIF MPU Driver");
MODULE_LICENSE("GPL");