soc: rockchip: grf: Add platform driver for edp phy grf

We need to overwrite the default register value to put the PHY into
low power mode in idle state.

Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
Change-Id: I4c788ce04880d6e25d4454e5594882d511b0bc97
This commit is contained in:
Wyon Bi
2022-02-14 16:51:59 +08:00
committed by Tao Huang
parent a9a635ccaa
commit 2cbb25ad93

View File

@@ -5,6 +5,7 @@
* Copyright (c) 2016 Heiko Stuebner <heiko@sntech.de>
*/
#include <linux/bitfield.h>
#include <linux/err.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
@@ -12,6 +13,97 @@
#include <linux/platform_device.h>
#include <linux/regmap.h>
struct rockchip_grf;
struct rockchip_grf_funcs {
int (*reset)(struct rockchip_grf *grf);
};
struct rockchip_grf {
struct regmap *regmap;
const struct rockchip_grf_funcs *funcs;
};
static int rockchip_edp_phy_grf_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct rockchip_grf *grf;
int ret;
grf = devm_kzalloc(dev, sizeof(*grf), GFP_KERNEL);
if (!grf)
return -ENOMEM;
grf->funcs = of_device_get_match_data(dev);
if (!grf->funcs)
return -ENODEV;
grf->regmap = syscon_node_to_regmap(dev->of_node);
if (IS_ERR(grf->regmap)) {
ret = PTR_ERR(grf->regmap);
dev_err(dev, "failed to get grf: %d\n", ret);
return ret;
}
ret = grf->funcs->reset(grf);
if (ret)
return ret;
platform_set_drvdata(pdev, grf);
return 0;
}
static int __maybe_unused rockchip_edp_phy_grf_resume(struct device *dev)
{
struct rockchip_grf *grf = dev_get_drvdata(dev);
return grf->funcs->reset(grf);
}
static const struct dev_pm_ops rockchip_edp_phy_grf_pm_ops = {
SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, rockchip_edp_phy_grf_resume)
};
static int rk3568_edp_phy_grf_reset(struct rockchip_grf *grf)
{
u32 status;
int ret;
ret = regmap_read(grf->regmap, 0x0030, &status);
if (ret < 0)
return ret;
if (!FIELD_GET(0x1, status)) {
regmap_write(grf->regmap, 0x0028, 0x00070007);
regmap_write(grf->regmap, 0x0000, 0x0ff10ff1);
}
return 0;
}
static const struct rockchip_grf_funcs rk3568_edp_phy_grf_funcs = {
.reset = rk3568_edp_phy_grf_reset,
};
static const struct of_device_id rockchip_edp_phy_grf_match[] = {
{
.compatible = "rockchip,rk3568-edp-phy-grf",
.data = &rk3568_edp_phy_grf_funcs,
},
{}
};
MODULE_DEVICE_TABLE(of, rockchip_edp_phy_grf_match);
static struct platform_driver rockchip_edp_phy_grf_driver = {
.driver = {
.name = "rockchip-edp-phy-grf",
.of_match_table = rockchip_edp_phy_grf_match,
.pm = &rockchip_edp_phy_grf_pm_ops,
},
.probe = rockchip_edp_phy_grf_probe,
};
#define HIWORD_UPDATE(val, mask, shift) \
((val) << (shift) | (mask) << ((shift) + 16))
@@ -204,6 +296,10 @@ static int __init rockchip_grf_init(void)
struct regmap *grf;
int ret, i;
ret = platform_driver_register(&rockchip_edp_phy_grf_driver);
if (ret)
return ret;
np = of_find_matching_node_and_match(NULL, rockchip_grf_dt_match,
&match);
if (!np)