1*140f074cSJian Hu // SPDX-License-Identifier: (GPL-2.0-only OR MIT) 2*140f074cSJian Hu /* 3*140f074cSJian Hu * Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved. 4*140f074cSJian Hu * Author: Jian Hu <jian.hu@amlogic.com> 5*140f074cSJian Hu */ 6*140f074cSJian Hu 7*140f074cSJian Hu #include <linux/clk-provider.h> 8*140f074cSJian Hu #include <linux/platform_device.h> 9*140f074cSJian Hu #include "clk-regmap.h" 10*140f074cSJian Hu #include "clk-pll.h" 11*140f074cSJian Hu #include "clk-mpll.h" 12*140f074cSJian Hu #include "meson-clkc-utils.h" 13*140f074cSJian Hu #include <dt-bindings/clock/amlogic,t7-pll-clkc.h> 14*140f074cSJian Hu 15*140f074cSJian Hu #define GP0PLL_CTRL0 0x00 16*140f074cSJian Hu #define GP0PLL_CTRL1 0x04 17*140f074cSJian Hu #define GP0PLL_CTRL2 0x08 18*140f074cSJian Hu #define GP0PLL_CTRL3 0x0c 19*140f074cSJian Hu #define GP0PLL_CTRL4 0x10 20*140f074cSJian Hu #define GP0PLL_CTRL5 0x14 21*140f074cSJian Hu #define GP0PLL_CTRL6 0x18 22*140f074cSJian Hu #define GP0PLL_STS 0x1c 23*140f074cSJian Hu 24*140f074cSJian Hu #define GP1PLL_CTRL0 0x00 25*140f074cSJian Hu #define GP1PLL_CTRL1 0x04 26*140f074cSJian Hu #define GP1PLL_CTRL2 0x08 27*140f074cSJian Hu #define GP1PLL_CTRL3 0x0c 28*140f074cSJian Hu #define GP1PLL_STS 0x1c 29*140f074cSJian Hu 30*140f074cSJian Hu #define HIFIPLL_CTRL0 0x00 31*140f074cSJian Hu #define HIFIPLL_CTRL1 0x04 32*140f074cSJian Hu #define HIFIPLL_CTRL2 0x08 33*140f074cSJian Hu #define HIFIPLL_CTRL3 0x0c 34*140f074cSJian Hu #define HIFIPLL_CTRL4 0x10 35*140f074cSJian Hu #define HIFIPLL_CTRL5 0x14 36*140f074cSJian Hu #define HIFIPLL_CTRL6 0x18 37*140f074cSJian Hu #define HIFIPLL_STS 0x1c 38*140f074cSJian Hu 39*140f074cSJian Hu #define PCIEPLL_CTRL0 0x00 40*140f074cSJian Hu #define PCIEPLL_CTRL1 0x04 41*140f074cSJian Hu #define PCIEPLL_CTRL2 0x08 42*140f074cSJian Hu #define PCIEPLL_CTRL3 0x0c 43*140f074cSJian Hu #define PCIEPLL_CTRL4 0x10 44*140f074cSJian Hu #define PCIEPLL_CTRL5 0x14 45*140f074cSJian Hu #define PCIEPLL_STS 0x18 46*140f074cSJian Hu 47*140f074cSJian Hu #define MPLL_CTRL0 0x00 48*140f074cSJian Hu #define MPLL_CTRL1 0x04 49*140f074cSJian Hu #define MPLL_CTRL2 0x08 50*140f074cSJian Hu #define MPLL_CTRL3 0x0c 51*140f074cSJian Hu #define MPLL_CTRL4 0x10 52*140f074cSJian Hu #define MPLL_CTRL5 0x14 53*140f074cSJian Hu #define MPLL_CTRL6 0x18 54*140f074cSJian Hu #define MPLL_CTRL7 0x1c 55*140f074cSJian Hu #define MPLL_CTRL8 0x20 56*140f074cSJian Hu #define MPLL_STS 0x24 57*140f074cSJian Hu 58*140f074cSJian Hu #define HDMIPLL_CTRL0 0x00 59*140f074cSJian Hu #define HDMIPLL_CTRL1 0x04 60*140f074cSJian Hu #define HDMIPLL_CTRL2 0x08 61*140f074cSJian Hu #define HDMIPLL_CTRL3 0x0c 62*140f074cSJian Hu #define HDMIPLL_CTRL4 0x10 63*140f074cSJian Hu #define HDMIPLL_CTRL5 0x14 64*140f074cSJian Hu #define HDMIPLL_CTRL6 0x18 65*140f074cSJian Hu #define HDMIPLL_STS 0x1c 66*140f074cSJian Hu 67*140f074cSJian Hu #define MCLK_PLL_CNTL0 0x00 68*140f074cSJian Hu #define MCLK_PLL_CNTL1 0x04 69*140f074cSJian Hu #define MCLK_PLL_CNTL2 0x08 70*140f074cSJian Hu #define MCLK_PLL_CNTL3 0x0c 71*140f074cSJian Hu #define MCLK_PLL_CNTL4 0x10 72*140f074cSJian Hu #define MCLK_PLL_STS 0x14 73*140f074cSJian Hu 74*140f074cSJian Hu static const struct pll_mult_range t7_media_pll_mult_range = { 75*140f074cSJian Hu .min = 125, 76*140f074cSJian Hu .max = 250, 77*140f074cSJian Hu }; 78*140f074cSJian Hu 79*140f074cSJian Hu static const struct reg_sequence t7_gp0_init_regs[] = { 80*140f074cSJian Hu { .reg = GP0PLL_CTRL1, .def = 0x00000000 }, 81*140f074cSJian Hu { .reg = GP0PLL_CTRL2, .def = 0x00000000 }, 82*140f074cSJian Hu { .reg = GP0PLL_CTRL3, .def = 0x48681c00 }, 83*140f074cSJian Hu { .reg = GP0PLL_CTRL4, .def = 0x88770290 }, 84*140f074cSJian Hu { .reg = GP0PLL_CTRL5, .def = 0x3927200a }, 85*140f074cSJian Hu { .reg = GP0PLL_CTRL6, .def = 0x56540000 }, 86*140f074cSJian Hu }; 87*140f074cSJian Hu 88*140f074cSJian Hu static struct clk_regmap t7_gp0_pll_dco = { 89*140f074cSJian Hu .data = &(struct meson_clk_pll_data){ 90*140f074cSJian Hu .en = { 91*140f074cSJian Hu .reg_off = GP0PLL_CTRL0, 92*140f074cSJian Hu .shift = 28, 93*140f074cSJian Hu .width = 1, 94*140f074cSJian Hu }, 95*140f074cSJian Hu .m = { 96*140f074cSJian Hu .reg_off = GP0PLL_CTRL0, 97*140f074cSJian Hu .shift = 0, 98*140f074cSJian Hu .width = 8, 99*140f074cSJian Hu }, 100*140f074cSJian Hu .n = { 101*140f074cSJian Hu .reg_off = GP0PLL_CTRL0, 102*140f074cSJian Hu .shift = 10, 103*140f074cSJian Hu .width = 5, 104*140f074cSJian Hu }, 105*140f074cSJian Hu .l = { 106*140f074cSJian Hu .reg_off = GP0PLL_STS, 107*140f074cSJian Hu .shift = 31, 108*140f074cSJian Hu .width = 1, 109*140f074cSJian Hu }, 110*140f074cSJian Hu .rst = { 111*140f074cSJian Hu .reg_off = GP0PLL_CTRL0, 112*140f074cSJian Hu .shift = 29, 113*140f074cSJian Hu .width = 1, 114*140f074cSJian Hu }, 115*140f074cSJian Hu .range = &t7_media_pll_mult_range, 116*140f074cSJian Hu .init_regs = t7_gp0_init_regs, 117*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_gp0_init_regs), 118*140f074cSJian Hu }, 119*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 120*140f074cSJian Hu .name = "gp0_pll_dco", 121*140f074cSJian Hu .ops = &meson_clk_pll_ops, 122*140f074cSJian Hu .parent_data = &(const struct clk_parent_data) { 123*140f074cSJian Hu .fw_name = "in0", 124*140f074cSJian Hu }, 125*140f074cSJian Hu .num_parents = 1, 126*140f074cSJian Hu }, 127*140f074cSJian Hu }; 128*140f074cSJian Hu 129*140f074cSJian Hu static struct clk_regmap t7_gp0_pll = { 130*140f074cSJian Hu .data = &(struct clk_regmap_div_data){ 131*140f074cSJian Hu .offset = GP0PLL_CTRL0, 132*140f074cSJian Hu .shift = 16, 133*140f074cSJian Hu .width = 3, 134*140f074cSJian Hu .flags = CLK_DIVIDER_POWER_OF_TWO, 135*140f074cSJian Hu }, 136*140f074cSJian Hu .hw.init = &(struct clk_init_data) { 137*140f074cSJian Hu .name = "gp0_pll", 138*140f074cSJian Hu .ops = &clk_regmap_divider_ops, 139*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 140*140f074cSJian Hu &t7_gp0_pll_dco.hw 141*140f074cSJian Hu }, 142*140f074cSJian Hu .num_parents = 1, 143*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 144*140f074cSJian Hu }, 145*140f074cSJian Hu }; 146*140f074cSJian Hu 147*140f074cSJian Hu /* 148*140f074cSJian Hu * Compared with GP0 PLL, GP1 PLL is a newly designed PLL with 149*140f074cSJian Hu * a DCO range of 1.6GHz to 3.2GHz. 150*140f074cSJian Hu */ 151*140f074cSJian Hu static const struct pll_mult_range t7_gp1_pll_mult_range = { 152*140f074cSJian Hu .min = 67, 153*140f074cSJian Hu .max = 133, 154*140f074cSJian Hu }; 155*140f074cSJian Hu 156*140f074cSJian Hu static const struct reg_sequence t7_gp1_init_regs[] = { 157*140f074cSJian Hu { .reg = GP1PLL_CTRL1, .def = 0x1420500f }, 158*140f074cSJian Hu { .reg = GP1PLL_CTRL2, .def = 0x00023001 }, 159*140f074cSJian Hu { .reg = GP1PLL_CTRL3, .def = 0x00000000 }, 160*140f074cSJian Hu }; 161*140f074cSJian Hu 162*140f074cSJian Hu static struct clk_regmap t7_gp1_pll_dco = { 163*140f074cSJian Hu .data = &(struct meson_clk_pll_data){ 164*140f074cSJian Hu .en = { 165*140f074cSJian Hu .reg_off = GP1PLL_CTRL0, 166*140f074cSJian Hu .shift = 28, 167*140f074cSJian Hu .width = 1, 168*140f074cSJian Hu }, 169*140f074cSJian Hu .m = { 170*140f074cSJian Hu .reg_off = GP1PLL_CTRL0, 171*140f074cSJian Hu .shift = 0, 172*140f074cSJian Hu .width = 8, 173*140f074cSJian Hu }, 174*140f074cSJian Hu .n = { 175*140f074cSJian Hu .reg_off = GP1PLL_CTRL0, 176*140f074cSJian Hu .shift = 16, 177*140f074cSJian Hu .width = 5, 178*140f074cSJian Hu }, 179*140f074cSJian Hu .l = { 180*140f074cSJian Hu .reg_off = GP1PLL_STS, 181*140f074cSJian Hu .shift = 31, 182*140f074cSJian Hu .width = 1, 183*140f074cSJian Hu }, 184*140f074cSJian Hu .rst = { 185*140f074cSJian Hu .reg_off = GP1PLL_CTRL0, 186*140f074cSJian Hu .shift = 29, 187*140f074cSJian Hu .width = 1, 188*140f074cSJian Hu }, 189*140f074cSJian Hu .range = &t7_gp1_pll_mult_range, 190*140f074cSJian Hu .init_regs = t7_gp1_init_regs, 191*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_gp1_init_regs), 192*140f074cSJian Hu }, 193*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 194*140f074cSJian Hu .name = "gp1_pll_dco", 195*140f074cSJian Hu .ops = &meson_clk_pll_ops, 196*140f074cSJian Hu .parent_data = &(const struct clk_parent_data) { 197*140f074cSJian Hu .fw_name = "in0", 198*140f074cSJian Hu }, 199*140f074cSJian Hu .num_parents = 1, 200*140f074cSJian Hu }, 201*140f074cSJian Hu }; 202*140f074cSJian Hu 203*140f074cSJian Hu static struct clk_regmap t7_gp1_pll = { 204*140f074cSJian Hu .data = &(struct clk_regmap_div_data){ 205*140f074cSJian Hu .offset = GP1PLL_CTRL0, 206*140f074cSJian Hu .shift = 12, 207*140f074cSJian Hu .width = 3, 208*140f074cSJian Hu .flags = CLK_DIVIDER_POWER_OF_TWO, 209*140f074cSJian Hu }, 210*140f074cSJian Hu .hw.init = &(struct clk_init_data) { 211*140f074cSJian Hu .name = "gp1_pll", 212*140f074cSJian Hu .ops = &clk_regmap_divider_ops, 213*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 214*140f074cSJian Hu &t7_gp1_pll_dco.hw 215*140f074cSJian Hu }, 216*140f074cSJian Hu .num_parents = 1, 217*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 218*140f074cSJian Hu }, 219*140f074cSJian Hu }; 220*140f074cSJian Hu 221*140f074cSJian Hu static const struct reg_sequence t7_hifi_init_regs[] = { 222*140f074cSJian Hu { .reg = HIFIPLL_CTRL1, .def = 0x00000000 }, 223*140f074cSJian Hu { .reg = HIFIPLL_CTRL2, .def = 0x00000000 }, 224*140f074cSJian Hu { .reg = HIFIPLL_CTRL3, .def = 0x6a285c00 }, 225*140f074cSJian Hu { .reg = HIFIPLL_CTRL4, .def = 0x65771290 }, 226*140f074cSJian Hu { .reg = HIFIPLL_CTRL5, .def = 0x3927200a }, 227*140f074cSJian Hu { .reg = HIFIPLL_CTRL6, .def = 0x56540000 } 228*140f074cSJian Hu }; 229*140f074cSJian Hu 230*140f074cSJian Hu static struct clk_regmap t7_hifi_pll_dco = { 231*140f074cSJian Hu .data = &(struct meson_clk_pll_data){ 232*140f074cSJian Hu .en = { 233*140f074cSJian Hu .reg_off = HIFIPLL_CTRL0, 234*140f074cSJian Hu .shift = 28, 235*140f074cSJian Hu .width = 1, 236*140f074cSJian Hu }, 237*140f074cSJian Hu .m = { 238*140f074cSJian Hu .reg_off = HIFIPLL_CTRL0, 239*140f074cSJian Hu .shift = 0, 240*140f074cSJian Hu .width = 8, 241*140f074cSJian Hu }, 242*140f074cSJian Hu .n = { 243*140f074cSJian Hu .reg_off = HIFIPLL_CTRL0, 244*140f074cSJian Hu .shift = 10, 245*140f074cSJian Hu .width = 5, 246*140f074cSJian Hu }, 247*140f074cSJian Hu .frac = { 248*140f074cSJian Hu .reg_off = HIFIPLL_CTRL1, 249*140f074cSJian Hu .shift = 0, 250*140f074cSJian Hu .width = 17, 251*140f074cSJian Hu }, 252*140f074cSJian Hu .l = { 253*140f074cSJian Hu .reg_off = HIFIPLL_STS, 254*140f074cSJian Hu .shift = 31, 255*140f074cSJian Hu .width = 1, 256*140f074cSJian Hu }, 257*140f074cSJian Hu .rst = { 258*140f074cSJian Hu .reg_off = HIFIPLL_CTRL0, 259*140f074cSJian Hu .shift = 29, 260*140f074cSJian Hu .width = 1, 261*140f074cSJian Hu }, 262*140f074cSJian Hu .range = &t7_media_pll_mult_range, 263*140f074cSJian Hu .init_regs = t7_hifi_init_regs, 264*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_hifi_init_regs), 265*140f074cSJian Hu .frac_max = 100000, 266*140f074cSJian Hu }, 267*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 268*140f074cSJian Hu .name = "hifi_pll_dco", 269*140f074cSJian Hu .ops = &meson_clk_pll_ops, 270*140f074cSJian Hu .parent_data = &(const struct clk_parent_data) { 271*140f074cSJian Hu .fw_name = "in0", 272*140f074cSJian Hu }, 273*140f074cSJian Hu .num_parents = 1, 274*140f074cSJian Hu }, 275*140f074cSJian Hu }; 276*140f074cSJian Hu 277*140f074cSJian Hu static struct clk_regmap t7_hifi_pll = { 278*140f074cSJian Hu .data = &(struct clk_regmap_div_data){ 279*140f074cSJian Hu .offset = HIFIPLL_CTRL0, 280*140f074cSJian Hu .shift = 16, 281*140f074cSJian Hu .width = 2, 282*140f074cSJian Hu .flags = CLK_DIVIDER_POWER_OF_TWO, 283*140f074cSJian Hu }, 284*140f074cSJian Hu .hw.init = &(struct clk_init_data) { 285*140f074cSJian Hu .name = "hifi_pll", 286*140f074cSJian Hu .ops = &clk_regmap_divider_ops, 287*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 288*140f074cSJian Hu &t7_hifi_pll_dco.hw 289*140f074cSJian Hu }, 290*140f074cSJian Hu .num_parents = 1, 291*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 292*140f074cSJian Hu }, 293*140f074cSJian Hu }; 294*140f074cSJian Hu 295*140f074cSJian Hu /* 296*140f074cSJian Hu * The T7 PCIE PLL is fined tuned to deliver a very precise 297*140f074cSJian Hu * 100MHz reference clock for the PCIe Analog PHY, and thus requires 298*140f074cSJian Hu * a strict register sequence to enable the PLL. 299*140f074cSJian Hu */ 300*140f074cSJian Hu static const struct reg_sequence t7_pcie_pll_init_regs[] = { 301*140f074cSJian Hu { .reg = PCIEPLL_CTRL0, .def = 0x200c04c8 }, 302*140f074cSJian Hu { .reg = PCIEPLL_CTRL0, .def = 0x300c04c8 }, 303*140f074cSJian Hu { .reg = PCIEPLL_CTRL1, .def = 0x30000000 }, 304*140f074cSJian Hu { .reg = PCIEPLL_CTRL2, .def = 0x00001100 }, 305*140f074cSJian Hu { .reg = PCIEPLL_CTRL3, .def = 0x10058e00 }, 306*140f074cSJian Hu { .reg = PCIEPLL_CTRL4, .def = 0x000100c0 }, 307*140f074cSJian Hu { .reg = PCIEPLL_CTRL5, .def = 0x68000048 }, 308*140f074cSJian Hu { .reg = PCIEPLL_CTRL5, .def = 0x68000068, .delay_us = 20 }, 309*140f074cSJian Hu { .reg = PCIEPLL_CTRL4, .def = 0x008100c0, .delay_us = 20 }, 310*140f074cSJian Hu { .reg = PCIEPLL_CTRL0, .def = 0x340c04c8 }, 311*140f074cSJian Hu { .reg = PCIEPLL_CTRL0, .def = 0x140c04c8, .delay_us = 20 }, 312*140f074cSJian Hu { .reg = PCIEPLL_CTRL2, .def = 0x00001000 } 313*140f074cSJian Hu }; 314*140f074cSJian Hu 315*140f074cSJian Hu static struct clk_regmap t7_pcie_pll_dco = { 316*140f074cSJian Hu .data = &(struct meson_clk_pll_data){ 317*140f074cSJian Hu .en = { 318*140f074cSJian Hu .reg_off = PCIEPLL_CTRL0, 319*140f074cSJian Hu .shift = 28, 320*140f074cSJian Hu .width = 1, 321*140f074cSJian Hu }, 322*140f074cSJian Hu .m = { 323*140f074cSJian Hu .reg_off = PCIEPLL_CTRL0, 324*140f074cSJian Hu .shift = 0, 325*140f074cSJian Hu .width = 8, 326*140f074cSJian Hu }, 327*140f074cSJian Hu .n = { 328*140f074cSJian Hu .reg_off = PCIEPLL_CTRL0, 329*140f074cSJian Hu .shift = 10, 330*140f074cSJian Hu .width = 5, 331*140f074cSJian Hu }, 332*140f074cSJian Hu .l = { 333*140f074cSJian Hu .reg_off = PCIEPLL_CTRL0, 334*140f074cSJian Hu .shift = 31, 335*140f074cSJian Hu .width = 1, 336*140f074cSJian Hu }, 337*140f074cSJian Hu .rst = { 338*140f074cSJian Hu .reg_off = PCIEPLL_CTRL0, 339*140f074cSJian Hu .shift = 29, 340*140f074cSJian Hu .width = 1, 341*140f074cSJian Hu }, 342*140f074cSJian Hu .init_regs = t7_pcie_pll_init_regs, 343*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_pcie_pll_init_regs), 344*140f074cSJian Hu }, 345*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 346*140f074cSJian Hu .name = "pcie_pll_dco", 347*140f074cSJian Hu .ops = &meson_clk_pcie_pll_ops, 348*140f074cSJian Hu .parent_data = &(const struct clk_parent_data) { 349*140f074cSJian Hu .fw_name = "in0", 350*140f074cSJian Hu }, 351*140f074cSJian Hu .num_parents = 1, 352*140f074cSJian Hu }, 353*140f074cSJian Hu }; 354*140f074cSJian Hu 355*140f074cSJian Hu static struct clk_fixed_factor t7_pcie_pll_dco_div2 = { 356*140f074cSJian Hu .mult = 1, 357*140f074cSJian Hu .div = 2, 358*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 359*140f074cSJian Hu .name = "pcie_pll_dco_div2", 360*140f074cSJian Hu .ops = &clk_fixed_factor_ops, 361*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 362*140f074cSJian Hu &t7_pcie_pll_dco.hw 363*140f074cSJian Hu }, 364*140f074cSJian Hu .num_parents = 1, 365*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 366*140f074cSJian Hu }, 367*140f074cSJian Hu }; 368*140f074cSJian Hu 369*140f074cSJian Hu static struct clk_regmap t7_pcie_pll_od = { 370*140f074cSJian Hu .data = &(struct clk_regmap_div_data){ 371*140f074cSJian Hu .offset = PCIEPLL_CTRL0, 372*140f074cSJian Hu .shift = 16, 373*140f074cSJian Hu .width = 5, 374*140f074cSJian Hu /* the divisor is 32 when [16:21] = 0 */ 375*140f074cSJian Hu .flags = CLK_DIVIDER_MAX_AT_ZERO, 376*140f074cSJian Hu }, 377*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 378*140f074cSJian Hu .name = "pcie_pll_od", 379*140f074cSJian Hu .ops = &clk_regmap_divider_ops, 380*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 381*140f074cSJian Hu &t7_pcie_pll_dco_div2.hw 382*140f074cSJian Hu }, 383*140f074cSJian Hu .num_parents = 1, 384*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 385*140f074cSJian Hu }, 386*140f074cSJian Hu }; 387*140f074cSJian Hu 388*140f074cSJian Hu static struct clk_fixed_factor t7_pcie_pll = { 389*140f074cSJian Hu .mult = 1, 390*140f074cSJian Hu .div = 2, 391*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 392*140f074cSJian Hu .name = "pcie_pll", 393*140f074cSJian Hu .ops = &clk_fixed_factor_ops, 394*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 395*140f074cSJian Hu &t7_pcie_pll_od.hw 396*140f074cSJian Hu }, 397*140f074cSJian Hu .num_parents = 1, 398*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 399*140f074cSJian Hu }, 400*140f074cSJian Hu }; 401*140f074cSJian Hu 402*140f074cSJian Hu static struct clk_fixed_factor t7_mpll_prediv = { 403*140f074cSJian Hu .mult = 1, 404*140f074cSJian Hu .div = 2, 405*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 406*140f074cSJian Hu .name = "mpll_prediv", 407*140f074cSJian Hu .ops = &clk_fixed_factor_ops, 408*140f074cSJian Hu .parent_data = &(const struct clk_parent_data) { 409*140f074cSJian Hu .fw_name = "in0", 410*140f074cSJian Hu }, 411*140f074cSJian Hu .num_parents = 1, 412*140f074cSJian Hu }, 413*140f074cSJian Hu }; 414*140f074cSJian Hu 415*140f074cSJian Hu static const struct reg_sequence t7_mpll0_init_regs[] = { 416*140f074cSJian Hu { .reg = MPLL_CTRL2, .def = 0x40000033 } 417*140f074cSJian Hu }; 418*140f074cSJian Hu 419*140f074cSJian Hu static struct clk_regmap t7_mpll0_div = { 420*140f074cSJian Hu .data = &(struct meson_clk_mpll_data){ 421*140f074cSJian Hu .sdm = { 422*140f074cSJian Hu .reg_off = MPLL_CTRL1, 423*140f074cSJian Hu .shift = 0, 424*140f074cSJian Hu .width = 14, 425*140f074cSJian Hu }, 426*140f074cSJian Hu .sdm_en = { 427*140f074cSJian Hu .reg_off = MPLL_CTRL1, 428*140f074cSJian Hu .shift = 30, 429*140f074cSJian Hu .width = 1, 430*140f074cSJian Hu }, 431*140f074cSJian Hu .n2 = { 432*140f074cSJian Hu .reg_off = MPLL_CTRL1, 433*140f074cSJian Hu .shift = 20, 434*140f074cSJian Hu .width = 9, 435*140f074cSJian Hu }, 436*140f074cSJian Hu .ssen = { 437*140f074cSJian Hu .reg_off = MPLL_CTRL1, 438*140f074cSJian Hu .shift = 29, 439*140f074cSJian Hu .width = 1, 440*140f074cSJian Hu }, 441*140f074cSJian Hu .init_regs = t7_mpll0_init_regs, 442*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_mpll0_init_regs), 443*140f074cSJian Hu }, 444*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 445*140f074cSJian Hu .name = "mpll0_div", 446*140f074cSJian Hu .ops = &meson_clk_mpll_ops, 447*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 448*140f074cSJian Hu &t7_mpll_prediv.hw 449*140f074cSJian Hu }, 450*140f074cSJian Hu .num_parents = 1, 451*140f074cSJian Hu }, 452*140f074cSJian Hu }; 453*140f074cSJian Hu 454*140f074cSJian Hu static struct clk_regmap t7_mpll0 = { 455*140f074cSJian Hu .data = &(struct clk_regmap_gate_data){ 456*140f074cSJian Hu .offset = MPLL_CTRL1, 457*140f074cSJian Hu .bit_idx = 31, 458*140f074cSJian Hu }, 459*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 460*140f074cSJian Hu .name = "mpll0", 461*140f074cSJian Hu .ops = &clk_regmap_gate_ops, 462*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { &t7_mpll0_div.hw }, 463*140f074cSJian Hu .num_parents = 1, 464*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 465*140f074cSJian Hu }, 466*140f074cSJian Hu }; 467*140f074cSJian Hu 468*140f074cSJian Hu static const struct reg_sequence t7_mpll1_init_regs[] = { 469*140f074cSJian Hu { .reg = MPLL_CTRL4, .def = 0x40000033 } 470*140f074cSJian Hu }; 471*140f074cSJian Hu 472*140f074cSJian Hu static struct clk_regmap t7_mpll1_div = { 473*140f074cSJian Hu .data = &(struct meson_clk_mpll_data){ 474*140f074cSJian Hu .sdm = { 475*140f074cSJian Hu .reg_off = MPLL_CTRL3, 476*140f074cSJian Hu .shift = 0, 477*140f074cSJian Hu .width = 14, 478*140f074cSJian Hu }, 479*140f074cSJian Hu .sdm_en = { 480*140f074cSJian Hu .reg_off = MPLL_CTRL3, 481*140f074cSJian Hu .shift = 30, 482*140f074cSJian Hu .width = 1, 483*140f074cSJian Hu }, 484*140f074cSJian Hu .n2 = { 485*140f074cSJian Hu .reg_off = MPLL_CTRL3, 486*140f074cSJian Hu .shift = 20, 487*140f074cSJian Hu .width = 9, 488*140f074cSJian Hu }, 489*140f074cSJian Hu .ssen = { 490*140f074cSJian Hu .reg_off = MPLL_CTRL3, 491*140f074cSJian Hu .shift = 29, 492*140f074cSJian Hu .width = 1, 493*140f074cSJian Hu }, 494*140f074cSJian Hu .init_regs = t7_mpll1_init_regs, 495*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_mpll1_init_regs), 496*140f074cSJian Hu }, 497*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 498*140f074cSJian Hu .name = "mpll1_div", 499*140f074cSJian Hu .ops = &meson_clk_mpll_ops, 500*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 501*140f074cSJian Hu &t7_mpll_prediv.hw 502*140f074cSJian Hu }, 503*140f074cSJian Hu .num_parents = 1, 504*140f074cSJian Hu }, 505*140f074cSJian Hu }; 506*140f074cSJian Hu 507*140f074cSJian Hu static struct clk_regmap t7_mpll1 = { 508*140f074cSJian Hu .data = &(struct clk_regmap_gate_data){ 509*140f074cSJian Hu .offset = MPLL_CTRL3, 510*140f074cSJian Hu .bit_idx = 31, 511*140f074cSJian Hu }, 512*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 513*140f074cSJian Hu .name = "mpll1", 514*140f074cSJian Hu .ops = &clk_regmap_gate_ops, 515*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { &t7_mpll1_div.hw }, 516*140f074cSJian Hu .num_parents = 1, 517*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 518*140f074cSJian Hu }, 519*140f074cSJian Hu }; 520*140f074cSJian Hu 521*140f074cSJian Hu static const struct reg_sequence t7_mpll2_init_regs[] = { 522*140f074cSJian Hu { .reg = MPLL_CTRL6, .def = 0x40000033 } 523*140f074cSJian Hu }; 524*140f074cSJian Hu 525*140f074cSJian Hu static struct clk_regmap t7_mpll2_div = { 526*140f074cSJian Hu .data = &(struct meson_clk_mpll_data){ 527*140f074cSJian Hu .sdm = { 528*140f074cSJian Hu .reg_off = MPLL_CTRL5, 529*140f074cSJian Hu .shift = 0, 530*140f074cSJian Hu .width = 14, 531*140f074cSJian Hu }, 532*140f074cSJian Hu .sdm_en = { 533*140f074cSJian Hu .reg_off = MPLL_CTRL5, 534*140f074cSJian Hu .shift = 30, 535*140f074cSJian Hu .width = 1, 536*140f074cSJian Hu }, 537*140f074cSJian Hu .n2 = { 538*140f074cSJian Hu .reg_off = MPLL_CTRL5, 539*140f074cSJian Hu .shift = 20, 540*140f074cSJian Hu .width = 9, 541*140f074cSJian Hu }, 542*140f074cSJian Hu .ssen = { 543*140f074cSJian Hu .reg_off = MPLL_CTRL5, 544*140f074cSJian Hu .shift = 29, 545*140f074cSJian Hu .width = 1, 546*140f074cSJian Hu }, 547*140f074cSJian Hu .init_regs = t7_mpll2_init_regs, 548*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_mpll2_init_regs), 549*140f074cSJian Hu }, 550*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 551*140f074cSJian Hu .name = "mpll2_div", 552*140f074cSJian Hu .ops = &meson_clk_mpll_ops, 553*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 554*140f074cSJian Hu &t7_mpll_prediv.hw 555*140f074cSJian Hu }, 556*140f074cSJian Hu .num_parents = 1, 557*140f074cSJian Hu }, 558*140f074cSJian Hu }; 559*140f074cSJian Hu 560*140f074cSJian Hu static struct clk_regmap t7_mpll2 = { 561*140f074cSJian Hu .data = &(struct clk_regmap_gate_data){ 562*140f074cSJian Hu .offset = MPLL_CTRL5, 563*140f074cSJian Hu .bit_idx = 31, 564*140f074cSJian Hu }, 565*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 566*140f074cSJian Hu .name = "mpll2", 567*140f074cSJian Hu .ops = &clk_regmap_gate_ops, 568*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { &t7_mpll2_div.hw }, 569*140f074cSJian Hu .num_parents = 1, 570*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 571*140f074cSJian Hu }, 572*140f074cSJian Hu }; 573*140f074cSJian Hu 574*140f074cSJian Hu static const struct reg_sequence t7_mpll3_init_regs[] = { 575*140f074cSJian Hu { .reg = MPLL_CTRL8, .def = 0x40000033 } 576*140f074cSJian Hu }; 577*140f074cSJian Hu 578*140f074cSJian Hu static struct clk_regmap t7_mpll3_div = { 579*140f074cSJian Hu .data = &(struct meson_clk_mpll_data){ 580*140f074cSJian Hu .sdm = { 581*140f074cSJian Hu .reg_off = MPLL_CTRL7, 582*140f074cSJian Hu .shift = 0, 583*140f074cSJian Hu .width = 14, 584*140f074cSJian Hu }, 585*140f074cSJian Hu .sdm_en = { 586*140f074cSJian Hu .reg_off = MPLL_CTRL7, 587*140f074cSJian Hu .shift = 30, 588*140f074cSJian Hu .width = 1, 589*140f074cSJian Hu }, 590*140f074cSJian Hu .n2 = { 591*140f074cSJian Hu .reg_off = MPLL_CTRL7, 592*140f074cSJian Hu .shift = 20, 593*140f074cSJian Hu .width = 9, 594*140f074cSJian Hu }, 595*140f074cSJian Hu .ssen = { 596*140f074cSJian Hu .reg_off = MPLL_CTRL7, 597*140f074cSJian Hu .shift = 29, 598*140f074cSJian Hu .width = 1, 599*140f074cSJian Hu }, 600*140f074cSJian Hu .init_regs = t7_mpll3_init_regs, 601*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_mpll3_init_regs), 602*140f074cSJian Hu }, 603*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 604*140f074cSJian Hu .name = "mpll3_div", 605*140f074cSJian Hu .ops = &meson_clk_mpll_ops, 606*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 607*140f074cSJian Hu &t7_mpll_prediv.hw 608*140f074cSJian Hu }, 609*140f074cSJian Hu .num_parents = 1, 610*140f074cSJian Hu }, 611*140f074cSJian Hu }; 612*140f074cSJian Hu 613*140f074cSJian Hu static struct clk_regmap t7_mpll3 = { 614*140f074cSJian Hu .data = &(struct clk_regmap_gate_data){ 615*140f074cSJian Hu .offset = MPLL_CTRL7, 616*140f074cSJian Hu .bit_idx = 31, 617*140f074cSJian Hu }, 618*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 619*140f074cSJian Hu .name = "mpll3", 620*140f074cSJian Hu .ops = &clk_regmap_gate_ops, 621*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { &t7_mpll3_div.hw }, 622*140f074cSJian Hu .num_parents = 1, 623*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 624*140f074cSJian Hu }, 625*140f074cSJian Hu }; 626*140f074cSJian Hu 627*140f074cSJian Hu static const struct reg_sequence t7_hdmi_init_regs[] = { 628*140f074cSJian Hu { .reg = HDMIPLL_CTRL1, .def = 0x00000000 }, 629*140f074cSJian Hu { .reg = HDMIPLL_CTRL2, .def = 0x00000000 }, 630*140f074cSJian Hu { .reg = HDMIPLL_CTRL3, .def = 0x6a28dc00 }, 631*140f074cSJian Hu { .reg = HDMIPLL_CTRL4, .def = 0x65771290 }, 632*140f074cSJian Hu { .reg = HDMIPLL_CTRL5, .def = 0x39272000 }, 633*140f074cSJian Hu { .reg = HDMIPLL_CTRL6, .def = 0x56540000 } 634*140f074cSJian Hu }; 635*140f074cSJian Hu 636*140f074cSJian Hu static struct clk_regmap t7_hdmi_pll_dco = { 637*140f074cSJian Hu .data = &(struct meson_clk_pll_data){ 638*140f074cSJian Hu .en = { 639*140f074cSJian Hu .reg_off = HDMIPLL_CTRL0, 640*140f074cSJian Hu .shift = 28, 641*140f074cSJian Hu .width = 1, 642*140f074cSJian Hu }, 643*140f074cSJian Hu .m = { 644*140f074cSJian Hu .reg_off = HDMIPLL_CTRL0, 645*140f074cSJian Hu .shift = 0, 646*140f074cSJian Hu .width = 9, 647*140f074cSJian Hu }, 648*140f074cSJian Hu .n = { 649*140f074cSJian Hu .reg_off = HDMIPLL_CTRL0, 650*140f074cSJian Hu .shift = 10, 651*140f074cSJian Hu .width = 5, 652*140f074cSJian Hu }, 653*140f074cSJian Hu .l = { 654*140f074cSJian Hu .reg_off = HDMIPLL_CTRL0, 655*140f074cSJian Hu .shift = 31, 656*140f074cSJian Hu .width = 1, 657*140f074cSJian Hu }, 658*140f074cSJian Hu .rst = { 659*140f074cSJian Hu .reg_off = HDMIPLL_CTRL0, 660*140f074cSJian Hu .shift = 29, 661*140f074cSJian Hu .width = 1, 662*140f074cSJian Hu }, 663*140f074cSJian Hu .range = &t7_media_pll_mult_range, 664*140f074cSJian Hu .init_regs = t7_hdmi_init_regs, 665*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_hdmi_init_regs), 666*140f074cSJian Hu }, 667*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 668*140f074cSJian Hu .name = "hdmi_pll_dco", 669*140f074cSJian Hu .ops = &meson_clk_pll_ops, 670*140f074cSJian Hu .parent_data = (const struct clk_parent_data []) { 671*140f074cSJian Hu { .fw_name = "in0", } 672*140f074cSJian Hu }, 673*140f074cSJian Hu .num_parents = 1, 674*140f074cSJian Hu }, 675*140f074cSJian Hu }; 676*140f074cSJian Hu 677*140f074cSJian Hu static struct clk_regmap t7_hdmi_pll_od = { 678*140f074cSJian Hu .data = &(struct clk_regmap_div_data){ 679*140f074cSJian Hu .offset = HDMIPLL_CTRL0, 680*140f074cSJian Hu .shift = 16, 681*140f074cSJian Hu .width = 4, 682*140f074cSJian Hu .flags = CLK_DIVIDER_POWER_OF_TWO, 683*140f074cSJian Hu }, 684*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 685*140f074cSJian Hu .name = "hdmi_pll_od", 686*140f074cSJian Hu .ops = &clk_regmap_divider_ops, 687*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 688*140f074cSJian Hu &t7_hdmi_pll_dco.hw 689*140f074cSJian Hu }, 690*140f074cSJian Hu .num_parents = 1, 691*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 692*140f074cSJian Hu }, 693*140f074cSJian Hu }; 694*140f074cSJian Hu 695*140f074cSJian Hu static struct clk_regmap t7_hdmi_pll = { 696*140f074cSJian Hu .data = &(struct clk_regmap_div_data){ 697*140f074cSJian Hu .offset = HDMIPLL_CTRL0, 698*140f074cSJian Hu .shift = 20, 699*140f074cSJian Hu .width = 2, 700*140f074cSJian Hu .flags = CLK_DIVIDER_POWER_OF_TWO, 701*140f074cSJian Hu }, 702*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 703*140f074cSJian Hu .name = "hdmi_pll", 704*140f074cSJian Hu .ops = &clk_regmap_divider_ops, 705*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 706*140f074cSJian Hu &t7_hdmi_pll_od.hw 707*140f074cSJian Hu }, 708*140f074cSJian Hu .num_parents = 1, 709*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 710*140f074cSJian Hu }, 711*140f074cSJian Hu }; 712*140f074cSJian Hu 713*140f074cSJian Hu static const struct pll_mult_range t7_mclk_pll_mult_range = { 714*140f074cSJian Hu .min = 67, 715*140f074cSJian Hu .max = 133, 716*140f074cSJian Hu }; 717*140f074cSJian Hu 718*140f074cSJian Hu static const struct reg_sequence t7_mclk_init_regs[] = { 719*140f074cSJian Hu { .reg = MCLK_PLL_CNTL1, .def = 0x1470500f }, 720*140f074cSJian Hu { .reg = MCLK_PLL_CNTL2, .def = 0x00023001 }, 721*140f074cSJian Hu { .reg = MCLK_PLL_CNTL3, .def = 0x18180000 }, 722*140f074cSJian Hu { .reg = MCLK_PLL_CNTL4, .def = 0x00180303 }, 723*140f074cSJian Hu }; 724*140f074cSJian Hu 725*140f074cSJian Hu static struct clk_regmap t7_mclk_pll_dco = { 726*140f074cSJian Hu .data = &(struct meson_clk_pll_data){ 727*140f074cSJian Hu .en = { 728*140f074cSJian Hu .reg_off = MCLK_PLL_CNTL0, 729*140f074cSJian Hu .shift = 28, 730*140f074cSJian Hu .width = 1, 731*140f074cSJian Hu }, 732*140f074cSJian Hu .m = { 733*140f074cSJian Hu .reg_off = MCLK_PLL_CNTL0, 734*140f074cSJian Hu .shift = 0, 735*140f074cSJian Hu .width = 8, 736*140f074cSJian Hu }, 737*140f074cSJian Hu .n = { 738*140f074cSJian Hu .reg_off = MCLK_PLL_CNTL0, 739*140f074cSJian Hu .shift = 16, 740*140f074cSJian Hu .width = 5, 741*140f074cSJian Hu }, 742*140f074cSJian Hu .l = { 743*140f074cSJian Hu .reg_off = MCLK_PLL_CNTL0, 744*140f074cSJian Hu .shift = 31, 745*140f074cSJian Hu .width = 1, 746*140f074cSJian Hu }, 747*140f074cSJian Hu .rst = { 748*140f074cSJian Hu .reg_off = MCLK_PLL_CNTL0, 749*140f074cSJian Hu .shift = 29, 750*140f074cSJian Hu .width = 1, 751*140f074cSJian Hu }, 752*140f074cSJian Hu .l_detect = { 753*140f074cSJian Hu .reg_off = MCLK_PLL_CNTL2, 754*140f074cSJian Hu .shift = 6, 755*140f074cSJian Hu .width = 1, 756*140f074cSJian Hu }, 757*140f074cSJian Hu .range = &t7_mclk_pll_mult_range, 758*140f074cSJian Hu .init_regs = t7_mclk_init_regs, 759*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_mclk_init_regs), 760*140f074cSJian Hu }, 761*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 762*140f074cSJian Hu .name = "mclk_pll_dco", 763*140f074cSJian Hu .ops = &meson_clk_pll_ops, 764*140f074cSJian Hu .parent_data = &(const struct clk_parent_data) { 765*140f074cSJian Hu .fw_name = "in0", 766*140f074cSJian Hu }, 767*140f074cSJian Hu .num_parents = 1, 768*140f074cSJian Hu }, 769*140f074cSJian Hu }; 770*140f074cSJian Hu 771*140f074cSJian Hu /* max div is 16 */ 772*140f074cSJian Hu static const struct clk_div_table t7_mclk_div[] = { 773*140f074cSJian Hu { .val = 0, .div = 1 }, 774*140f074cSJian Hu { .val = 1, .div = 2 }, 775*140f074cSJian Hu { .val = 2, .div = 4 }, 776*140f074cSJian Hu { .val = 3, .div = 8 }, 777*140f074cSJian Hu { .val = 4, .div = 16 }, 778*140f074cSJian Hu { /* sentinel */ } 779*140f074cSJian Hu }; 780*140f074cSJian Hu 781*140f074cSJian Hu static struct clk_regmap t7_mclk_pre_od = { 782*140f074cSJian Hu .data = &(struct clk_regmap_div_data){ 783*140f074cSJian Hu .offset = MCLK_PLL_CNTL0, 784*140f074cSJian Hu .shift = 12, 785*140f074cSJian Hu .width = 3, 786*140f074cSJian Hu .table = t7_mclk_div, 787*140f074cSJian Hu }, 788*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 789*140f074cSJian Hu .name = "mclk_pre_od", 790*140f074cSJian Hu .ops = &clk_regmap_divider_ops, 791*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 792*140f074cSJian Hu &t7_mclk_pll_dco.hw 793*140f074cSJian Hu }, 794*140f074cSJian Hu .num_parents = 1, 795*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 796*140f074cSJian Hu }, 797*140f074cSJian Hu }; 798*140f074cSJian Hu 799*140f074cSJian Hu static struct clk_regmap t7_mclk_pll = { 800*140f074cSJian Hu .data = &(struct clk_regmap_div_data){ 801*140f074cSJian Hu .offset = MCLK_PLL_CNTL4, 802*140f074cSJian Hu .shift = 16, 803*140f074cSJian Hu .width = 5, 804*140f074cSJian Hu .flags = CLK_DIVIDER_ONE_BASED, 805*140f074cSJian Hu }, 806*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 807*140f074cSJian Hu .name = "mclk_pll", 808*140f074cSJian Hu .ops = &clk_regmap_divider_ops, 809*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 810*140f074cSJian Hu &t7_mclk_pre_od.hw 811*140f074cSJian Hu }, 812*140f074cSJian Hu .num_parents = 1, 813*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 814*140f074cSJian Hu }, 815*140f074cSJian Hu }; 816*140f074cSJian Hu 817*140f074cSJian Hu static struct clk_regmap t7_mclk_0_sel = { 818*140f074cSJian Hu .data = &(struct clk_regmap_mux_data){ 819*140f074cSJian Hu .offset = MCLK_PLL_CNTL4, 820*140f074cSJian Hu .mask = 0x3, 821*140f074cSJian Hu .shift = 4, 822*140f074cSJian Hu }, 823*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 824*140f074cSJian Hu .name = "mclk_0_sel", 825*140f074cSJian Hu .ops = &clk_regmap_mux_ops, 826*140f074cSJian Hu .parent_data = (const struct clk_parent_data []) { 827*140f074cSJian Hu { .hw = &t7_mclk_pll.hw }, 828*140f074cSJian Hu { .fw_name = "in1", }, 829*140f074cSJian Hu { .fw_name = "in2", }, 830*140f074cSJian Hu }, 831*140f074cSJian Hu .num_parents = 3, 832*140f074cSJian Hu }, 833*140f074cSJian Hu }; 834*140f074cSJian Hu 835*140f074cSJian Hu static struct clk_fixed_factor t7_mclk_0_div2 = { 836*140f074cSJian Hu .mult = 1, 837*140f074cSJian Hu .div = 2, 838*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 839*140f074cSJian Hu .name = "mclk_0_div2", 840*140f074cSJian Hu .ops = &clk_fixed_factor_ops, 841*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { &t7_mclk_0_sel.hw }, 842*140f074cSJian Hu .num_parents = 1, 843*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 844*140f074cSJian Hu }, 845*140f074cSJian Hu }; 846*140f074cSJian Hu 847*140f074cSJian Hu static struct clk_regmap t7_mclk_0_pre = { 848*140f074cSJian Hu .data = &(struct clk_regmap_gate_data){ 849*140f074cSJian Hu .offset = MCLK_PLL_CNTL4, 850*140f074cSJian Hu .bit_idx = 2, 851*140f074cSJian Hu }, 852*140f074cSJian Hu .hw.init = &(struct clk_init_data) { 853*140f074cSJian Hu .name = "mclk_0_pre", 854*140f074cSJian Hu .ops = &clk_regmap_gate_ops, 855*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 856*140f074cSJian Hu &t7_mclk_0_div2.hw 857*140f074cSJian Hu }, 858*140f074cSJian Hu .num_parents = 1, 859*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 860*140f074cSJian Hu }, 861*140f074cSJian Hu }; 862*140f074cSJian Hu 863*140f074cSJian Hu static struct clk_regmap t7_mclk_0 = { 864*140f074cSJian Hu .data = &(struct clk_regmap_gate_data){ 865*140f074cSJian Hu .offset = MCLK_PLL_CNTL4, 866*140f074cSJian Hu .bit_idx = 0, 867*140f074cSJian Hu }, 868*140f074cSJian Hu .hw.init = &(struct clk_init_data) { 869*140f074cSJian Hu .name = "mclk_0", 870*140f074cSJian Hu .ops = &clk_regmap_gate_ops, 871*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 872*140f074cSJian Hu &t7_mclk_0_pre.hw 873*140f074cSJian Hu }, 874*140f074cSJian Hu .num_parents = 1, 875*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 876*140f074cSJian Hu }, 877*140f074cSJian Hu }; 878*140f074cSJian Hu 879*140f074cSJian Hu static struct clk_regmap t7_mclk_1_sel = { 880*140f074cSJian Hu .data = &(struct clk_regmap_mux_data){ 881*140f074cSJian Hu .offset = MCLK_PLL_CNTL4, 882*140f074cSJian Hu .mask = 0x3, 883*140f074cSJian Hu .shift = 12, 884*140f074cSJian Hu }, 885*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 886*140f074cSJian Hu .name = "mclk_1_sel", 887*140f074cSJian Hu .ops = &clk_regmap_mux_ops, 888*140f074cSJian Hu .parent_data = (const struct clk_parent_data []) { 889*140f074cSJian Hu { .hw = &t7_mclk_pll.hw }, 890*140f074cSJian Hu { .fw_name = "in1", }, 891*140f074cSJian Hu { .fw_name = "in2", }, 892*140f074cSJian Hu }, 893*140f074cSJian Hu .num_parents = 3, 894*140f074cSJian Hu }, 895*140f074cSJian Hu }; 896*140f074cSJian Hu 897*140f074cSJian Hu static struct clk_fixed_factor t7_mclk_1_div2 = { 898*140f074cSJian Hu .mult = 1, 899*140f074cSJian Hu .div = 2, 900*140f074cSJian Hu .hw.init = &(struct clk_init_data){ 901*140f074cSJian Hu .name = "mclk_1_div2", 902*140f074cSJian Hu .ops = &clk_fixed_factor_ops, 903*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { &t7_mclk_1_sel.hw }, 904*140f074cSJian Hu .num_parents = 1, 905*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 906*140f074cSJian Hu }, 907*140f074cSJian Hu }; 908*140f074cSJian Hu 909*140f074cSJian Hu static struct clk_regmap t7_mclk_1_pre = { 910*140f074cSJian Hu .data = &(struct clk_regmap_gate_data){ 911*140f074cSJian Hu .offset = MCLK_PLL_CNTL4, 912*140f074cSJian Hu .bit_idx = 10, 913*140f074cSJian Hu }, 914*140f074cSJian Hu .hw.init = &(struct clk_init_data) { 915*140f074cSJian Hu .name = "mclk_1_pre", 916*140f074cSJian Hu .ops = &clk_regmap_gate_ops, 917*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 918*140f074cSJian Hu &t7_mclk_1_div2.hw 919*140f074cSJian Hu }, 920*140f074cSJian Hu .num_parents = 1, 921*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 922*140f074cSJian Hu }, 923*140f074cSJian Hu }; 924*140f074cSJian Hu 925*140f074cSJian Hu static struct clk_regmap t7_mclk_1 = { 926*140f074cSJian Hu .data = &(struct clk_regmap_gate_data){ 927*140f074cSJian Hu .offset = MCLK_PLL_CNTL4, 928*140f074cSJian Hu .bit_idx = 8, 929*140f074cSJian Hu }, 930*140f074cSJian Hu .hw.init = &(struct clk_init_data) { 931*140f074cSJian Hu .name = "mclk_1", 932*140f074cSJian Hu .ops = &clk_regmap_gate_ops, 933*140f074cSJian Hu .parent_hws = (const struct clk_hw *[]) { 934*140f074cSJian Hu &t7_mclk_1_pre.hw 935*140f074cSJian Hu }, 936*140f074cSJian Hu .num_parents = 1, 937*140f074cSJian Hu .flags = CLK_SET_RATE_PARENT, 938*140f074cSJian Hu }, 939*140f074cSJian Hu }; 940*140f074cSJian Hu 941*140f074cSJian Hu static struct clk_hw *t7_gp0_hw_clks[] = { 942*140f074cSJian Hu [CLKID_GP0_PLL_DCO] = &t7_gp0_pll_dco.hw, 943*140f074cSJian Hu [CLKID_GP0_PLL] = &t7_gp0_pll.hw, 944*140f074cSJian Hu }; 945*140f074cSJian Hu 946*140f074cSJian Hu static struct clk_hw *t7_gp1_hw_clks[] = { 947*140f074cSJian Hu [CLKID_GP1_PLL_DCO] = &t7_gp1_pll_dco.hw, 948*140f074cSJian Hu [CLKID_GP1_PLL] = &t7_gp1_pll.hw, 949*140f074cSJian Hu }; 950*140f074cSJian Hu 951*140f074cSJian Hu static struct clk_hw *t7_hifi_hw_clks[] = { 952*140f074cSJian Hu [CLKID_HIFI_PLL_DCO] = &t7_hifi_pll_dco.hw, 953*140f074cSJian Hu [CLKID_HIFI_PLL] = &t7_hifi_pll.hw, 954*140f074cSJian Hu }; 955*140f074cSJian Hu 956*140f074cSJian Hu static struct clk_hw *t7_pcie_hw_clks[] = { 957*140f074cSJian Hu [CLKID_PCIE_PLL_DCO] = &t7_pcie_pll_dco.hw, 958*140f074cSJian Hu [CLKID_PCIE_PLL_DCO_DIV2] = &t7_pcie_pll_dco_div2.hw, 959*140f074cSJian Hu [CLKID_PCIE_PLL_OD] = &t7_pcie_pll_od.hw, 960*140f074cSJian Hu [CLKID_PCIE_PLL] = &t7_pcie_pll.hw, 961*140f074cSJian Hu }; 962*140f074cSJian Hu 963*140f074cSJian Hu static struct clk_hw *t7_mpll_hw_clks[] = { 964*140f074cSJian Hu [CLKID_MPLL_PREDIV] = &t7_mpll_prediv.hw, 965*140f074cSJian Hu [CLKID_MPLL0_DIV] = &t7_mpll0_div.hw, 966*140f074cSJian Hu [CLKID_MPLL0] = &t7_mpll0.hw, 967*140f074cSJian Hu [CLKID_MPLL1_DIV] = &t7_mpll1_div.hw, 968*140f074cSJian Hu [CLKID_MPLL1] = &t7_mpll1.hw, 969*140f074cSJian Hu [CLKID_MPLL2_DIV] = &t7_mpll2_div.hw, 970*140f074cSJian Hu [CLKID_MPLL2] = &t7_mpll2.hw, 971*140f074cSJian Hu [CLKID_MPLL3_DIV] = &t7_mpll3_div.hw, 972*140f074cSJian Hu [CLKID_MPLL3] = &t7_mpll3.hw, 973*140f074cSJian Hu }; 974*140f074cSJian Hu 975*140f074cSJian Hu static struct clk_hw *t7_hdmi_hw_clks[] = { 976*140f074cSJian Hu [CLKID_HDMI_PLL_DCO] = &t7_hdmi_pll_dco.hw, 977*140f074cSJian Hu [CLKID_HDMI_PLL_OD] = &t7_hdmi_pll_od.hw, 978*140f074cSJian Hu [CLKID_HDMI_PLL] = &t7_hdmi_pll.hw, 979*140f074cSJian Hu }; 980*140f074cSJian Hu 981*140f074cSJian Hu static struct clk_hw *t7_mclk_hw_clks[] = { 982*140f074cSJian Hu [CLKID_MCLK_PLL_DCO] = &t7_mclk_pll_dco.hw, 983*140f074cSJian Hu [CLKID_MCLK_PRE] = &t7_mclk_pre_od.hw, 984*140f074cSJian Hu [CLKID_MCLK_PLL] = &t7_mclk_pll.hw, 985*140f074cSJian Hu [CLKID_MCLK_0_SEL] = &t7_mclk_0_sel.hw, 986*140f074cSJian Hu [CLKID_MCLK_0_DIV2] = &t7_mclk_0_div2.hw, 987*140f074cSJian Hu [CLKID_MCLK_0_PRE] = &t7_mclk_0_pre.hw, 988*140f074cSJian Hu [CLKID_MCLK_0] = &t7_mclk_0.hw, 989*140f074cSJian Hu [CLKID_MCLK_1_SEL] = &t7_mclk_1_sel.hw, 990*140f074cSJian Hu [CLKID_MCLK_1_DIV2] = &t7_mclk_1_div2.hw, 991*140f074cSJian Hu [CLKID_MCLK_1_PRE] = &t7_mclk_1_pre.hw, 992*140f074cSJian Hu [CLKID_MCLK_1] = &t7_mclk_1.hw, 993*140f074cSJian Hu }; 994*140f074cSJian Hu 995*140f074cSJian Hu static const struct meson_clkc_data t7_gp0_data = { 996*140f074cSJian Hu .hw_clks = { 997*140f074cSJian Hu .hws = t7_gp0_hw_clks, 998*140f074cSJian Hu .num = ARRAY_SIZE(t7_gp0_hw_clks), 999*140f074cSJian Hu }, 1000*140f074cSJian Hu }; 1001*140f074cSJian Hu 1002*140f074cSJian Hu static const struct meson_clkc_data t7_gp1_data = { 1003*140f074cSJian Hu .hw_clks = { 1004*140f074cSJian Hu .hws = t7_gp1_hw_clks, 1005*140f074cSJian Hu .num = ARRAY_SIZE(t7_gp1_hw_clks), 1006*140f074cSJian Hu }, 1007*140f074cSJian Hu }; 1008*140f074cSJian Hu 1009*140f074cSJian Hu static const struct meson_clkc_data t7_hifi_data = { 1010*140f074cSJian Hu .hw_clks = { 1011*140f074cSJian Hu .hws = t7_hifi_hw_clks, 1012*140f074cSJian Hu .num = ARRAY_SIZE(t7_hifi_hw_clks), 1013*140f074cSJian Hu }, 1014*140f074cSJian Hu }; 1015*140f074cSJian Hu 1016*140f074cSJian Hu static const struct meson_clkc_data t7_pcie_data = { 1017*140f074cSJian Hu .hw_clks = { 1018*140f074cSJian Hu .hws = t7_pcie_hw_clks, 1019*140f074cSJian Hu .num = ARRAY_SIZE(t7_pcie_hw_clks), 1020*140f074cSJian Hu }, 1021*140f074cSJian Hu }; 1022*140f074cSJian Hu 1023*140f074cSJian Hu static const struct reg_sequence t7_mpll_init_regs[] = { 1024*140f074cSJian Hu { .reg = MPLL_CTRL0, .def = 0x00000543 } 1025*140f074cSJian Hu }; 1026*140f074cSJian Hu 1027*140f074cSJian Hu static const struct meson_clkc_data t7_mpll_data = { 1028*140f074cSJian Hu .hw_clks = { 1029*140f074cSJian Hu .hws = t7_mpll_hw_clks, 1030*140f074cSJian Hu .num = ARRAY_SIZE(t7_mpll_hw_clks), 1031*140f074cSJian Hu }, 1032*140f074cSJian Hu .init_regs = t7_mpll_init_regs, 1033*140f074cSJian Hu .init_count = ARRAY_SIZE(t7_mpll_init_regs), 1034*140f074cSJian Hu }; 1035*140f074cSJian Hu 1036*140f074cSJian Hu static const struct meson_clkc_data t7_hdmi_data = { 1037*140f074cSJian Hu .hw_clks = { 1038*140f074cSJian Hu .hws = t7_hdmi_hw_clks, 1039*140f074cSJian Hu .num = ARRAY_SIZE(t7_hdmi_hw_clks), 1040*140f074cSJian Hu }, 1041*140f074cSJian Hu }; 1042*140f074cSJian Hu 1043*140f074cSJian Hu static const struct meson_clkc_data t7_mclk_data = { 1044*140f074cSJian Hu .hw_clks = { 1045*140f074cSJian Hu .hws = t7_mclk_hw_clks, 1046*140f074cSJian Hu .num = ARRAY_SIZE(t7_mclk_hw_clks), 1047*140f074cSJian Hu }, 1048*140f074cSJian Hu }; 1049*140f074cSJian Hu 1050*140f074cSJian Hu static const struct of_device_id t7_pll_clkc_match_table[] = { 1051*140f074cSJian Hu { .compatible = "amlogic,t7-gp0-pll", .data = &t7_gp0_data, }, 1052*140f074cSJian Hu { .compatible = "amlogic,t7-gp1-pll", .data = &t7_gp1_data, }, 1053*140f074cSJian Hu { .compatible = "amlogic,t7-hifi-pll", .data = &t7_hifi_data, }, 1054*140f074cSJian Hu { .compatible = "amlogic,t7-pcie-pll", .data = &t7_pcie_data, }, 1055*140f074cSJian Hu { .compatible = "amlogic,t7-mpll", .data = &t7_mpll_data, }, 1056*140f074cSJian Hu { .compatible = "amlogic,t7-hdmi-pll", .data = &t7_hdmi_data, }, 1057*140f074cSJian Hu { .compatible = "amlogic,t7-mclk-pll", .data = &t7_mclk_data, }, 1058*140f074cSJian Hu {} 1059*140f074cSJian Hu }; 1060*140f074cSJian Hu MODULE_DEVICE_TABLE(of, t7_pll_clkc_match_table); 1061*140f074cSJian Hu 1062*140f074cSJian Hu static struct platform_driver t7_pll_clkc_driver = { 1063*140f074cSJian Hu .probe = meson_clkc_mmio_probe, 1064*140f074cSJian Hu .driver = { 1065*140f074cSJian Hu .name = "t7-pll-clkc", 1066*140f074cSJian Hu .of_match_table = t7_pll_clkc_match_table, 1067*140f074cSJian Hu }, 1068*140f074cSJian Hu }; 1069*140f074cSJian Hu module_platform_driver(t7_pll_clkc_driver); 1070*140f074cSJian Hu 1071*140f074cSJian Hu MODULE_DESCRIPTION("Amlogic T7 PLL Clock Controller driver"); 1072*140f074cSJian Hu MODULE_AUTHOR("Jian Hu <jian.hu@amlogic.com>"); 1073*140f074cSJian Hu MODULE_LICENSE("GPL"); 1074*140f074cSJian Hu MODULE_IMPORT_NS("CLK_MESON"); 1075