Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.5.6.
   1/*
   2 * AmLogic S802 (Meson8) / S805 (Meson8b) / S812 (Meson8m2) Clock Controller
   3 * Driver
   4 *
   5 * Copyright (c) 2015 Endless Mobile, Inc.
   6 * Author: Carlo Caione <carlo@endlessm.com>
   7 *
   8 * Copyright (c) 2016 BayLibre, Inc.
   9 * Michael Turquette <mturquette@baylibre.com>
  10 *
  11 * This program is free software; you can redistribute it and/or modify it
  12 * under the terms and conditions of the GNU General Public License,
  13 * version 2, as published by the Free Software Foundation.
  14 *
  15 * This program is distributed in the hope it will be useful, but WITHOUT
  16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  17 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
  18 * more details.
  19 *
  20 * You should have received a copy of the GNU General Public License along with
  21 * this program.  If not, see <http://www.gnu.org/licenses/>.
  22 */
  23
  24#include <linux/clk.h>
  25#include <linux/clk-provider.h>
  26#include <linux/init.h>
  27#include <linux/of_address.h>
  28#include <linux/platform_device.h>
  29#include <linux/reset-controller.h>
  30#include <linux/slab.h>
  31#include <linux/regmap.h>
  32
  33#include "clkc.h"
  34#include "meson8b.h"
  35#include "clk-regmap.h"
  36
  37static DEFINE_SPINLOCK(meson_clk_lock);
  38
  39static void __iomem *clk_base;
  40
  41struct meson8b_clk_reset {
  42	struct reset_controller_dev reset;
  43	void __iomem *base;
  44};
  45
  46static const struct pll_rate_table sys_pll_rate_table[] = {
  47	PLL_RATE(312000000, 52, 1, 2),
  48	PLL_RATE(336000000, 56, 1, 2),
  49	PLL_RATE(360000000, 60, 1, 2),
  50	PLL_RATE(384000000, 64, 1, 2),
  51	PLL_RATE(408000000, 68, 1, 2),
  52	PLL_RATE(432000000, 72, 1, 2),
  53	PLL_RATE(456000000, 76, 1, 2),
  54	PLL_RATE(480000000, 80, 1, 2),
  55	PLL_RATE(504000000, 84, 1, 2),
  56	PLL_RATE(528000000, 88, 1, 2),
  57	PLL_RATE(552000000, 92, 1, 2),
  58	PLL_RATE(576000000, 96, 1, 2),
  59	PLL_RATE(600000000, 50, 1, 1),
  60	PLL_RATE(624000000, 52, 1, 1),
  61	PLL_RATE(648000000, 54, 1, 1),
  62	PLL_RATE(672000000, 56, 1, 1),
  63	PLL_RATE(696000000, 58, 1, 1),
  64	PLL_RATE(720000000, 60, 1, 1),
  65	PLL_RATE(744000000, 62, 1, 1),
  66	PLL_RATE(768000000, 64, 1, 1),
  67	PLL_RATE(792000000, 66, 1, 1),
  68	PLL_RATE(816000000, 68, 1, 1),
  69	PLL_RATE(840000000, 70, 1, 1),
  70	PLL_RATE(864000000, 72, 1, 1),
  71	PLL_RATE(888000000, 74, 1, 1),
  72	PLL_RATE(912000000, 76, 1, 1),
  73	PLL_RATE(936000000, 78, 1, 1),
  74	PLL_RATE(960000000, 80, 1, 1),
  75	PLL_RATE(984000000, 82, 1, 1),
  76	PLL_RATE(1008000000, 84, 1, 1),
  77	PLL_RATE(1032000000, 86, 1, 1),
  78	PLL_RATE(1056000000, 88, 1, 1),
  79	PLL_RATE(1080000000, 90, 1, 1),
  80	PLL_RATE(1104000000, 92, 1, 1),
  81	PLL_RATE(1128000000, 94, 1, 1),
  82	PLL_RATE(1152000000, 96, 1, 1),
  83	PLL_RATE(1176000000, 98, 1, 1),
  84	PLL_RATE(1200000000, 50, 1, 0),
  85	PLL_RATE(1224000000, 51, 1, 0),
  86	PLL_RATE(1248000000, 52, 1, 0),
  87	PLL_RATE(1272000000, 53, 1, 0),
  88	PLL_RATE(1296000000, 54, 1, 0),
  89	PLL_RATE(1320000000, 55, 1, 0),
  90	PLL_RATE(1344000000, 56, 1, 0),
  91	PLL_RATE(1368000000, 57, 1, 0),
  92	PLL_RATE(1392000000, 58, 1, 0),
  93	PLL_RATE(1416000000, 59, 1, 0),
  94	PLL_RATE(1440000000, 60, 1, 0),
  95	PLL_RATE(1464000000, 61, 1, 0),
  96	PLL_RATE(1488000000, 62, 1, 0),
  97	PLL_RATE(1512000000, 63, 1, 0),
  98	PLL_RATE(1536000000, 64, 1, 0),
  99	{ /* sentinel */ },
 100};
 101
 102static struct clk_fixed_rate meson8b_xtal = {
 103	.fixed_rate = 24000000,
 104	.hw.init = &(struct clk_init_data){
 105		.name = "xtal",
 106		.num_parents = 0,
 107		.ops = &clk_fixed_rate_ops,
 108	},
 109};
 110
 111static struct clk_regmap meson8b_fixed_pll = {
 112	.data = &(struct meson_clk_pll_data){
 113		.m = {
 114			.reg_off = HHI_MPLL_CNTL,
 115			.shift   = 0,
 116			.width   = 9,
 117		},
 118		.n = {
 119			.reg_off = HHI_MPLL_CNTL,
 120			.shift   = 9,
 121			.width   = 5,
 122		},
 123		.od = {
 124			.reg_off = HHI_MPLL_CNTL,
 125			.shift   = 16,
 126			.width   = 2,
 127		},
 128		.frac = {
 129			.reg_off = HHI_MPLL_CNTL2,
 130			.shift   = 0,
 131			.width   = 12,
 132		},
 133		.l = {
 134			.reg_off = HHI_MPLL_CNTL,
 135			.shift   = 31,
 136			.width   = 1,
 137		},
 138		.rst = {
 139			.reg_off = HHI_MPLL_CNTL,
 140			.shift   = 29,
 141			.width   = 1,
 142		},
 143	},
 144	.hw.init = &(struct clk_init_data){
 145		.name = "fixed_pll",
 146		.ops = &meson_clk_pll_ro_ops,
 147		.parent_names = (const char *[]){ "xtal" },
 148		.num_parents = 1,
 149		.flags = CLK_GET_RATE_NOCACHE,
 150	},
 151};
 152
 153static struct clk_regmap meson8b_vid_pll = {
 154	.data = &(struct meson_clk_pll_data){
 155		.m = {
 156			.reg_off = HHI_VID_PLL_CNTL,
 157			.shift   = 0,
 158			.width   = 9,
 159		},
 160		.n = {
 161			.reg_off = HHI_VID_PLL_CNTL,
 162			.shift   = 9,
 163			.width   = 5,
 164		},
 165		.od = {
 166			.reg_off = HHI_VID_PLL_CNTL,
 167			.shift   = 16,
 168			.width   = 2,
 169		},
 170		.l = {
 171			.reg_off = HHI_VID_PLL_CNTL,
 172			.shift   = 31,
 173			.width   = 1,
 174		},
 175		.rst = {
 176			.reg_off = HHI_VID_PLL_CNTL,
 177			.shift   = 29,
 178			.width   = 1,
 179		},
 180	},
 181	.hw.init = &(struct clk_init_data){
 182		.name = "vid_pll",
 183		.ops = &meson_clk_pll_ro_ops,
 184		.parent_names = (const char *[]){ "xtal" },
 185		.num_parents = 1,
 186		.flags = CLK_GET_RATE_NOCACHE,
 187	},
 188};
 189
 190static struct clk_regmap meson8b_sys_pll = {
 191	.data = &(struct meson_clk_pll_data){
 192		.m = {
 193			.reg_off = HHI_SYS_PLL_CNTL,
 194			.shift   = 0,
 195			.width   = 9,
 196		},
 197		.n = {
 198			.reg_off = HHI_SYS_PLL_CNTL,
 199			.shift   = 9,
 200			.width   = 5,
 201		},
 202		.od = {
 203			.reg_off = HHI_SYS_PLL_CNTL,
 204			.shift   = 16,
 205			.width   = 2,
 206		},
 207		.l = {
 208			.reg_off = HHI_SYS_PLL_CNTL,
 209			.shift   = 31,
 210			.width   = 1,
 211		},
 212		.rst = {
 213			.reg_off = HHI_SYS_PLL_CNTL,
 214			.shift   = 29,
 215			.width   = 1,
 216		},
 217		.table = sys_pll_rate_table,
 218	},
 219	.hw.init = &(struct clk_init_data){
 220		.name = "sys_pll",
 221		.ops = &meson_clk_pll_ro_ops,
 222		.parent_names = (const char *[]){ "xtal" },
 223		.num_parents = 1,
 224		.flags = CLK_GET_RATE_NOCACHE,
 225	},
 226};
 227
 228static struct clk_fixed_factor meson8b_fclk_div2_div = {
 229	.mult = 1,
 230	.div = 2,
 231	.hw.init = &(struct clk_init_data){
 232		.name = "fclk_div2_div",
 233		.ops = &clk_fixed_factor_ops,
 234		.parent_names = (const char *[]){ "fixed_pll" },
 235		.num_parents = 1,
 236	},
 237};
 238
 239static struct clk_regmap meson8b_fclk_div2 = {
 240	.data = &(struct clk_regmap_gate_data){
 241		.offset = HHI_MPLL_CNTL6,
 242		.bit_idx = 27,
 243	},
 244	.hw.init = &(struct clk_init_data){
 245		.name = "fclk_div2",
 246		.ops = &clk_regmap_gate_ops,
 247		.parent_names = (const char *[]){ "fclk_div2_div" },
 248		.num_parents = 1,
 249	},
 250};
 251
 252static struct clk_fixed_factor meson8b_fclk_div3_div = {
 253	.mult = 1,
 254	.div = 3,
 255	.hw.init = &(struct clk_init_data){
 256		.name = "fclk_div3_div",
 257		.ops = &clk_fixed_factor_ops,
 258		.parent_names = (const char *[]){ "fixed_pll" },
 259		.num_parents = 1,
 260	},
 261};
 262
 263static struct clk_regmap meson8b_fclk_div3 = {
 264	.data = &(struct clk_regmap_gate_data){
 265		.offset = HHI_MPLL_CNTL6,
 266		.bit_idx = 28,
 267	},
 268	.hw.init = &(struct clk_init_data){
 269		.name = "fclk_div3",
 270		.ops = &clk_regmap_gate_ops,
 271		.parent_names = (const char *[]){ "fclk_div3_div" },
 272		.num_parents = 1,
 273	},
 274};
 275
 276static struct clk_fixed_factor meson8b_fclk_div4_div = {
 277	.mult = 1,
 278	.div = 4,
 279	.hw.init = &(struct clk_init_data){
 280		.name = "fclk_div4_div",
 281		.ops = &clk_fixed_factor_ops,
 282		.parent_names = (const char *[]){ "fixed_pll" },
 283		.num_parents = 1,
 284	},
 285};
 286
 287static struct clk_regmap meson8b_fclk_div4 = {
 288	.data = &(struct clk_regmap_gate_data){
 289		.offset = HHI_MPLL_CNTL6,
 290		.bit_idx = 29,
 291	},
 292	.hw.init = &(struct clk_init_data){
 293		.name = "fclk_div4",
 294		.ops = &clk_regmap_gate_ops,
 295		.parent_names = (const char *[]){ "fclk_div4_div" },
 296		.num_parents = 1,
 297	},
 298};
 299
 300static struct clk_fixed_factor meson8b_fclk_div5_div = {
 301	.mult = 1,
 302	.div = 5,
 303	.hw.init = &(struct clk_init_data){
 304		.name = "fclk_div5_div",
 305		.ops = &clk_fixed_factor_ops,
 306		.parent_names = (const char *[]){ "fixed_pll" },
 307		.num_parents = 1,
 308	},
 309};
 310
 311static struct clk_regmap meson8b_fclk_div5 = {
 312	.data = &(struct clk_regmap_gate_data){
 313		.offset = HHI_MPLL_CNTL6,
 314		.bit_idx = 30,
 315	},
 316	.hw.init = &(struct clk_init_data){
 317		.name = "fclk_div5",
 318		.ops = &clk_regmap_gate_ops,
 319		.parent_names = (const char *[]){ "fclk_div5_div" },
 320		.num_parents = 1,
 321	},
 322};
 323
 324static struct clk_fixed_factor meson8b_fclk_div7_div = {
 325	.mult = 1,
 326	.div = 7,
 327	.hw.init = &(struct clk_init_data){
 328		.name = "fclk_div7_div",
 329		.ops = &clk_fixed_factor_ops,
 330		.parent_names = (const char *[]){ "fixed_pll" },
 331		.num_parents = 1,
 332	},
 333};
 334
 335static struct clk_regmap meson8b_fclk_div7 = {
 336	.data = &(struct clk_regmap_gate_data){
 337		.offset = HHI_MPLL_CNTL6,
 338		.bit_idx = 31,
 339	},
 340	.hw.init = &(struct clk_init_data){
 341		.name = "fclk_div7",
 342		.ops = &clk_regmap_gate_ops,
 343		.parent_names = (const char *[]){ "fclk_div7_div" },
 344		.num_parents = 1,
 345	},
 346};
 347
 348static struct clk_regmap meson8b_mpll_prediv = {
 349	.data = &(struct clk_regmap_div_data){
 350		.offset = HHI_MPLL_CNTL5,
 351		.shift = 12,
 352		.width = 1,
 353	},
 354	.hw.init = &(struct clk_init_data){
 355		.name = "mpll_prediv",
 356		.ops = &clk_regmap_divider_ro_ops,
 357		.parent_names = (const char *[]){ "fixed_pll" },
 358		.num_parents = 1,
 359	},
 360};
 361
 362static struct clk_regmap meson8b_mpll0_div = {
 363	.data = &(struct meson_clk_mpll_data){
 364		.sdm = {
 365			.reg_off = HHI_MPLL_CNTL7,
 366			.shift   = 0,
 367			.width   = 14,
 368		},
 369		.sdm_en = {
 370			.reg_off = HHI_MPLL_CNTL7,
 371			.shift   = 15,
 372			.width   = 1,
 373		},
 374		.n2 = {
 375			.reg_off = HHI_MPLL_CNTL7,
 376			.shift   = 16,
 377			.width   = 9,
 378		},
 379		.ssen = {
 380			.reg_off = HHI_MPLL_CNTL,
 381			.shift   = 25,
 382			.width   = 1,
 383		},
 384		.lock = &meson_clk_lock,
 385	},
 386	.hw.init = &(struct clk_init_data){
 387		.name = "mpll0_div",
 388		.ops = &meson_clk_mpll_ops,
 389		.parent_names = (const char *[]){ "mpll_prediv" },
 390		.num_parents = 1,
 391	},
 392};
 393
 394static struct clk_regmap meson8b_mpll0 = {
 395	.data = &(struct clk_regmap_gate_data){
 396		.offset = HHI_MPLL_CNTL7,
 397		.bit_idx = 14,
 398	},
 399	.hw.init = &(struct clk_init_data){
 400		.name = "mpll0",
 401		.ops = &clk_regmap_gate_ops,
 402		.parent_names = (const char *[]){ "mpll0_div" },
 403		.num_parents = 1,
 404		.flags = CLK_SET_RATE_PARENT,
 405	},
 406};
 407
 408static struct clk_regmap meson8b_mpll1_div = {
 409	.data = &(struct meson_clk_mpll_data){
 410		.sdm = {
 411			.reg_off = HHI_MPLL_CNTL8,
 412			.shift   = 0,
 413			.width   = 14,
 414		},
 415		.sdm_en = {
 416			.reg_off = HHI_MPLL_CNTL8,
 417			.shift   = 15,
 418			.width   = 1,
 419		},
 420		.n2 = {
 421			.reg_off = HHI_MPLL_CNTL8,
 422			.shift   = 16,
 423			.width   = 9,
 424		},
 425		.lock = &meson_clk_lock,
 426	},
 427	.hw.init = &(struct clk_init_data){
 428		.name = "mpll1_div",
 429		.ops = &meson_clk_mpll_ops,
 430		.parent_names = (const char *[]){ "mpll_prediv" },
 431		.num_parents = 1,
 432	},
 433};
 434
 435static struct clk_regmap meson8b_mpll1 = {
 436	.data = &(struct clk_regmap_gate_data){
 437		.offset = HHI_MPLL_CNTL8,
 438		.bit_idx = 14,
 439	},
 440	.hw.init = &(struct clk_init_data){
 441		.name = "mpll1",
 442		.ops = &clk_regmap_gate_ops,
 443		.parent_names = (const char *[]){ "mpll1_div" },
 444		.num_parents = 1,
 445		.flags = CLK_SET_RATE_PARENT,
 446	},
 447};
 448
 449static struct clk_regmap meson8b_mpll2_div = {
 450	.data = &(struct meson_clk_mpll_data){
 451		.sdm = {
 452			.reg_off = HHI_MPLL_CNTL9,
 453			.shift   = 0,
 454			.width   = 14,
 455		},
 456		.sdm_en = {
 457			.reg_off = HHI_MPLL_CNTL9,
 458			.shift   = 15,
 459			.width   = 1,
 460		},
 461		.n2 = {
 462			.reg_off = HHI_MPLL_CNTL9,
 463			.shift   = 16,
 464			.width   = 9,
 465		},
 466		.lock = &meson_clk_lock,
 467	},
 468	.hw.init = &(struct clk_init_data){
 469		.name = "mpll2_div",
 470		.ops = &meson_clk_mpll_ops,
 471		.parent_names = (const char *[]){ "mpll_prediv" },
 472		.num_parents = 1,
 473	},
 474};
 475
 476static struct clk_regmap meson8b_mpll2 = {
 477	.data = &(struct clk_regmap_gate_data){
 478		.offset = HHI_MPLL_CNTL9,
 479		.bit_idx = 14,
 480	},
 481	.hw.init = &(struct clk_init_data){
 482		.name = "mpll2",
 483		.ops = &clk_regmap_gate_ops,
 484		.parent_names = (const char *[]){ "mpll2_div" },
 485		.num_parents = 1,
 486		.flags = CLK_SET_RATE_PARENT,
 487	},
 488};
 489
 490static u32 mux_table_clk81[]	= { 6, 5, 7 };
 491static struct clk_regmap meson8b_mpeg_clk_sel = {
 492	.data = &(struct clk_regmap_mux_data){
 493		.offset = HHI_MPEG_CLK_CNTL,
 494		.mask = 0x7,
 495		.shift = 12,
 496		.table = mux_table_clk81,
 497	},
 498	.hw.init = &(struct clk_init_data){
 499		.name = "mpeg_clk_sel",
 500		.ops = &clk_regmap_mux_ro_ops,
 501		/*
 502		 * FIXME bits 14:12 selects from 8 possible parents:
 503		 * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2,
 504		 * fclk_div4, fclk_div3, fclk_div5
 505		 */
 506		.parent_names = (const char *[]){ "fclk_div3", "fclk_div4",
 507			"fclk_div5" },
 508		.num_parents = 3,
 509	},
 510};
 511
 512static struct clk_regmap meson8b_mpeg_clk_div = {
 513	.data = &(struct clk_regmap_div_data){
 514		.offset = HHI_MPEG_CLK_CNTL,
 515		.shift = 0,
 516		.width = 7,
 517	},
 518	.hw.init = &(struct clk_init_data){
 519		.name = "mpeg_clk_div",
 520		.ops = &clk_regmap_divider_ro_ops,
 521		.parent_names = (const char *[]){ "mpeg_clk_sel" },
 522		.num_parents = 1,
 523	},
 524};
 525
 526static struct clk_regmap meson8b_clk81 = {
 527	.data = &(struct clk_regmap_gate_data){
 528		.offset = HHI_MPEG_CLK_CNTL,
 529		.bit_idx = 7,
 530	},
 531	.hw.init = &(struct clk_init_data){
 532		.name = "clk81",
 533		.ops = &clk_regmap_gate_ops,
 534		.parent_names = (const char *[]){ "mpeg_clk_div" },
 535		.num_parents = 1,
 536		.flags = CLK_IS_CRITICAL,
 537	},
 538};
 539
 540static struct clk_regmap meson8b_cpu_in_sel = {
 541	.data = &(struct clk_regmap_mux_data){
 542		.offset = HHI_SYS_CPU_CLK_CNTL0,
 543		.mask = 0x1,
 544		.shift = 0,
 545	},
 546	.hw.init = &(struct clk_init_data){
 547		.name = "cpu_in_sel",
 548		.ops = &clk_regmap_mux_ro_ops,
 549		.parent_names = (const char *[]){ "xtal", "sys_pll" },
 550		.num_parents = 2,
 551		.flags = (CLK_SET_RATE_PARENT |
 552			  CLK_SET_RATE_NO_REPARENT),
 553	},
 554};
 555
 556static struct clk_fixed_factor meson8b_cpu_div2 = {
 557	.mult = 1,
 558	.div = 2,
 559	.hw.init = &(struct clk_init_data){
 560		.name = "cpu_div2",
 561		.ops = &clk_fixed_factor_ops,
 562		.parent_names = (const char *[]){ "cpu_in_sel" },
 563		.num_parents = 1,
 564		.flags = CLK_SET_RATE_PARENT,
 565	},
 566};
 567
 568static struct clk_fixed_factor meson8b_cpu_div3 = {
 569	.mult = 1,
 570	.div = 3,
 571	.hw.init = &(struct clk_init_data){
 572		.name = "cpu_div3",
 573		.ops = &clk_fixed_factor_ops,
 574		.parent_names = (const char *[]){ "cpu_in_sel" },
 575		.num_parents = 1,
 576		.flags = CLK_SET_RATE_PARENT,
 577	},
 578};
 579
 580static const struct clk_div_table cpu_scale_table[] = {
 581	{ .val = 2, .div = 4 },
 582	{ .val = 3, .div = 6 },
 583	{ .val = 4, .div = 8 },
 584	{ .val = 5, .div = 10 },
 585	{ .val = 6, .div = 12 },
 586	{ .val = 7, .div = 14 },
 587	{ .val = 8, .div = 16 },
 588	{ /* sentinel */ },
 589};
 590
 591static struct clk_regmap meson8b_cpu_scale_div = {
 592	.data = &(struct clk_regmap_div_data){
 593		.offset =  HHI_SYS_CPU_CLK_CNTL1,
 594		.shift = 20,
 595		.width = 9,
 596		.table = cpu_scale_table,
 597		.flags = CLK_DIVIDER_ALLOW_ZERO,
 598	},
 599	.hw.init = &(struct clk_init_data){
 600		.name = "cpu_scale_div",
 601		.ops = &clk_regmap_divider_ro_ops,
 602		.parent_names = (const char *[]){ "cpu_in_sel" },
 603		.num_parents = 1,
 604		.flags = CLK_SET_RATE_PARENT,
 605	},
 606};
 607
 608static struct clk_regmap meson8b_cpu_scale_out_sel = {
 609	.data = &(struct clk_regmap_mux_data){
 610		.offset = HHI_SYS_CPU_CLK_CNTL0,
 611		.mask = 0x3,
 612		.shift = 2,
 613	},
 614	.hw.init = &(struct clk_init_data){
 615		.name = "cpu_scale_out_sel",
 616		.ops = &clk_regmap_mux_ro_ops,
 617		.parent_names = (const char *[]) { "cpu_in_sel",
 618						   "cpu_div2",
 619						   "cpu_div3",
 620						   "cpu_scale_div" },
 621		.num_parents = 4,
 622		.flags = CLK_SET_RATE_PARENT,
 623	},
 624};
 625
 626static struct clk_regmap meson8b_cpu_clk = {
 627	.data = &(struct clk_regmap_mux_data){
 628		.offset = HHI_SYS_CPU_CLK_CNTL0,
 629		.mask = 0x1,
 630		.shift = 7,
 631	},
 632	.hw.init = &(struct clk_init_data){
 633		.name = "cpu_clk",
 634		.ops = &clk_regmap_mux_ro_ops,
 635		.parent_names = (const char *[]){ "xtal",
 636						  "cpu_scale_out_sel" },
 637		.num_parents = 2,
 638		.flags = (CLK_SET_RATE_PARENT |
 639			  CLK_SET_RATE_NO_REPARENT),
 640	},
 641};
 642
 643/* Everything Else (EE) domain gates */
 644
 645static MESON_GATE(meson8b_ddr, HHI_GCLK_MPEG0, 0);
 646static MESON_GATE(meson8b_dos, HHI_GCLK_MPEG0, 1);
 647static MESON_GATE(meson8b_isa, HHI_GCLK_MPEG0, 5);
 648static MESON_GATE(meson8b_pl301, HHI_GCLK_MPEG0, 6);
 649static MESON_GATE(meson8b_periphs, HHI_GCLK_MPEG0, 7);
 650static MESON_GATE(meson8b_spicc, HHI_GCLK_MPEG0, 8);
 651static MESON_GATE(meson8b_i2c, HHI_GCLK_MPEG0, 9);
 652static MESON_GATE(meson8b_sar_adc, HHI_GCLK_MPEG0, 10);
 653static MESON_GATE(meson8b_smart_card, HHI_GCLK_MPEG0, 11);
 654static MESON_GATE(meson8b_rng0, HHI_GCLK_MPEG0, 12);
 655static MESON_GATE(meson8b_uart0, HHI_GCLK_MPEG0, 13);
 656static MESON_GATE(meson8b_sdhc, HHI_GCLK_MPEG0, 14);
 657static MESON_GATE(meson8b_stream, HHI_GCLK_MPEG0, 15);
 658static MESON_GATE(meson8b_async_fifo, HHI_GCLK_MPEG0, 16);
 659static MESON_GATE(meson8b_sdio, HHI_GCLK_MPEG0, 17);
 660static MESON_GATE(meson8b_abuf, HHI_GCLK_MPEG0, 18);
 661static MESON_GATE(meson8b_hiu_iface, HHI_GCLK_MPEG0, 19);
 662static MESON_GATE(meson8b_assist_misc, HHI_GCLK_MPEG0, 23);
 663static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30);
 664
 665static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2);
 666static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3);
 667static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4);
 668static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6);
 669static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7);
 670static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8);
 671static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9);
 672static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10);
 673static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11);
 674static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12);
 675static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13);
 676static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14);
 677static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15);
 678static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16);
 679static MESON_GATE(meson8b_g2d, HHI_GCLK_MPEG1, 20);
 680static MESON_GATE(meson8b_usb0, HHI_GCLK_MPEG1, 21);
 681static MESON_GATE(meson8b_usb1, HHI_GCLK_MPEG1, 22);
 682static MESON_GATE(meson8b_reset, HHI_GCLK_MPEG1, 23);
 683static MESON_GATE(meson8b_nand, HHI_GCLK_MPEG1, 24);
 684static MESON_GATE(meson8b_dos_parser, HHI_GCLK_MPEG1, 25);
 685static MESON_GATE(meson8b_usb, HHI_GCLK_MPEG1, 26);
 686static MESON_GATE(meson8b_vdin1, HHI_GCLK_MPEG1, 28);
 687static MESON_GATE(meson8b_ahb_arb0, HHI_GCLK_MPEG1, 29);
 688static MESON_GATE(meson8b_efuse, HHI_GCLK_MPEG1, 30);
 689static MESON_GATE(meson8b_boot_rom, HHI_GCLK_MPEG1, 31);
 690
 691static MESON_GATE(meson8b_ahb_data_bus, HHI_GCLK_MPEG2, 1);
 692static MESON_GATE(meson8b_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2);
 693static MESON_GATE(meson8b_hdmi_intr_sync, HHI_GCLK_MPEG2, 3);
 694static MESON_GATE(meson8b_hdmi_pclk, HHI_GCLK_MPEG2, 4);
 695static MESON_GATE(meson8b_usb1_ddr_bridge, HHI_GCLK_MPEG2, 8);
 696static MESON_GATE(meson8b_usb0_ddr_bridge, HHI_GCLK_MPEG2, 9);
 697static MESON_GATE(meson8b_mmc_pclk, HHI_GCLK_MPEG2, 11);
 698static MESON_GATE(meson8b_dvin, HHI_GCLK_MPEG2, 12);
 699static MESON_GATE(meson8b_uart2, HHI_GCLK_MPEG2, 15);
 700static MESON_GATE(meson8b_sana, HHI_GCLK_MPEG2, 22);
 701static MESON_GATE(meson8b_vpu_intr, HHI_GCLK_MPEG2, 25);
 702static MESON_GATE(meson8b_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26);
 703static MESON_GATE(meson8b_clk81_a9, HHI_GCLK_MPEG2, 29);
 704
 705static MESON_GATE(meson8b_vclk2_venci0, HHI_GCLK_OTHER, 1);
 706static MESON_GATE(meson8b_vclk2_venci1, HHI_GCLK_OTHER, 2);
 707static MESON_GATE(meson8b_vclk2_vencp0, HHI_GCLK_OTHER, 3);
 708static MESON_GATE(meson8b_vclk2_vencp1, HHI_GCLK_OTHER, 4);
 709static MESON_GATE(meson8b_gclk_venci_int, HHI_GCLK_OTHER, 8);
 710static MESON_GATE(meson8b_gclk_vencp_int, HHI_GCLK_OTHER, 9);
 711static MESON_GATE(meson8b_dac_clk, HHI_GCLK_OTHER, 10);
 712static MESON_GATE(meson8b_aoclk_gate, HHI_GCLK_OTHER, 14);
 713static MESON_GATE(meson8b_iec958_gate, HHI_GCLK_OTHER, 16);
 714static MESON_GATE(meson8b_enc480p, HHI_GCLK_OTHER, 20);
 715static MESON_GATE(meson8b_rng1, HHI_GCLK_OTHER, 21);
 716static MESON_GATE(meson8b_gclk_vencl_int, HHI_GCLK_OTHER, 22);
 717static MESON_GATE(meson8b_vclk2_venclmcc, HHI_GCLK_OTHER, 24);
 718static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25);
 719static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26);
 720static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31);
 721
 722/* Always On (AO) domain gates */
 723
 724static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0);
 725static MESON_GATE(meson8b_ao_ahb_sram, HHI_GCLK_AO, 1);
 726static MESON_GATE(meson8b_ao_ahb_bus, HHI_GCLK_AO, 2);
 727static MESON_GATE(meson8b_ao_iface, HHI_GCLK_AO, 3);
 728
 729static struct clk_hw_onecell_data meson8b_hw_onecell_data = {
 730	.hws = {
 731		[CLKID_XTAL] = &meson8b_xtal.hw,
 732		[CLKID_PLL_FIXED] = &meson8b_fixed_pll.hw,
 733		[CLKID_PLL_VID] = &meson8b_vid_pll.hw,
 734		[CLKID_PLL_SYS] = &meson8b_sys_pll.hw,
 735		[CLKID_FCLK_DIV2] = &meson8b_fclk_div2.hw,
 736		[CLKID_FCLK_DIV3] = &meson8b_fclk_div3.hw,
 737		[CLKID_FCLK_DIV4] = &meson8b_fclk_div4.hw,
 738		[CLKID_FCLK_DIV5] = &meson8b_fclk_div5.hw,
 739		[CLKID_FCLK_DIV7] = &meson8b_fclk_div7.hw,
 740		[CLKID_CPUCLK] = &meson8b_cpu_clk.hw,
 741		[CLKID_MPEG_SEL] = &meson8b_mpeg_clk_sel.hw,
 742		[CLKID_MPEG_DIV] = &meson8b_mpeg_clk_div.hw,
 743		[CLKID_CLK81] = &meson8b_clk81.hw,
 744		[CLKID_DDR]		    = &meson8b_ddr.hw,
 745		[CLKID_DOS]		    = &meson8b_dos.hw,
 746		[CLKID_ISA]		    = &meson8b_isa.hw,
 747		[CLKID_PL301]		    = &meson8b_pl301.hw,
 748		[CLKID_PERIPHS]		    = &meson8b_periphs.hw,
 749		[CLKID_SPICC]		    = &meson8b_spicc.hw,
 750		[CLKID_I2C]		    = &meson8b_i2c.hw,
 751		[CLKID_SAR_ADC]		    = &meson8b_sar_adc.hw,
 752		[CLKID_SMART_CARD]	    = &meson8b_smart_card.hw,
 753		[CLKID_RNG0]		    = &meson8b_rng0.hw,
 754		[CLKID_UART0]		    = &meson8b_uart0.hw,
 755		[CLKID_SDHC]		    = &meson8b_sdhc.hw,
 756		[CLKID_STREAM]		    = &meson8b_stream.hw,
 757		[CLKID_ASYNC_FIFO]	    = &meson8b_async_fifo.hw,
 758		[CLKID_SDIO]		    = &meson8b_sdio.hw,
 759		[CLKID_ABUF]		    = &meson8b_abuf.hw,
 760		[CLKID_HIU_IFACE]	    = &meson8b_hiu_iface.hw,
 761		[CLKID_ASSIST_MISC]	    = &meson8b_assist_misc.hw,
 762		[CLKID_SPI]		    = &meson8b_spi.hw,
 763		[CLKID_I2S_SPDIF]	    = &meson8b_i2s_spdif.hw,
 764		[CLKID_ETH]		    = &meson8b_eth.hw,
 765		[CLKID_DEMUX]		    = &meson8b_demux.hw,
 766		[CLKID_AIU_GLUE]	    = &meson8b_aiu_glue.hw,
 767		[CLKID_IEC958]		    = &meson8b_iec958.hw,
 768		[CLKID_I2S_OUT]		    = &meson8b_i2s_out.hw,
 769		[CLKID_AMCLK]		    = &meson8b_amclk.hw,
 770		[CLKID_AIFIFO2]		    = &meson8b_aififo2.hw,
 771		[CLKID_MIXER]		    = &meson8b_mixer.hw,
 772		[CLKID_MIXER_IFACE]	    = &meson8b_mixer_iface.hw,
 773		[CLKID_ADC]		    = &meson8b_adc.hw,
 774		[CLKID_BLKMV]		    = &meson8b_blkmv.hw,
 775		[CLKID_AIU]		    = &meson8b_aiu.hw,
 776		[CLKID_UART1]		    = &meson8b_uart1.hw,
 777		[CLKID_G2D]		    = &meson8b_g2d.hw,
 778		[CLKID_USB0]		    = &meson8b_usb0.hw,
 779		[CLKID_USB1]		    = &meson8b_usb1.hw,
 780		[CLKID_RESET]		    = &meson8b_reset.hw,
 781		[CLKID_NAND]		    = &meson8b_nand.hw,
 782		[CLKID_DOS_PARSER]	    = &meson8b_dos_parser.hw,
 783		[CLKID_USB]		    = &meson8b_usb.hw,
 784		[CLKID_VDIN1]		    = &meson8b_vdin1.hw,
 785		[CLKID_AHB_ARB0]	    = &meson8b_ahb_arb0.hw,
 786		[CLKID_EFUSE]		    = &meson8b_efuse.hw,
 787		[CLKID_BOOT_ROM]	    = &meson8b_boot_rom.hw,
 788		[CLKID_AHB_DATA_BUS]	    = &meson8b_ahb_data_bus.hw,
 789		[CLKID_AHB_CTRL_BUS]	    = &meson8b_ahb_ctrl_bus.hw,
 790		[CLKID_HDMI_INTR_SYNC]	    = &meson8b_hdmi_intr_sync.hw,
 791		[CLKID_HDMI_PCLK]	    = &meson8b_hdmi_pclk.hw,
 792		[CLKID_USB1_DDR_BRIDGE]	    = &meson8b_usb1_ddr_bridge.hw,
 793		[CLKID_USB0_DDR_BRIDGE]	    = &meson8b_usb0_ddr_bridge.hw,
 794		[CLKID_MMC_PCLK]	    = &meson8b_mmc_pclk.hw,
 795		[CLKID_DVIN]		    = &meson8b_dvin.hw,
 796		[CLKID_UART2]		    = &meson8b_uart2.hw,
 797		[CLKID_SANA]		    = &meson8b_sana.hw,
 798		[CLKID_VPU_INTR]	    = &meson8b_vpu_intr.hw,
 799		[CLKID_SEC_AHB_AHB3_BRIDGE] = &meson8b_sec_ahb_ahb3_bridge.hw,
 800		[CLKID_CLK81_A9]	    = &meson8b_clk81_a9.hw,
 801		[CLKID_VCLK2_VENCI0]	    = &meson8b_vclk2_venci0.hw,
 802		[CLKID_VCLK2_VENCI1]	    = &meson8b_vclk2_venci1.hw,
 803		[CLKID_VCLK2_VENCP0]	    = &meson8b_vclk2_vencp0.hw,
 804		[CLKID_VCLK2_VENCP1]	    = &meson8b_vclk2_vencp1.hw,
 805		[CLKID_GCLK_VENCI_INT]	    = &meson8b_gclk_venci_int.hw,
 806		[CLKID_GCLK_VENCP_INT]	    = &meson8b_gclk_vencp_int.hw,
 807		[CLKID_DAC_CLK]		    = &meson8b_dac_clk.hw,
 808		[CLKID_AOCLK_GATE]	    = &meson8b_aoclk_gate.hw,
 809		[CLKID_IEC958_GATE]	    = &meson8b_iec958_gate.hw,
 810		[CLKID_ENC480P]		    = &meson8b_enc480p.hw,
 811		[CLKID_RNG1]		    = &meson8b_rng1.hw,
 812		[CLKID_GCLK_VENCL_INT]	    = &meson8b_gclk_vencl_int.hw,
 813		[CLKID_VCLK2_VENCLMCC]	    = &meson8b_vclk2_venclmcc.hw,
 814		[CLKID_VCLK2_VENCL]	    = &meson8b_vclk2_vencl.hw,
 815		[CLKID_VCLK2_OTHER]	    = &meson8b_vclk2_other.hw,
 816		[CLKID_EDP]		    = &meson8b_edp.hw,
 817		[CLKID_AO_MEDIA_CPU]	    = &meson8b_ao_media_cpu.hw,
 818		[CLKID_AO_AHB_SRAM]	    = &meson8b_ao_ahb_sram.hw,
 819		[CLKID_AO_AHB_BUS]	    = &meson8b_ao_ahb_bus.hw,
 820		[CLKID_AO_IFACE]	    = &meson8b_ao_iface.hw,
 821		[CLKID_MPLL0]		    = &meson8b_mpll0.hw,
 822		[CLKID_MPLL1]		    = &meson8b_mpll1.hw,
 823		[CLKID_MPLL2]		    = &meson8b_mpll2.hw,
 824		[CLKID_MPLL0_DIV]	    = &meson8b_mpll0_div.hw,
 825		[CLKID_MPLL1_DIV]	    = &meson8b_mpll1_div.hw,
 826		[CLKID_MPLL2_DIV]	    = &meson8b_mpll2_div.hw,
 827		[CLKID_CPU_IN_SEL]	    = &meson8b_cpu_in_sel.hw,
 828		[CLKID_CPU_DIV2]	    = &meson8b_cpu_div2.hw,
 829		[CLKID_CPU_DIV3]	    = &meson8b_cpu_div3.hw,
 830		[CLKID_CPU_SCALE_DIV]	    = &meson8b_cpu_scale_div.hw,
 831		[CLKID_CPU_SCALE_OUT_SEL]   = &meson8b_cpu_scale_out_sel.hw,
 832		[CLKID_MPLL_PREDIV]	    = &meson8b_mpll_prediv.hw,
 833		[CLKID_FCLK_DIV2_DIV]	    = &meson8b_fclk_div2_div.hw,
 834		[CLKID_FCLK_DIV3_DIV]	    = &meson8b_fclk_div3_div.hw,
 835		[CLKID_FCLK_DIV4_DIV]	    = &meson8b_fclk_div4_div.hw,
 836		[CLKID_FCLK_DIV5_DIV]	    = &meson8b_fclk_div5_div.hw,
 837		[CLKID_FCLK_DIV7_DIV]	    = &meson8b_fclk_div7_div.hw,
 838		[CLK_NR_CLKS]		    = NULL,
 839	},
 840	.num = CLK_NR_CLKS,
 841};
 842
 843static struct clk_regmap *const meson8b_clk_regmaps[] = {
 844	&meson8b_clk81,
 845	&meson8b_ddr,
 846	&meson8b_dos,
 847	&meson8b_isa,
 848	&meson8b_pl301,
 849	&meson8b_periphs,
 850	&meson8b_spicc,
 851	&meson8b_i2c,
 852	&meson8b_sar_adc,
 853	&meson8b_smart_card,
 854	&meson8b_rng0,
 855	&meson8b_uart0,
 856	&meson8b_sdhc,
 857	&meson8b_stream,
 858	&meson8b_async_fifo,
 859	&meson8b_sdio,
 860	&meson8b_abuf,
 861	&meson8b_hiu_iface,
 862	&meson8b_assist_misc,
 863	&meson8b_spi,
 864	&meson8b_i2s_spdif,
 865	&meson8b_eth,
 866	&meson8b_demux,
 867	&meson8b_aiu_glue,
 868	&meson8b_iec958,
 869	&meson8b_i2s_out,
 870	&meson8b_amclk,
 871	&meson8b_aififo2,
 872	&meson8b_mixer,
 873	&meson8b_mixer_iface,
 874	&meson8b_adc,
 875	&meson8b_blkmv,
 876	&meson8b_aiu,
 877	&meson8b_uart1,
 878	&meson8b_g2d,
 879	&meson8b_usb0,
 880	&meson8b_usb1,
 881	&meson8b_reset,
 882	&meson8b_nand,
 883	&meson8b_dos_parser,
 884	&meson8b_usb,
 885	&meson8b_vdin1,
 886	&meson8b_ahb_arb0,
 887	&meson8b_efuse,
 888	&meson8b_boot_rom,
 889	&meson8b_ahb_data_bus,
 890	&meson8b_ahb_ctrl_bus,
 891	&meson8b_hdmi_intr_sync,
 892	&meson8b_hdmi_pclk,
 893	&meson8b_usb1_ddr_bridge,
 894	&meson8b_usb0_ddr_bridge,
 895	&meson8b_mmc_pclk,
 896	&meson8b_dvin,
 897	&meson8b_uart2,
 898	&meson8b_sana,
 899	&meson8b_vpu_intr,
 900	&meson8b_sec_ahb_ahb3_bridge,
 901	&meson8b_clk81_a9,
 902	&meson8b_vclk2_venci0,
 903	&meson8b_vclk2_venci1,
 904	&meson8b_vclk2_vencp0,
 905	&meson8b_vclk2_vencp1,
 906	&meson8b_gclk_venci_int,
 907	&meson8b_gclk_vencp_int,
 908	&meson8b_dac_clk,
 909	&meson8b_aoclk_gate,
 910	&meson8b_iec958_gate,
 911	&meson8b_enc480p,
 912	&meson8b_rng1,
 913	&meson8b_gclk_vencl_int,
 914	&meson8b_vclk2_venclmcc,
 915	&meson8b_vclk2_vencl,
 916	&meson8b_vclk2_other,
 917	&meson8b_edp,
 918	&meson8b_ao_media_cpu,
 919	&meson8b_ao_ahb_sram,
 920	&meson8b_ao_ahb_bus,
 921	&meson8b_ao_iface,
 922	&meson8b_mpeg_clk_div,
 923	&meson8b_mpeg_clk_sel,
 924	&meson8b_mpll0,
 925	&meson8b_mpll1,
 926	&meson8b_mpll2,
 927	&meson8b_mpll0_div,
 928	&meson8b_mpll1_div,
 929	&meson8b_mpll2_div,
 930	&meson8b_fixed_pll,
 931	&meson8b_vid_pll,
 932	&meson8b_sys_pll,
 933	&meson8b_cpu_in_sel,
 934	&meson8b_cpu_scale_div,
 935	&meson8b_cpu_scale_out_sel,
 936	&meson8b_cpu_clk,
 937	&meson8b_mpll_prediv,
 938	&meson8b_fclk_div2,
 939	&meson8b_fclk_div3,
 940	&meson8b_fclk_div4,
 941	&meson8b_fclk_div5,
 942	&meson8b_fclk_div7,
 943};
 944
 945static const struct meson8b_clk_reset_line {
 946	u32 reg;
 947	u8 bit_idx;
 948} meson8b_clk_reset_bits[] = {
 949	[CLKC_RESET_L2_CACHE_SOFT_RESET] = {
 950		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 30
 951	},
 952	[CLKC_RESET_AXI_64_TO_128_BRIDGE_A5_SOFT_RESET] = {
 953		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 29
 954	},
 955	[CLKC_RESET_SCU_SOFT_RESET] = {
 956		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 28
 957	},
 958	[CLKC_RESET_CPU3_SOFT_RESET] = {
 959		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 27
 960	},
 961	[CLKC_RESET_CPU2_SOFT_RESET] = {
 962		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 26
 963	},
 964	[CLKC_RESET_CPU1_SOFT_RESET] = {
 965		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 25
 966	},
 967	[CLKC_RESET_CPU0_SOFT_RESET] = {
 968		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 24
 969	},
 970	[CLKC_RESET_A5_GLOBAL_RESET] = {
 971		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 18
 972	},
 973	[CLKC_RESET_A5_AXI_SOFT_RESET] = {
 974		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 17
 975	},
 976	[CLKC_RESET_A5_ABP_SOFT_RESET] = {
 977		.reg = HHI_SYS_CPU_CLK_CNTL0, .bit_idx = 16
 978	},
 979	[CLKC_RESET_AXI_64_TO_128_BRIDGE_MMC_SOFT_RESET] = {
 980		.reg = HHI_SYS_CPU_CLK_CNTL1, .bit_idx = 30
 981	},
 982	[CLKC_RESET_VID_CLK_CNTL_SOFT_RESET] = {
 983		.reg = HHI_VID_CLK_CNTL, .bit_idx = 15
 984	},
 985	[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_POST] = {
 986		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 7
 987	},
 988	[CLKC_RESET_VID_DIVIDER_CNTL_SOFT_RESET_PRE] = {
 989		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 3
 990	},
 991	[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_POST] = {
 992		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 1
 993	},
 994	[CLKC_RESET_VID_DIVIDER_CNTL_RESET_N_PRE] = {
 995		.reg = HHI_VID_DIVIDER_CNTL, .bit_idx = 0
 996	},
 997};
 998
 999static int meson8b_clk_reset_update(struct reset_controller_dev *rcdev,
1000				    unsigned long id, bool assert)
1001{
1002	struct meson8b_clk_reset *meson8b_clk_reset =
1003		container_of(rcdev, struct meson8b_clk_reset, reset);
1004	unsigned long flags;
1005	const struct meson8b_clk_reset_line *reset;
1006	u32 val;
1007
1008	if (id >= ARRAY_SIZE(meson8b_clk_reset_bits))
1009		return -EINVAL;
1010
1011	reset = &meson8b_clk_reset_bits[id];
1012
1013	spin_lock_irqsave(&meson_clk_lock, flags);
1014
1015	val = readl(meson8b_clk_reset->base + reset->reg);
1016	if (assert)
1017		val |= BIT(reset->bit_idx);
1018	else
1019		val &= ~BIT(reset->bit_idx);
1020	writel(val, meson8b_clk_reset->base + reset->reg);
1021
1022	spin_unlock_irqrestore(&meson_clk_lock, flags);
1023
1024	return 0;
1025}
1026
1027static int meson8b_clk_reset_assert(struct reset_controller_dev *rcdev,
1028				     unsigned long id)
1029{
1030	return meson8b_clk_reset_update(rcdev, id, true);
1031}
1032
1033static int meson8b_clk_reset_deassert(struct reset_controller_dev *rcdev,
1034				       unsigned long id)
1035{
1036	return meson8b_clk_reset_update(rcdev, id, false);
1037}
1038
1039static const struct reset_control_ops meson8b_clk_reset_ops = {
1040	.assert = meson8b_clk_reset_assert,
1041	.deassert = meson8b_clk_reset_deassert,
1042};
1043
1044static const struct regmap_config clkc_regmap_config = {
1045	.reg_bits       = 32,
1046	.val_bits       = 32,
1047	.reg_stride     = 4,
1048};
1049
1050static int meson8b_clkc_probe(struct platform_device *pdev)
1051{
1052	int ret, i;
1053	struct device *dev = &pdev->dev;
1054	struct regmap *map;
1055
1056	if (!clk_base)
1057		return -ENXIO;
1058
1059	map = devm_regmap_init_mmio(dev, clk_base, &clkc_regmap_config);
1060	if (IS_ERR(map))
1061		return PTR_ERR(map);
1062
1063	/* Populate regmap for the regmap backed clocks */
1064	for (i = 0; i < ARRAY_SIZE(meson8b_clk_regmaps); i++)
1065		meson8b_clk_regmaps[i]->map = map;
1066
1067	/*
1068	 * register all clks
1069	 * CLKID_UNUSED = 0, so skip it and start with CLKID_XTAL = 1
1070	 */
1071	for (i = CLKID_XTAL; i < CLK_NR_CLKS; i++) {
1072		/* array might be sparse */
1073		if (!meson8b_hw_onecell_data.hws[i])
1074			continue;
1075
1076		ret = devm_clk_hw_register(dev, meson8b_hw_onecell_data.hws[i]);
1077		if (ret)
1078			return ret;
1079	}
1080
1081	return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
1082					   &meson8b_hw_onecell_data);
1083}
1084
1085static const struct of_device_id meson8b_clkc_match_table[] = {
1086	{ .compatible = "amlogic,meson8-clkc" },
1087	{ .compatible = "amlogic,meson8b-clkc" },
1088	{ .compatible = "amlogic,meson8m2-clkc" },
1089	{ }
1090};
1091
1092static struct platform_driver meson8b_driver = {
1093	.probe		= meson8b_clkc_probe,
1094	.driver		= {
1095		.name	= "meson8b-clkc",
1096		.of_match_table = meson8b_clkc_match_table,
1097	},
1098};
1099
1100builtin_platform_driver(meson8b_driver);
1101
1102static void __init meson8b_clkc_reset_init(struct device_node *np)
1103{
1104	struct meson8b_clk_reset *rstc;
1105	int ret;
1106
1107	/* Generic clocks, PLLs and some of the reset-bits */
1108	clk_base = of_iomap(np, 1);
1109	if (!clk_base) {
1110		pr_err("%s: Unable to map clk base\n", __func__);
1111		return;
1112	}
1113
1114	rstc = kzalloc(sizeof(*rstc), GFP_KERNEL);
1115	if (!rstc)
1116		return;
1117
1118	/* Reset Controller */
1119	rstc->base = clk_base;
1120	rstc->reset.ops = &meson8b_clk_reset_ops;
1121	rstc->reset.nr_resets = ARRAY_SIZE(meson8b_clk_reset_bits);
1122	rstc->reset.of_node = np;
1123	ret = reset_controller_register(&rstc->reset);
1124	if (ret) {
1125		pr_err("%s: Failed to register clkc reset controller: %d\n",
1126		       __func__, ret);
1127		return;
1128	}
1129}
1130
1131CLK_OF_DECLARE_DRIVER(meson8_clkc, "amlogic,meson8-clkc",
1132		      meson8b_clkc_reset_init);
1133CLK_OF_DECLARE_DRIVER(meson8b_clkc, "amlogic,meson8b-clkc",
1134		      meson8b_clkc_reset_init);
1135CLK_OF_DECLARE_DRIVER(meson8m2_clkc, "amlogic,meson8m2-clkc",
1136		      meson8b_clkc_reset_init);