Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * AmLogic Meson-AXG Clock Controller Driver
   4 *
   5 * Copyright (c) 2016 Baylibre SAS.
   6 * Author: Michael Turquette <mturquette@baylibre.com>
   7 *
   8 * Copyright (c) 2017 Amlogic, inc.
   9 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
  10 */
  11
  12#include <linux/clk.h>
  13#include <linux/clk-provider.h>
  14#include <linux/init.h>
  15#include <linux/of_address.h>
  16#include <linux/of_device.h>
  17#include <linux/mfd/syscon.h>
  18#include <linux/platform_device.h>
  19#include <linux/regmap.h>
  20
  21#include "clkc.h"
  22#include "axg.h"
  23
  24static DEFINE_SPINLOCK(meson_clk_lock);
  25
  26static struct clk_regmap axg_fixed_pll = {
  27	.data = &(struct meson_clk_pll_data){
  28		.m = {
  29			.reg_off = HHI_MPLL_CNTL,
  30			.shift   = 0,
  31			.width   = 9,
  32		},
  33		.n = {
  34			.reg_off = HHI_MPLL_CNTL,
  35			.shift   = 9,
  36			.width   = 5,
  37		},
  38		.od = {
  39			.reg_off = HHI_MPLL_CNTL,
  40			.shift   = 16,
  41			.width   = 2,
  42		},
  43		.frac = {
  44			.reg_off = HHI_MPLL_CNTL2,
  45			.shift   = 0,
  46			.width   = 12,
  47		},
  48		.l = {
  49			.reg_off = HHI_MPLL_CNTL,
  50			.shift   = 31,
  51			.width   = 1,
  52		},
  53		.rst = {
  54			.reg_off = HHI_MPLL_CNTL,
  55			.shift   = 29,
  56			.width   = 1,
  57		},
  58	},
  59	.hw.init = &(struct clk_init_data){
  60		.name = "fixed_pll",
  61		.ops = &meson_clk_pll_ro_ops,
  62		.parent_names = (const char *[]){ "xtal" },
  63		.num_parents = 1,
  64	},
  65};
  66
  67static struct clk_regmap axg_sys_pll = {
  68	.data = &(struct meson_clk_pll_data){
  69		.m = {
  70			.reg_off = HHI_SYS_PLL_CNTL,
  71			.shift   = 0,
  72			.width   = 9,
  73		},
  74		.n = {
  75			.reg_off = HHI_SYS_PLL_CNTL,
  76			.shift   = 9,
  77			.width   = 5,
  78		},
  79		.od = {
  80			.reg_off = HHI_SYS_PLL_CNTL,
  81			.shift   = 16,
  82			.width   = 2,
  83		},
  84		.l = {
  85			.reg_off = HHI_SYS_PLL_CNTL,
  86			.shift   = 31,
  87			.width   = 1,
  88		},
  89		.rst = {
  90			.reg_off = HHI_SYS_PLL_CNTL,
  91			.shift   = 29,
  92			.width   = 1,
  93		},
  94	},
  95	.hw.init = &(struct clk_init_data){
  96		.name = "sys_pll",
  97		.ops = &meson_clk_pll_ro_ops,
  98		.parent_names = (const char *[]){ "xtal" },
  99		.num_parents = 1,
 100		.flags = CLK_GET_RATE_NOCACHE,
 101	},
 102};
 103
 104static const struct pll_rate_table axg_gp0_pll_rate_table[] = {
 105	PLL_RATE(240000000, 40, 1, 2),
 106	PLL_RATE(246000000, 41, 1, 2),
 107	PLL_RATE(252000000, 42, 1, 2),
 108	PLL_RATE(258000000, 43, 1, 2),
 109	PLL_RATE(264000000, 44, 1, 2),
 110	PLL_RATE(270000000, 45, 1, 2),
 111	PLL_RATE(276000000, 46, 1, 2),
 112	PLL_RATE(282000000, 47, 1, 2),
 113	PLL_RATE(288000000, 48, 1, 2),
 114	PLL_RATE(294000000, 49, 1, 2),
 115	PLL_RATE(300000000, 50, 1, 2),
 116	PLL_RATE(306000000, 51, 1, 2),
 117	PLL_RATE(312000000, 52, 1, 2),
 118	PLL_RATE(318000000, 53, 1, 2),
 119	PLL_RATE(324000000, 54, 1, 2),
 120	PLL_RATE(330000000, 55, 1, 2),
 121	PLL_RATE(336000000, 56, 1, 2),
 122	PLL_RATE(342000000, 57, 1, 2),
 123	PLL_RATE(348000000, 58, 1, 2),
 124	PLL_RATE(354000000, 59, 1, 2),
 125	PLL_RATE(360000000, 60, 1, 2),
 126	PLL_RATE(366000000, 61, 1, 2),
 127	PLL_RATE(372000000, 62, 1, 2),
 128	PLL_RATE(378000000, 63, 1, 2),
 129	PLL_RATE(384000000, 64, 1, 2),
 130	PLL_RATE(390000000, 65, 1, 3),
 131	PLL_RATE(396000000, 66, 1, 3),
 132	PLL_RATE(402000000, 67, 1, 3),
 133	PLL_RATE(408000000, 68, 1, 3),
 134	PLL_RATE(480000000, 40, 1, 1),
 135	PLL_RATE(492000000, 41, 1, 1),
 136	PLL_RATE(504000000, 42, 1, 1),
 137	PLL_RATE(516000000, 43, 1, 1),
 138	PLL_RATE(528000000, 44, 1, 1),
 139	PLL_RATE(540000000, 45, 1, 1),
 140	PLL_RATE(552000000, 46, 1, 1),
 141	PLL_RATE(564000000, 47, 1, 1),
 142	PLL_RATE(576000000, 48, 1, 1),
 143	PLL_RATE(588000000, 49, 1, 1),
 144	PLL_RATE(600000000, 50, 1, 1),
 145	PLL_RATE(612000000, 51, 1, 1),
 146	PLL_RATE(624000000, 52, 1, 1),
 147	PLL_RATE(636000000, 53, 1, 1),
 148	PLL_RATE(648000000, 54, 1, 1),
 149	PLL_RATE(660000000, 55, 1, 1),
 150	PLL_RATE(672000000, 56, 1, 1),
 151	PLL_RATE(684000000, 57, 1, 1),
 152	PLL_RATE(696000000, 58, 1, 1),
 153	PLL_RATE(708000000, 59, 1, 1),
 154	PLL_RATE(720000000, 60, 1, 1),
 155	PLL_RATE(732000000, 61, 1, 1),
 156	PLL_RATE(744000000, 62, 1, 1),
 157	PLL_RATE(756000000, 63, 1, 1),
 158	PLL_RATE(768000000, 64, 1, 1),
 159	PLL_RATE(780000000, 65, 1, 1),
 160	PLL_RATE(792000000, 66, 1, 1),
 161	PLL_RATE(804000000, 67, 1, 1),
 162	PLL_RATE(816000000, 68, 1, 1),
 163	PLL_RATE(960000000, 40, 1, 0),
 164	PLL_RATE(984000000, 41, 1, 0),
 165	PLL_RATE(1008000000, 42, 1, 0),
 166	PLL_RATE(1032000000, 43, 1, 0),
 167	PLL_RATE(1056000000, 44, 1, 0),
 168	PLL_RATE(1080000000, 45, 1, 0),
 169	PLL_RATE(1104000000, 46, 1, 0),
 170	PLL_RATE(1128000000, 47, 1, 0),
 171	PLL_RATE(1152000000, 48, 1, 0),
 172	PLL_RATE(1176000000, 49, 1, 0),
 173	PLL_RATE(1200000000, 50, 1, 0),
 174	PLL_RATE(1224000000, 51, 1, 0),
 175	PLL_RATE(1248000000, 52, 1, 0),
 176	PLL_RATE(1272000000, 53, 1, 0),
 177	PLL_RATE(1296000000, 54, 1, 0),
 178	PLL_RATE(1320000000, 55, 1, 0),
 179	PLL_RATE(1344000000, 56, 1, 0),
 180	PLL_RATE(1368000000, 57, 1, 0),
 181	PLL_RATE(1392000000, 58, 1, 0),
 182	PLL_RATE(1416000000, 59, 1, 0),
 183	PLL_RATE(1440000000, 60, 1, 0),
 184	PLL_RATE(1464000000, 61, 1, 0),
 185	PLL_RATE(1488000000, 62, 1, 0),
 186	PLL_RATE(1512000000, 63, 1, 0),
 187	PLL_RATE(1536000000, 64, 1, 0),
 188	PLL_RATE(1560000000, 65, 1, 0),
 189	PLL_RATE(1584000000, 66, 1, 0),
 190	PLL_RATE(1608000000, 67, 1, 0),
 191	PLL_RATE(1632000000, 68, 1, 0),
 192	{ /* sentinel */ },
 193};
 194
 195static const struct reg_sequence axg_gp0_init_regs[] = {
 196	{ .reg = HHI_GP0_PLL_CNTL1,	.def = 0xc084b000 },
 197	{ .reg = HHI_GP0_PLL_CNTL2,	.def = 0xb75020be },
 198	{ .reg = HHI_GP0_PLL_CNTL3,	.def = 0x0a59a288 },
 199	{ .reg = HHI_GP0_PLL_CNTL4,	.def = 0xc000004d },
 200	{ .reg = HHI_GP0_PLL_CNTL5,	.def = 0x00078000 },
 201	{ .reg = HHI_GP0_PLL_CNTL,	.def = 0x40010250 },
 202};
 203
 204static struct clk_regmap axg_gp0_pll = {
 205	.data = &(struct meson_clk_pll_data){
 206		.m = {
 207			.reg_off = HHI_GP0_PLL_CNTL,
 208			.shift   = 0,
 209			.width   = 9,
 210		},
 211		.n = {
 212			.reg_off = HHI_GP0_PLL_CNTL,
 213			.shift   = 9,
 214			.width   = 5,
 215		},
 216		.od = {
 217			.reg_off = HHI_GP0_PLL_CNTL,
 218			.shift   = 16,
 219			.width   = 2,
 220		},
 221		.frac = {
 222			.reg_off = HHI_GP0_PLL_CNTL1,
 223			.shift   = 0,
 224			.width   = 10,
 225		},
 226		.l = {
 227			.reg_off = HHI_GP0_PLL_CNTL,
 228			.shift   = 31,
 229			.width   = 1,
 230		},
 231		.rst = {
 232			.reg_off = HHI_GP0_PLL_CNTL,
 233			.shift   = 29,
 234			.width   = 1,
 235		},
 236		.table = axg_gp0_pll_rate_table,
 237		.init_regs = axg_gp0_init_regs,
 238		.init_count = ARRAY_SIZE(axg_gp0_init_regs),
 239	},
 240	.hw.init = &(struct clk_init_data){
 241		.name = "gp0_pll",
 242		.ops = &meson_clk_pll_ops,
 243		.parent_names = (const char *[]){ "xtal" },
 244		.num_parents = 1,
 245	},
 246};
 247
 248static const struct reg_sequence axg_hifi_init_regs[] = {
 249	{ .reg = HHI_HIFI_PLL_CNTL1,	.def = 0xc084b000 },
 250	{ .reg = HHI_HIFI_PLL_CNTL2,	.def = 0xb75020be },
 251	{ .reg = HHI_HIFI_PLL_CNTL3,	.def = 0x0a6a3a88 },
 252	{ .reg = HHI_HIFI_PLL_CNTL4,	.def = 0xc000004d },
 253	{ .reg = HHI_HIFI_PLL_CNTL5,	.def = 0x00058000 },
 254	{ .reg = HHI_HIFI_PLL_CNTL,	.def = 0x40010250 },
 255};
 256
 257static struct clk_regmap axg_hifi_pll = {
 258	.data = &(struct meson_clk_pll_data){
 259		.m = {
 260			.reg_off = HHI_HIFI_PLL_CNTL,
 261			.shift   = 0,
 262			.width   = 9,
 263		},
 264		.n = {
 265			.reg_off = HHI_HIFI_PLL_CNTL,
 266			.shift   = 9,
 267			.width   = 5,
 268		},
 269		.od = {
 270			.reg_off = HHI_HIFI_PLL_CNTL,
 271			.shift   = 16,
 272			.width   = 2,
 273		},
 274		.frac = {
 275			.reg_off = HHI_HIFI_PLL_CNTL5,
 276			.shift   = 0,
 277			.width   = 13,
 278		},
 279		.l = {
 280			.reg_off = HHI_HIFI_PLL_CNTL,
 281			.shift   = 31,
 282			.width   = 1,
 283		},
 284		.rst = {
 285			.reg_off = HHI_HIFI_PLL_CNTL,
 286			.shift   = 29,
 287			.width   = 1,
 288		},
 289		.table = axg_gp0_pll_rate_table,
 290		.init_regs = axg_hifi_init_regs,
 291		.init_count = ARRAY_SIZE(axg_hifi_init_regs),
 292		.flags = CLK_MESON_PLL_ROUND_CLOSEST,
 293	},
 294	.hw.init = &(struct clk_init_data){
 295		.name = "hifi_pll",
 296		.ops = &meson_clk_pll_ops,
 297		.parent_names = (const char *[]){ "xtal" },
 298		.num_parents = 1,
 299	},
 300};
 301
 302static struct clk_fixed_factor axg_fclk_div2_div = {
 303	.mult = 1,
 304	.div = 2,
 305	.hw.init = &(struct clk_init_data){
 306		.name = "fclk_div2_div",
 307		.ops = &clk_fixed_factor_ops,
 308		.parent_names = (const char *[]){ "fixed_pll" },
 309		.num_parents = 1,
 310	},
 311};
 312
 313static struct clk_regmap axg_fclk_div2 = {
 314	.data = &(struct clk_regmap_gate_data){
 315		.offset = HHI_MPLL_CNTL6,
 316		.bit_idx = 27,
 317	},
 318	.hw.init = &(struct clk_init_data){
 319		.name = "fclk_div2",
 320		.ops = &clk_regmap_gate_ops,
 321		.parent_names = (const char *[]){ "fclk_div2_div" },
 322		.num_parents = 1,
 323	},
 324};
 325
 326static struct clk_fixed_factor axg_fclk_div3_div = {
 327	.mult = 1,
 328	.div = 3,
 329	.hw.init = &(struct clk_init_data){
 330		.name = "fclk_div3_div",
 331		.ops = &clk_fixed_factor_ops,
 332		.parent_names = (const char *[]){ "fixed_pll" },
 333		.num_parents = 1,
 334	},
 335};
 336
 337static struct clk_regmap axg_fclk_div3 = {
 338	.data = &(struct clk_regmap_gate_data){
 339		.offset = HHI_MPLL_CNTL6,
 340		.bit_idx = 28,
 341	},
 342	.hw.init = &(struct clk_init_data){
 343		.name = "fclk_div3",
 344		.ops = &clk_regmap_gate_ops,
 345		.parent_names = (const char *[]){ "fclk_div3_div" },
 346		.num_parents = 1,
 347	},
 348};
 349
 350static struct clk_fixed_factor axg_fclk_div4_div = {
 351	.mult = 1,
 352	.div = 4,
 353	.hw.init = &(struct clk_init_data){
 354		.name = "fclk_div4_div",
 355		.ops = &clk_fixed_factor_ops,
 356		.parent_names = (const char *[]){ "fixed_pll" },
 357		.num_parents = 1,
 358	},
 359};
 360
 361static struct clk_regmap axg_fclk_div4 = {
 362	.data = &(struct clk_regmap_gate_data){
 363		.offset = HHI_MPLL_CNTL6,
 364		.bit_idx = 29,
 365	},
 366	.hw.init = &(struct clk_init_data){
 367		.name = "fclk_div4",
 368		.ops = &clk_regmap_gate_ops,
 369		.parent_names = (const char *[]){ "fclk_div4_div" },
 370		.num_parents = 1,
 371	},
 372};
 373
 374static struct clk_fixed_factor axg_fclk_div5_div = {
 375	.mult = 1,
 376	.div = 5,
 377	.hw.init = &(struct clk_init_data){
 378		.name = "fclk_div5_div",
 379		.ops = &clk_fixed_factor_ops,
 380		.parent_names = (const char *[]){ "fixed_pll" },
 381		.num_parents = 1,
 382	},
 383};
 384
 385static struct clk_regmap axg_fclk_div5 = {
 386	.data = &(struct clk_regmap_gate_data){
 387		.offset = HHI_MPLL_CNTL6,
 388		.bit_idx = 30,
 389	},
 390	.hw.init = &(struct clk_init_data){
 391		.name = "fclk_div5",
 392		.ops = &clk_regmap_gate_ops,
 393		.parent_names = (const char *[]){ "fclk_div5_div" },
 394		.num_parents = 1,
 395	},
 396};
 397
 398static struct clk_fixed_factor axg_fclk_div7_div = {
 399	.mult = 1,
 400	.div = 7,
 401	.hw.init = &(struct clk_init_data){
 402		.name = "fclk_div7_div",
 403		.ops = &clk_fixed_factor_ops,
 404		.parent_names = (const char *[]){ "fixed_pll" },
 405		.num_parents = 1,
 406	},
 407};
 408
 409static struct clk_regmap axg_fclk_div7 = {
 410	.data = &(struct clk_regmap_gate_data){
 411		.offset = HHI_MPLL_CNTL6,
 412		.bit_idx = 31,
 413	},
 414	.hw.init = &(struct clk_init_data){
 415		.name = "fclk_div7",
 416		.ops = &clk_regmap_gate_ops,
 417		.parent_names = (const char *[]){ "fclk_div7_div" },
 418		.num_parents = 1,
 419	},
 420};
 421
 422static struct clk_regmap axg_mpll_prediv = {
 423	.data = &(struct clk_regmap_div_data){
 424		.offset = HHI_MPLL_CNTL5,
 425		.shift = 12,
 426		.width = 1,
 427	},
 428	.hw.init = &(struct clk_init_data){
 429		.name = "mpll_prediv",
 430		.ops = &clk_regmap_divider_ro_ops,
 431		.parent_names = (const char *[]){ "fixed_pll" },
 432		.num_parents = 1,
 433	},
 434};
 435
 436static struct clk_regmap axg_mpll0_div = {
 437	.data = &(struct meson_clk_mpll_data){
 438		.sdm = {
 439			.reg_off = HHI_MPLL_CNTL7,
 440			.shift   = 0,
 441			.width   = 14,
 442		},
 443		.sdm_en = {
 444			.reg_off = HHI_MPLL_CNTL7,
 445			.shift   = 15,
 446			.width	 = 1,
 447		},
 448		.n2 = {
 449			.reg_off = HHI_MPLL_CNTL7,
 450			.shift   = 16,
 451			.width   = 9,
 452		},
 453		.ssen = {
 454			.reg_off = HHI_MPLL_CNTL,
 455			.shift   = 25,
 456			.width	 = 1,
 457		},
 458		.misc = {
 459			.reg_off = HHI_PLL_TOP_MISC,
 460			.shift   = 0,
 461			.width	 = 1,
 462		},
 463		.lock = &meson_clk_lock,
 464	},
 465	.hw.init = &(struct clk_init_data){
 466		.name = "mpll0_div",
 467		.ops = &meson_clk_mpll_ops,
 468		.parent_names = (const char *[]){ "mpll_prediv" },
 469		.num_parents = 1,
 470	},
 471};
 472
 473static struct clk_regmap axg_mpll0 = {
 474	.data = &(struct clk_regmap_gate_data){
 475		.offset = HHI_MPLL_CNTL7,
 476		.bit_idx = 14,
 477	},
 478	.hw.init = &(struct clk_init_data){
 479		.name = "mpll0",
 480		.ops = &clk_regmap_gate_ops,
 481		.parent_names = (const char *[]){ "mpll0_div" },
 482		.num_parents = 1,
 483		.flags = CLK_SET_RATE_PARENT,
 484	},
 485};
 486
 487static struct clk_regmap axg_mpll1_div = {
 488	.data = &(struct meson_clk_mpll_data){
 489		.sdm = {
 490			.reg_off = HHI_MPLL_CNTL8,
 491			.shift   = 0,
 492			.width   = 14,
 493		},
 494		.sdm_en = {
 495			.reg_off = HHI_MPLL_CNTL8,
 496			.shift   = 15,
 497			.width	 = 1,
 498		},
 499		.n2 = {
 500			.reg_off = HHI_MPLL_CNTL8,
 501			.shift   = 16,
 502			.width   = 9,
 503		},
 504		.misc = {
 505			.reg_off = HHI_PLL_TOP_MISC,
 506			.shift   = 1,
 507			.width	 = 1,
 508		},
 509		.lock = &meson_clk_lock,
 510	},
 511	.hw.init = &(struct clk_init_data){
 512		.name = "mpll1_div",
 513		.ops = &meson_clk_mpll_ops,
 514		.parent_names = (const char *[]){ "mpll_prediv" },
 515		.num_parents = 1,
 516	},
 517};
 518
 519static struct clk_regmap axg_mpll1 = {
 520	.data = &(struct clk_regmap_gate_data){
 521		.offset = HHI_MPLL_CNTL8,
 522		.bit_idx = 14,
 523	},
 524	.hw.init = &(struct clk_init_data){
 525		.name = "mpll1",
 526		.ops = &clk_regmap_gate_ops,
 527		.parent_names = (const char *[]){ "mpll1_div" },
 528		.num_parents = 1,
 529		.flags = CLK_SET_RATE_PARENT,
 530	},
 531};
 532
 533static struct clk_regmap axg_mpll2_div = {
 534	.data = &(struct meson_clk_mpll_data){
 535		.sdm = {
 536			.reg_off = HHI_MPLL_CNTL9,
 537			.shift   = 0,
 538			.width   = 14,
 539		},
 540		.sdm_en = {
 541			.reg_off = HHI_MPLL_CNTL9,
 542			.shift   = 15,
 543			.width	 = 1,
 544		},
 545		.n2 = {
 546			.reg_off = HHI_MPLL_CNTL9,
 547			.shift   = 16,
 548			.width   = 9,
 549		},
 550		.misc = {
 551			.reg_off = HHI_PLL_TOP_MISC,
 552			.shift   = 2,
 553			.width	 = 1,
 554		},
 555		.lock = &meson_clk_lock,
 556	},
 557	.hw.init = &(struct clk_init_data){
 558		.name = "mpll2_div",
 559		.ops = &meson_clk_mpll_ops,
 560		.parent_names = (const char *[]){ "mpll_prediv" },
 561		.num_parents = 1,
 562	},
 563};
 564
 565static struct clk_regmap axg_mpll2 = {
 566	.data = &(struct clk_regmap_gate_data){
 567		.offset = HHI_MPLL_CNTL9,
 568		.bit_idx = 14,
 569	},
 570	.hw.init = &(struct clk_init_data){
 571		.name = "mpll2",
 572		.ops = &clk_regmap_gate_ops,
 573		.parent_names = (const char *[]){ "mpll2_div" },
 574		.num_parents = 1,
 575		.flags = CLK_SET_RATE_PARENT,
 576	},
 577};
 578
 579static struct clk_regmap axg_mpll3_div = {
 580	.data = &(struct meson_clk_mpll_data){
 581		.sdm = {
 582			.reg_off = HHI_MPLL3_CNTL0,
 583			.shift   = 12,
 584			.width   = 14,
 585		},
 586		.sdm_en = {
 587			.reg_off = HHI_MPLL3_CNTL0,
 588			.shift   = 11,
 589			.width	 = 1,
 590		},
 591		.n2 = {
 592			.reg_off = HHI_MPLL3_CNTL0,
 593			.shift   = 2,
 594			.width   = 9,
 595		},
 596		.misc = {
 597			.reg_off = HHI_PLL_TOP_MISC,
 598			.shift   = 3,
 599			.width	 = 1,
 600		},
 601		.lock = &meson_clk_lock,
 602	},
 603	.hw.init = &(struct clk_init_data){
 604		.name = "mpll3_div",
 605		.ops = &meson_clk_mpll_ops,
 606		.parent_names = (const char *[]){ "mpll_prediv" },
 607		.num_parents = 1,
 608	},
 609};
 610
 611static struct clk_regmap axg_mpll3 = {
 612	.data = &(struct clk_regmap_gate_data){
 613		.offset = HHI_MPLL3_CNTL0,
 614		.bit_idx = 0,
 615	},
 616	.hw.init = &(struct clk_init_data){
 617		.name = "mpll3",
 618		.ops = &clk_regmap_gate_ops,
 619		.parent_names = (const char *[]){ "mpll3_div" },
 620		.num_parents = 1,
 621		.flags = CLK_SET_RATE_PARENT,
 622	},
 623};
 624
 625static u32 mux_table_clk81[]	= { 0, 2, 3, 4, 5, 6, 7 };
 626static const char * const clk81_parent_names[] = {
 627	"xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
 628	"fclk_div3", "fclk_div5"
 629};
 630
 631static struct clk_regmap axg_mpeg_clk_sel = {
 632	.data = &(struct clk_regmap_mux_data){
 633		.offset = HHI_MPEG_CLK_CNTL,
 634		.mask = 0x7,
 635		.shift = 12,
 636		.table = mux_table_clk81,
 637	},
 638	.hw.init = &(struct clk_init_data){
 639		.name = "mpeg_clk_sel",
 640		.ops = &clk_regmap_mux_ro_ops,
 641		.parent_names = clk81_parent_names,
 642		.num_parents = ARRAY_SIZE(clk81_parent_names),
 643	},
 644};
 645
 646static struct clk_regmap axg_mpeg_clk_div = {
 647	.data = &(struct clk_regmap_div_data){
 648		.offset = HHI_MPEG_CLK_CNTL,
 649		.shift = 0,
 650		.width = 7,
 651	},
 652	.hw.init = &(struct clk_init_data){
 653		.name = "mpeg_clk_div",
 654		.ops = &clk_regmap_divider_ops,
 655		.parent_names = (const char *[]){ "mpeg_clk_sel" },
 656		.num_parents = 1,
 657		.flags = CLK_SET_RATE_PARENT,
 658	},
 659};
 660
 661static struct clk_regmap axg_clk81 = {
 662	.data = &(struct clk_regmap_gate_data){
 663		.offset = HHI_MPEG_CLK_CNTL,
 664		.bit_idx = 7,
 665	},
 666	.hw.init = &(struct clk_init_data){
 667		.name = "clk81",
 668		.ops = &clk_regmap_gate_ops,
 669		.parent_names = (const char *[]){ "mpeg_clk_div" },
 670		.num_parents = 1,
 671		.flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
 672	},
 673};
 674
 675static const char * const axg_sd_emmc_clk0_parent_names[] = {
 676	"xtal", "fclk_div2", "fclk_div3", "fclk_div5", "fclk_div7",
 677
 678	/*
 679	 * Following these parent clocks, we should also have had mpll2, mpll3
 680	 * and gp0_pll but these clocks are too precious to be used here. All
 681	 * the necessary rates for MMC and NAND operation can be acheived using
 682	 * xtal or fclk_div clocks
 683	 */
 684};
 685
 686/* SDcard clock */
 687static struct clk_regmap axg_sd_emmc_b_clk0_sel = {
 688	.data = &(struct clk_regmap_mux_data){
 689		.offset = HHI_SD_EMMC_CLK_CNTL,
 690		.mask = 0x7,
 691		.shift = 25,
 692	},
 693	.hw.init = &(struct clk_init_data) {
 694		.name = "sd_emmc_b_clk0_sel",
 695		.ops = &clk_regmap_mux_ops,
 696		.parent_names = axg_sd_emmc_clk0_parent_names,
 697		.num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
 698		.flags = CLK_SET_RATE_PARENT,
 699	},
 700};
 701
 702static struct clk_regmap axg_sd_emmc_b_clk0_div = {
 703	.data = &(struct clk_regmap_div_data){
 704		.offset = HHI_SD_EMMC_CLK_CNTL,
 705		.shift = 16,
 706		.width = 7,
 707		.flags = CLK_DIVIDER_ROUND_CLOSEST,
 708	},
 709	.hw.init = &(struct clk_init_data) {
 710		.name = "sd_emmc_b_clk0_div",
 711		.ops = &clk_regmap_divider_ops,
 712		.parent_names = (const char *[]){ "sd_emmc_b_clk0_sel" },
 713		.num_parents = 1,
 714		.flags = CLK_SET_RATE_PARENT,
 715	},
 716};
 717
 718static struct clk_regmap axg_sd_emmc_b_clk0 = {
 719	.data = &(struct clk_regmap_gate_data){
 720		.offset = HHI_SD_EMMC_CLK_CNTL,
 721		.bit_idx = 23,
 722	},
 723	.hw.init = &(struct clk_init_data){
 724		.name = "sd_emmc_b_clk0",
 725		.ops = &clk_regmap_gate_ops,
 726		.parent_names = (const char *[]){ "sd_emmc_b_clk0_div" },
 727		.num_parents = 1,
 728		.flags = CLK_SET_RATE_PARENT,
 729	},
 730};
 731
 732/* EMMC/NAND clock */
 733static struct clk_regmap axg_sd_emmc_c_clk0_sel = {
 734	.data = &(struct clk_regmap_mux_data){
 735		.offset = HHI_NAND_CLK_CNTL,
 736		.mask = 0x7,
 737		.shift = 9,
 738	},
 739	.hw.init = &(struct clk_init_data) {
 740		.name = "sd_emmc_c_clk0_sel",
 741		.ops = &clk_regmap_mux_ops,
 742		.parent_names = axg_sd_emmc_clk0_parent_names,
 743		.num_parents = ARRAY_SIZE(axg_sd_emmc_clk0_parent_names),
 744		.flags = CLK_SET_RATE_PARENT,
 745	},
 746};
 747
 748static struct clk_regmap axg_sd_emmc_c_clk0_div = {
 749	.data = &(struct clk_regmap_div_data){
 750		.offset = HHI_NAND_CLK_CNTL,
 751		.shift = 0,
 752		.width = 7,
 753		.flags = CLK_DIVIDER_ROUND_CLOSEST,
 754	},
 755	.hw.init = &(struct clk_init_data) {
 756		.name = "sd_emmc_c_clk0_div",
 757		.ops = &clk_regmap_divider_ops,
 758		.parent_names = (const char *[]){ "sd_emmc_c_clk0_sel" },
 759		.num_parents = 1,
 760		.flags = CLK_SET_RATE_PARENT,
 761	},
 762};
 763
 764static struct clk_regmap axg_sd_emmc_c_clk0 = {
 765	.data = &(struct clk_regmap_gate_data){
 766		.offset = HHI_NAND_CLK_CNTL,
 767		.bit_idx = 7,
 768	},
 769	.hw.init = &(struct clk_init_data){
 770		.name = "sd_emmc_c_clk0",
 771		.ops = &clk_regmap_gate_ops,
 772		.parent_names = (const char *[]){ "sd_emmc_c_clk0_div" },
 773		.num_parents = 1,
 774		.flags = CLK_SET_RATE_PARENT,
 775	},
 776};
 777
 778/* Everything Else (EE) domain gates */
 779static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0);
 780static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2);
 781static MESON_GATE(axg_mipi_dsi_host, HHI_GCLK_MPEG0, 3);
 782static MESON_GATE(axg_isa, HHI_GCLK_MPEG0, 5);
 783static MESON_GATE(axg_pl301, HHI_GCLK_MPEG0, 6);
 784static MESON_GATE(axg_periphs, HHI_GCLK_MPEG0, 7);
 785static MESON_GATE(axg_spicc_0, HHI_GCLK_MPEG0, 8);
 786static MESON_GATE(axg_i2c, HHI_GCLK_MPEG0, 9);
 787static MESON_GATE(axg_rng0, HHI_GCLK_MPEG0, 12);
 788static MESON_GATE(axg_uart0, HHI_GCLK_MPEG0, 13);
 789static MESON_GATE(axg_mipi_dsi_phy, HHI_GCLK_MPEG0, 14);
 790static MESON_GATE(axg_spicc_1, HHI_GCLK_MPEG0, 15);
 791static MESON_GATE(axg_pcie_a, HHI_GCLK_MPEG0, 16);
 792static MESON_GATE(axg_pcie_b, HHI_GCLK_MPEG0, 17);
 793static MESON_GATE(axg_hiu_reg, HHI_GCLK_MPEG0, 19);
 794static MESON_GATE(axg_assist_misc, HHI_GCLK_MPEG0, 23);
 795static MESON_GATE(axg_emmc_b, HHI_GCLK_MPEG0, 25);
 796static MESON_GATE(axg_emmc_c, HHI_GCLK_MPEG0, 26);
 797static MESON_GATE(axg_dma, HHI_GCLK_MPEG0, 27);
 798static MESON_GATE(axg_spi, HHI_GCLK_MPEG0, 30);
 799
 800static MESON_GATE(axg_audio, HHI_GCLK_MPEG1, 0);
 801static MESON_GATE(axg_eth_core, HHI_GCLK_MPEG1, 3);
 802static MESON_GATE(axg_uart1, HHI_GCLK_MPEG1, 16);
 803static MESON_GATE(axg_g2d, HHI_GCLK_MPEG1, 20);
 804static MESON_GATE(axg_usb0, HHI_GCLK_MPEG1, 21);
 805static MESON_GATE(axg_usb1, HHI_GCLK_MPEG1, 22);
 806static MESON_GATE(axg_reset, HHI_GCLK_MPEG1, 23);
 807static MESON_GATE(axg_usb_general, HHI_GCLK_MPEG1, 26);
 808static MESON_GATE(axg_ahb_arb0, HHI_GCLK_MPEG1, 29);
 809static MESON_GATE(axg_efuse, HHI_GCLK_MPEG1, 30);
 810static MESON_GATE(axg_boot_rom, HHI_GCLK_MPEG1, 31);
 811
 812static MESON_GATE(axg_ahb_data_bus, HHI_GCLK_MPEG2, 1);
 813static MESON_GATE(axg_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
 814static MESON_GATE(axg_usb1_to_ddr, HHI_GCLK_MPEG2, 8);
 815static MESON_GATE(axg_usb0_to_ddr, HHI_GCLK_MPEG2, 9);
 816static MESON_GATE(axg_mmc_pclk, HHI_GCLK_MPEG2, 11);
 817static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25);
 818static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
 819static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30);
 820
 821/* Always On (AO) domain gates */
 822
 823static MESON_GATE(axg_ao_media_cpu, HHI_GCLK_AO, 0);
 824static MESON_GATE(axg_ao_ahb_sram, HHI_GCLK_AO, 1);
 825static MESON_GATE(axg_ao_ahb_bus, HHI_GCLK_AO, 2);
 826static MESON_GATE(axg_ao_iface, HHI_GCLK_AO, 3);
 827static MESON_GATE(axg_ao_i2c, HHI_GCLK_AO, 4);
 828
 829/* Array of all clocks provided by this provider */
 830
 831static struct clk_hw_onecell_data axg_hw_onecell_data = {
 832	.hws = {
 833		[CLKID_SYS_PLL]			= &axg_sys_pll.hw,
 834		[CLKID_FIXED_PLL]		= &axg_fixed_pll.hw,
 835		[CLKID_FCLK_DIV2]		= &axg_fclk_div2.hw,
 836		[CLKID_FCLK_DIV3]		= &axg_fclk_div3.hw,
 837		[CLKID_FCLK_DIV4]		= &axg_fclk_div4.hw,
 838		[CLKID_FCLK_DIV5]		= &axg_fclk_div5.hw,
 839		[CLKID_FCLK_DIV7]		= &axg_fclk_div7.hw,
 840		[CLKID_GP0_PLL]			= &axg_gp0_pll.hw,
 841		[CLKID_MPEG_SEL]		= &axg_mpeg_clk_sel.hw,
 842		[CLKID_MPEG_DIV]		= &axg_mpeg_clk_div.hw,
 843		[CLKID_CLK81]			= &axg_clk81.hw,
 844		[CLKID_MPLL0]			= &axg_mpll0.hw,
 845		[CLKID_MPLL1]			= &axg_mpll1.hw,
 846		[CLKID_MPLL2]			= &axg_mpll2.hw,
 847		[CLKID_MPLL3]			= &axg_mpll3.hw,
 848		[CLKID_DDR]			= &axg_ddr.hw,
 849		[CLKID_AUDIO_LOCKER]		= &axg_audio_locker.hw,
 850		[CLKID_MIPI_DSI_HOST]		= &axg_mipi_dsi_host.hw,
 851		[CLKID_ISA]			= &axg_isa.hw,
 852		[CLKID_PL301]			= &axg_pl301.hw,
 853		[CLKID_PERIPHS]			= &axg_periphs.hw,
 854		[CLKID_SPICC0]			= &axg_spicc_0.hw,
 855		[CLKID_I2C]			= &axg_i2c.hw,
 856		[CLKID_RNG0]			= &axg_rng0.hw,
 857		[CLKID_UART0]			= &axg_uart0.hw,
 858		[CLKID_MIPI_DSI_PHY]		= &axg_mipi_dsi_phy.hw,
 859		[CLKID_SPICC1]			= &axg_spicc_1.hw,
 860		[CLKID_PCIE_A]			= &axg_pcie_a.hw,
 861		[CLKID_PCIE_B]			= &axg_pcie_b.hw,
 862		[CLKID_HIU_IFACE]		= &axg_hiu_reg.hw,
 863		[CLKID_ASSIST_MISC]		= &axg_assist_misc.hw,
 864		[CLKID_SD_EMMC_B]		= &axg_emmc_b.hw,
 865		[CLKID_SD_EMMC_C]		= &axg_emmc_c.hw,
 866		[CLKID_DMA]			= &axg_dma.hw,
 867		[CLKID_SPI]			= &axg_spi.hw,
 868		[CLKID_AUDIO]			= &axg_audio.hw,
 869		[CLKID_ETH]			= &axg_eth_core.hw,
 870		[CLKID_UART1]			= &axg_uart1.hw,
 871		[CLKID_G2D]			= &axg_g2d.hw,
 872		[CLKID_USB0]			= &axg_usb0.hw,
 873		[CLKID_USB1]			= &axg_usb1.hw,
 874		[CLKID_RESET]			= &axg_reset.hw,
 875		[CLKID_USB]			= &axg_usb_general.hw,
 876		[CLKID_AHB_ARB0]		= &axg_ahb_arb0.hw,
 877		[CLKID_EFUSE]			= &axg_efuse.hw,
 878		[CLKID_BOOT_ROM]		= &axg_boot_rom.hw,
 879		[CLKID_AHB_DATA_BUS]		= &axg_ahb_data_bus.hw,
 880		[CLKID_AHB_CTRL_BUS]		= &axg_ahb_ctrl_bus.hw,
 881		[CLKID_USB1_DDR_BRIDGE]		= &axg_usb1_to_ddr.hw,
 882		[CLKID_USB0_DDR_BRIDGE]		= &axg_usb0_to_ddr.hw,
 883		[CLKID_MMC_PCLK]		= &axg_mmc_pclk.hw,
 884		[CLKID_VPU_INTR]		= &axg_vpu_intr.hw,
 885		[CLKID_SEC_AHB_AHB3_BRIDGE]	= &axg_sec_ahb_ahb3_bridge.hw,
 886		[CLKID_GIC]			= &axg_gic.hw,
 887		[CLKID_AO_MEDIA_CPU]		= &axg_ao_media_cpu.hw,
 888		[CLKID_AO_AHB_SRAM]		= &axg_ao_ahb_sram.hw,
 889		[CLKID_AO_AHB_BUS]		= &axg_ao_ahb_bus.hw,
 890		[CLKID_AO_IFACE]		= &axg_ao_iface.hw,
 891		[CLKID_AO_I2C]			= &axg_ao_i2c.hw,
 892		[CLKID_SD_EMMC_B_CLK0_SEL]	= &axg_sd_emmc_b_clk0_sel.hw,
 893		[CLKID_SD_EMMC_B_CLK0_DIV]	= &axg_sd_emmc_b_clk0_div.hw,
 894		[CLKID_SD_EMMC_B_CLK0]		= &axg_sd_emmc_b_clk0.hw,
 895		[CLKID_SD_EMMC_C_CLK0_SEL]	= &axg_sd_emmc_c_clk0_sel.hw,
 896		[CLKID_SD_EMMC_C_CLK0_DIV]	= &axg_sd_emmc_c_clk0_div.hw,
 897		[CLKID_SD_EMMC_C_CLK0]		= &axg_sd_emmc_c_clk0.hw,
 898		[CLKID_MPLL0_DIV]		= &axg_mpll0_div.hw,
 899		[CLKID_MPLL1_DIV]		= &axg_mpll1_div.hw,
 900		[CLKID_MPLL2_DIV]		= &axg_mpll2_div.hw,
 901		[CLKID_MPLL3_DIV]		= &axg_mpll3_div.hw,
 902		[CLKID_HIFI_PLL]		= &axg_hifi_pll.hw,
 903		[CLKID_MPLL_PREDIV]		= &axg_mpll_prediv.hw,
 904		[CLKID_FCLK_DIV2_DIV]		= &axg_fclk_div2_div.hw,
 905		[CLKID_FCLK_DIV3_DIV]		= &axg_fclk_div3_div.hw,
 906		[CLKID_FCLK_DIV4_DIV]		= &axg_fclk_div4_div.hw,
 907		[CLKID_FCLK_DIV5_DIV]		= &axg_fclk_div5_div.hw,
 908		[CLKID_FCLK_DIV7_DIV]		= &axg_fclk_div7_div.hw,
 909		[NR_CLKS]			= NULL,
 910	},
 911	.num = NR_CLKS,
 912};
 913
 914/* Convenience table to populate regmap in .probe */
 915static struct clk_regmap *const axg_clk_regmaps[] = {
 916	&axg_clk81,
 917	&axg_ddr,
 918	&axg_audio_locker,
 919	&axg_mipi_dsi_host,
 920	&axg_isa,
 921	&axg_pl301,
 922	&axg_periphs,
 923	&axg_spicc_0,
 924	&axg_i2c,
 925	&axg_rng0,
 926	&axg_uart0,
 927	&axg_mipi_dsi_phy,
 928	&axg_spicc_1,
 929	&axg_pcie_a,
 930	&axg_pcie_b,
 931	&axg_hiu_reg,
 932	&axg_assist_misc,
 933	&axg_emmc_b,
 934	&axg_emmc_c,
 935	&axg_dma,
 936	&axg_spi,
 937	&axg_audio,
 938	&axg_eth_core,
 939	&axg_uart1,
 940	&axg_g2d,
 941	&axg_usb0,
 942	&axg_usb1,
 943	&axg_reset,
 944	&axg_usb_general,
 945	&axg_ahb_arb0,
 946	&axg_efuse,
 947	&axg_boot_rom,
 948	&axg_ahb_data_bus,
 949	&axg_ahb_ctrl_bus,
 950	&axg_usb1_to_ddr,
 951	&axg_usb0_to_ddr,
 952	&axg_mmc_pclk,
 953	&axg_vpu_intr,
 954	&axg_sec_ahb_ahb3_bridge,
 955	&axg_gic,
 956	&axg_ao_media_cpu,
 957	&axg_ao_ahb_sram,
 958	&axg_ao_ahb_bus,
 959	&axg_ao_iface,
 960	&axg_ao_i2c,
 961	&axg_sd_emmc_b_clk0,
 962	&axg_sd_emmc_c_clk0,
 963	&axg_mpeg_clk_div,
 964	&axg_sd_emmc_b_clk0_div,
 965	&axg_sd_emmc_c_clk0_div,
 966	&axg_mpeg_clk_sel,
 967	&axg_sd_emmc_b_clk0_sel,
 968	&axg_sd_emmc_c_clk0_sel,
 969	&axg_mpll0,
 970	&axg_mpll1,
 971	&axg_mpll2,
 972	&axg_mpll3,
 973	&axg_mpll0_div,
 974	&axg_mpll1_div,
 975	&axg_mpll2_div,
 976	&axg_mpll3_div,
 977	&axg_fixed_pll,
 978	&axg_sys_pll,
 979	&axg_gp0_pll,
 980	&axg_hifi_pll,
 981	&axg_mpll_prediv,
 982	&axg_fclk_div2,
 983	&axg_fclk_div3,
 984	&axg_fclk_div4,
 985	&axg_fclk_div5,
 986	&axg_fclk_div7,
 987};
 988
 989static const struct of_device_id clkc_match_table[] = {
 990	{ .compatible = "amlogic,axg-clkc" },
 991	{}
 992};
 993
 994static const struct regmap_config clkc_regmap_config = {
 995	.reg_bits       = 32,
 996	.val_bits       = 32,
 997	.reg_stride     = 4,
 998};
 999
