diff options
Diffstat (limited to 'drivers/clk')
-rw-r--r-- | drivers/clk/mediatek/clk-mt8183.c | 16 | ||||
-rw-r--r-- | drivers/clk/mediatek/clk-mtk.h | 3 | ||||
-rw-r--r-- | drivers/clk/mediatek/reset.c | 56 |
3 files changed, 71 insertions, 4 deletions
diff --git a/drivers/clk/mediatek/clk-mt8183.c b/drivers/clk/mediatek/clk-mt8183.c index 1aa5f4059251..94bbadc0d259 100644 --- a/drivers/clk/mediatek/clk-mt8183.c +++ b/drivers/clk/mediatek/clk-mt8183.c @@ -17,6 +17,9 @@ #include <dt-bindings/clock/mt8183-clk.h> +/* Infra global controller reset set register */ +#define INFRA_RST0_SET_OFFSET 0x120 + static DEFINE_SPINLOCK(mt8183_clk_lock); static const struct mtk_fixed_clk top_fixed_clks[] = { @@ -1185,13 +1188,24 @@ static int clk_mt8183_infra_probe(struct platform_device *pdev) { struct clk_onecell_data *clk_data; struct device_node *node = pdev->dev.of_node; + int r; clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK); mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks), clk_data); - return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data); + if (r) { + dev_err(&pdev->dev, + "%s(): could not register clock provider: %d\n", + __func__, r); + return r; + } + + mtk_register_reset_controller_set_clr(node, 4, INFRA_RST0_SET_OFFSET); + + return r; } static int clk_mt8183_mcu_probe(struct platform_device *pdev) diff --git a/drivers/clk/mediatek/clk-mtk.h b/drivers/clk/mediatek/clk-mtk.h index 733a11d1de94..2e9e26084798 100644 --- a/drivers/clk/mediatek/clk-mtk.h +++ b/drivers/clk/mediatek/clk-mtk.h @@ -240,4 +240,7 @@ struct clk *mtk_clk_register_ref2usb_tx(const char *name, void mtk_register_reset_controller(struct device_node *np, unsigned int num_regs, int regofs); +void mtk_register_reset_controller_set_clr(struct device_node *np, + unsigned int num_regs, int regofs); + #endif /* __DRV_CLK_MTK_H */ diff --git a/drivers/clk/mediatek/reset.c b/drivers/clk/mediatek/reset.c index d8376b92349e..cb939c071b0c 100644 --- a/drivers/clk/mediatek/reset.c +++ b/drivers/clk/mediatek/reset.c @@ -19,6 +19,24 @@ struct mtk_reset { struct reset_controller_dev rcdev; }; +static int mtk_reset_assert_set_clr(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); + unsigned int reg = data->regofs + ((id / 32) << 4); + + return regmap_write(data->regmap, reg, 1); +} + +static int mtk_reset_deassert_set_clr(struct reset_controller_dev *rcdev, + unsigned long id) +{ + struct mtk_reset *data = container_of(rcdev, struct mtk_reset, rcdev); + unsigned int reg = data->regofs + ((id / 32) << 4) + 0x4; + + return regmap_write(data->regmap, reg, 1); +} + static int mtk_reset_assert(struct reset_controller_dev *rcdev, unsigned long id) { @@ -49,14 +67,32 @@ static int mtk_reset(struct reset_controller_dev *rcdev, return mtk_reset_deassert(rcdev, id); } +static int mtk_reset_set_clr(struct reset_controller_dev *rcdev, + unsigned long id) +{ + int ret; + + ret = mtk_reset_assert_set_clr(rcdev, id); + if (ret) + return ret; + return mtk_reset_deassert_set_clr(rcdev, id); +} + static const struct reset_control_ops mtk_reset_ops = { .assert = mtk_reset_assert, .deassert = mtk_reset_deassert, .reset = mtk_reset, }; -void mtk_register_reset_controller(struct device_node *np, - unsigned int num_regs, int regofs) +static const struct reset_control_ops mtk_reset_ops_set_clr = { + .assert = mtk_reset_assert_set_clr, + .deassert = mtk_reset_deassert_set_clr, + .reset = mtk_reset_set_clr, +}; + +static void mtk_register_reset_controller_common(struct device_node *np, + unsigned int num_regs, int regofs, + const struct reset_control_ops *reset_ops) { struct mtk_reset *data; int ret; @@ -77,7 +113,7 @@ void mtk_register_reset_controller(struct device_node *np, data->regofs = regofs; data->rcdev.owner = THIS_MODULE; data->rcdev.nr_resets = num_regs * 32; - data->rcdev.ops = &mtk_reset_ops; + data->rcdev.ops = reset_ops; data->rcdev.of_node = np; ret = reset_controller_register(&data->rcdev); @@ -87,3 +123,17 @@ void mtk_register_reset_controller(struct device_node *np, return; } } + +void mtk_register_reset_controller(struct device_node *np, + unsigned int num_regs, int regofs) +{ + mtk_register_reset_controller_common(np, num_regs, regofs, + &mtk_reset_ops); +} + +void mtk_register_reset_controller_set_clr(struct device_node *np, + unsigned int num_regs, int regofs) +{ + mtk_register_reset_controller_common(np, num_regs, regofs, + &mtk_reset_ops_set_clr); +} |