Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 //
0003 // Copyright (c) 2021 MediaTek Inc.
0004 // Author: Chun-Jie Chen <chun-jie.chen@mediatek.com>
0005 
0006 #include "clk-mtk.h"
0007 #include "clk-pll.h"
0008 
0009 #include <dt-bindings/clock/mt8195-clk.h>
0010 #include <linux/clk-provider.h>
0011 #include <linux/platform_device.h>
0012 
0013 #define MT8195_PLL_FMAX     (3800UL * MHZ)
0014 #define MT8195_PLL_FMIN     (1500UL * MHZ)
0015 #define MT8195_INTEGER_BITS (8)
0016 #define MT8195_PCW_BITS     (22)
0017 #define MT8195_POSDIV_SHIFT (24)
0018 #define MT8195_PLL_EN_BIT   (0)
0019 #define MT8195_PCW_SHIFT    (0)
0020 
0021 /*
0022  * The "en_reg" and "pcw_chg_reg" fields are standard offset register compared
0023  * with "reg" field, so set zero to imply it.
0024  * No tuner control in apu pll, so set "tuner_XXX" as zero to imply it.
0025  * No rst or post divider enable in apu pll, so set "rst_bar_mask" and "en_mask"
0026  * as zero to imply it.
0027  */
0028 #define PLL(_id, _name, _reg, _pwr_reg, _pd_reg, _pcw_reg) {        \
0029         .id = _id,                      \
0030         .name = _name,                      \
0031         .reg = _reg,                        \
0032         .pwr_reg = _pwr_reg,                    \
0033         .en_mask = 0,                       \
0034         .flags = 0,                     \
0035         .rst_bar_mask = 0,                  \
0036         .fmax = MT8195_PLL_FMAX,                \
0037         .fmin = MT8195_PLL_FMIN,                \
0038         .pcwbits = MT8195_PCW_BITS,             \
0039         .pcwibits = MT8195_INTEGER_BITS,            \
0040         .pd_reg = _pd_reg,                  \
0041         .pd_shift = MT8195_POSDIV_SHIFT,            \
0042         .tuner_reg = 0,                     \
0043         .tuner_en_reg = 0,                  \
0044         .tuner_en_bit = 0,                  \
0045         .pcw_reg = _pcw_reg,                    \
0046         .pcw_shift = MT8195_PCW_SHIFT,              \
0047         .pcw_chg_reg = 0,                   \
0048         .en_reg = 0,                        \
0049         .pll_en_bit = MT8195_PLL_EN_BIT,            \
0050     }
0051 
0052 static const struct mtk_pll_data apusys_plls[] = {
0053     PLL(CLK_APUSYS_PLL_APUPLL, "apusys_pll_apupll", 0x008, 0x014, 0x00c, 0x00c),
0054     PLL(CLK_APUSYS_PLL_NPUPLL, "apusys_pll_npupll", 0x018, 0x024, 0x01c, 0x01c),
0055     PLL(CLK_APUSYS_PLL_APUPLL1, "apusys_pll_apupll1", 0x028, 0x034, 0x02c, 0x02c),
0056     PLL(CLK_APUSYS_PLL_APUPLL2, "apusys_pll_apupll2", 0x038, 0x044, 0x03c, 0x03c),
0057 };
0058 
0059 static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev)
0060 {
0061     struct clk_hw_onecell_data *clk_data;
0062     struct device_node *node = pdev->dev.of_node;
0063     int r;
0064 
0065     clk_data = mtk_alloc_clk_data(CLK_APUSYS_PLL_NR_CLK);
0066     if (!clk_data)
0067         return -ENOMEM;
0068 
0069     r = mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
0070     if (r)
0071         goto free_apusys_pll_data;
0072 
0073     r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
0074     if (r)
0075         goto unregister_plls;
0076 
0077     platform_set_drvdata(pdev, clk_data);
0078 
0079     return r;
0080 
0081 unregister_plls:
0082     mtk_clk_unregister_plls(apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
0083 free_apusys_pll_data:
0084     mtk_free_clk_data(clk_data);
0085     return r;
0086 }
0087 
0088 static int clk_mt8195_apusys_pll_remove(struct platform_device *pdev)
0089 {
0090     struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
0091     struct device_node *node = pdev->dev.of_node;
0092 
0093     of_clk_del_provider(node);
0094     mtk_clk_unregister_plls(apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
0095     mtk_free_clk_data(clk_data);
0096 
0097     return 0;
0098 }
0099 
0100 static const struct of_device_id of_match_clk_mt8195_apusys_pll[] = {
0101     { .compatible = "mediatek,mt8195-apusys_pll", },
0102     {}
0103 };
0104 
0105 static struct platform_driver clk_mt8195_apusys_pll_drv = {
0106     .probe = clk_mt8195_apusys_pll_probe,
0107     .remove = clk_mt8195_apusys_pll_remove,
0108     .driver = {
0109         .name = "clk-mt8195-apusys_pll",
0110         .of_match_table = of_match_clk_mt8195_apusys_pll,
0111     },
0112 };
0113 builtin_platform_driver(clk_mt8195_apusys_pll_drv);