linux/drivers/clk/bcm/clk-sr.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * Copyright 2017 Broadcom
   4 */
   5
   6#include <linux/err.h>
   7#include <linux/clk-provider.h>
   8#include <linux/of_device.h>
   9#include <linux/platform_device.h>
  10
  11#include <dt-bindings/clock/bcm-sr.h>
  12#include "clk-iproc.h"
  13
  14#define REG_VAL(o, s, w) { .offset = o, .shift = s, .width = w, }
  15
  16#define AON_VAL(o, pw, ps, is) { .offset = o, .pwr_width = pw, \
  17        .pwr_shift = ps, .iso_shift = is }
  18
  19#define SW_CTRL_VAL(o, s) { .offset = o, .shift = s, }
  20
  21#define RESET_VAL(o, rs, prs) { .offset = o, .reset_shift = rs, \
  22        .p_reset_shift = prs }
  23
  24#define DF_VAL(o, kis, kiw, kps, kpw, kas, kaw) { .offset = o, \
  25        .ki_shift = kis, .ki_width = kiw, .kp_shift = kps, .kp_width = kpw, \
  26        .ka_shift = kas, .ka_width = kaw }
  27
  28#define VCO_CTRL_VAL(uo, lo) { .u_offset = uo, .l_offset = lo }
  29
  30#define ENABLE_VAL(o, es, hs, bs) { .offset = o, .enable_shift = es, \
  31        .hold_shift = hs, .bypass_shift = bs }
  32
  33
  34static const struct iproc_pll_ctrl sr_genpll0 = {
  35        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
  36                IPROC_CLK_PLL_NEEDS_SW_CFG,
  37        .aon = AON_VAL(0x0, 5, 1, 0),
  38        .reset = RESET_VAL(0x0, 12, 11),
  39        .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
  40        .sw_ctrl = SW_CTRL_VAL(0x10, 31),
  41        .ndiv_int = REG_VAL(0x10, 20, 10),
  42        .ndiv_frac = REG_VAL(0x10, 0, 20),
  43        .pdiv = REG_VAL(0x14, 0, 4),
  44        .status = REG_VAL(0x30, 12, 1),
  45};
  46
  47static const struct iproc_clk_ctrl sr_genpll0_clk[] = {
  48        [BCM_SR_GENPLL0_125M_CLK] = {
  49                .channel = BCM_SR_GENPLL0_125M_CLK,
  50                .flags = IPROC_CLK_AON,
  51                .enable = ENABLE_VAL(0x4, 6, 0, 12),
  52                .mdiv = REG_VAL(0x18, 0, 9),
  53        },
  54        [BCM_SR_GENPLL0_SCR_CLK] = {
  55                .channel = BCM_SR_GENPLL0_SCR_CLK,
  56                .flags = IPROC_CLK_AON,
  57                .enable = ENABLE_VAL(0x4, 7, 1, 13),
  58                .mdiv = REG_VAL(0x18, 10, 9),
  59        },
  60        [BCM_SR_GENPLL0_250M_CLK] = {
  61                .channel = BCM_SR_GENPLL0_250M_CLK,
  62                .flags = IPROC_CLK_AON,
  63                .enable = ENABLE_VAL(0x4, 8, 2, 14),
  64                .mdiv = REG_VAL(0x18, 20, 9),
  65        },
  66        [BCM_SR_GENPLL0_PCIE_AXI_CLK] = {
  67                .channel = BCM_SR_GENPLL0_PCIE_AXI_CLK,
  68                .flags = IPROC_CLK_AON,
  69                .enable = ENABLE_VAL(0x4, 9, 3, 15),
  70                .mdiv = REG_VAL(0x1c, 0, 9),
  71        },
  72        [BCM_SR_GENPLL0_PAXC_AXI_X2_CLK] = {
  73                .channel = BCM_SR_GENPLL0_PAXC_AXI_X2_CLK,
  74                .flags = IPROC_CLK_AON,
  75                .enable = ENABLE_VAL(0x4, 10, 4, 16),
  76                .mdiv = REG_VAL(0x1c, 10, 9),
  77        },
  78        [BCM_SR_GENPLL0_PAXC_AXI_CLK] = {
  79                .channel = BCM_SR_GENPLL0_PAXC_AXI_CLK,
  80                .flags = IPROC_CLK_AON,
  81                .enable = ENABLE_VAL(0x4, 11, 5, 17),
  82                .mdiv = REG_VAL(0x1c, 20, 9),
  83        },
  84};
  85
  86static int sr_genpll0_clk_init(struct platform_device *pdev)
  87{
  88        iproc_pll_clk_setup(pdev->dev.of_node,
  89                            &sr_genpll0, NULL, 0, sr_genpll0_clk,
  90                            ARRAY_SIZE(sr_genpll0_clk));
  91        return 0;
  92}
  93
  94static const struct iproc_pll_ctrl sr_genpll2 = {
  95        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
  96                IPROC_CLK_PLL_NEEDS_SW_CFG,
  97        .aon = AON_VAL(0x0, 1, 13, 12),
  98        .reset = RESET_VAL(0x0, 12, 11),
  99        .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
 100        .sw_ctrl = SW_CTRL_VAL(0x10, 31),
 101        .ndiv_int = REG_VAL(0x10, 20, 10),
 102        .ndiv_frac = REG_VAL(0x10, 0, 20),
 103        .pdiv = REG_VAL(0x14, 0, 4),
 104        .status = REG_VAL(0x30, 12, 1),
 105};
 106
 107static const struct iproc_clk_ctrl sr_genpll2_clk[] = {
 108        [BCM_SR_GENPLL2_NIC_CLK] = {
 109                .channel = BCM_SR_GENPLL2_NIC_CLK,
 110                .flags = IPROC_CLK_AON,
 111                .enable = ENABLE_VAL(0x4, 6, 0, 12),
 112                .mdiv = REG_VAL(0x18, 0, 9),
 113        },
 114        [BCM_SR_GENPLL2_TS_500_CLK] = {
 115                .channel = BCM_SR_GENPLL2_TS_500_CLK,
 116                .flags = IPROC_CLK_AON,
 117                .enable = ENABLE_VAL(0x4, 7, 1, 13),
 118                .mdiv = REG_VAL(0x18, 10, 9),
 119        },
 120        [BCM_SR_GENPLL2_125_NITRO_CLK] = {
 121                .channel = BCM_SR_GENPLL2_125_NITRO_CLK,
 122                .flags = IPROC_CLK_AON,
 123                .enable = ENABLE_VAL(0x4, 8, 2, 14),
 124                .mdiv = REG_VAL(0x18, 20, 9),
 125        },
 126        [BCM_SR_GENPLL2_CHIMP_CLK] = {
 127                .channel = BCM_SR_GENPLL2_CHIMP_CLK,
 128                .flags = IPROC_CLK_AON,
 129                .enable = ENABLE_VAL(0x4, 9, 3, 15),
 130                .mdiv = REG_VAL(0x1c, 0, 9),
 131        },
 132        [BCM_SR_GENPLL2_NIC_FLASH_CLK] = {
 133                .channel = BCM_SR_GENPLL2_NIC_FLASH_CLK,
 134                .flags = IPROC_CLK_AON,
 135                .enable = ENABLE_VAL(0x4, 10, 4, 16),
 136                .mdiv = REG_VAL(0x1c, 10, 9),
 137        },
 138        [BCM_SR_GENPLL2_FS4_CLK] = {
 139                .channel = BCM_SR_GENPLL2_FS4_CLK,
 140                .enable = ENABLE_VAL(0x4, 11, 5, 17),
 141                .mdiv = REG_VAL(0x1c, 20, 9),
 142        },
 143};
 144
 145static int sr_genpll2_clk_init(struct platform_device *pdev)
 146{
 147        iproc_pll_clk_setup(pdev->dev.of_node,
 148                            &sr_genpll2, NULL, 0, sr_genpll2_clk,
 149                            ARRAY_SIZE(sr_genpll2_clk));
 150        return 0;
 151}
 152
 153static const struct iproc_pll_ctrl sr_genpll3 = {
 154        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
 155                IPROC_CLK_PLL_NEEDS_SW_CFG,
 156        .aon = AON_VAL(0x0, 1, 19, 18),
 157        .reset = RESET_VAL(0x0, 12, 11),
 158        .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
 159        .sw_ctrl = SW_CTRL_VAL(0x10, 31),
 160        .ndiv_int = REG_VAL(0x10, 20, 10),
 161        .ndiv_frac = REG_VAL(0x10, 0, 20),
 162        .pdiv = REG_VAL(0x14, 0, 4),
 163        .status = REG_VAL(0x30, 12, 1),
 164};
 165
 166static const struct iproc_clk_ctrl sr_genpll3_clk[] = {
 167        [BCM_SR_GENPLL3_HSLS_CLK] = {
 168                .channel = BCM_SR_GENPLL3_HSLS_CLK,
 169                .flags = IPROC_CLK_AON,
 170                .enable = ENABLE_VAL(0x4, 6, 0, 12),
 171                .mdiv = REG_VAL(0x18, 0, 9),
 172        },
 173        [BCM_SR_GENPLL3_SDIO_CLK] = {
 174                .channel = BCM_SR_GENPLL3_SDIO_CLK,
 175                .flags = IPROC_CLK_AON,
 176                .enable = ENABLE_VAL(0x4, 7, 1, 13),
 177                .mdiv = REG_VAL(0x18, 10, 9),
 178        },
 179};
 180
 181static void sr_genpll3_clk_init(struct device_node *node)
 182{
 183        iproc_pll_clk_setup(node, &sr_genpll3, NULL, 0, sr_genpll3_clk,
 184                            ARRAY_SIZE(sr_genpll3_clk));
 185}
 186CLK_OF_DECLARE(sr_genpll3_clk, "brcm,sr-genpll3", sr_genpll3_clk_init);
 187
 188static const struct iproc_pll_ctrl sr_genpll4 = {
 189        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
 190                IPROC_CLK_PLL_NEEDS_SW_CFG,
 191        .aon = AON_VAL(0x0, 1, 25, 24),
 192        .reset = RESET_VAL(0x0, 12, 11),
 193        .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
 194        .sw_ctrl = SW_CTRL_VAL(0x10, 31),
 195        .ndiv_int = REG_VAL(0x10, 20, 10),
 196        .ndiv_frac = REG_VAL(0x10, 0, 20),
 197        .pdiv = REG_VAL(0x14, 0, 4),
 198        .status = REG_VAL(0x30, 12, 1),
 199};
 200
 201static const struct iproc_clk_ctrl sr_genpll4_clk[] = {
 202        [BCM_SR_GENPLL4_CCN_CLK] = {
 203                .channel = BCM_SR_GENPLL4_CCN_CLK,
 204                .flags = IPROC_CLK_AON,
 205                .enable = ENABLE_VAL(0x4, 6, 0, 12),
 206                .mdiv = REG_VAL(0x18, 0, 9),
 207        },
 208        [BCM_SR_GENPLL4_TPIU_PLL_CLK] = {
 209                .channel = BCM_SR_GENPLL4_TPIU_PLL_CLK,
 210                .flags = IPROC_CLK_AON,
 211                .enable = ENABLE_VAL(0x4, 7, 1, 13),
 212                .mdiv = REG_VAL(0x18, 10, 9),
 213        },
 214        [BCM_SR_GENPLL4_NOC_CLK] = {
 215                .channel = BCM_SR_GENPLL4_NOC_CLK,
 216                .flags = IPROC_CLK_AON,
 217                .enable = ENABLE_VAL(0x4, 8, 2, 14),
 218                .mdiv = REG_VAL(0x18, 20, 9),
 219        },
 220        [BCM_SR_GENPLL4_CHCLK_FS4_CLK] = {
 221                .channel = BCM_SR_GENPLL4_CHCLK_FS4_CLK,
 222                .flags = IPROC_CLK_AON,
 223                .enable = ENABLE_VAL(0x4, 9, 3, 15),
 224                .mdiv = REG_VAL(0x1c, 0, 9),
 225        },
 226        [BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK] = {
 227                .channel = BCM_SR_GENPLL4_BRIDGE_FSCPU_CLK,
 228                .flags = IPROC_CLK_AON,
 229                .enable = ENABLE_VAL(0x4, 10, 4, 16),
 230                .mdiv = REG_VAL(0x1c, 10, 9),
 231        },
 232};
 233
 234static int sr_genpll4_clk_init(struct platform_device *pdev)
 235{
 236        iproc_pll_clk_setup(pdev->dev.of_node,
 237                            &sr_genpll4, NULL, 0, sr_genpll4_clk,
 238                            ARRAY_SIZE(sr_genpll4_clk));
 239        return 0;
 240}
 241
 242static const struct iproc_pll_ctrl sr_genpll5 = {
 243        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_HAS_NDIV_FRAC |
 244                IPROC_CLK_PLL_NEEDS_SW_CFG,
 245        .aon = AON_VAL(0x0, 1, 1, 0),
 246        .reset = RESET_VAL(0x0, 12, 11),
 247        .dig_filter = DF_VAL(0x0, 4, 3, 0, 4, 7, 3),
 248        .sw_ctrl = SW_CTRL_VAL(0x10, 31),
 249        .ndiv_int = REG_VAL(0x10, 20, 10),
 250        .ndiv_frac = REG_VAL(0x10, 0, 20),
 251        .pdiv = REG_VAL(0x14, 0, 4),
 252        .status = REG_VAL(0x30, 12, 1),
 253};
 254
 255static const struct iproc_clk_ctrl sr_genpll5_clk[] = {
 256        [BCM_SR_GENPLL5_FS4_HF_CLK] = {
 257                .channel = BCM_SR_GENPLL5_FS4_HF_CLK,
 258                .enable = ENABLE_VAL(0x4, 6, 0, 12),
 259                .mdiv = REG_VAL(0x18, 0, 9),
 260        },
 261        [BCM_SR_GENPLL5_CRYPTO_AE_CLK] = {
 262                .channel = BCM_SR_GENPLL5_CRYPTO_AE_CLK,
 263                .enable = ENABLE_VAL(0x4, 7, 1, 12),
 264                .mdiv = REG_VAL(0x18, 10, 9),
 265        },
 266        [BCM_SR_GENPLL5_RAID_AE_CLK] = {
 267                .channel = BCM_SR_GENPLL5_RAID_AE_CLK,
 268                .enable = ENABLE_VAL(0x4, 8, 2, 14),
 269                .mdiv = REG_VAL(0x18, 20, 9),
 270        },
 271};
 272
 273static int sr_genpll5_clk_init(struct platform_device *pdev)
 274{
 275        iproc_pll_clk_setup(pdev->dev.of_node,
 276                            &sr_genpll5, NULL, 0, sr_genpll5_clk,
 277                            ARRAY_SIZE(sr_genpll5_clk));
 278        return 0;
 279}
 280
 281static const struct iproc_pll_ctrl sr_lcpll0 = {
 282        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
 283        .aon = AON_VAL(0x0, 2, 19, 18),
 284        .reset = RESET_VAL(0x0, 31, 30),
 285        .sw_ctrl = SW_CTRL_VAL(0x4, 31),
 286        .ndiv_int = REG_VAL(0x4, 16, 10),
 287        .pdiv = REG_VAL(0x4, 26, 4),
 288        .status = REG_VAL(0x38, 12, 1),
 289};
 290
 291static const struct iproc_clk_ctrl sr_lcpll0_clk[] = {
 292        [BCM_SR_LCPLL0_SATA_REFP_CLK] = {
 293                .channel = BCM_SR_LCPLL0_SATA_REFP_CLK,
 294                .flags = IPROC_CLK_AON,
 295                .enable = ENABLE_VAL(0x0, 7, 1, 13),
 296                .mdiv = REG_VAL(0x14, 0, 9),
 297        },
 298        [BCM_SR_LCPLL0_SATA_REFN_CLK] = {
 299                .channel = BCM_SR_LCPLL0_SATA_REFN_CLK,
 300                .flags = IPROC_CLK_AON,
 301                .enable = ENABLE_VAL(0x0, 8, 2, 14),
 302                .mdiv = REG_VAL(0x14, 10, 9),
 303        },
 304        [BCM_SR_LCPLL0_SATA_350_CLK] = {
 305                .channel = BCM_SR_LCPLL0_SATA_350_CLK,
 306                .flags = IPROC_CLK_AON,
 307                .enable = ENABLE_VAL(0x0, 9, 3, 15),
 308                .mdiv = REG_VAL(0x14, 20, 9),
 309        },
 310        [BCM_SR_LCPLL0_SATA_500_CLK] = {
 311                .channel = BCM_SR_LCPLL0_SATA_500_CLK,
 312                .flags = IPROC_CLK_AON,
 313                .enable = ENABLE_VAL(0x0, 10, 4, 16),
 314                .mdiv = REG_VAL(0x18, 0, 9),
 315        },
 316};
 317
 318static int sr_lcpll0_clk_init(struct platform_device *pdev)
 319{
 320        iproc_pll_clk_setup(pdev->dev.of_node,
 321                            &sr_lcpll0, NULL, 0, sr_lcpll0_clk,
 322                            ARRAY_SIZE(sr_lcpll0_clk));
 323        return 0;
 324}
 325
 326static const struct iproc_pll_ctrl sr_lcpll1 = {
 327        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
 328        .aon = AON_VAL(0x0, 2, 22, 21),
 329        .reset = RESET_VAL(0x0, 31, 30),
 330        .sw_ctrl = SW_CTRL_VAL(0x4, 31),
 331        .ndiv_int = REG_VAL(0x4, 16, 10),
 332        .pdiv = REG_VAL(0x4, 26, 4),
 333        .status = REG_VAL(0x38, 12, 1),
 334};
 335
 336static const struct iproc_clk_ctrl sr_lcpll1_clk[] = {
 337        [BCM_SR_LCPLL1_WAN_CLK] = {
 338                .channel = BCM_SR_LCPLL1_WAN_CLK,
 339                .flags = IPROC_CLK_AON,
 340                .enable = ENABLE_VAL(0x0, 7, 1, 13),
 341                .mdiv = REG_VAL(0x14, 0, 9),
 342        },
 343        [BCM_SR_LCPLL1_USB_REF_CLK] = {
 344                .channel = BCM_SR_LCPLL1_USB_REF_CLK,
 345                .flags = IPROC_CLK_AON,
 346                .enable = ENABLE_VAL(0x0, 8, 2, 14),
 347                .mdiv = REG_VAL(0x14, 10, 9),
 348        },
 349        [BCM_SR_LCPLL1_CRMU_TS_CLK] = {
 350                .channel = BCM_SR_LCPLL1_CRMU_TS_CLK,
 351                .flags = IPROC_CLK_AON,
 352                .enable = ENABLE_VAL(0x0, 9, 3, 15),
 353                .mdiv = REG_VAL(0x14, 20, 9),
 354        },
 355};
 356
 357static int sr_lcpll1_clk_init(struct platform_device *pdev)
 358{
 359        iproc_pll_clk_setup(pdev->dev.of_node,
 360                            &sr_lcpll1, NULL, 0, sr_lcpll1_clk,
 361                            ARRAY_SIZE(sr_lcpll1_clk));
 362        return 0;
 363}
 364
 365static const struct iproc_pll_ctrl sr_lcpll_pcie = {
 366        .flags = IPROC_CLK_AON | IPROC_CLK_PLL_NEEDS_SW_CFG,
 367        .aon = AON_VAL(0x0, 2, 25, 24),
 368        .reset = RESET_VAL(0x0, 31, 30),
 369        .sw_ctrl = SW_CTRL_VAL(0x4, 31),
 370        .ndiv_int = REG_VAL(0x4, 16, 10),
 371        .pdiv = REG_VAL(0x4, 26, 4),
 372        .status = REG_VAL(0x38, 12, 1),
 373};
 374
 375static const struct iproc_clk_ctrl sr_lcpll_pcie_clk[] = {
 376        [BCM_SR_LCPLL_PCIE_PHY_REF_CLK] = {
 377                .channel = BCM_SR_LCPLL_PCIE_PHY_REF_CLK,
 378                .flags = IPROC_CLK_AON,
 379                .enable = ENABLE_VAL(0x0, 7, 1, 13),
 380                .mdiv = REG_VAL(0x14, 0, 9),
 381        },
 382};
 383
 384static int sr_lcpll_pcie_clk_init(struct platform_device *pdev)
 385{
 386        iproc_pll_clk_setup(pdev->dev.of_node,
 387                            &sr_lcpll_pcie, NULL, 0, sr_lcpll_pcie_clk,
 388                            ARRAY_SIZE(sr_lcpll_pcie_clk));
 389        return 0;
 390}
 391
 392static const struct of_device_id sr_clk_dt_ids[] = {
 393        { .compatible = "brcm,sr-genpll0", .data = sr_genpll0_clk_init },
 394        { .compatible = "brcm,sr-genpll2", .data = sr_genpll2_clk_init },
 395        { .compatible = "brcm,sr-genpll4", .data = sr_genpll4_clk_init },
 396        { .compatible = "brcm,sr-genpll5", .data = sr_genpll5_clk_init },
 397        { .compatible = "brcm,sr-lcpll0", .data = sr_lcpll0_clk_init },
 398        { .compatible = "brcm,sr-lcpll1", .data = sr_lcpll1_clk_init },
 399        { .compatible = "brcm,sr-lcpll-pcie", .data = sr_lcpll_pcie_clk_init },
 400        { /* sentinel */ }
 401};
 402
 403static int sr_clk_probe(struct platform_device *pdev)
 404{
 405        int (*probe_func)(struct platform_device *);
 406
 407        probe_func = of_device_get_match_data(&pdev->dev);
 408        if (!probe_func)
 409                return -ENODEV;
 410
 411        return probe_func(pdev);
 412}
 413
 414static struct platform_driver sr_clk_driver = {
 415        .driver = {
 416                .name = "sr-clk",
 417                .of_match_table = sr_clk_dt_ids,
 418        },
 419        .probe = sr_clk_probe,
 420};
 421builtin_platform_driver(sr_clk_driver);
 422