1000static int axg_clkc_probe(struct platform_device *pdev)
1001{
1002	struct device *dev = &pdev->dev;
1003	struct resource *res;
1004	void __iomem *clk_base = NULL;
1005	struct regmap *map;
1006	int ret, i;
1007
1008	/* Get the hhi system controller node if available */
1009	map = syscon_node_to_regmap(of_get_parent(dev->of_node));
1010	if (IS_ERR(map)) {
1011		dev_err(dev,
1012			"failed to get HHI regmap - Trying obsolete regs\n");
1013
1014		/*
1015		 * FIXME: HHI registers should be accessed through
1016		 * the appropriate system controller. This is required because
1017		 * there is more than just clocks in this register space
1018		 *
1019		 * This fallback method is only provided temporarily until
1020		 * all the platform DTs are properly using the syscon node
1021		 */
1022		res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1023		if (!res)
1024			return -EINVAL;
1025
1026
1027		clk_base = devm_ioremap(dev, res->start, resource_size(res));
1028		if (!clk_base) {
1029			dev_err(dev, "Unable to map clk base\n");
1030			return -ENXIO;
1031		}
1032
1033		map = devm_regmap_init_mmio(dev, clk_base,
1034					    &clkc_regmap_config);
1035		if (IS_ERR(map))
1036			return PTR_ERR(map);
1037	}
1038
1039	/* Populate regmap for the regmap backed clocks */
1040	for (i = 0; i < ARRAY_SIZE(axg_clk_regmaps); i++)
1041		axg_clk_regmaps[i]->map = map;
1042
1043	for (i = 0; i < axg_hw_onecell_data.num; i++) {
1044		/* array might be sparse */
1045		if (!axg_hw_onecell_data.hws[i])
1046			continue;
1047
1048		ret = devm_clk_hw_register(dev, axg_hw_onecell_data.hws[i]);
1049		if (ret) {
1050			dev_err(dev, "Clock registration failed\n");
1051			return ret;
1052		}
1053	}
1054
1055	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
1056					   &axg_hw_onecell_data);
1057}
1058
1059static struct platform_driver axg_driver = {
1060	.probe		= axg_clkc_probe,
1061	.driver		= {
1062		.name	= "axg-clkc",
1063		.of_match_table = clkc_match_table,
1064	},
1065};
1066
1067builtin_platform_driver(axg_driver);