Linux Audio

Check our new training course

Loading...
   1// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
   2/*
   3 * Amlogic S4 Peripherals Clock Controller Driver
   4 *
   5 * Copyright (c) 2022-2023 Amlogic, inc. All rights reserved
   6 * Author: Yu Tu <yu.tu@amlogic.com>
   7 */
   8
   9#include <linux/clk-provider.h>
  10#include <linux/of_device.h>
  11#include <linux/platform_device.h>
  12
  13#include "clk-regmap.h"
  14#include "vid-pll-div.h"
  15#include "clk-dualdiv.h"
  16#include "s4-peripherals.h"
  17#include "meson-clkc-utils.h"
  18#include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h>
  19
  20static struct clk_regmap s4_rtc_32k_by_oscin_clkin = {
  21	.data = &(struct clk_regmap_gate_data){
  22		.offset = CLKCTRL_RTC_BY_OSCIN_CTRL0,
  23		.bit_idx = 31,
  24	},
  25	.hw.init = &(struct clk_init_data) {
  26		.name = "rtc_32k_by_oscin_clkin",
  27		.ops = &clk_regmap_gate_ops,
  28		.parent_data = (const struct clk_parent_data []) {
  29			{ .fw_name = "xtal", }
  30		},
  31		.num_parents = 1,
  32	},
  33};
  34
  35static const struct meson_clk_dualdiv_param s4_32k_div_table[] = {
  36	{
  37		.dual	= 1,
  38		.n1	= 733,
  39		.m1	= 8,
  40		.n2	= 732,
  41		.m2	= 11,
  42	},
  43	{}
  44};
  45
  46static struct clk_regmap s4_rtc_32k_by_oscin_div = {
  47	.data = &(struct meson_clk_dualdiv_data){
  48		.n1 = {
  49			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
  50			.shift   = 0,
  51			.width   = 12,
  52		},
  53		.n2 = {
  54			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
  55			.shift   = 12,
  56			.width   = 12,
  57		},
  58		.m1 = {
  59			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1,
  60			.shift   = 0,
  61			.width   = 12,
  62		},
  63		.m2 = {
  64			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL1,
  65			.shift   = 12,
  66			.width   = 12,
  67		},
  68		.dual = {
  69			.reg_off = CLKCTRL_RTC_BY_OSCIN_CTRL0,
  70			.shift   = 28,
  71			.width   = 1,
  72		},
  73		.table = s4_32k_div_table,
  74	},
  75	.hw.init = &(struct clk_init_data){
  76		.name = "rtc_32k_by_oscin_div",
  77		.ops = &meson_clk_dualdiv_ops,
  78		.parent_hws = (const struct clk_hw *[]) {
  79			&s4_rtc_32k_by_oscin_clkin.hw
  80		},
  81		.num_parents = 1,
  82	},
  83};
  84
  85static struct clk_regmap s4_rtc_32k_by_oscin_sel = {
  86	.data = &(struct clk_regmap_mux_data) {
  87		.offset = CLKCTRL_RTC_BY_OSCIN_CTRL1,
  88		.mask = 0x1,
  89		.shift = 24,
  90		.flags = CLK_MUX_ROUND_CLOSEST,
  91	},
  92	.hw.init = &(struct clk_init_data){
  93		.name = "rtc_32k_by_oscin_sel",
  94		.ops = &clk_regmap_mux_ops,
  95		.parent_hws = (const struct clk_hw *[]) {
  96			&s4_rtc_32k_by_oscin_div.hw,
  97			&s4_rtc_32k_by_oscin_clkin.hw,
  98		},
  99		.num_parents = 2,
 100		.flags = CLK_SET_RATE_PARENT,
 101	},
 102};
 103
 104static struct clk_regmap s4_rtc_32k_by_oscin = {
 105	.data = &(struct clk_regmap_gate_data){
 106		.offset = CLKCTRL_RTC_BY_OSCIN_CTRL0,
 107		.bit_idx = 30,
 108	},
 109	.hw.init = &(struct clk_init_data) {
 110		.name = "rtc_32k_by_oscin",
 111		.ops = &clk_regmap_gate_ops,
 112		.parent_hws = (const struct clk_hw *[]) {
 113			&s4_rtc_32k_by_oscin_sel.hw
 114		},
 115		.num_parents = 1,
 116		.flags = CLK_SET_RATE_PARENT,
 117	},
 118};
 119
 120static struct clk_regmap s4_rtc_clk = {
 121	.data = &(struct clk_regmap_mux_data) {
 122		.offset = CLKCTRL_RTC_CTRL,
 123		.mask = 0x3,
 124		.shift = 0,
 125		.flags = CLK_MUX_ROUND_CLOSEST,
 126	},
 127	.hw.init = &(struct clk_init_data){
 128		.name = "rtc_clk_sel",
 129		.ops = &clk_regmap_mux_ops,
 130		.parent_hws = (const struct clk_hw *[]) {
 131			&s4_rtc_32k_by_oscin.hw,
 132			&s4_rtc_32k_by_oscin_div.hw,
 133		},
 134		.num_parents = 2,
 135		.flags = CLK_SET_RATE_PARENT,
 136	},
 137};
 138
 139/* The index 5 is AXI_CLK, which is dedicated to AXI. So skip it. */
 140static u32 mux_table_sys_ab_clk_sel[] = { 0, 1, 2, 3, 4, 6, 7 };
 141static const struct clk_parent_data sys_ab_clk_parent_data[] = {
 142	{ .fw_name = "xtal" },
 143	{ .fw_name = "fclk_div2" },
 144	{ .fw_name = "fclk_div3" },
 145	{ .fw_name = "fclk_div4" },
 146	{ .fw_name = "fclk_div5" },
 147	{ .fw_name = "fclk_div7" },
 148	{ .hw = &s4_rtc_clk.hw }
 149};
 150
 151/*
 152 * This clock is initialized by ROMcode.
 153 * The chip was changed SYS CLK for security reasons. SYS CLK registers are not writable
 154 * in the kernel phase. Write of SYS related register will cause the system to crash.
 155 * Meanwhile, these clock won't ever change at runtime.
 156 * For the above reasons, we can only use ro_ops for SYS related clocks.
 157 */
 158static struct clk_regmap s4_sysclk_b_sel = {
 159	.data = &(struct clk_regmap_mux_data){
 160		.offset = CLKCTRL_SYS_CLK_CTRL0,
 161		.mask = 0x7,
 162		.shift = 26,
 163		.table = mux_table_sys_ab_clk_sel,
 164	},
 165	.hw.init = &(struct clk_init_data){
 166		.name = "sysclk_b_sel",
 167		.ops = &clk_regmap_mux_ro_ops,
 168		.parent_data = sys_ab_clk_parent_data,
 169		.num_parents = ARRAY_SIZE(sys_ab_clk_parent_data),
 170	},
 171};
 172
 173static struct clk_regmap s4_sysclk_b_div = {
 174	.data = &(struct clk_regmap_div_data){
 175		.offset = CLKCTRL_SYS_CLK_CTRL0,
 176		.shift = 16,
 177		.width = 10,
 178	},
 179	.hw.init = &(struct clk_init_data){
 180		.name = "sysclk_b_div",
 181		.ops = &clk_regmap_divider_ro_ops,
 182		.parent_hws = (const struct clk_hw *[]) {
 183			&s4_sysclk_b_sel.hw
 184		},
 185		.num_parents = 1,
 186	},
 187};
 188
 189static struct clk_regmap s4_sysclk_b = {
 190	.data = &(struct clk_regmap_gate_data){
 191		.offset = CLKCTRL_SYS_CLK_CTRL0,
 192		.bit_idx = 29,
 193	},
 194	.hw.init = &(struct clk_init_data) {
 195		.name = "sysclk_b",
 196		.ops = &clk_regmap_gate_ro_ops,
 197		.parent_hws = (const struct clk_hw *[]) {
 198			&s4_sysclk_b_div.hw
 199		},
 200		.num_parents = 1,
 201	},
 202};
 203
 204static struct clk_regmap s4_sysclk_a_sel = {
 205	.data = &(struct clk_regmap_mux_data){
 206		.offset = CLKCTRL_SYS_CLK_CTRL0,
 207		.mask = 0x7,
 208		.shift = 10,
 209		.table = mux_table_sys_ab_clk_sel,
 210	},
 211	.hw.init = &(struct clk_init_data){
 212		.name = "sysclk_a_sel",
 213		.ops = &clk_regmap_mux_ro_ops,
 214		.parent_data = sys_ab_clk_parent_data,
 215		.num_parents = ARRAY_SIZE(sys_ab_clk_parent_data),
 216	},
 217};
 218
 219static struct clk_regmap s4_sysclk_a_div = {
 220	.data = &(struct clk_regmap_div_data){
 221		.offset = CLKCTRL_SYS_CLK_CTRL0,
 222		.shift = 0,
 223		.width = 10,
 224	},
 225	.hw.init = &(struct clk_init_data){
 226		.name = "sysclk_a_div",
 227		.ops = &clk_regmap_divider_ro_ops,
 228		.parent_hws = (const struct clk_hw *[]) {
 229			&s4_sysclk_a_sel.hw
 230		},
 231		.num_parents = 1,
 232	},
 233};
 234
 235static struct clk_regmap s4_sysclk_a = {
 236	.data = &(struct clk_regmap_gate_data){
 237		.offset = CLKCTRL_SYS_CLK_CTRL0,
 238		.bit_idx = 13,
 239	},
 240	.hw.init = &(struct clk_init_data) {
 241		.name = "sysclk_a",
 242		.ops = &clk_regmap_gate_ro_ops,
 243		.parent_hws = (const struct clk_hw *[]) {
 244			&s4_sysclk_a_div.hw
 245		},
 246		.num_parents = 1,
 247	},
 248};
 249
 250static struct clk_regmap s4_sys_clk = {
 251	.data = &(struct clk_regmap_mux_data){
 252		.offset = CLKCTRL_SYS_CLK_CTRL0,
 253		.mask = 0x1,
 254		.shift = 31,
 255	},
 256	.hw.init = &(struct clk_init_data){
 257		.name = "sys_clk",
 258		.ops = &clk_regmap_mux_ro_ops,
 259		.parent_hws = (const struct clk_hw *[]) {
 260			&s4_sysclk_a.hw,
 261			&s4_sysclk_b.hw
 262		},
 263		.num_parents = 2,
 264	},
 265};
 266
 267static struct clk_regmap s4_ceca_32k_clkin = {
 268	.data = &(struct clk_regmap_gate_data){
 269		.offset = CLKCTRL_CECA_CTRL0,
 270		.bit_idx = 31,
 271	},
 272	.hw.init = &(struct clk_init_data) {
 273		.name = "ceca_32k_clkin",
 274		.ops = &clk_regmap_gate_ops,
 275		.parent_data = (const struct clk_parent_data []) {
 276			{ .fw_name = "xtal", }
 277		},
 278		.num_parents = 1,
 279	},
 280};
 281
 282static struct clk_regmap s4_ceca_32k_div = {
 283	.data = &(struct meson_clk_dualdiv_data){
 284		.n1 = {
 285			.reg_off = CLKCTRL_CECA_CTRL0,
 286			.shift   = 0,
 287			.width   = 12,
 288		},
 289		.n2 = {
 290			.reg_off = CLKCTRL_CECA_CTRL0,
 291			.shift   = 12,
 292			.width   = 12,
 293		},
 294		.m1 = {
 295			.reg_off = CLKCTRL_CECA_CTRL1,
 296			.shift   = 0,
 297			.width   = 12,
 298		},
 299		.m2 = {
 300			.reg_off = CLKCTRL_CECA_CTRL1,
 301			.shift   = 12,
 302			.width   = 12,
 303		},
 304		.dual = {
 305			.reg_off = CLKCTRL_CECA_CTRL0,
 306			.shift   = 28,
 307			.width   = 1,
 308		},
 309		.table = s4_32k_div_table,
 310	},
 311	.hw.init = &(struct clk_init_data){
 312		.name = "ceca_32k_div",
 313		.ops = &meson_clk_dualdiv_ops,
 314		.parent_hws = (const struct clk_hw *[]) {
 315			&s4_ceca_32k_clkin.hw
 316		},
 317		.num_parents = 1,
 318	},
 319};
 320
 321static struct clk_regmap s4_ceca_32k_sel_pre = {
 322	.data = &(struct clk_regmap_mux_data) {
 323		.offset = CLKCTRL_CECA_CTRL1,
 324		.mask = 0x1,
 325		.shift = 24,
 326		.flags = CLK_MUX_ROUND_CLOSEST,
 327	},
 328	.hw.init = &(struct clk_init_data){
 329		.name = "ceca_32k_sel_pre",
 330		.ops = &clk_regmap_mux_ops,
 331		.parent_hws = (const struct clk_hw *[]) {
 332			&s4_ceca_32k_div.hw,
 333			&s4_ceca_32k_clkin.hw
 334		},
 335		.num_parents = 2,
 336		.flags = CLK_SET_RATE_PARENT,
 337	},
 338};
 339
 340static struct clk_regmap s4_ceca_32k_sel = {
 341	.data = &(struct clk_regmap_mux_data) {
 342		.offset = CLKCTRL_CECA_CTRL1,
 343		.mask = 0x1,
 344		.shift = 31,
 345		.flags = CLK_MUX_ROUND_CLOSEST,
 346	},
 347	.hw.init = &(struct clk_init_data){
 348		.name = "ceca_32k_sel",
 349		.ops = &clk_regmap_mux_ops,
 350		.parent_hws = (const struct clk_hw *[]) {
 351			&s4_ceca_32k_sel_pre.hw,
 352			&s4_rtc_clk.hw
 353		},
 354		.num_parents = 2,
 355	},
 356};
 357
 358static struct clk_regmap s4_ceca_32k_clkout = {
 359	.data = &(struct clk_regmap_gate_data){
 360		.offset = CLKCTRL_CECA_CTRL0,
 361		.bit_idx = 30,
 362	},
 363	.hw.init = &(struct clk_init_data){
 364		.name = "ceca_32k_clkout",
 365		.ops = &clk_regmap_gate_ops,
 366		.parent_hws = (const struct clk_hw *[]) {
 367			&s4_ceca_32k_sel.hw
 368		},
 369		.num_parents = 1,
 370		.flags = CLK_SET_RATE_PARENT,
 371	},
 372};
 373
 374static struct clk_regmap s4_cecb_32k_clkin = {
 375	.data = &(struct clk_regmap_gate_data){
 376		.offset = CLKCTRL_CECB_CTRL0,
 377		.bit_idx = 31,
 378	},
 379	.hw.init = &(struct clk_init_data) {
 380		.name = "cecb_32k_clkin",
 381		.ops = &clk_regmap_gate_ops,
 382		.parent_data = (const struct clk_parent_data []) {
 383			{ .fw_name = "xtal", }
 384		},
 385		.num_parents = 1,
 386	},
 387};
 388
 389static struct clk_regmap s4_cecb_32k_div = {
 390	.data = &(struct meson_clk_dualdiv_data){
 391		.n1 = {
 392			.reg_off = CLKCTRL_CECB_CTRL0,
 393			.shift   = 0,
 394			.width   = 12,
 395		},
 396		.n2 = {
 397			.reg_off = CLKCTRL_CECB_CTRL0,
 398			.shift   = 12,
 399			.width   = 12,
 400		},
 401		.m1 = {
 402			.reg_off = CLKCTRL_CECB_CTRL1,
 403			.shift   = 0,
 404			.width   = 12,
 405		},
 406		.m2 = {
 407			.reg_off = CLKCTRL_CECB_CTRL1,
 408			.shift   = 12,
 409			.width   = 12,
 410		},
 411		.dual = {
 412			.reg_off = CLKCTRL_CECB_CTRL0,
 413			.shift   = 28,
 414			.width   = 1,
 415		},
 416		.table = s4_32k_div_table,
 417	},
 418	.hw.init = &(struct clk_init_data){
 419		.name = "cecb_32k_div",
 420		.ops = &meson_clk_dualdiv_ops,
 421		.parent_hws = (const struct clk_hw *[]) {
 422			&s4_cecb_32k_clkin.hw
 423		},
 424		.num_parents = 1,
 425	},
 426};
 427
 428static struct clk_regmap s4_cecb_32k_sel_pre = {
 429	.data = &(struct clk_regmap_mux_data) {
 430		.offset = CLKCTRL_CECB_CTRL1,
 431		.mask = 0x1,
 432		.shift = 24,
 433		.flags = CLK_MUX_ROUND_CLOSEST,
 434	},
 435	.hw.init = &(struct clk_init_data){
 436		.name = "cecb_32k_sel_pre",
 437		.ops = &clk_regmap_mux_ops,
 438		.parent_hws = (const struct clk_hw *[]) {
 439			&s4_cecb_32k_div.hw,
 440			&s4_cecb_32k_clkin.hw
 441		},
 442		.num_parents = 2,
 443		.flags = CLK_SET_RATE_PARENT,
 444	},
 445};
 446
 447static struct clk_regmap s4_cecb_32k_sel = {
 448	.data = &(struct clk_regmap_mux_data) {
 449		.offset = CLKCTRL_CECB_CTRL1,
 450		.mask = 0x1,
 451		.shift = 31,
 452		.flags = CLK_MUX_ROUND_CLOSEST,
 453	},
 454	.hw.init = &(struct clk_init_data){
 455		.name = "cecb_32k_sel",
 456		.ops = &clk_regmap_mux_ops,
 457		.parent_hws = (const struct clk_hw *[]) {
 458			&s4_cecb_32k_sel_pre.hw,
 459			&s4_rtc_clk.hw
 460		},
 461		.num_parents = 2,
 462	},
 463};
 464
 465static struct clk_regmap s4_cecb_32k_clkout = {
 466	.data = &(struct clk_regmap_gate_data){
 467		.offset = CLKCTRL_CECB_CTRL0,
 468		.bit_idx = 30,
 469	},
 470	.hw.init = &(struct clk_init_data){
 471		.name = "cecb_32k_clkout",
 472		.ops = &clk_regmap_gate_ops,
 473		.parent_hws = (const struct clk_hw *[]) {
 474			&s4_cecb_32k_sel.hw
 475		},
 476		.num_parents = 1,
 477		.flags = CLK_SET_RATE_PARENT,
 478	},
 479};
 480
 481static const struct clk_parent_data s4_sc_parent_data[] = {
 482	{ .fw_name = "fclk_div4" },
 483	{ .fw_name = "fclk_div3" },
 484	{ .fw_name = "fclk_div5" },
 485	{ .fw_name = "xtal", }
 486};
 487
 488static struct clk_regmap s4_sc_clk_mux = {
 489	.data = &(struct clk_regmap_mux_data){
 490		.offset = CLKCTRL_SC_CLK_CTRL,
 491		.mask = 0x3,
 492		.shift = 9,
 493	},
 494	.hw.init = &(struct clk_init_data) {
 495		.name = "sc_clk_mux",
 496		.ops = &clk_regmap_mux_ops,
 497		.parent_data = s4_sc_parent_data,
 498		.num_parents = ARRAY_SIZE(s4_sc_parent_data),
 499		.flags = CLK_SET_RATE_PARENT,
 500	},
 501};
 502
 503static struct clk_regmap s4_sc_clk_div = {
 504	.data = &(struct clk_regmap_div_data){
 505		.offset = CLKCTRL_SC_CLK_CTRL,
 506		.shift = 0,
 507		.width = 8,
 508	},
 509	.hw.init = &(struct clk_init_data) {
 510		.name = "sc_clk_div",
 511		.ops = &clk_regmap_divider_ops,
 512		.parent_hws = (const struct clk_hw *[]) {
 513			&s4_sc_clk_mux.hw
 514		},
 515		.num_parents = 1,
 516		.flags = CLK_SET_RATE_PARENT,
 517	},
 518};
 519
 520static struct clk_regmap s4_sc_clk_gate = {
 521	.data = &(struct clk_regmap_gate_data){
 522		.offset = CLKCTRL_SC_CLK_CTRL,
 523		.bit_idx = 8,
 524	},
 525	.hw.init = &(struct clk_init_data){
 526		.name = "sc_clk_gate",
 527		.ops = &clk_regmap_gate_ops,
 528		.parent_hws = (const struct clk_hw *[]) {
 529			&s4_sc_clk_div.hw
 530		},
 531		.num_parents = 1,
 532		.flags = CLK_SET_RATE_PARENT,
 533	},
 534};
 535
 536static struct clk_regmap s4_12_24M_clk_gate = {
 537	.data = &(struct clk_regmap_gate_data){
 538		.offset = CLKCTRL_CLK12_24_CTRL,
 539		.bit_idx = 11,
 540	},
 541	.hw.init = &(struct clk_init_data) {
 542		.name = "12_24m_gate",
 543		.ops = &clk_regmap_gate_ops,
 544		.parent_data = (const struct clk_parent_data []) {
 545			{ .fw_name = "xtal", }
 546		},
 547		.num_parents = 1,
 548	},
 549};
 550
 551static struct clk_fixed_factor s4_12M_clk_div = {
 552	.mult = 1,
 553	.div = 2,
 554	.hw.init = &(struct clk_init_data){
 555		.name = "12M",
 556		.ops = &clk_fixed_factor_ops,
 557		.parent_hws = (const struct clk_hw *[]) {
 558			&s4_12_24M_clk_gate.hw
 559		},
 560		.num_parents = 1,
 561		.flags = CLK_SET_RATE_PARENT,
 562	},
 563};
 564
 565static struct clk_regmap s4_12_24M_clk = {
 566	.data = &(struct clk_regmap_mux_data){
 567		.offset = CLKCTRL_CLK12_24_CTRL,
 568		.mask = 0x1,
 569		.shift = 10,
 570	},
 571	.hw.init = &(struct clk_init_data) {
 572		.name = "12_24m",
 573		.ops = &clk_regmap_mux_ops,
 574		.parent_hws = (const struct clk_hw *[]) {
 575			&s4_12_24M_clk_gate.hw,
 576			&s4_12M_clk_div.hw,
 577		},
 578		.num_parents = 2,
 579		.flags = CLK_SET_RATE_PARENT,
 580	},
 581};
 582
 583/* Video Clocks */
 584static struct clk_regmap s4_vid_pll_div = {
 585	.data = &(struct meson_vid_pll_div_data){
 586		.val = {
 587			.reg_off = CLKCTRL_VID_PLL_CLK_DIV,
 588			.shift   = 0,
 589			.width   = 15,
 590		},
 591		.sel = {
 592			.reg_off = CLKCTRL_VID_PLL_CLK_DIV,
 593			.shift   = 16,
 594			.width   = 2,
 595		},
 596	},
 597	.hw.init = &(struct clk_init_data) {
 598		.name = "vid_pll_div",
 599		/*
 600		 * TODO meson_vid_pll_div_ro_ops to meson_vid_pll_div_ops
 601		 */
 602		.ops = &meson_vid_pll_div_ro_ops,
 603		.parent_data = (const struct clk_parent_data []) {
 604			{ .fw_name = "hdmi_pll", }
 605		},
 606		.num_parents = 1,
 607		.flags = CLK_SET_RATE_PARENT,
 608	},
 609};
 610
 611static struct clk_regmap s4_vid_pll_sel = {
 612	.data = &(struct clk_regmap_mux_data){
 613		.offset = CLKCTRL_VID_PLL_CLK_DIV,
 614		.mask = 0x1,
 615		.shift = 18,
 616	},
 617	.hw.init = &(struct clk_init_data){
 618		.name = "vid_pll_sel",
 619		.ops = &clk_regmap_mux_ops,
 620		.parent_data = (const struct clk_parent_data []) {
 621			{ .hw = &s4_vid_pll_div.hw },
 622			{ .fw_name = "hdmi_pll", }
 623		},
 624		.num_parents = 2,
 625		.flags = CLK_SET_RATE_PARENT,
 626	},
 627};
 628
 629static struct clk_regmap s4_vid_pll = {
 630	.data = &(struct clk_regmap_gate_data){
 631		.offset = CLKCTRL_VID_PLL_CLK_DIV,
 632		.bit_idx = 19,
 633	},
 634	.hw.init = &(struct clk_init_data) {
 635		.name = "vid_pll",
 636		.ops = &clk_regmap_gate_ops,
 637		.parent_hws = (const struct clk_hw *[]) {
 638			&s4_vid_pll_sel.hw
 639		},
 640		.num_parents = 1,
 641		.flags = CLK_SET_RATE_PARENT,
 642	},
 643};
 644
 645static const struct clk_parent_data s4_vclk_parent_data[] = {
 646	{ .hw = &s4_vid_pll.hw },
 647	{ .fw_name = "gp0_pll", },
 648	{ .fw_name = "hifi_pll", },
 649	{ .fw_name = "mpll1", },
 650	{ .fw_name = "fclk_div3", },
 651	{ .fw_name = "fclk_div4", },
 652	{ .fw_name = "fclk_div5", },
 653	{ .fw_name = "fclk_div7", },
 654};
 655
 656static struct clk_regmap s4_vclk_sel = {
 657	.data = &(struct clk_regmap_mux_data){
 658		.offset = CLKCTRL_VID_CLK_CTRL,
 659		.mask = 0x7,
 660		.shift = 16,
 661	},
 662	.hw.init = &(struct clk_init_data){
 663		.name = "vclk_sel",
 664		.ops = &clk_regmap_mux_ops,
 665		.parent_data = s4_vclk_parent_data,
 666		.num_parents = ARRAY_SIZE(s4_vclk_parent_data),
 667		.flags = 0,
 668	},
 669};
 670
 671static struct clk_regmap s4_vclk2_sel = {
 672	.data = &(struct clk_regmap_mux_data){
 673		.offset = CLKCTRL_VIID_CLK_CTRL,
 674		.mask = 0x7,
 675		.shift = 16,
 676	},
 677	.hw.init = &(struct clk_init_data){
 678		.name = "vclk2_sel",
 679		.ops = &clk_regmap_mux_ops,
 680		.parent_data = s4_vclk_parent_data,
 681		.num_parents = ARRAY_SIZE(s4_vclk_parent_data),
 682		.flags = 0,
 683	},
 684};
 685
 686static struct clk_regmap s4_vclk_input = {
 687	.data = &(struct clk_regmap_gate_data){
 688		.offset = CLKCTRL_VID_CLK_DIV,
 689		.bit_idx = 16,
 690	},
 691	.hw.init = &(struct clk_init_data) {
 692		.name = "vclk_input",
 693		.ops = &clk_regmap_gate_ops,
 694		.parent_hws = (const struct clk_hw *[]) { &s4_vclk_sel.hw },
 695		.num_parents = 1,
 696		.flags = CLK_SET_RATE_PARENT,
 697	},
 698};
 699
 700static struct clk_regmap s4_vclk2_input = {
 701	.data = &(struct clk_regmap_gate_data){
 702		.offset = CLKCTRL_VIID_CLK_DIV,
 703		.bit_idx = 16,
 704	},
 705	.hw.init = &(struct clk_init_data) {
 706		.name = "vclk2_input",
 707		.ops = &clk_regmap_gate_ops,
 708		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2_sel.hw },
 709		.num_parents = 1,
 710		.flags = CLK_SET_RATE_PARENT,
 711	},
 712};
 713
 714static struct clk_regmap s4_vclk_div = {
 715	.data = &(struct clk_regmap_div_data){
 716		.offset = CLKCTRL_VID_CLK_DIV,
 717		.shift = 0,
 718		.width = 8,
 719	},
 720	.hw.init = &(struct clk_init_data){
 721		.name = "vclk_div",
 722		.ops = &clk_regmap_divider_ops,
 723		.parent_hws = (const struct clk_hw *[]) {
 724			&s4_vclk_input.hw
 725		},
 726		.num_parents = 1,
 727		.flags = CLK_SET_RATE_PARENT,
 728	},
 729};
 730
 731static struct clk_regmap s4_vclk2_div = {
 732	.data = &(struct clk_regmap_div_data){
 733		.offset = CLKCTRL_VIID_CLK_DIV,
 734		.shift = 0,
 735		.width = 8,
 736	},
 737	.hw.init = &(struct clk_init_data){
 738		.name = "vclk2_div",
 739		.ops = &clk_regmap_divider_ops,
 740		.parent_hws = (const struct clk_hw *[]) {
 741			&s4_vclk2_input.hw
 742		},
 743		.num_parents = 1,
 744		.flags = CLK_SET_RATE_PARENT,
 745	},
 746};
 747
 748static struct clk_regmap s4_vclk = {
 749	.data = &(struct clk_regmap_gate_data){
 750		.offset = CLKCTRL_VID_CLK_CTRL,
 751		.bit_idx = 19,
 752	},
 753	.hw.init = &(struct clk_init_data) {
 754		.name = "vclk",
 755		.ops = &clk_regmap_gate_ops,
 756		.parent_hws = (const struct clk_hw *[]) { &s4_vclk_div.hw },
 757		.num_parents = 1,
 758		.flags = CLK_SET_RATE_PARENT,
 759	},
 760};
 761
 762static struct clk_regmap s4_vclk2 = {
 763	.data = &(struct clk_regmap_gate_data){
 764		.offset = CLKCTRL_VIID_CLK_CTRL,
 765		.bit_idx = 19,
 766	},
 767	.hw.init = &(struct clk_init_data) {
 768		.name = "vclk2",
 769		.ops = &clk_regmap_gate_ops,
 770		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2_div.hw },
 771		.num_parents = 1,
 772		.flags = CLK_SET_RATE_PARENT,
 773	},
 774};
 775
 776static struct clk_regmap s4_vclk_div1 = {
 777	.data = &(struct clk_regmap_gate_data){
 778		.offset = CLKCTRL_VID_CLK_CTRL,
 779		.bit_idx = 0,
 780	},
 781	.hw.init = &(struct clk_init_data) {
 782		.name = "vclk_div1",
 783		.ops = &clk_regmap_gate_ops,
 784		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
 785		.num_parents = 1,
 786		.flags = CLK_SET_RATE_PARENT,
 787	},
 788};
 789
 790static struct clk_regmap s4_vclk_div2_en = {
 791	.data = &(struct clk_regmap_gate_data){
 792		.offset = CLKCTRL_VID_CLK_CTRL,
 793		.bit_idx = 1,
 794	},
 795	.hw.init = &(struct clk_init_data) {
 796		.name = "vclk_div2_en",
 797		.ops = &clk_regmap_gate_ops,
 798		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
 799		.num_parents = 1,
 800		.flags = CLK_SET_RATE_PARENT,
 801	},
 802};
 803
 804static struct clk_regmap s4_vclk_div4_en = {
 805	.data = &(struct clk_regmap_gate_data){
 806		.offset = CLKCTRL_VID_CLK_CTRL,
 807		.bit_idx = 2,
 808	},
 809	.hw.init = &(struct clk_init_data) {
 810		.name = "vclk_div4_en",
 811		.ops = &clk_regmap_gate_ops,
 812		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
 813		.num_parents = 1,
 814		.flags = CLK_SET_RATE_PARENT,
 815	},
 816};
 817
 818static struct clk_regmap s4_vclk_div6_en = {
 819	.data = &(struct clk_regmap_gate_data){
 820		.offset = CLKCTRL_VID_CLK_CTRL,
 821		.bit_idx = 3,
 822	},
 823	.hw.init = &(struct clk_init_data) {
 824		.name = "vclk_div6_en",
 825		.ops = &clk_regmap_gate_ops,
 826		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
 827		.num_parents = 1,
 828		.flags = CLK_SET_RATE_PARENT,
 829	},
 830};
 831
 832static struct clk_regmap s4_vclk_div12_en = {
 833	.data = &(struct clk_regmap_gate_data){
 834		.offset = CLKCTRL_VID_CLK_CTRL,
 835		.bit_idx = 4,
 836	},
 837	.hw.init = &(struct clk_init_data) {
 838		.name = "vclk_div12_en",
 839		.ops = &clk_regmap_gate_ops,
 840		.parent_hws = (const struct clk_hw *[]) { &s4_vclk.hw },
 841		.num_parents = 1,
 842		.flags = CLK_SET_RATE_PARENT,
 843	},
 844};
 845
 846static struct clk_regmap s4_vclk2_div1 = {
 847	.data = &(struct clk_regmap_gate_data){
 848		.offset = CLKCTRL_VIID_CLK_CTRL,
 849		.bit_idx = 0,
 850	},
 851	.hw.init = &(struct clk_init_data) {
 852		.name = "vclk2_div1",
 853		.ops = &clk_regmap_gate_ops,
 854		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
 855		.num_parents = 1,
 856		.flags = CLK_SET_RATE_PARENT,
 857	},
 858};
 859
 860static struct clk_regmap s4_vclk2_div2_en = {
 861	.data = &(struct clk_regmap_gate_data){
 862		.offset = CLKCTRL_VIID_CLK_CTRL,
 863		.bit_idx = 1,
 864	},
 865	.hw.init = &(struct clk_init_data) {
 866		.name = "vclk2_div2_en",
 867		.ops = &clk_regmap_gate_ops,
 868		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
 869		.num_parents = 1,
 870		.flags = CLK_SET_RATE_PARENT,
 871	},
 872};
 873
 874static struct clk_regmap s4_vclk2_div4_en = {
 875	.data = &(struct clk_regmap_gate_data){
 876		.offset = CLKCTRL_VIID_CLK_CTRL,
 877		.bit_idx = 2,
 878	},
 879	.hw.init = &(struct clk_init_data) {
 880		.name = "vclk2_div4_en",
 881		.ops = &clk_regmap_gate_ops,
 882		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
 883		.num_parents = 1,
 884		.flags = CLK_SET_RATE_PARENT,
 885	},
 886};
 887
 888static struct clk_regmap s4_vclk2_div6_en = {
 889	.data = &(struct clk_regmap_gate_data){
 890		.offset = CLKCTRL_VIID_CLK_CTRL,
 891		.bit_idx = 3,
 892	},
 893	.hw.init = &(struct clk_init_data) {
 894		.name = "vclk2_div6_en",
 895		.ops = &clk_regmap_gate_ops,
 896		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
 897		.num_parents = 1,
 898		.flags = CLK_SET_RATE_PARENT,
 899	},
 900};
 901
 902static struct clk_regmap s4_vclk2_div12_en = {
 903	.data = &(struct clk_regmap_gate_data){
 904		.offset = CLKCTRL_VIID_CLK_CTRL,
 905		.bit_idx = 4,
 906	},
 907	.hw.init = &(struct clk_init_data) {
 908		.name = "vclk2_div12_en",
 909		.ops = &clk_regmap_gate_ops,
 910		.parent_hws = (const struct clk_hw *[]) { &s4_vclk2.hw },
 911		.num_parents = 1,
 912		.flags = CLK_SET_RATE_PARENT,
 913	},
 914};
 915
 916static struct clk_fixed_factor s4_vclk_div2 = {
 917	.mult = 1,
 918	.div = 2,
 919	.hw.init = &(struct clk_init_data){
 920		.name = "vclk_div2",
 921		.ops = &clk_fixed_factor_ops,
 922		.parent_hws = (const struct clk_hw *[]) {
 923			&s4_vclk_div2_en.hw
 924		},
 925		.num_parents = 1,
 926		.flags = CLK_SET_RATE_PARENT,
 927	},
 928};
 929
 930static struct clk_fixed_factor s4_vclk_div4 = {
 931	.mult = 1,
 932	.div = 4,
 933	.hw.init = &(struct clk_init_data){
 934		.name = "vclk_div4",
 935		.ops = &clk_fixed_factor_ops,
 936		.parent_hws = (const struct clk_hw *[]) {
 937			&s4_vclk_div4_en.hw
 938		},
 939		.num_parents = 1,
 940		.flags = CLK_SET_RATE_PARENT,
 941	},
 942};
 943
 944static struct clk_fixed_factor s4_vclk_div6 = {
 945	.mult = 1,
 946	.div = 6,
 947	.hw.init = &(struct clk_init_data){
 948		.name = "vclk_div6",
 949		.ops = &clk_fixed_factor_ops,
 950		.parent_hws = (const struct clk_hw *[]) {
 951			&s4_vclk_div6_en.hw
 952		},
 953		.num_parents = 1,
 954		.flags = CLK_SET_RATE_PARENT,
 955	},
 956};
 957
 958static struct clk_fixed_factor s4_vclk_div12 = {
 959	.mult = 1,
 960	.div = 12,
 961	.hw.init = &(struct clk_init_data){
 962		.name = "vclk_div12",
 963		.ops = &clk_fixed_factor_ops,
 964		.parent_hws = (const struct clk_hw *[]) {
 965			&s4_vclk_div12_en.hw
 966		},
 967		.num_parents = 1,
 968		.flags = CLK_SET_RATE_PARENT,
 969	},
 970};
 971
 972static struct clk_fixed_factor s4_vclk2_div2 = {
 973	.mult = 1,
 974	.div = 2,
 975	.hw.init = &(struct clk_init_data){
 976		.name = "vclk2_div2",
 977		.ops = &clk_fixed_factor_ops,
 978		.parent_hws = (const struct clk_hw *[]) {
 979			&s4_vclk2_div2_en.hw
 980		},
 981		.num_parents = 1,
 982		.flags = CLK_SET_RATE_PARENT,
 983	},
 984};
 985
 986static struct clk_fixed_factor s4_vclk2_div4 = {
 987	.mult = 1,
 988	.div = 4,
 989	.hw.init = &(struct clk_init_data){
 990		.name = "vclk2_div4",
 991		.ops = &clk_fixed_factor_ops,
 992		.parent_hws = (const struct clk_hw *[]) {
 993			&s4_vclk2_div4_en.hw
 994		},
 995		.num_parents = 1,
 996		.flags = CLK_SET_RATE_PARENT,
 997	},
 998};
 999
1000static struct clk_fixed_factor s4_vclk2_div6 = {
1001	.mult = 1,
1002	.div = 6,
1003	.hw.init = &(struct clk_init_data){
1004		.name = "vclk2_div6",
1005		.ops = &clk_fixed_factor_ops,
1006		.parent_hws = (const struct clk_hw *[]) {
1007			&s4_vclk2_div6_en.hw
1008		},
1009		.num_parents = 1,
1010		.flags = CLK_SET_RATE_PARENT,
1011	},
1012};
1013
1014static struct clk_fixed_factor s4_vclk2_div12 = {
1015	.mult = 1,
1016	.div = 12,
1017	.hw.init = &(struct clk_init_data){
1018		.name = "vclk2_div12",
1019		.ops = &clk_fixed_factor_ops,
1020		.parent_hws = (const struct clk_hw *[]) {
1021			&s4_vclk2_div12_en.hw
1022		},
1023		.num_parents = 1,
1024		.flags = CLK_SET_RATE_PARENT,
1025	},
1026};
1027
1028/* The 5,6,7 indexes corresponds to no real clock, so there are not used. */
1029static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
1030static const struct clk_hw *s4_cts_parent_hws[] = {
1031	&s4_vclk_div1.hw,
1032	&s4_vclk_div2.hw,
1033	&s4_vclk_div4.hw,
1034	&s4_vclk_div6.hw,
1035	&s4_vclk_div12.hw,
1036	&s4_vclk2_div1.hw,
1037	&s4_vclk2_div2.hw,
1038	&s4_vclk2_div4.hw,
1039	&s4_vclk2_div6.hw,
1040	&s4_vclk2_div12.hw
1041};
1042
1043static struct clk_regmap s4_cts_enci_sel = {
1044	.data = &(struct clk_regmap_mux_data){
1045		.offset = CLKCTRL_VID_CLK_DIV,
1046		.mask = 0xf,
1047		.shift = 28,
1048		.table = mux_table_cts_sel,
1049	},
1050	.hw.init = &(struct clk_init_data){
1051		.name = "cts_enci_sel",
1052		.ops = &clk_regmap_mux_ops,
1053		.parent_hws = s4_cts_parent_hws,
1054		.num_parents = ARRAY_SIZE(s4_cts_parent_hws),
1055		.flags = CLK_SET_RATE_PARENT,
1056	},
1057};
1058
1059static struct clk_regmap s4_cts_encp_sel = {
1060	.data = &(struct clk_regmap_mux_data){
1061		.offset = CLKCTRL_VID_CLK_DIV,
1062		.mask = 0xf,
1063		.shift = 20,
1064		.table = mux_table_cts_sel,
1065	},
1066	.hw.init = &(struct clk_init_data){
1067		.name = "cts_encp_sel",
1068		.ops = &clk_regmap_mux_ops,
1069		.parent_hws = s4_cts_parent_hws,
1070		.num_parents = ARRAY_SIZE(s4_cts_parent_hws),
1071		.flags = CLK_SET_RATE_PARENT,
1072	},
1073};
1074
1075static struct clk_regmap s4_cts_vdac_sel = {
1076	.data = &(struct clk_regmap_mux_data){
1077		.offset = CLKCTRL_VIID_CLK_DIV,
1078		.mask = 0xf,
1079		.shift = 28,
1080		.table = mux_table_cts_sel,
1081	},
1082	.hw.init = &(struct clk_init_data){
1083		.name = "cts_vdac_sel",
1084		.ops = &clk_regmap_mux_ops,
1085		.parent_hws = s4_cts_parent_hws,
1086		.num_parents = ARRAY_SIZE(s4_cts_parent_hws),
1087		.flags = CLK_SET_RATE_PARENT,
1088	},
1089};
1090
1091/* The 5,6,7 indexes corresponds to no real clock, so there are not used. */
1092static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
1093static const struct clk_hw *s4_cts_hdmi_tx_parent_hws[] = {
1094	&s4_vclk_div1.hw,
1095	&s4_vclk_div2.hw,
1096	&s4_vclk_div4.hw,
1097	&s4_vclk_div6.hw,
1098	&s4_vclk_div12.hw,
1099	&s4_vclk2_div1.hw,
1100	&s4_vclk2_div2.hw,
1101	&s4_vclk2_div4.hw,
1102	&s4_vclk2_div6.hw,
1103	&s4_vclk2_div12.hw
1104};
1105
1106static struct clk_regmap s4_hdmi_tx_sel = {
1107	.data = &(struct clk_regmap_mux_data){
1108		.offset = CLKCTRL_HDMI_CLK_CTRL,
1109		.mask = 0xf,
1110		.shift = 16,
1111		.table = mux_table_hdmi_tx_sel,
1112	},
1113	.hw.init = &(struct clk_init_data){
1114		.name = "hdmi_tx_sel",
1115		.ops = &clk_regmap_mux_ops,
1116		.parent_hws = s4_cts_hdmi_tx_parent_hws,
1117		.num_parents = ARRAY_SIZE(s4_cts_hdmi_tx_parent_hws),
1118		.flags = CLK_SET_RATE_PARENT,
1119	},
1120};
1121
1122static struct clk_regmap s4_cts_enci = {
1123	.data = &(struct clk_regmap_gate_data){
1124		.offset = CLKCTRL_VID_CLK_CTRL2,
1125		.bit_idx = 0,
1126	},
1127	.hw.init = &(struct clk_init_data) {
1128		.name = "cts_enci",
1129		.ops = &clk_regmap_gate_ops,
1130		.parent_hws = (const struct clk_hw *[]) {
1131			&s4_cts_enci_sel.hw
1132		},
1133		.num_parents = 1,
1134		.flags = CLK_SET_RATE_PARENT,
1135	},
1136};
1137
1138static struct clk_regmap s4_cts_encp = {
1139	.data = &(struct clk_regmap_gate_data){
1140		.offset = CLKCTRL_VID_CLK_CTRL2,
1141		.bit_idx = 2,
1142	},
1143	.hw.init = &(struct clk_init_data) {
1144		.name = "cts_encp",
1145		.ops = &clk_regmap_gate_ops,
1146		.parent_hws = (const struct clk_hw *[]) {
1147			&s4_cts_encp_sel.hw
1148		},
1149		.num_parents = 1,
1150		.flags = CLK_SET_RATE_PARENT,
1151	},
1152};
1153
1154static struct clk_regmap s4_cts_vdac = {
1155	.data = &(struct clk_regmap_gate_data){
1156		.offset = CLKCTRL_VID_CLK_CTRL2,
1157		.bit_idx = 4,
1158	},
1159	.hw.init = &(struct clk_init_data) {
1160		.name = "cts_vdac",
1161		.ops = &clk_regmap_gate_ops,
1162		.parent_hws = (const struct clk_hw *[]) {
1163			&s4_cts_vdac_sel.hw
1164		},
1165		.num_parents = 1,
1166		.flags = CLK_SET_RATE_PARENT,
1167	},
1168};
1169
1170static struct clk_regmap s4_hdmi_tx = {
1171	.data = &(struct clk_regmap_gate_data){
1172		.offset = CLKCTRL_VID_CLK_CTRL2,
1173		.bit_idx = 5,
1174	},
1175	.hw.init = &(struct clk_init_data) {
1176		.name = "hdmi_tx",
1177		.ops = &clk_regmap_gate_ops,
1178		.parent_hws = (const struct clk_hw *[]) {
1179			&s4_hdmi_tx_sel.hw
1180		},
1181		.num_parents = 1,
1182		.flags = CLK_SET_RATE_PARENT,
1183	},
1184};
1185
1186/* HDMI Clocks */
1187static const struct clk_parent_data s4_hdmi_parent_data[] = {
1188	{ .fw_name = "xtal", },
1189	{ .fw_name = "fclk_div4", },
1190	{ .fw_name = "fclk_div3", },
1191	{ .fw_name = "fclk_div5", }
1192};
1193
1194static struct clk_regmap s4_hdmi_sel = {
1195	.data = &(struct clk_regmap_mux_data){
1196		.offset = CLKCTRL_HDMI_CLK_CTRL,
1197		.mask = 0x3,
1198		.shift = 9,
1199		.flags = CLK_MUX_ROUND_CLOSEST,
1200	},
1201	.hw.init = &(struct clk_init_data){
1202		.name = "hdmi_sel",
1203		.ops = &clk_regmap_mux_ops,
1204		.parent_data = s4_hdmi_parent_data,
1205		.num_parents = ARRAY_SIZE(s4_hdmi_parent_data),
1206		.flags = CLK_SET_RATE_PARENT,
1207	},
1208};
1209
1210static struct clk_regmap s4_hdmi_div = {
1211	.data = &(struct clk_regmap_div_data){
1212		.offset = CLKCTRL_HDMI_CLK_CTRL,
1213		.shift = 0,
1214		.width = 7,
1215	},
1216	.hw.init = &(struct clk_init_data){
1217		.name = "hdmi_div",
1218		.ops = &clk_regmap_divider_ops,
1219		.parent_hws = (const struct clk_hw *[]) { &s4_hdmi_sel.hw },
1220		.num_parents = 1,
1221		.flags = CLK_SET_RATE_PARENT,
1222	},
1223};
1224
1225static struct clk_regmap s4_hdmi = {
1226	.data = &(struct clk_regmap_gate_data){
1227		.offset = CLKCTRL_HDMI_CLK_CTRL,
1228		.bit_idx = 8,
1229	},
1230	.hw.init = &(struct clk_init_data) {
1231		.name = "hdmi",
1232		.ops = &clk_regmap_gate_ops,
1233		.parent_hws = (const struct clk_hw *[]) { &s4_hdmi_div.hw },
1234		.num_parents = 1,
1235		.flags = CLK_SET_RATE_PARENT,
1236	},
1237};
1238
1239static struct clk_regmap s4_ts_clk_div = {
1240	.data = &(struct clk_regmap_div_data){
1241		.offset = CLKCTRL_TS_CLK_CTRL,
1242		.shift = 0,
1243		.width = 8,
1244	},
1245	.hw.init = &(struct clk_init_data){
1246		.name = "ts_clk_div",
1247		.ops = &clk_regmap_divider_ops,
1248		.parent_data = &(const struct clk_parent_data) {
1249			.fw_name = "xtal",
1250		},
1251		.num_parents = 1,
1252		.flags = CLK_SET_RATE_PARENT,
1253	},
1254};
1255
1256static struct clk_regmap s4_ts_clk_gate = {
1257	.data = &(struct clk_regmap_gate_data){
1258		.offset = CLKCTRL_TS_CLK_CTRL,
1259		.bit_idx = 8,
1260	},
1261	.hw.init = &(struct clk_init_data){
1262		.name = "ts_clk",
1263		.ops = &clk_regmap_gate_ops,
1264		.parent_hws = (const struct clk_hw *[]) {
1265			&s4_ts_clk_div.hw
1266		},
1267		.num_parents = 1,
1268		.flags = CLK_SET_RATE_PARENT,
1269	},
1270};
1271
1272/*
1273 * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
1274 * muxed by a glitch-free switch. The CCF can manage this glitch-free
1275 * mux because it does top-to-bottom updates the each clock tree and
1276 * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
1277 */
1278static const struct clk_parent_data s4_mali_0_1_parent_data[] = {
1279	{ .fw_name = "xtal", },
1280	{ .fw_name = "gp0_pll", },
1281	{ .fw_name = "hifi_pll", },
1282	{ .fw_name = "fclk_div2p5", },
1283	{ .fw_name = "fclk_div3", },
1284	{ .fw_name = "fclk_div4", },
1285	{ .fw_name = "fclk_div5", },
1286	{ .fw_name = "fclk_div7", }
1287};
1288
1289static struct clk_regmap s4_mali_0_sel = {
1290	.data = &(struct clk_regmap_mux_data){
1291		.offset = CLKCTRL_MALI_CLK_CTRL,
1292		.mask = 0x7,
1293		.shift = 9,
1294	},
1295	.hw.init = &(struct clk_init_data){
1296		.name = "mali_0_sel",
1297		.ops = &clk_regmap_mux_ops,
1298		.parent_data = s4_mali_0_1_parent_data,
1299		.num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data),
1300		/*
1301		 * Don't request the parent to change the rate because
1302		 * all GPU frequencies can be derived from the fclk_*
1303		 * clocks and one special GP0_PLL setting. This is
1304		 * important because we need the HIFI PLL clock for audio.
1305		 */
1306		.flags = 0,
1307	},
1308};
1309
1310static struct clk_regmap s4_mali_0_div = {
1311	.data = &(struct clk_regmap_div_data){
1312		.offset = CLKCTRL_MALI_CLK_CTRL,
1313		.shift = 0,
1314		.width = 7,
1315	},
1316	.hw.init = &(struct clk_init_data){
1317		.name = "mali_0_div",
1318		.ops = &clk_regmap_divider_ops,
1319		.parent_hws = (const struct clk_hw *[]) {
1320			&s4_mali_0_sel.hw
1321		},
1322		.num_parents = 1,
1323		.flags = CLK_SET_RATE_PARENT,
1324	},
1325};
1326
1327static struct clk_regmap s4_mali_0 = {
1328	.data = &(struct clk_regmap_gate_data){
1329		.offset = CLKCTRL_MALI_CLK_CTRL,
1330		.bit_idx = 8,
1331	},
1332	.hw.init = &(struct clk_init_data){
1333		.name = "mali_0",
1334		.ops = &clk_regmap_gate_ops,
1335		.parent_hws = (const struct clk_hw *[]) {
1336			&s4_mali_0_div.hw
1337		},
1338		.num_parents = 1,
1339		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
1340	},
1341};
1342
1343static struct clk_regmap s4_mali_1_sel = {
1344	.data = &(struct clk_regmap_mux_data){
1345		.offset = CLKCTRL_MALI_CLK_CTRL,
1346		.mask = 0x7,
1347		.shift = 25,
1348	},
1349	.hw.init = &(struct clk_init_data){
1350		.name = "mali_1_sel",
1351		.ops = &clk_regmap_mux_ops,
1352		.parent_data = s4_mali_0_1_parent_data,
1353		.num_parents = ARRAY_SIZE(s4_mali_0_1_parent_data),
1354		.flags = 0,
1355	},
1356};
1357
1358static struct clk_regmap s4_mali_1_div = {
1359	.data = &(struct clk_regmap_div_data){
1360		.offset = CLKCTRL_MALI_CLK_CTRL,
1361		.shift = 16,
1362		.width = 7,
1363	},
1364	.hw.init = &(struct clk_init_data){
1365		.name = "mali_1_div",
1366		.ops = &clk_regmap_divider_ops,
1367		.parent_hws = (const struct clk_hw *[]) {
1368			&s4_mali_1_sel.hw
1369		},
1370		.num_parents = 1,
1371		.flags = CLK_SET_RATE_PARENT,
1372	},
1373};
1374
1375static struct clk_regmap s4_mali_1 = {
1376	.data = &(struct clk_regmap_gate_data){
1377		.offset = CLKCTRL_MALI_CLK_CTRL,
1378		.bit_idx = 24,
1379	},
1380	.hw.init = &(struct clk_init_data){
1381		.name = "mali_1",
1382		.ops = &clk_regmap_gate_ops,
1383		.parent_hws = (const struct clk_hw *[]) {
1384			&s4_mali_1_div.hw
1385		},
1386		.num_parents = 1,
1387		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
1388	},
1389};
1390
1391static const struct clk_hw *s4_mali_parent_hws[] = {
1392	&s4_mali_0.hw,
1393	&s4_mali_1.hw
1394};
1395
1396static struct clk_regmap s4_mali_mux = {
1397	.data = &(struct clk_regmap_mux_data){
1398		.offset = CLKCTRL_MALI_CLK_CTRL,
1399		.mask = 1,
1400		.shift = 31,
1401	},
1402	.hw.init = &(struct clk_init_data){
1403		.name = "mali",
1404		.ops = &clk_regmap_mux_ops,
1405		.parent_hws = s4_mali_parent_hws,
1406		.num_parents = 2,
1407		.flags = CLK_SET_RATE_PARENT,
1408	},
1409};
1410
1411/* VDEC clocks */
1412static const struct clk_parent_data s4_dec_parent_data[] = {
1413	{ .fw_name = "fclk_div2p5", },
1414	{ .fw_name = "fclk_div3", },
1415	{ .fw_name = "fclk_div4", },
1416	{ .fw_name = "fclk_div5", },
1417	{ .fw_name = "fclk_div7", },
1418	{ .fw_name = "hifi_pll", },
1419	{ .fw_name = "gp0_pll", },
1420	{ .fw_name = "xtal", }
1421};
1422
1423static struct clk_regmap s4_vdec_p0_mux = {
1424	.data = &(struct clk_regmap_mux_data){
1425		.offset = CLKCTRL_VDEC_CLK_CTRL,
1426		.mask = 0x7,
1427		.shift = 9,
1428		.flags = CLK_MUX_ROUND_CLOSEST,
1429	},
1430	.hw.init = &(struct clk_init_data) {
1431		.name = "vdec_p0_mux",
1432		.ops = &clk_regmap_mux_ops,
1433		.parent_data = s4_dec_parent_data,
1434		.num_parents = ARRAY_SIZE(s4_dec_parent_data),
1435		.flags = 0,
1436	},
1437};
1438
1439static struct clk_regmap s4_vdec_p0_div = {
1440	.data = &(struct clk_regmap_div_data){
1441		.offset = CLKCTRL_VDEC_CLK_CTRL,
1442		.shift = 0,
1443		.width = 7,
1444		.flags = CLK_DIVIDER_ROUND_CLOSEST,
1445	},
1446	.hw.init = &(struct clk_init_data) {
1447		.name = "vdec_p0_div",
1448		.ops = &clk_regmap_divider_ops,
1449		.parent_hws = (const struct clk_hw *[]) {
1450			&s4_vdec_p0_mux.hw
1451		},
1452		.num_parents = 1,
1453		.flags = CLK_SET_RATE_PARENT,
1454	},
1455};
1456
1457static struct clk_regmap s4_vdec_p0 = {
1458	.data = &(struct clk_regmap_gate_data){
1459		.offset = CLKCTRL_VDEC_CLK_CTRL,
1460		.bit_idx = 8,
1461	},
1462	.hw.init = &(struct clk_init_data){
1463		.name = "vdec_p0",
1464		.ops = &clk_regmap_gate_ops,
1465		.parent_hws = (const struct clk_hw *[]) {
1466			&s4_vdec_p0_div.hw
1467		},
1468		.num_parents = 1,
1469		.flags = CLK_SET_RATE_PARENT,
1470	},
1471};
1472
1473static struct clk_regmap s4_vdec_p1_mux = {
1474	.data = &(struct clk_regmap_mux_data){
1475		.offset = CLKCTRL_VDEC3_CLK_CTRL,
1476		.mask = 0x7,
1477		.shift = 9,
1478		.flags = CLK_MUX_ROUND_CLOSEST,
1479	},
1480	.hw.init = &(struct clk_init_data) {
1481		.name = "vdec_p1_mux",
1482		.ops = &clk_regmap_mux_ops,
1483		.parent_data = s4_dec_parent_data,
1484		.num_parents = ARRAY_SIZE(s4_dec_parent_data),
1485		.flags = 0,
1486	},
1487};
1488
1489static struct clk_regmap s4_vdec_p1_div = {
1490	.data = &(struct clk_regmap_div_data){
1491		.offset = CLKCTRL_VDEC3_CLK_CTRL,
1492		.shift = 0,
1493		.width = 7,
1494		.flags = CLK_DIVIDER_ROUND_CLOSEST,
1495	},
1496	.hw.init = &(struct clk_init_data) {
1497		.name = "vdec_p1_div",
1498		.ops = &clk_regmap_divider_ops,
1499		.parent_hws = (const struct clk_hw *[]) {
1500			&s4_vdec_p1_mux.hw
1501		},
1502		.num_parents = 1,
1503		.flags = CLK_SET_RATE_PARENT,
1504	},
1505};
1506
1507static struct clk_regmap s4_vdec_p1 = {
1508	.data = &(struct clk_regmap_gate_data){
1509		.offset = CLKCTRL_VDEC3_CLK_CTRL,
1510		.bit_idx = 8,
1511	},
1512	.hw.init = &(struct clk_init_data){
1513		.name = "vdec_p1",
1514		.ops = &clk_regmap_gate_ops,
1515		.parent_hws = (const struct clk_hw *[]) {
1516			&s4_vdec_p1_div.hw
1517		},
1518		.num_parents = 1,
1519		.flags = CLK_SET_RATE_PARENT,
1520	},
1521};
1522
1523static const struct clk_hw *s4_vdec_mux_parent_hws[] = {
1524	&s4_vdec_p0.hw,
1525	&s4_vdec_p1.hw
1526};
1527
1528static struct clk_regmap s4_vdec_mux = {
1529	.data = &(struct clk_regmap_mux_data){
1530		.offset = CLKCTRL_VDEC3_CLK_CTRL,
1531		.mask = 0x1,
1532		.shift = 15,
1533	},
1534	.hw.init = &(struct clk_init_data) {
1535		.name = "vdec_mux",
1536		.ops = &clk_regmap_mux_ops,
1537		.parent_hws = s4_vdec_mux_parent_hws,
1538		.num_parents = ARRAY_SIZE(s4_vdec_mux_parent_hws),
1539		.flags = CLK_SET_RATE_PARENT,
1540	},
1541};
1542
1543static struct clk_regmap s4_hevcf_p0_mux = {
1544	.data = &(struct clk_regmap_mux_data){
1545		.offset = CLKCTRL_VDEC2_CLK_CTRL,
1546		.mask = 0x7,
1547		.shift = 9,
1548		.flags = CLK_MUX_ROUND_CLOSEST,
1549	},
1550	.hw.init = &(struct clk_init_data) {
1551		.name = "hevcf_p0_mux",
1552		.ops = &clk_regmap_mux_ops,
1553		.parent_data = s4_dec_parent_data,
1554		.num_parents = ARRAY_SIZE(s4_dec_parent_data),
1555		.flags = 0,
1556	},
1557};
1558
1559static struct clk_regmap s4_hevcf_p0_div = {
1560	.data = &(struct clk_regmap_div_data){
1561		.offset = CLKCTRL_VDEC2_CLK_CTRL,
1562		.shift = 0,
1563		.width = 7,
1564		.flags = CLK_DIVIDER_ROUND_CLOSEST,
1565	},
1566	.hw.init = &(struct clk_init_data) {
1567		.name = "hevcf_p0_div",
1568		.ops = &clk_regmap_divider_ops,
1569		.parent_hws = (const struct clk_hw *[]) {
1570			&s4_hevcf_p0_mux.hw
1571		},
1572		.num_parents = 1,
1573		.flags = CLK_SET_RATE_PARENT,
1574	},
1575};
1576
1577static struct clk_regmap s4_hevcf_p0 = {
1578	.data = &(struct clk_regmap_gate_data){
1579		.offset = CLKCTRL_VDEC2_CLK_CTRL,
1580		.bit_idx = 8,
1581	},
1582	.hw.init = &(struct clk_init_data){
1583		.name = "hevcf_p0_gate",
1584		.ops = &clk_regmap_gate_ops,
1585		.parent_hws = (const struct clk_hw *[]) {
1586			&s4_hevcf_p0_div.hw
1587		},
1588		.num_parents = 1,
1589		.flags = CLK_SET_RATE_PARENT,
1590	},
1591};
1592
1593static struct clk_regmap s4_hevcf_p1_mux = {
1594	.data = &(struct clk_regmap_mux_data){
1595		.offset = CLKCTRL_VDEC4_CLK_CTRL,
1596		.mask = 0x7,
1597		.shift = 9,
1598		.flags = CLK_MUX_ROUND_CLOSEST,
1599	},
1600	.hw.init = &(struct clk_init_data) {
1601		.name = "hevcf_p1_mux",
1602		.ops = &clk_regmap_mux_ops,
1603		.parent_data = s4_dec_parent_data,
1604		.num_parents = ARRAY_SIZE(s4_dec_parent_data),
1605		.flags = 0,
1606	},
1607};
1608
1609static struct clk_regmap s4_hevcf_p1_div = {
1610	.data = &(struct clk_regmap_div_data){
1611		.offset = CLKCTRL_VDEC4_CLK_CTRL,
1612		.shift = 0,
1613		.width = 7,
1614		.flags = CLK_DIVIDER_ROUND_CLOSEST,
1615	},
1616	.hw.init = &(struct clk_init_data) {
1617		.name = "hevcf_p1_div",
1618		.ops = &clk_regmap_divider_ops,
1619		.parent_hws = (const struct clk_hw *[]) {
1620			&s4_hevcf_p1_mux.hw
1621		},
1622		.num_parents = 1,
1623		.flags = CLK_SET_RATE_PARENT,
1624	},
1625};
1626
1627static struct clk_regmap s4_hevcf_p1 = {
1628	.data = &(struct clk_regmap_gate_data){
1629		.offset = CLKCTRL_VDEC4_CLK_CTRL,
1630		.bit_idx = 8,
1631	},
1632	.hw.init = &(struct clk_init_data){
1633		.name = "hevcf_p1",
1634		.ops = &clk_regmap_gate_ops,
1635		.parent_hws = (const struct clk_hw *[]) {
1636			&s4_hevcf_p1_div.hw
1637		},
1638		.num_parents = 1,
1639		.flags = CLK_SET_RATE_PARENT,
1640	},
1641};
1642
1643static const struct clk_hw *s4_hevcf_mux_parent_hws[] = {
1644	&s4_hevcf_p0.hw,
1645	&s4_hevcf_p1.hw
1646};
1647
1648static struct clk_regmap s4_hevcf_mux = {
1649	.data = &(struct clk_regmap_mux_data){
1650		.offset = CLKCTRL_VDEC4_CLK_CTRL,
1651		.mask = 0x1,
1652		.shift = 15,
1653	},
1654	.hw.init = &(struct clk_init_data) {
1655		.name = "hevcf",
1656		.ops = &clk_regmap_mux_ops,
1657		.parent_hws = s4_hevcf_mux_parent_hws,
1658		.num_parents = ARRAY_SIZE(s4_hevcf_mux_parent_hws),
1659		.flags = CLK_SET_RATE_PARENT,
1660	},
1661};
1662
1663/* VPU Clock */
1664static const struct clk_parent_data s4_vpu_parent_data[] = {
1665	{ .fw_name = "fclk_div3", },
1666	{ .fw_name = "fclk_div4", },
1667	{ .fw_name = "fclk_div5", },
1668	{ .fw_name = "fclk_div7", },
1669	{ .fw_name = "mpll1", },
1670	{ .hw = &s4_vid_pll.hw },
1671	{ .fw_name = "hifi_pll", },
1672	{ .fw_name = "gp0_pll", },
1673};
1674
1675static struct clk_regmap s4_vpu_0_sel = {
1676	.data = &(struct clk_regmap_mux_data){
1677		.offset = CLKCTRL_VPU_CLK_CTRL,
1678		.mask = 0x7,
1679		.shift = 9,
1680	},
1681	.hw.init = &(struct clk_init_data){
1682		.name = "vpu_0_sel",
1683		.ops = &clk_regmap_mux_ops,
1684		.parent_data = s4_vpu_parent_data,
1685		.num_parents = ARRAY_SIZE(s4_vpu_parent_data),
1686		.flags = 0,
1687	},
1688};
1689
1690static struct clk_regmap s4_vpu_0_div = {
1691	.data = &(struct clk_regmap_div_data){
1692		.offset = CLKCTRL_VPU_CLK_CTRL,
1693		.shift = 0,
1694		.width = 7,
1695	},
1696	.hw.init = &(struct clk_init_data){
1697		.name = "vpu_0_div",
1698		.ops = &clk_regmap_divider_ops,
1699		.parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_sel.hw },
1700		.num_parents = 1,
1701		.flags = CLK_SET_RATE_PARENT,
1702	},
1703};
1704
1705static struct clk_regmap s4_vpu_0 = {
1706	.data = &(struct clk_regmap_gate_data){
1707		.offset = CLKCTRL_VPU_CLK_CTRL,
1708		.bit_idx = 8,
1709	},
1710	.hw.init = &(struct clk_init_data) {
1711		.name = "vpu_0",
1712		.ops = &clk_regmap_gate_ops,
1713		.parent_hws = (const struct clk_hw *[]) { &s4_vpu_0_div.hw },
1714		.num_parents = 1,
1715		.flags = CLK_SET_RATE_PARENT,
1716	},
1717};
1718
1719static struct clk_regmap s4_vpu_1_sel = {
1720	.data = &(struct clk_regmap_mux_data){
1721		.offset = CLKCTRL_VPU_CLK_CTRL,
1722		.mask = 0x7,
1723		.shift = 25,
1724	},
1725	.hw.init = &(struct clk_init_data){
1726		.name = "vpu_1_sel",
1727		.ops = &clk_regmap_mux_ops,
1728		.parent_data = s4_vpu_parent_data,
1729		.num_parents = ARRAY_SIZE(s4_vpu_parent_data),
1730		.flags = 0,
1731	},
1732};
1733
1734static struct clk_regmap s4_vpu_1_div = {
1735	.data = &(struct clk_regmap_div_data){
1736		.offset = CLKCTRL_VPU_CLK_CTRL,
1737		.shift = 16,
1738		.width = 7,
1739	},
1740	.hw.init = &(struct clk_init_data){
1741		.name = "vpu_1_div",
1742		.ops = &clk_regmap_divider_ops,
1743		.parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_sel.hw },
1744		.num_parents = 1,
1745		.flags = CLK_SET_RATE_PARENT,
1746	},
1747};
1748
1749static struct clk_regmap s4_vpu_1 = {
1750	.data = &(struct clk_regmap_gate_data){
1751		.offset = CLKCTRL_VPU_CLK_CTRL,
1752		.bit_idx = 24,
1753	},
1754	.hw.init = &(struct clk_init_data) {
1755		.name = "vpu_1",
1756		.ops = &clk_regmap_gate_ops,
1757		.parent_hws = (const struct clk_hw *[]) { &s4_vpu_1_div.hw },
1758		.num_parents = 1,
1759		.flags = CLK_SET_RATE_PARENT,
1760	},
1761};
1762
1763static struct clk_regmap s4_vpu = {
1764	.data = &(struct clk_regmap_mux_data){
1765		.offset = CLKCTRL_VPU_CLK_CTRL,
1766		.mask = 1,
1767		.shift = 31,
1768	},
1769	.hw.init = &(struct clk_init_data){
1770		.name = "vpu",
1771		.ops = &clk_regmap_mux_ops,
1772		.parent_hws = (const struct clk_hw *[]) {
1773			&s4_vpu_0.hw,
1774			&s4_vpu_1.hw,
1775		},
1776		.num_parents = 2,
1777		.flags = CLK_SET_RATE_PARENT,
1778	},
1779};
1780
1781static const struct clk_parent_data vpu_clkb_tmp_parent_data[] = {
1782	{ .hw = &s4_vpu.hw },
1783	{ .fw_name = "fclk_div4", },
1784	{ .fw_name = "fclk_div5", },
1785	{ .fw_name = "fclk_div7", }
1786};
1787
1788static struct clk_regmap s4_vpu_clkb_tmp_mux = {
1789	.data = &(struct clk_regmap_mux_data){
1790		.offset = CLKCTRL_VPU_CLKB_CTRL,
1791		.mask = 0x3,
1792		.shift = 20,
1793	},
1794	.hw.init = &(struct clk_init_data) {
1795		.name = "vpu_clkb_tmp_mux",
1796		.ops = &clk_regmap_mux_ops,
1797		.parent_data = vpu_clkb_tmp_parent_data,
1798		.num_parents = ARRAY_SIZE(vpu_clkb_tmp_parent_data),
1799		.flags = CLK_SET_RATE_PARENT,
1800	},
1801};
1802
1803static struct clk_regmap s4_vpu_clkb_tmp_div = {
1804	.data = &(struct clk_regmap_div_data){
1805		.offset = CLKCTRL_VPU_CLKB_CTRL,
1806		.shift = 16,
1807		.width = 4,
1808	},
1809	.hw.init = &(struct clk_init_data) {
1810		.name = "vpu_clkb_tmp_div",
1811		.ops = &clk_regmap_divider_ops,
1812		.parent_hws = (const struct clk_hw *[]) {
1813			&s4_vpu_clkb_tmp_mux.hw
1814		},
1815		.num_parents = 1,
1816		.flags = CLK_SET_RATE_PARENT,
1817	},
1818};
1819
1820static struct clk_regmap s4_vpu_clkb_tmp = {
1821	.data = &(struct clk_regmap_gate_data){
1822		.offset = CLKCTRL_VPU_CLKB_CTRL,
1823		.bit_idx = 24,
1824	},
1825	.hw.init = &(struct clk_init_data){
1826		.name = "vpu_clkb_tmp",
1827		.ops = &clk_regmap_gate_ops,
1828		.parent_hws = (const struct clk_hw *[]) {
1829			&s4_vpu_clkb_tmp_div.hw
1830		},
1831		.num_parents = 1,
1832		.flags = CLK_SET_RATE_PARENT,
1833	},
1834};
1835
1836static struct clk_regmap s4_vpu_clkb_div = {
1837	.data = &(struct clk_regmap_div_data){
1838		.offset = CLKCTRL_VPU_CLKB_CTRL,
1839		.shift = 0,
1840		.width = 8,
1841	},
1842	.hw.init = &(struct clk_init_data) {
1843		.name = "vpu_clkb_div",
1844		.ops = &clk_regmap_divider_ops,
1845		.parent_hws = (const struct clk_hw *[]) {
1846			&s4_vpu_clkb_tmp.hw
1847		},
1848		.num_parents = 1,
1849		.flags = CLK_SET_RATE_PARENT,
1850	},
1851};
1852
1853static struct clk_regmap s4_vpu_clkb = {
1854	.data = &(struct clk_regmap_gate_data){
1855		.offset = CLKCTRL_VPU_CLKB_CTRL,
1856		.bit_idx = 8,
1857	},
1858	.hw.init = &(struct clk_init_data){
1859		.name = "vpu_clkb",
1860		.ops = &clk_regmap_gate_ops,
1861		.parent_hws = (const struct clk_hw *[]) {
1862			&s4_vpu_clkb_div.hw
1863		},
1864		.num_parents = 1,
1865		.flags = CLK_SET_RATE_PARENT,
1866	},
1867};
1868
1869static const struct clk_parent_data s4_vpu_clkc_parent_data[] = {
1870	{ .fw_name = "fclk_div4", },
1871	{ .fw_name = "fclk_div3", },
1872	{ .fw_name = "fclk_div5", },
1873	{ .fw_name = "fclk_div7", },
1874	{ .fw_name = "mpll1", },
1875	{ .hw = &s4_vid_pll.hw },
1876	{ .fw_name = "mpll2", },
1877	{ .fw_name = "gp0_pll", },
1878};
1879
1880static struct clk_regmap s4_vpu_clkc_p0_mux  = {
1881	.data = &(struct clk_regmap_mux_data){
1882		.offset = CLKCTRL_VPU_CLKC_CTRL,
1883		.mask = 0x7,
1884		.shift = 9,
1885	},
1886	.hw.init = &(struct clk_init_data) {
1887		.name = "vpu_clkc_p0_mux",
1888		.ops = &clk_regmap_mux_ops,
1889		.parent_data = s4_vpu_clkc_parent_data,
1890		.num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data),
1891		.flags = 0,
1892	},
1893};
1894
1895static struct clk_regmap s4_vpu_clkc_p0_div = {
1896	.data = &(struct clk_regmap_div_data){
1897		.offset = CLKCTRL_VPU_CLKC_CTRL,
1898		.shift = 0,
1899		.width = 7,
1900	},
1901	.hw.init = &(struct clk_init_data) {
1902		.name = "vpu_clkc_p0_div",
1903		.ops = &clk_regmap_divider_ops,
1904		.parent_hws = (const struct clk_hw *[]) {
1905			&s4_vpu_clkc_p0_mux.hw
1906		},
1907		.num_parents = 1,
1908		.flags = CLK_SET_RATE_PARENT,
1909	},
1910};
1911
1912static struct clk_regmap s4_vpu_clkc_p0 = {
1913	.data = &(struct clk_regmap_gate_data){
1914		.offset = CLKCTRL_VPU_CLKC_CTRL,
1915		.bit_idx = 8,
1916	},
1917	.hw.init = &(struct clk_init_data){
1918		.name = "vpu_clkc_p0",
1919		.ops = &clk_regmap_gate_ops,
1920		.parent_hws = (const struct clk_hw *[]) {
1921			&s4_vpu_clkc_p0_div.hw
1922		},
1923		.num_parents = 1,
1924		.flags = CLK_SET_RATE_PARENT,
1925	},
1926};
1927
1928static struct clk_regmap s4_vpu_clkc_p1_mux = {
1929	.data = &(struct clk_regmap_mux_data){
1930		.offset = CLKCTRL_VPU_CLKC_CTRL,
1931		.mask = 0x7,
1932		.shift = 25,
1933	},
1934	.hw.init = &(struct clk_init_data) {
1935		.name = "vpu_clkc_p1_mux",
1936		.ops = &clk_regmap_mux_ops,
1937		.parent_data = s4_vpu_clkc_parent_data,
1938		.num_parents = ARRAY_SIZE(s4_vpu_clkc_parent_data),
1939		.flags = 0,
1940	},
1941};
1942
1943static struct clk_regmap s4_vpu_clkc_p1_div = {
1944	.data = &(struct clk_regmap_div_data){
1945		.offset = CLKCTRL_VPU_CLKC_CTRL,
1946		.shift = 16,
1947		.width = 7,
1948	},
1949	.hw.init = &(struct clk_init_data) {
1950		.name = "vpu_clkc_p1_div",
1951		.ops = &clk_regmap_divider_ops,
1952		.parent_hws = (const struct clk_hw *[]) {
1953			&s4_vpu_clkc_p1_mux.hw
1954		},
1955		.num_parents = 1,
1956		.flags = CLK_SET_RATE_PARENT,
1957	},
1958};
1959
1960static struct clk_regmap s4_vpu_clkc_p1 = {
1961	.data = &(struct clk_regmap_gate_data){
1962		.offset = CLKCTRL_VPU_CLKC_CTRL,
1963		.bit_idx = 24,
1964	},
1965	.hw.init = &(struct clk_init_data){
1966		.name = "vpu_clkc_p1",
1967		.ops = &clk_regmap_gate_ops,
1968		.parent_hws = (const struct clk_hw *[]) {
1969			&s4_vpu_clkc_p1_div.hw
1970		},
1971		.num_parents = 1,
1972		.flags = CLK_SET_RATE_PARENT,
1973	},
1974};
1975
1976static const struct clk_hw *s4_vpu_mux_parent_hws[] = {
1977	&s4_vpu_clkc_p0.hw,
1978	&s4_vpu_clkc_p1.hw
1979};
1980
1981static struct clk_regmap s4_vpu_clkc_mux = {
1982	.data = &(struct clk_regmap_mux_data){
1983		.offset = CLKCTRL_VPU_CLKC_CTRL,
1984		.mask = 0x1,
1985		.shift = 31,
1986	},
1987	.hw.init = &(struct clk_init_data) {
1988		.name = "vpu_clkc_mux",
1989		.ops = &clk_regmap_mux_ops,
1990		.parent_hws = s4_vpu_mux_parent_hws,
1991		.num_parents = ARRAY_SIZE(s4_vpu_mux_parent_hws),
1992		.flags = CLK_SET_RATE_PARENT,
1993	},
1994};
1995
1996/* VAPB Clock */
1997static const struct clk_parent_data s4_vapb_parent_data[] = {
1998	{ .fw_name = "fclk_div4", },
1999	{ .fw_name = "fclk_div3", },
2000	{ .fw_name = "fclk_div5", },
2001	{ .fw_name = "fclk_div7", },
2002	{ .fw_name = "mpll1", },
2003	{ .hw = &s4_vid_pll.hw },
2004	{ .fw_name = "mpll2", },
2005	{ .fw_name = "fclk_div2p5", },
2006};
2007
2008static struct clk_regmap s4_vapb_0_sel = {
2009	.data = &(struct clk_regmap_mux_data){
2010		.offset = CLKCTRL_VAPBCLK_CTRL,
2011		.mask = 0x7,
2012		.shift = 9,
2013	},
2014	.hw.init = &(struct clk_init_data){
2015		.name = "vapb_0_sel",
2016		.ops = &clk_regmap_mux_ops,
2017		.parent_data = s4_vapb_parent_data,
2018		.num_parents = ARRAY_SIZE(s4_vapb_parent_data),
2019		.flags = 0,
2020	},
2021};
2022
2023static struct clk_regmap s4_vapb_0_div = {
2024	.data = &(struct clk_regmap_div_data){
2025		.offset = CLKCTRL_VAPBCLK_CTRL,
2026		.shift = 0,
2027		.width = 7,
2028	},
2029	.hw.init = &(struct clk_init_data){
2030		.name = "vapb_0_div",
2031		.ops = &clk_regmap_divider_ops,
2032		.parent_hws = (const struct clk_hw *[]) {
2033			&s4_vapb_0_sel.hw
2034		},
2035		.num_parents = 1,
2036		.flags = CLK_SET_RATE_PARENT,
2037	},
2038};
2039
2040static struct clk_regmap s4_vapb_0 = {
2041	.data = &(struct clk_regmap_gate_data){
2042		.offset = CLKCTRL_VAPBCLK_CTRL,
2043		.bit_idx = 8,
2044	},
2045	.hw.init = &(struct clk_init_data) {
2046		.name = "vapb_0",
2047		.ops = &clk_regmap_gate_ops,
2048		.parent_hws = (const struct clk_hw *[]) {
2049			&s4_vapb_0_div.hw
2050		},
2051		.num_parents = 1,
2052		.flags = CLK_SET_RATE_PARENT,
2053	},
2054};
2055
2056static struct clk_regmap s4_vapb_1_sel = {
2057	.data = &(struct clk_regmap_mux_data){
2058		.offset = CLKCTRL_VAPBCLK_CTRL,
2059		.mask = 0x7,
2060		.shift = 25,
2061	},
2062	.hw.init = &(struct clk_init_data){
2063		.name = "vapb_1_sel",
2064		.ops = &clk_regmap_mux_ops,
2065		.parent_data = s4_vapb_parent_data,
2066		.num_parents = ARRAY_SIZE(s4_vapb_parent_data),
2067		.flags = 0,
2068	},
2069};
2070
2071static struct clk_regmap s4_vapb_1_div = {
2072	.data = &(struct clk_regmap_div_data){
2073		.offset = CLKCTRL_VAPBCLK_CTRL,
2074		.shift = 16,
2075		.width = 7,
2076	},
2077	.hw.init = &(struct clk_init_data){
2078		.name = "vapb_1_div",
2079		.ops = &clk_regmap_divider_ops,
2080		.parent_hws = (const struct clk_hw *[]) {
2081			&s4_vapb_1_sel.hw
2082		},
2083		.num_parents = 1,
2084		.flags = CLK_SET_RATE_PARENT,
2085	},
2086};
2087
2088static struct clk_regmap s4_vapb_1 = {
2089	.data = &(struct clk_regmap_gate_data){
2090		.offset = CLKCTRL_VAPBCLK_CTRL,
2091		.bit_idx = 24,
2092	},
2093	.hw.init = &(struct clk_init_data) {
2094		.name = "vapb_1",
2095		.ops = &clk_regmap_gate_ops,
2096		.parent_hws = (const struct clk_hw *[]) {
2097			&s4_vapb_1_div.hw
2098		},
2099		.num_parents = 1,
2100		.flags = CLK_SET_RATE_PARENT,
2101	},
2102};
2103
2104static struct clk_regmap s4_vapb = {
2105	.data = &(struct clk_regmap_mux_data){
2106		.offset = CLKCTRL_VAPBCLK_CTRL,
2107		.mask = 1,
2108		.shift = 31,
2109	},
2110	.hw.init = &(struct clk_init_data){
2111		.name = "vapb_sel",
2112		.ops = &clk_regmap_mux_ops,
2113		.parent_hws = (const struct clk_hw *[]) {
2114			&s4_vapb_0.hw,
2115			&s4_vapb_1.hw
2116		},
2117		.num_parents = 2,
2118		.flags = CLK_SET_RATE_PARENT,
2119	},
2120};
2121
2122static struct clk_regmap s4_ge2d_gate = {
2123	.data = &(struct clk_regmap_gate_data){
2124		.offset = CLKCTRL_VAPBCLK_CTRL,
2125		.bit_idx = 30,
2126	},
2127	.hw.init = &(struct clk_init_data) {
2128		.name = "ge2d_clk",
2129		.ops = &clk_regmap_gate_ops,
2130		.parent_hws = (const struct clk_hw *[]) { &s4_vapb.hw },
2131		.num_parents = 1,
2132		.flags = CLK_SET_RATE_PARENT,
2133	},
2134};
2135
2136static const struct clk_parent_data s4_esmclk_parent_data[] = {
2137	{ .fw_name = "fclk_div7", },
2138	{ .fw_name = "fclk_div4", },
2139	{ .fw_name = "fclk_div3", },
2140	{ .fw_name = "fclk_div5", },
2141};
2142
2143static struct clk_regmap s4_hdcp22_esmclk_mux = {
2144	.data = &(struct clk_regmap_mux_data){
2145		.offset = CLKCTRL_HDCP22_CTRL,
2146		.mask = 0x3,
2147		.shift = 9,
2148	},
2149	.hw.init = &(struct clk_init_data) {
2150		.name = "hdcp22_esmclk_mux",
2151		.ops = &clk_regmap_mux_ops,
2152		.parent_data = s4_esmclk_parent_data,
2153		.num_parents = ARRAY_SIZE(s4_esmclk_parent_data),
2154		.flags = CLK_SET_RATE_PARENT,
2155	},
2156};
2157
2158static struct clk_regmap s4_hdcp22_esmclk_div = {
2159	.data = &(struct clk_regmap_div_data){
2160		.offset = CLKCTRL_HDCP22_CTRL,
2161		.shift = 0,
2162		.width = 7,
2163	},
2164	.hw.init = &(struct clk_init_data) {
2165		.name = "hdcp22_esmclk_div",
2166		.ops = &clk_regmap_divider_ops,
2167		.parent_hws = (const struct clk_hw *[]) {
2168			&s4_hdcp22_esmclk_mux.hw
2169		},
2170		.num_parents = 1,
2171		.flags = CLK_SET_RATE_PARENT,
2172	},
2173};
2174
2175static struct clk_regmap s4_hdcp22_esmclk_gate = {
2176	.data = &(struct clk_regmap_gate_data){
2177		.offset = CLKCTRL_HDCP22_CTRL,
2178		.bit_idx = 8,
2179	},
2180	.hw.init = &(struct clk_init_data){
2181		.name = "hdcp22_esmclk_gate",
2182		.ops = &clk_regmap_gate_ops,
2183		.parent_hws = (const struct clk_hw *[]) {
2184			&s4_hdcp22_esmclk_div.hw
2185		},
2186		.num_parents = 1,
2187		.flags = CLK_SET_RATE_PARENT,
2188	},
2189};
2190
2191static const struct clk_parent_data s4_skpclk_parent_data[] = {
2192	{ .fw_name = "xtal", },
2193	{ .fw_name = "fclk_div4", },
2194	{ .fw_name = "fclk_div3", },
2195	{ .fw_name = "fclk_div5", },
2196};
2197
2198static struct clk_regmap s4_hdcp22_skpclk_mux = {
2199	.data = &(struct clk_regmap_mux_data){
2200		.offset = CLKCTRL_HDCP22_CTRL,
2201		.mask = 0x3,
2202		.shift = 25,
2203	},
2204	.hw.init = &(struct clk_init_data) {
2205		.name = "hdcp22_skpclk_mux",
2206		.ops = &clk_regmap_mux_ops,
2207		.parent_data = s4_skpclk_parent_data,
2208		.num_parents = ARRAY_SIZE(s4_skpclk_parent_data),
2209		.flags = CLK_SET_RATE_PARENT,
2210	},
2211};
2212
2213static struct clk_regmap s4_hdcp22_skpclk_div = {
2214	.data = &(struct clk_regmap_div_data){
2215		.offset = CLKCTRL_HDCP22_CTRL,
2216		.shift = 16,
2217		.width = 7,
2218	},
2219	.hw.init = &(struct clk_init_data) {
2220		.name = "hdcp22_skpclk_div",
2221		.ops = &clk_regmap_divider_ops,
2222		.parent_hws = (const struct clk_hw *[]) {
2223			&s4_hdcp22_skpclk_mux.hw
2224		},
2225		.num_parents = 1,
2226		.flags = CLK_SET_RATE_PARENT,
2227	},
2228};
2229
2230static struct clk_regmap s4_hdcp22_skpclk_gate = {
2231	.data = &(struct clk_regmap_gate_data){
2232		.offset = CLKCTRL_HDCP22_CTRL,
2233		.bit_idx = 24,
2234	},
2235	.hw.init = &(struct clk_init_data){
2236		.name = "hdcp22_skpclk_gate",
2237		.ops = &clk_regmap_gate_ops,
2238		.parent_hws = (const struct clk_hw *[]) {
2239			&s4_hdcp22_skpclk_div.hw
2240		},
2241		.num_parents = 1,
2242		.flags = CLK_SET_RATE_PARENT,
2243	},
2244};
2245
2246static const struct clk_parent_data s4_vdin_parent_data[]  = {
2247	{ .fw_name = "xtal", },
2248	{ .fw_name = "fclk_div4", },
2249	{ .fw_name = "fclk_div3", },
2250	{ .fw_name = "fclk_div5", },
2251	{ .hw = &s4_vid_pll.hw }
2252};
2253
2254static struct clk_regmap s4_vdin_meas_mux = {
2255	.data = &(struct clk_regmap_mux_data){
2256		.offset = CLKCTRL_VDIN_MEAS_CLK_CTRL,
2257		.mask = 0x7,
2258		.shift = 9,
2259	},
2260	.hw.init = &(struct clk_init_data) {
2261		.name = "vdin_meas_mux",
2262		.ops = &clk_regmap_mux_ops,
2263		.parent_data = s4_vdin_parent_data,
2264		.num_parents = ARRAY_SIZE(s4_vdin_parent_data),
2265		.flags = CLK_SET_RATE_PARENT,
2266	},
2267};
2268
2269static struct clk_regmap s4_vdin_meas_div = {
2270	.data = &(struct clk_regmap_div_data){
2271		.offset = CLKCTRL_VDIN_MEAS_CLK_CTRL,
2272		.shift = 0,
2273		.width = 7,
2274	},
2275	.hw.init = &(struct clk_init_data) {
2276		.name = "vdin_meas_div",
2277		.ops = &clk_regmap_divider_ops,
2278		.parent_hws = (const struct clk_hw *[]) {
2279			&s4_vdin_meas_mux.hw
2280		},
2281		.num_parents = 1,
2282		.flags = CLK_SET_RATE_PARENT,
2283	},
2284};
2285
2286static struct clk_regmap s4_vdin_meas_gate = {
2287	.data = &(struct clk_regmap_gate_data){
2288		.offset = CLKCTRL_VDIN_MEAS_CLK_CTRL,
2289		.bit_idx = 8,
2290	},
2291	.hw.init = &(struct clk_init_data){
2292		.name = "vdin_meas_gate",
2293		.ops = &clk_regmap_gate_ops,
2294		.parent_hws = (const struct clk_hw *[]) {
2295			&s4_vdin_meas_div.hw
2296		},
2297		.num_parents = 1,
2298		.flags = CLK_SET_RATE_PARENT,
2299	},
2300};
2301
2302/* EMMC/NAND clock */
2303static const struct clk_parent_data s4_sd_emmc_clk0_parent_data[] = {
2304	{ .fw_name = "xtal", },
2305	{ .fw_name = "fclk_div2", },
2306	{ .fw_name = "fclk_div3", },
2307	{ .fw_name = "hifi_pll", },
2308	{ .fw_name = "fclk_div2p5", },
2309	{ .fw_name = "mpll2", },
2310	{ .fw_name = "mpll3", },
2311	{ .fw_name = "gp0_pll", },
2312};
2313
2314static struct clk_regmap s4_sd_emmc_c_clk0_sel = {
2315	.data = &(struct clk_regmap_mux_data){
2316		.offset = CLKCTRL_NAND_CLK_CTRL,
2317		.mask = 0x7,
2318		.shift = 9,
2319	},
2320	.hw.init = &(struct clk_init_data) {
2321		.name = "sd_emmc_c_clk0_sel",
2322		.ops = &clk_regmap_mux_ops,
2323		.parent_data = s4_sd_emmc_clk0_parent_data,
2324		.num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data),
2325		.flags = 0,
2326	},
2327};
2328
2329static struct clk_regmap s4_sd_emmc_c_clk0_div = {
2330	.data = &(struct clk_regmap_div_data){
2331		.offset = CLKCTRL_NAND_CLK_CTRL,
2332		.shift = 0,
2333		.width = 7,
2334	},
2335	.hw.init = &(struct clk_init_data) {
2336		.name = "sd_emmc_c_clk0_div",
2337		.ops = &clk_regmap_divider_ops,
2338		.parent_hws = (const struct clk_hw *[]) {
2339			&s4_sd_emmc_c_clk0_sel.hw
2340		},
2341		.num_parents = 1,
2342		.flags = CLK_SET_RATE_PARENT,
2343	},
2344};
2345
2346static struct clk_regmap s4_sd_emmc_c_clk0 = {
2347	.data = &(struct clk_regmap_gate_data){
2348		.offset = CLKCTRL_NAND_CLK_CTRL,
2349		.bit_idx = 7,
2350	},
2351	.hw.init = &(struct clk_init_data){
2352		.name = "sd_emmc_c_clk0",
2353		.ops = &clk_regmap_gate_ops,
2354		.parent_hws = (const struct clk_hw *[]) {
2355			&s4_sd_emmc_c_clk0_div.hw
2356		},
2357		.num_parents = 1,
2358		.flags = CLK_SET_RATE_PARENT,
2359	},
2360};
2361
2362static struct clk_regmap s4_sd_emmc_a_clk0_sel = {
2363	.data = &(struct clk_regmap_mux_data){
2364		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2365		.mask = 0x7,
2366		.shift = 9,
2367	},
2368	.hw.init = &(struct clk_init_data) {
2369		.name = "sd_emmc_a_clk0_sel",
2370		.ops = &clk_regmap_mux_ops,
2371		.parent_data = s4_sd_emmc_clk0_parent_data,
2372		.num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data),
2373		.flags = 0,
2374	},
2375};
2376
2377static struct clk_regmap s4_sd_emmc_a_clk0_div = {
2378	.data = &(struct clk_regmap_div_data){
2379		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2380		.shift = 0,
2381		.width = 7,
2382	},
2383	.hw.init = &(struct clk_init_data) {
2384		.name = "sd_emmc_a_clk0_div",
2385		.ops = &clk_regmap_divider_ops,
2386		.parent_hws = (const struct clk_hw *[]) {
2387			&s4_sd_emmc_a_clk0_sel.hw
2388		},
2389		.num_parents = 1,
2390		.flags = CLK_SET_RATE_PARENT,
2391	},
2392};
2393
2394static struct clk_regmap s4_sd_emmc_a_clk0 = {
2395	.data = &(struct clk_regmap_gate_data){
2396		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2397		.bit_idx = 7,
2398	},
2399	.hw.init = &(struct clk_init_data){
2400		.name = "sd_emmc_a_clk0",
2401		.ops = &clk_regmap_gate_ops,
2402		.parent_hws = (const struct clk_hw *[]) {
2403			&s4_sd_emmc_a_clk0_div.hw
2404		},
2405		.num_parents = 1,
2406		.flags = CLK_SET_RATE_PARENT,
2407	},
2408};
2409
2410static struct clk_regmap s4_sd_emmc_b_clk0_sel = {
2411	.data = &(struct clk_regmap_mux_data){
2412		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2413		.mask = 0x7,
2414		.shift = 25,
2415	},
2416	.hw.init = &(struct clk_init_data) {
2417		.name = "sd_emmc_b_clk0_sel",
2418		.ops = &clk_regmap_mux_ops,
2419		.parent_data = s4_sd_emmc_clk0_parent_data,
2420		.num_parents = ARRAY_SIZE(s4_sd_emmc_clk0_parent_data),
2421		.flags = 0,
2422	},
2423};
2424
2425static struct clk_regmap s4_sd_emmc_b_clk0_div = {
2426	.data = &(struct clk_regmap_div_data){
2427		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2428		.shift = 16,
2429		.width = 7,
2430	},
2431	.hw.init = &(struct clk_init_data) {
2432		.name = "sd_emmc_b_clk0_div",
2433		.ops = &clk_regmap_divider_ops,
2434		.parent_hws = (const struct clk_hw *[]) {
2435			&s4_sd_emmc_b_clk0_sel.hw
2436		},
2437		.num_parents = 1,
2438		.flags = CLK_SET_RATE_PARENT,
2439	},
2440};
2441
2442static struct clk_regmap s4_sd_emmc_b_clk0 = {
2443	.data = &(struct clk_regmap_gate_data){
2444		.offset = CLKCTRL_SD_EMMC_CLK_CTRL,
2445		.bit_idx = 23,
2446	},
2447	.hw.init = &(struct clk_init_data){
2448		.name = "sd_emmc_b_clk0",
2449		.ops = &clk_regmap_gate_ops,
2450		.parent_hws = (const struct clk_hw *[]) {
2451			&s4_sd_emmc_b_clk0_div.hw
2452		},
2453		.num_parents = 1,
2454		.flags = CLK_SET_RATE_PARENT,
2455	},
2456};
2457
2458/* SPICC Clock */
2459static const struct clk_parent_data s4_spicc_parent_data[] = {
2460	{ .fw_name = "xtal", },
2461	{ .hw = &s4_sys_clk.hw },
2462	{ .fw_name = "fclk_div4", },
2463	{ .fw_name = "fclk_div3", },
2464	{ .fw_name = "fclk_div2", },
2465	{ .fw_name = "fclk_div5", },
2466	{ .fw_name = "fclk_div7", },
2467};
2468
2469static struct clk_regmap s4_spicc0_mux = {
2470	.data = &(struct clk_regmap_mux_data){
2471		.offset = CLKCTRL_SPICC_CLK_CTRL,
2472		.mask = 0x7,
2473		.shift = 7,
2474	},
2475	.hw.init = &(struct clk_init_data) {
2476		.name = "spicc0_mux",
2477		.ops = &clk_regmap_mux_ops,
2478		.parent_data = s4_spicc_parent_data,
2479		.num_parents = ARRAY_SIZE(s4_spicc_parent_data),
2480		.flags = CLK_SET_RATE_PARENT,
2481	},
2482};
2483
2484static struct clk_regmap s4_spicc0_div = {
2485	.data = &(struct clk_regmap_div_data){
2486		.offset = CLKCTRL_SPICC_CLK_CTRL,
2487		.shift = 0,
2488		.width = 6,
2489	},
2490	.hw.init = &(struct clk_init_data) {
2491		.name = "spicc0_div",
2492		.ops = &clk_regmap_divider_ops,
2493		.parent_hws = (const struct clk_hw *[]) {
2494			&s4_spicc0_mux.hw
2495		},
2496		.num_parents = 1,
2497		.flags = CLK_SET_RATE_PARENT,
2498	},
2499};
2500
2501static struct clk_regmap s4_spicc0_gate = {
2502	.data = &(struct clk_regmap_gate_data){
2503		.offset = CLKCTRL_SPICC_CLK_CTRL,
2504		.bit_idx = 6,
2505	},
2506	.hw.init = &(struct clk_init_data){
2507		.name = "spicc0",
2508		.ops = &clk_regmap_gate_ops,
2509		.parent_hws = (const struct clk_hw *[]) {
2510			&s4_spicc0_div.hw
2511		},
2512		.num_parents = 1,
2513		.flags = CLK_SET_RATE_PARENT,
2514	},
2515};
2516
2517/* PWM Clock */
2518static const struct clk_parent_data s4_pwm_parent_data[] = {
2519	{ .fw_name = "xtal", },
2520	{ .hw = &s4_vid_pll.hw },
2521	{ .fw_name = "fclk_div4", },
2522	{ .fw_name = "fclk_div3", },
2523};
2524
2525static struct clk_regmap s4_pwm_a_mux = {
2526	.data = &(struct clk_regmap_mux_data) {
2527		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2528		.mask = 0x3,
2529		.shift = 9,
2530	},
2531	.hw.init = &(struct clk_init_data){
2532		.name = "pwm_a_mux",
2533		.ops = &clk_regmap_mux_ops,
2534		.parent_data = s4_pwm_parent_data,
2535		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2536		.flags = 0,
2537	},
2538};
2539
2540static struct clk_regmap s4_pwm_a_div = {
2541	.data = &(struct clk_regmap_div_data) {
2542		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2543		.shift = 0,
2544		.width = 8,
2545	},
2546	.hw.init = &(struct clk_init_data){
2547		.name = "pwm_a_div",
2548		.ops = &clk_regmap_divider_ops,
2549		.parent_hws = (const struct clk_hw *[]) {
2550			&s4_pwm_a_mux.hw
2551		},
2552		.num_parents = 1,
2553		.flags = CLK_SET_RATE_PARENT,
2554	},
2555};
2556
2557static struct clk_regmap s4_pwm_a_gate = {
2558	.data = &(struct clk_regmap_gate_data) {
2559		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2560		.bit_idx = 8,
2561	},
2562	.hw.init = &(struct clk_init_data){
2563		.name = "pwm_a_gate",
2564		.ops = &clk_regmap_gate_ops,
2565		.parent_hws = (const struct clk_hw *[]) {
2566			&s4_pwm_a_div.hw
2567		},
2568		.num_parents = 1,
2569		.flags = CLK_SET_RATE_PARENT,
2570	},
2571};
2572
2573static struct clk_regmap s4_pwm_b_mux = {
2574	.data = &(struct clk_regmap_mux_data) {
2575		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2576		.mask = 0x3,
2577		.shift = 25,
2578	},
2579	.hw.init = &(struct clk_init_data){
2580		.name = "pwm_b_mux",
2581		.ops = &clk_regmap_mux_ops,
2582		.parent_data = s4_pwm_parent_data,
2583		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2584		.flags = 0,
2585	},
2586};
2587
2588static struct clk_regmap s4_pwm_b_div = {
2589	.data = &(struct clk_regmap_div_data) {
2590		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2591		.shift = 16,
2592		.width = 8,
2593	},
2594	.hw.init = &(struct clk_init_data){
2595		.name = "pwm_b_div",
2596		.ops = &clk_regmap_divider_ops,
2597		.parent_hws = (const struct clk_hw *[]) {
2598			&s4_pwm_b_mux.hw
2599		},
2600		.num_parents = 1,
2601		.flags = CLK_SET_RATE_PARENT,
2602	},
2603};
2604
2605static struct clk_regmap s4_pwm_b_gate = {
2606	.data = &(struct clk_regmap_gate_data) {
2607		.offset = CLKCTRL_PWM_CLK_AB_CTRL,
2608		.bit_idx = 24,
2609	},
2610	.hw.init = &(struct clk_init_data){
2611		.name = "pwm_b_gate",
2612		.ops = &clk_regmap_gate_ops,
2613		.parent_hws = (const struct clk_hw *[]) {
2614			&s4_pwm_b_div.hw
2615		},
2616		.num_parents = 1,
2617		.flags = CLK_SET_RATE_PARENT,
2618	},
2619};
2620
2621static struct clk_regmap s4_pwm_c_mux = {
2622	.data = &(struct clk_regmap_mux_data) {
2623		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2624		.mask = 0x3,
2625		.shift = 9,
2626	},
2627	.hw.init = &(struct clk_init_data){
2628		.name = "pwm_c_mux",
2629		.ops = &clk_regmap_mux_ops,
2630		.parent_data = s4_pwm_parent_data,
2631		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2632		.flags = 0,
2633	},
2634};
2635
2636static struct clk_regmap s4_pwm_c_div = {
2637	.data = &(struct clk_regmap_div_data) {
2638		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2639		.shift = 0,
2640		.width = 8,
2641	},
2642	.hw.init = &(struct clk_init_data){
2643		.name = "pwm_c_div",
2644		.ops = &clk_regmap_divider_ops,
2645		.parent_hws = (const struct clk_hw *[]) {
2646			&s4_pwm_c_mux.hw
2647		},
2648		.num_parents = 1,
2649	},
2650};
2651
2652static struct clk_regmap s4_pwm_c_gate = {
2653	.data = &(struct clk_regmap_gate_data) {
2654		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2655		.bit_idx = 8,
2656	},
2657	.hw.init = &(struct clk_init_data){
2658		.name = "pwm_c_gate",
2659		.ops = &clk_regmap_gate_ops,
2660		.parent_hws = (const struct clk_hw *[]) {
2661			&s4_pwm_c_div.hw
2662		},
2663		.num_parents = 1,
2664		.flags = CLK_SET_RATE_PARENT,
2665	},
2666};
2667
2668static struct clk_regmap s4_pwm_d_mux = {
2669	.data = &(struct clk_regmap_mux_data) {
2670		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2671		.mask = 0x3,
2672		.shift = 25,
2673	},
2674	.hw.init = &(struct clk_init_data){
2675		.name = "pwm_d_mux",
2676		.ops = &clk_regmap_mux_ops,
2677		.parent_data = s4_pwm_parent_data,
2678		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2679		.flags = 0,
2680	},
2681};
2682
2683static struct clk_regmap s4_pwm_d_div = {
2684	.data = &(struct clk_regmap_div_data) {
2685		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2686		.shift = 16,
2687		.width = 8,
2688	},
2689	.hw.init = &(struct clk_init_data){
2690		.name = "pwm_d_div",
2691		.ops = &clk_regmap_divider_ops,
2692		.parent_hws = (const struct clk_hw *[]) {
2693			&s4_pwm_d_mux.hw
2694		},
2695		.num_parents = 1,
2696		.flags = CLK_SET_RATE_PARENT,
2697	},
2698};
2699
2700static struct clk_regmap s4_pwm_d_gate = {
2701	.data = &(struct clk_regmap_gate_data) {
2702		.offset = CLKCTRL_PWM_CLK_CD_CTRL,
2703		.bit_idx = 24,
2704	},
2705	.hw.init = &(struct clk_init_data){
2706		.name = "pwm_d_gate",
2707		.ops = &clk_regmap_gate_ops,
2708		.parent_hws = (const struct clk_hw *[]) {
2709			&s4_pwm_d_div.hw
2710		},
2711		.num_parents = 1,
2712		.flags = CLK_SET_RATE_PARENT,
2713	},
2714};
2715
2716static struct clk_regmap s4_pwm_e_mux = {
2717	.data = &(struct clk_regmap_mux_data) {
2718		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2719		.mask = 0x3,
2720		.shift = 9,
2721	},
2722	.hw.init = &(struct clk_init_data){
2723		.name = "pwm_e_mux",
2724		.ops = &clk_regmap_mux_ops,
2725		.parent_data = s4_pwm_parent_data,
2726		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2727		.flags = 0,
2728	},
2729};
2730
2731static struct clk_regmap s4_pwm_e_div = {
2732	.data = &(struct clk_regmap_div_data) {
2733		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2734		.shift = 0,
2735		.width = 8,
2736	},
2737	.hw.init = &(struct clk_init_data){
2738		.name = "pwm_e_div",
2739		.ops = &clk_regmap_divider_ops,
2740		.parent_hws = (const struct clk_hw *[]) {
2741			&s4_pwm_e_mux.hw
2742		},
2743		.num_parents = 1,
2744		.flags = CLK_SET_RATE_PARENT,
2745	},
2746};
2747
2748static struct clk_regmap s4_pwm_e_gate = {
2749	.data = &(struct clk_regmap_gate_data) {
2750		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2751		.bit_idx = 8,
2752	},
2753	.hw.init = &(struct clk_init_data){
2754		.name = "pwm_e_gate",
2755		.ops = &clk_regmap_gate_ops,
2756		.parent_hws = (const struct clk_hw *[]) {
2757			&s4_pwm_e_div.hw
2758		},
2759		.num_parents = 1,
2760		.flags = CLK_SET_RATE_PARENT,
2761	},
2762};
2763
2764static struct clk_regmap s4_pwm_f_mux = {
2765	.data = &(struct clk_regmap_mux_data) {
2766		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2767		.mask = 0x3,
2768		.shift = 25,
2769	},
2770	.hw.init = &(struct clk_init_data){
2771		.name = "pwm_f_mux",
2772		.ops = &clk_regmap_mux_ops,
2773		.parent_data = s4_pwm_parent_data,
2774		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2775		.flags = 0,
2776	},
2777};
2778
2779static struct clk_regmap s4_pwm_f_div = {
2780	.data = &(struct clk_regmap_div_data) {
2781		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2782		.shift = 16,
2783		.width = 8,
2784	},
2785	.hw.init = &(struct clk_init_data){
2786		.name = "pwm_f_div",
2787		.ops = &clk_regmap_divider_ops,
2788		.parent_hws = (const struct clk_hw *[]) {
2789			&s4_pwm_f_mux.hw
2790		},
2791		.num_parents = 1,
2792		.flags = CLK_SET_RATE_PARENT,
2793	},
2794};
2795
2796static struct clk_regmap s4_pwm_f_gate = {
2797	.data = &(struct clk_regmap_gate_data) {
2798		.offset = CLKCTRL_PWM_CLK_EF_CTRL,
2799		.bit_idx = 24,
2800	},
2801	.hw.init = &(struct clk_init_data){
2802		.name = "pwm_f_gate",
2803		.ops = &clk_regmap_gate_ops,
2804		.parent_hws = (const struct clk_hw *[]) {
2805			&s4_pwm_f_div.hw
2806		},
2807		.num_parents = 1,
2808		.flags = CLK_SET_RATE_PARENT,
2809	},
2810};
2811
2812static struct clk_regmap s4_pwm_g_mux = {
2813	.data = &(struct clk_regmap_mux_data) {
2814		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2815		.mask = 0x3,
2816		.shift = 9,
2817	},
2818	.hw.init = &(struct clk_init_data){
2819		.name = "pwm_g_mux",
2820		.ops = &clk_regmap_mux_ops,
2821		.parent_data = s4_pwm_parent_data,
2822		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2823		.flags = 0,
2824	},
2825};
2826
2827static struct clk_regmap s4_pwm_g_div = {
2828	.data = &(struct clk_regmap_div_data) {
2829		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2830		.shift = 0,
2831		.width = 8,
2832	},
2833	.hw.init = &(struct clk_init_data){
2834		.name = "pwm_g_div",
2835		.ops = &clk_regmap_divider_ops,
2836		.parent_hws = (const struct clk_hw *[]) {
2837			&s4_pwm_g_mux.hw
2838		},
2839		.num_parents = 1,
2840		.flags = CLK_SET_RATE_PARENT,
2841	},
2842};
2843
2844static struct clk_regmap s4_pwm_g_gate = {
2845	.data = &(struct clk_regmap_gate_data) {
2846		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2847		.bit_idx = 8,
2848	},
2849	.hw.init = &(struct clk_init_data){
2850		.name = "pwm_g_gate",
2851		.ops = &clk_regmap_gate_ops,
2852		.parent_hws = (const struct clk_hw *[]) {
2853			&s4_pwm_g_div.hw
2854		},
2855		.num_parents = 1,
2856		.flags = CLK_SET_RATE_PARENT,
2857	},
2858};
2859
2860static struct clk_regmap s4_pwm_h_mux = {
2861	.data = &(struct clk_regmap_mux_data) {
2862		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2863		.mask = 0x3,
2864		.shift = 25,
2865	},
2866	.hw.init = &(struct clk_init_data){
2867		.name = "pwm_h_mux",
2868		.ops = &clk_regmap_mux_ops,
2869		.parent_data = s4_pwm_parent_data,
2870		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2871		.flags = 0,
2872	},
2873};
2874
2875static struct clk_regmap s4_pwm_h_div = {
2876	.data = &(struct clk_regmap_div_data) {
2877		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2878		.shift = 16,
2879		.width = 8,
2880	},
2881	.hw.init = &(struct clk_init_data){
2882		.name = "pwm_h_div",
2883		.ops = &clk_regmap_divider_ops,
2884		.parent_hws = (const struct clk_hw *[]) {
2885			&s4_pwm_h_mux.hw
2886		},
2887		.num_parents = 1,
2888		.flags = CLK_SET_RATE_PARENT,
2889	},
2890};
2891
2892static struct clk_regmap s4_pwm_h_gate = {
2893	.data = &(struct clk_regmap_gate_data) {
2894		.offset = CLKCTRL_PWM_CLK_GH_CTRL,
2895		.bit_idx = 24,
2896	},
2897	.hw.init = &(struct clk_init_data){
2898		.name = "pwm_h_gate",
2899		.ops = &clk_regmap_gate_ops,
2900		.parent_hws = (const struct clk_hw *[]) {
2901			&s4_pwm_h_div.hw
2902		},
2903		.num_parents = 1,
2904		.flags = CLK_SET_RATE_PARENT,
2905	},
2906};
2907
2908static struct clk_regmap s4_pwm_i_mux = {
2909	.data = &(struct clk_regmap_mux_data) {
2910		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2911		.mask = 0x3,
2912		.shift = 9,
2913	},
2914	.hw.init = &(struct clk_init_data){
2915		.name = "pwm_i_mux",
2916		.ops = &clk_regmap_mux_ops,
2917		.parent_data = s4_pwm_parent_data,
2918		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2919		.flags = 0,
2920	},
2921};
2922
2923static struct clk_regmap s4_pwm_i_div = {
2924	.data = &(struct clk_regmap_div_data) {
2925		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2926		.shift = 0,
2927		.width = 8,
2928	},
2929	.hw.init = &(struct clk_init_data){
2930		.name = "pwm_i_div",
2931		.ops = &clk_regmap_divider_ops,
2932		.parent_hws = (const struct clk_hw *[]) {
2933			&s4_pwm_i_mux.hw
2934		},
2935		.num_parents = 1,
2936		.flags = CLK_SET_RATE_PARENT,
2937	},
2938};
2939
2940static struct clk_regmap s4_pwm_i_gate = {
2941	.data = &(struct clk_regmap_gate_data) {
2942		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2943		.bit_idx = 8,
2944	},
2945	.hw.init = &(struct clk_init_data){
2946		.name = "pwm_i_gate",
2947		.ops = &clk_regmap_gate_ops,
2948		.parent_hws = (const struct clk_hw *[]) {
2949			&s4_pwm_i_div.hw
2950		},
2951		.num_parents = 1,
2952		.flags = CLK_SET_RATE_PARENT,
2953	},
2954};
2955
2956static struct clk_regmap s4_pwm_j_mux = {
2957	.data = &(struct clk_regmap_mux_data) {
2958		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2959		.mask = 0x3,
2960		.shift = 25,
2961	},
2962	.hw.init = &(struct clk_init_data){
2963		.name = "pwm_j_mux",
2964		.ops = &clk_regmap_mux_ops,
2965		.parent_data = s4_pwm_parent_data,
2966		.num_parents = ARRAY_SIZE(s4_pwm_parent_data),
2967		.flags = 0,
2968	},
2969};
2970
2971static struct clk_regmap s4_pwm_j_div = {
2972	.data = &(struct clk_regmap_div_data) {
2973		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2974		.shift = 16,
2975		.width = 8,
2976	},
2977	.hw.init = &(struct clk_init_data){
2978		.name = "pwm_j_div",
2979		.ops = &clk_regmap_divider_ops,
2980		.parent_hws = (const struct clk_hw *[]) {
2981			&s4_pwm_h_mux.hw
2982		},
2983		.num_parents = 1,
2984		.flags = CLK_SET_RATE_PARENT,
2985	},
2986};
2987
2988static struct clk_regmap s4_pwm_j_gate = {
2989	.data = &(struct clk_regmap_gate_data) {
2990		.offset = CLKCTRL_PWM_CLK_IJ_CTRL,
2991		.bit_idx = 24,
2992	},
2993	.hw.init = &(struct clk_init_data){
2994		.name = "pwm_j_gate",
2995		.ops = &clk_regmap_gate_ops,
2996		.parent_hws = (const struct clk_hw *[]) {
2997			&s4_pwm_j_div.hw
2998		},
2999		.num_parents = 1,
3000		.flags = CLK_SET_RATE_PARENT,
3001	},
3002};
3003
3004static struct clk_regmap s4_saradc_mux = {
3005	.data = &(struct clk_regmap_mux_data) {
3006		.offset = CLKCTRL_SAR_CLK_CTRL,
3007		.mask = 0x3,
3008		.shift = 9,
3009	},
3010	.hw.init = &(struct clk_init_data){
3011		.name = "saradc_mux",
3012		.ops = &clk_regmap_mux_ops,
3013		.parent_data = (const struct clk_parent_data []) {
3014			{ .fw_name = "xtal", },
3015			{ .hw = &s4_sys_clk.hw },
3016		},
3017		.num_parents = 2,
3018		.flags = CLK_SET_RATE_PARENT,
3019	},
3020};
3021
3022static struct clk_regmap s4_saradc_div = {
3023	.data = &(struct clk_regmap_div_data) {
3024		.offset = CLKCTRL_SAR_CLK_CTRL,
3025		.shift = 0,
3026		.width = 8,
3027	},
3028	.hw.init = &(struct clk_init_data){
3029		.name = "saradc_div",
3030		.ops = &clk_regmap_divider_ops,
3031		.parent_hws = (const struct clk_hw *[]) {
3032			&s4_saradc_mux.hw
3033		},
3034		.num_parents = 1,
3035		.flags = CLK_SET_RATE_PARENT,
3036	},
3037};
3038
3039static struct clk_regmap s4_saradc_gate = {
3040	.data = &(struct clk_regmap_gate_data) {
3041		.offset = CLKCTRL_SAR_CLK_CTRL,
3042		.bit_idx = 8,
3043	},
3044	.hw.init = &(struct clk_init_data){
3045		.name = "saradc_clk",
3046		.ops = &clk_regmap_gate_ops,
3047		.parent_hws = (const struct clk_hw *[]) {
3048			&s4_saradc_div.hw
3049		},
3050		.num_parents = 1,
3051		.flags = CLK_SET_RATE_PARENT,
3052	},
3053};
3054
3055/*
3056 * gen clk is designed for debug/monitor some internal clock quality. Some of the
3057 * corresponding clock sources are not described in the clock tree and internal clock
3058 * for debug, so they are skipped.
3059 */
3060static u32 s4_gen_clk_mux_table[] = { 0, 4, 5, 7, 19, 21, 22,
3061				      23, 24, 25, 26, 27, 28 };
3062static const struct clk_parent_data s4_gen_clk_parent_data[] = {
3063	{ .fw_name = "xtal", },
3064	{ .hw = &s4_vid_pll.hw },
3065	{ .fw_name = "gp0_pll", },
3066	{ .fw_name = "hifi_pll", },
3067	{ .fw_name = "fclk_div2", },
3068	{ .fw_name = "fclk_div3", },
3069	{ .fw_name = "fclk_div4", },
3070	{ .fw_name = "fclk_div5", },
3071	{ .fw_name = "fclk_div7", },
3072	{ .fw_name = "mpll0", },
3073	{ .fw_name = "mpll1", },
3074	{ .fw_name = "mpll2", },
3075	{ .fw_name = "mpll3", },
3076};
3077
3078static struct clk_regmap s4_gen_clk_sel = {
3079	.data = &(struct clk_regmap_mux_data){
3080		.offset = CLKCTRL_GEN_CLK_CTRL,
3081		.mask = 0x1f,
3082		.shift = 12,
3083		.table = s4_gen_clk_mux_table,
3084	},
3085	.hw.init = &(struct clk_init_data){
3086		.name = "gen_clk_sel",
3087		.ops = &clk_regmap_mux_ops,
3088		.parent_data = s4_gen_clk_parent_data,
3089		.num_parents = ARRAY_SIZE(s4_gen_clk_parent_data),
3090		/*
3091		 *  Because the GEN clock can be connected to an external pad
3092		 *  and may be set up directly from the device tree. Don't
3093		 *  really want to automatically reparent.
3094		 */
3095		.flags = CLK_SET_RATE_NO_REPARENT,
3096	},
3097};
3098
3099static struct clk_regmap s4_gen_clk_div = {
3100	.data = &(struct clk_regmap_div_data){
3101		.offset = CLKCTRL_GEN_CLK_CTRL,
3102		.shift = 0,
3103		.width = 11,
3104	},
3105	.hw.init = &(struct clk_init_data){
3106		.name = "gen_clk_div",
3107		.ops = &clk_regmap_divider_ops,
3108		.parent_hws = (const struct clk_hw *[]) {
3109			&s4_gen_clk_sel.hw
3110		},
3111		.num_parents = 1,
3112		.flags = CLK_SET_RATE_PARENT,
3113	},
3114};
3115
3116static struct clk_regmap s4_gen_clk = {
3117	.data = &(struct clk_regmap_gate_data){
3118		.offset = CLKCTRL_GEN_CLK_CTRL,
3119		.bit_idx = 11,
3120	},
3121	.hw.init = &(struct clk_init_data) {
3122		.name = "gen_clk",
3123		.ops = &clk_regmap_gate_ops,
3124		.parent_hws = (const struct clk_hw *[]) {
3125			&s4_gen_clk_div.hw
3126		},
3127		.num_parents = 1,
3128		.flags = CLK_SET_RATE_PARENT,
3129	},
3130};
3131
3132static const struct clk_parent_data s4_adc_extclk_in_parent_data[]  = {
3133	{ .fw_name = "xtal", },
3134	{ .fw_name = "fclk_div4", },
3135	{ .fw_name = "fclk_div3", },
3136	{ .fw_name = "fclk_div5", },
3137	{ .fw_name = "fclk_div7", },
3138	{ .fw_name = "mpll2", },
3139	{ .fw_name = "gp0_pll", },
3140	{ .fw_name = "hifi_pll", },
3141};
3142
3143static struct clk_regmap s4_adc_extclk_in_mux = {
3144	.data = &(struct clk_regmap_mux_data) {
3145		.offset = CLKCTRL_DEMOD_CLK_CTRL,
3146		.mask = 0x7,
3147		.shift = 25,
3148	},
3149	.hw.init = &(struct clk_init_data){
3150		.name = "adc_extclk_in_mux",
3151		.ops = &clk_regmap_mux_ops,
3152		.parent_data = s4_adc_extclk_in_parent_data,
3153		.num_parents = ARRAY_SIZE(s4_adc_extclk_in_parent_data),
3154		.flags = 0,
3155	},
3156};
3157
3158static struct clk_regmap s4_adc_extclk_in_div = {
3159	.data = &(struct clk_regmap_div_data) {
3160		.offset = CLKCTRL_DEMOD_CLK_CTRL,
3161		.shift = 16,
3162		.width = 7,
3163	},
3164	.hw.init = &(struct clk_init_data){
3165		.name = "adc_extclk_in_div",
3166		.ops = &clk_regmap_divider_ops,
3167		.parent_hws = (const struct clk_hw *[]) {
3168			&s4_adc_extclk_in_mux.hw
3169		},
3170		.num_parents = 1,
3171		.flags = CLK_SET_RATE_PARENT,
3172	},
3173};
3174
3175static struct clk_regmap s4_adc_extclk_in_gate = {
3176	.data = &(struct clk_regmap_gate_data) {
3177		.offset = CLKCTRL_DEMOD_CLK_CTRL,
3178		.bit_idx = 24,
3179	},
3180	.hw.init = &(struct clk_init_data){
3181		.name = "adc_extclk_in",
3182		.ops = &clk_regmap_gate_ops,
3183		.parent_hws = (const struct clk_hw *[]) {
3184			&s4_adc_extclk_in_div.hw
3185		},
3186		.num_parents = 1,
3187		.flags = CLK_SET_RATE_PARENT,
3188	},
3189};
3190
3191static struct clk_regmap s4_demod_core_clk_mux = {
3192	.data = &(struct clk_regmap_mux_data) {
3193		.offset = CLKCTRL_DEMOD_CLK_CTRL,
3194		.mask = 0x3,
3195		.shift = 9,
3196	},
3197	.hw.init = &(struct clk_init_data){
3198		.name = "demod_core_clk_mux",
3199		.ops = &clk_regmap_mux_ops,
3200		.parent_data = (const struct clk_parent_data []) {
3201			{ .fw_name = "xtal", },
3202			{ .fw_name = "fclk_div7", },
3203			{ .fw_name = "fclk_div4", },
3204			{ .hw = &s4_adc_extclk_in_gate.hw }
3205		},
3206		.num_parents = 4,
3207		.flags = CLK_SET_RATE_PARENT,
3208	},
3209};
3210
3211static struct clk_regmap s4_demod_core_clk_div = {
3212	.data = &(struct clk_regmap_div_data) {
3213		.offset = CLKCTRL_DEMOD_CLK_CTRL,
3214		.shift = 0,
3215		.width = 7,
3216	},
3217	.hw.init = &(struct clk_init_data){
3218		.name = "demod_core_clk_div",
3219		.ops = &clk_regmap_divider_ops,
3220		.parent_hws = (const struct clk_hw *[]) {
3221			&s4_demod_core_clk_mux.hw
3222		},
3223		.num_parents = 1,
3224		.flags = CLK_SET_RATE_PARENT,
3225	},
3226};
3227
3228static struct clk_regmap s4_demod_core_clk_gate = {
3229	.data = &(struct clk_regmap_gate_data) {
3230		.offset = CLKCTRL_DEMOD_CLK_CTRL,
3231		.bit_idx = 8,
3232	},
3233	.hw.init = &(struct clk_init_data){
3234		.name = "demod_core_clk",
3235		.ops = &clk_regmap_gate_ops,
3236		.parent_hws = (const struct clk_hw *[]) {
3237			&s4_demod_core_clk_div.hw
3238		},
3239		.num_parents = 1,
3240		.flags = CLK_SET_RATE_PARENT,
3241	},
3242};
3243
3244#define MESON_GATE(_name, _reg, _bit) \
3245	MESON_PCLK(_name, _reg, _bit, &s4_sys_clk.hw)
3246
3247static MESON_GATE(s4_ddr,		CLKCTRL_SYS_CLK_EN0_REG0, 0);
3248static MESON_GATE(s4_dos,		CLKCTRL_SYS_CLK_EN0_REG0, 1);
3249static MESON_GATE(s4_ethphy,		CLKCTRL_SYS_CLK_EN0_REG0, 4);
3250static MESON_GATE(s4_mali,		CLKCTRL_SYS_CLK_EN0_REG0, 6);
3251static MESON_GATE(s4_aocpu,		CLKCTRL_SYS_CLK_EN0_REG0, 13);
3252static MESON_GATE(s4_aucpu,		CLKCTRL_SYS_CLK_EN0_REG0, 14);
3253static MESON_GATE(s4_cec,		CLKCTRL_SYS_CLK_EN0_REG0, 16);
3254static MESON_GATE(s4_sdemmca,		CLKCTRL_SYS_CLK_EN0_REG0, 24);
3255static MESON_GATE(s4_sdemmcb,		CLKCTRL_SYS_CLK_EN0_REG0, 25);
3256static MESON_GATE(s4_nand,		CLKCTRL_SYS_CLK_EN0_REG0, 26);
3257static MESON_GATE(s4_smartcard,		CLKCTRL_SYS_CLK_EN0_REG0, 27);
3258static MESON_GATE(s4_acodec,		CLKCTRL_SYS_CLK_EN0_REG0, 28);
3259static MESON_GATE(s4_spifc,		CLKCTRL_SYS_CLK_EN0_REG0, 29);
3260static MESON_GATE(s4_msr_clk,		CLKCTRL_SYS_CLK_EN0_REG0, 30);
3261static MESON_GATE(s4_ir_ctrl,		CLKCTRL_SYS_CLK_EN0_REG0, 31);
3262static MESON_GATE(s4_audio,		CLKCTRL_SYS_CLK_EN0_REG1, 0);
3263static MESON_GATE(s4_eth,		CLKCTRL_SYS_CLK_EN0_REG1, 3);
3264static MESON_GATE(s4_uart_a,		CLKCTRL_SYS_CLK_EN0_REG1, 5);
3265static MESON_GATE(s4_uart_b,		CLKCTRL_SYS_CLK_EN0_REG1, 6);
3266static MESON_GATE(s4_uart_c,		CLKCTRL_SYS_CLK_EN0_REG1, 7);
3267static MESON_GATE(s4_uart_d,		CLKCTRL_SYS_CLK_EN0_REG1, 8);
3268static MESON_GATE(s4_uart_e,		CLKCTRL_SYS_CLK_EN0_REG1, 9);
3269static MESON_GATE(s4_aififo,		CLKCTRL_SYS_CLK_EN0_REG1, 11);
3270static MESON_GATE(s4_ts_ddr,		CLKCTRL_SYS_CLK_EN0_REG1, 15);
3271static MESON_GATE(s4_ts_pll,		CLKCTRL_SYS_CLK_EN0_REG1, 16);
3272static MESON_GATE(s4_g2d,		CLKCTRL_SYS_CLK_EN0_REG1, 20);
3273static MESON_GATE(s4_spicc0,		CLKCTRL_SYS_CLK_EN0_REG1, 21);
3274static MESON_GATE(s4_usb,		CLKCTRL_SYS_CLK_EN0_REG1, 26);
3275static MESON_GATE(s4_i2c_m_a,		CLKCTRL_SYS_CLK_EN0_REG1, 30);
3276static MESON_GATE(s4_i2c_m_b,		CLKCTRL_SYS_CLK_EN0_REG1, 31);
3277static MESON_GATE(s4_i2c_m_c,		CLKCTRL_SYS_CLK_EN0_REG2, 0);
3278static MESON_GATE(s4_i2c_m_d,		CLKCTRL_SYS_CLK_EN0_REG2, 1);
3279static MESON_GATE(s4_i2c_m_e,		CLKCTRL_SYS_CLK_EN0_REG2, 2);
3280static MESON_GATE(s4_hdmitx_apb,	CLKCTRL_SYS_CLK_EN0_REG2, 4);
3281static MESON_GATE(s4_i2c_s_a,		CLKCTRL_SYS_CLK_EN0_REG2, 5);
3282static MESON_GATE(s4_usb1_to_ddr,	CLKCTRL_SYS_CLK_EN0_REG2, 8);
3283static MESON_GATE(s4_hdcp22,		CLKCTRL_SYS_CLK_EN0_REG2, 10);
3284static MESON_GATE(s4_mmc_apb,		CLKCTRL_SYS_CLK_EN0_REG2, 11);
3285static MESON_GATE(s4_rsa,		CLKCTRL_SYS_CLK_EN0_REG2, 18);
3286static MESON_GATE(s4_cpu_debug,		CLKCTRL_SYS_CLK_EN0_REG2, 19);
3287static MESON_GATE(s4_vpu_intr,		CLKCTRL_SYS_CLK_EN0_REG2, 25);
3288static MESON_GATE(s4_demod,		CLKCTRL_SYS_CLK_EN0_REG2, 27);
3289static MESON_GATE(s4_sar_adc,		CLKCTRL_SYS_CLK_EN0_REG2, 28);
3290static MESON_GATE(s4_gic,		CLKCTRL_SYS_CLK_EN0_REG2, 30);
3291static MESON_GATE(s4_pwm_ab,		CLKCTRL_SYS_CLK_EN0_REG3, 7);
3292static MESON_GATE(s4_pwm_cd,		CLKCTRL_SYS_CLK_EN0_REG3, 8);
3293static MESON_GATE(s4_pwm_ef,		CLKCTRL_SYS_CLK_EN0_REG3, 9);
3294static MESON_GATE(s4_pwm_gh,		CLKCTRL_SYS_CLK_EN0_REG3, 10);
3295static MESON_GATE(s4_pwm_ij,		CLKCTRL_SYS_CLK_EN0_REG3, 11);
3296
3297/* Array of all clocks provided by this provider */
3298static struct clk_hw *s4_periphs_hw_clks[] = {
3299	[CLKID_RTC_32K_CLKIN]		= &s4_rtc_32k_by_oscin_clkin.hw,
3300	[CLKID_RTC_32K_DIV]		= &s4_rtc_32k_by_oscin_div.hw,
3301	[CLKID_RTC_32K_SEL]		= &s4_rtc_32k_by_oscin_sel.hw,
3302	[CLKID_RTC_32K_XATL]		= &s4_rtc_32k_by_oscin.hw,
3303	[CLKID_RTC]			= &s4_rtc_clk.hw,
3304	[CLKID_SYS_CLK_B_SEL]		= &s4_sysclk_b_sel.hw,
3305	[CLKID_SYS_CLK_B_DIV]		= &s4_sysclk_b_div.hw,
3306	[CLKID_SYS_CLK_B]		= &s4_sysclk_b.hw,
3307	[CLKID_SYS_CLK_A_SEL]		= &s4_sysclk_a_sel.hw,
3308	[CLKID_SYS_CLK_A_DIV]		= &s4_sysclk_a_div.hw,
3309	[CLKID_SYS_CLK_A]		= &s4_sysclk_a.hw,
3310	[CLKID_SYS]			= &s4_sys_clk.hw,
3311	[CLKID_CECA_32K_CLKIN]		= &s4_ceca_32k_clkin.hw,
3312	[CLKID_CECA_32K_DIV]		= &s4_ceca_32k_div.hw,
3313	[CLKID_CECA_32K_SEL_PRE]	= &s4_ceca_32k_sel_pre.hw,
3314	[CLKID_CECA_32K_SEL]		= &s4_ceca_32k_sel.hw,
3315	[CLKID_CECA_32K_CLKOUT]		= &s4_ceca_32k_clkout.hw,
3316	[CLKID_CECB_32K_CLKIN]		= &s4_cecb_32k_clkin.hw,
3317	[CLKID_CECB_32K_DIV]		= &s4_cecb_32k_div.hw,
3318	[CLKID_CECB_32K_SEL_PRE]	= &s4_cecb_32k_sel_pre.hw,
3319	[CLKID_CECB_32K_SEL]		= &s4_cecb_32k_sel.hw,
3320	[CLKID_CECB_32K_CLKOUT]		= &s4_cecb_32k_clkout.hw,
3321	[CLKID_SC_CLK_SEL]		= &s4_sc_clk_mux.hw,
3322	[CLKID_SC_CLK_DIV]		= &s4_sc_clk_div.hw,
3323	[CLKID_SC]			= &s4_sc_clk_gate.hw,
3324	[CLKID_12_24M]			= &s4_12_24M_clk_gate.hw,
3325	[CLKID_12M_CLK_DIV]		= &s4_12M_clk_div.hw,
3326	[CLKID_12_24M_CLK_SEL]		= &s4_12_24M_clk.hw,
3327	[CLKID_VID_PLL_DIV]		= &s4_vid_pll_div.hw,
3328	[CLKID_VID_PLL_SEL]		= &s4_vid_pll_sel.hw,
3329	[CLKID_VID_PLL]			= &s4_vid_pll.hw,
3330	[CLKID_VCLK_SEL]		= &s4_vclk_sel.hw,
3331	[CLKID_VCLK2_SEL]		= &s4_vclk2_sel.hw,
3332	[CLKID_VCLK_INPUT]		= &s4_vclk_input.hw,
3333	[CLKID_VCLK2_INPUT]		= &s4_vclk2_input.hw,
3334	[CLKID_VCLK_DIV]		= &s4_vclk_div.hw,
3335	[CLKID_VCLK2_DIV]		= &s4_vclk2_div.hw,
3336	[CLKID_VCLK]			= &s4_vclk.hw,
3337	[CLKID_VCLK2]			= &s4_vclk2.hw,
3338	[CLKID_VCLK_DIV1]		= &s4_vclk_div1.hw,
3339	[CLKID_VCLK_DIV2_EN]		= &s4_vclk_div2_en.hw,
3340	[CLKID_VCLK_DIV4_EN]		= &s4_vclk_div4_en.hw,
3341	[CLKID_VCLK_DIV6_EN]		= &s4_vclk_div6_en.hw,
3342	[CLKID_VCLK_DIV12_EN]		= &s4_vclk_div12_en.hw,
3343	[CLKID_VCLK2_DIV1]		= &s4_vclk2_div1.hw,
3344	[CLKID_VCLK2_DIV2_EN]		= &s4_vclk2_div2_en.hw,
3345	[CLKID_VCLK2_DIV4_EN]		= &s4_vclk2_div4_en.hw,
3346	[CLKID_VCLK2_DIV6_EN]		= &s4_vclk2_div6_en.hw,
3347	[CLKID_VCLK2_DIV12_EN]		= &s4_vclk2_div12_en.hw,
3348	[CLKID_VCLK_DIV2]		= &s4_vclk_div2.hw,
3349	[CLKID_VCLK_DIV4]		= &s4_vclk_div4.hw,
3350	[CLKID_VCLK_DIV6]		= &s4_vclk_div6.hw,
3351	[CLKID_VCLK_DIV12]		= &s4_vclk_div12.hw,
3352	[CLKID_VCLK2_DIV2]		= &s4_vclk2_div2.hw,
3353	[CLKID_VCLK2_DIV4]		= &s4_vclk2_div4.hw,
3354	[CLKID_VCLK2_DIV6]		= &s4_vclk2_div6.hw,
3355	[CLKID_VCLK2_DIV12]		= &s4_vclk2_div12.hw,
3356	[CLKID_CTS_ENCI_SEL]		= &s4_cts_enci_sel.hw,
3357	[CLKID_CTS_ENCP_SEL]		= &s4_cts_encp_sel.hw,
3358	[CLKID_CTS_VDAC_SEL]		= &s4_cts_vdac_sel.hw,
3359	[CLKID_HDMI_TX_SEL]		= &s4_hdmi_tx_sel.hw,
3360	[CLKID_CTS_ENCI]		= &s4_cts_enci.hw,
3361	[CLKID_CTS_ENCP]		= &s4_cts_encp.hw,
3362	[CLKID_CTS_VDAC]		= &s4_cts_vdac.hw,
3363	[CLKID_HDMI_TX]			= &s4_hdmi_tx.hw,
3364	[CLKID_HDMI_SEL]		= &s4_hdmi_sel.hw,
3365	[CLKID_HDMI_DIV]		= &s4_hdmi_div.hw,
3366	[CLKID_HDMI]			= &s4_hdmi.hw,
3367	[CLKID_TS_CLK_DIV]		= &s4_ts_clk_div.hw,
3368	[CLKID_TS]			= &s4_ts_clk_gate.hw,
3369	[CLKID_MALI_0_SEL]		= &s4_mali_0_sel.hw,
3370	[CLKID_MALI_0_DIV]		= &s4_mali_0_div.hw,
3371	[CLKID_MALI_0]			= &s4_mali_0.hw,
3372	[CLKID_MALI_1_SEL]		= &s4_mali_1_sel.hw,
3373	[CLKID_MALI_1_DIV]		= &s4_mali_1_div.hw,
3374	[CLKID_MALI_1]			= &s4_mali_1.hw,
3375	[CLKID_MALI_SEL]		= &s4_mali_mux.hw,
3376	[CLKID_VDEC_P0_SEL]		= &s4_vdec_p0_mux.hw,
3377	[CLKID_VDEC_P0_DIV]		= &s4_vdec_p0_div.hw,
3378	[CLKID_VDEC_P0]			= &s4_vdec_p0.hw,
3379	[CLKID_VDEC_P1_SEL]		= &s4_vdec_p1_mux.hw,
3380	[CLKID_VDEC_P1_DIV]		= &s4_vdec_p1_div.hw,
3381	[CLKID_VDEC_P1]			= &s4_vdec_p1.hw,
3382	[CLKID_VDEC_SEL]		= &s4_vdec_mux.hw,
3383	[CLKID_HEVCF_P0_SEL]		= &s4_hevcf_p0_mux.hw,
3384	[CLKID_HEVCF_P0_DIV]		= &s4_hevcf_p0_div.hw,
3385	[CLKID_HEVCF_P0]		= &s4_hevcf_p0.hw,
3386	[CLKID_HEVCF_P1_SEL]		= &s4_hevcf_p1_mux.hw,
3387	[CLKID_HEVCF_P1_DIV]		= &s4_hevcf_p1_div.hw,
3388	[CLKID_HEVCF_P1]		= &s4_hevcf_p1.hw,
3389	[CLKID_HEVCF_SEL]		= &s4_hevcf_mux.hw,
3390	[CLKID_VPU_0_SEL]		= &s4_vpu_0_sel.hw,
3391	[CLKID_VPU_0_DIV]		= &s4_vpu_0_div.hw,
3392	[CLKID_VPU_0]			= &s4_vpu_0.hw,
3393	[CLKID_VPU_1_SEL]		= &s4_vpu_1_sel.hw,
3394	[CLKID_VPU_1_DIV]		= &s4_vpu_1_div.hw,
3395	[CLKID_VPU_1]			= &s4_vpu_1.hw,
3396	[CLKID_VPU]			= &s4_vpu.hw,
3397	[CLKID_VPU_CLKB_TMP_SEL]	= &s4_vpu_clkb_tmp_mux.hw,
3398	[CLKID_VPU_CLKB_TMP_DIV]	= &s4_vpu_clkb_tmp_div.hw,
3399	[CLKID_VPU_CLKB_TMP]		= &s4_vpu_clkb_tmp.hw,
3400	[CLKID_VPU_CLKB_DIV]		= &s4_vpu_clkb_div.hw,
3401	[CLKID_VPU_CLKB]		= &s4_vpu_clkb.hw,
3402	[CLKID_VPU_CLKC_P0_SEL]		= &s4_vpu_clkc_p0_mux.hw,
3403	[CLKID_VPU_CLKC_P0_DIV]		= &s4_vpu_clkc_p0_div.hw,
3404	[CLKID_VPU_CLKC_P0]		= &s4_vpu_clkc_p0.hw,
3405	[CLKID_VPU_CLKC_P1_SEL]		= &s4_vpu_clkc_p1_mux.hw,
3406	[CLKID_VPU_CLKC_P1_DIV]		= &s4_vpu_clkc_p1_div.hw,
3407	[CLKID_VPU_CLKC_P1]		= &s4_vpu_clkc_p1.hw,
3408	[CLKID_VPU_CLKC_SEL]		= &s4_vpu_clkc_mux.hw,
3409	[CLKID_VAPB_0_SEL]		= &s4_vapb_0_sel.hw,
3410	[CLKID_VAPB_0_DIV]		= &s4_vapb_0_div.hw,
3411	[CLKID_VAPB_0]			= &s4_vapb_0.hw,
3412	[CLKID_VAPB_1_SEL]		= &s4_vapb_1_sel.hw,
3413	[CLKID_VAPB_1_DIV]		= &s4_vapb_1_div.hw,
3414	[CLKID_VAPB_1]			= &s4_vapb_1.hw,
3415	[CLKID_VAPB]			= &s4_vapb.hw,
3416	[CLKID_GE2D]			= &s4_ge2d_gate.hw,
3417	[CLKID_VDIN_MEAS_SEL]		= &s4_vdin_meas_mux.hw,
3418	[CLKID_VDIN_MEAS_DIV]		= &s4_vdin_meas_div.hw,
3419	[CLKID_VDIN_MEAS]		= &s4_vdin_meas_gate.hw,
3420	[CLKID_SD_EMMC_C_CLK_SEL]	= &s4_sd_emmc_c_clk0_sel.hw,
3421	[CLKID_SD_EMMC_C_CLK_DIV]	= &s4_sd_emmc_c_clk0_div.hw,
3422	[CLKID_SD_EMMC_C]		= &s4_sd_emmc_c_clk0.hw,
3423	[CLKID_SD_EMMC_A_CLK_SEL]	= &s4_sd_emmc_a_clk0_sel.hw,
3424	[CLKID_SD_EMMC_A_CLK_DIV]	= &s4_sd_emmc_a_clk0_div.hw,
3425	[CLKID_SD_EMMC_A]		= &s4_sd_emmc_a_clk0.hw,
3426	[CLKID_SD_EMMC_B_CLK_SEL]	= &s4_sd_emmc_b_clk0_sel.hw,
3427	[CLKID_SD_EMMC_B_CLK_DIV]	= &s4_sd_emmc_b_clk0_div.hw,
3428	[CLKID_SD_EMMC_B]		= &s4_sd_emmc_b_clk0.hw,
3429	[CLKID_SPICC0_SEL]		= &s4_spicc0_mux.hw,
3430	[CLKID_SPICC0_DIV]		= &s4_spicc0_div.hw,
3431	[CLKID_SPICC0_EN]		= &s4_spicc0_gate.hw,
3432	[CLKID_PWM_A_SEL]		= &s4_pwm_a_mux.hw,
3433	[CLKID_PWM_A_DIV]		= &s4_pwm_a_div.hw,
3434	[CLKID_PWM_A]			= &s4_pwm_a_gate.hw,
3435	[CLKID_PWM_B_SEL]		= &s4_pwm_b_mux.hw,
3436	[CLKID_PWM_B_DIV]		= &s4_pwm_b_div.hw,
3437	[CLKID_PWM_B]			= &s4_pwm_b_gate.hw,
3438	[CLKID_PWM_C_SEL]		= &s4_pwm_c_mux.hw,
3439	[CLKID_PWM_C_DIV]		= &s4_pwm_c_div.hw,
3440	[CLKID_PWM_C]			= &s4_pwm_c_gate.hw,
3441	[CLKID_PWM_D_SEL]		= &s4_pwm_d_mux.hw,
3442	[CLKID_PWM_D_DIV]		= &s4_pwm_d_div.hw,
3443	[CLKID_PWM_D]			= &s4_pwm_d_gate.hw,
3444	[CLKID_PWM_E_SEL]		= &s4_pwm_e_mux.hw,
3445	[CLKID_PWM_E_DIV]		= &s4_pwm_e_div.hw,
3446	[CLKID_PWM_E]			= &s4_pwm_e_gate.hw,
3447	[CLKID_PWM_F_SEL]		= &s4_pwm_f_mux.hw,
3448	[CLKID_PWM_F_DIV]		= &s4_pwm_f_div.hw,
3449	[CLKID_PWM_F]			= &s4_pwm_f_gate.hw,
3450	[CLKID_PWM_G_SEL]		= &s4_pwm_g_mux.hw,
3451	[CLKID_PWM_G_DIV]		= &s4_pwm_g_div.hw,
3452	[CLKID_PWM_G]			= &s4_pwm_g_gate.hw,
3453	[CLKID_PWM_H_SEL]		= &s4_pwm_h_mux.hw,
3454	[CLKID_PWM_H_DIV]		= &s4_pwm_h_div.hw,
3455	[CLKID_PWM_H]			= &s4_pwm_h_gate.hw,
3456	[CLKID_PWM_I_SEL]		= &s4_pwm_i_mux.hw,
3457	[CLKID_PWM_I_DIV]		= &s4_pwm_i_div.hw,
3458	[CLKID_PWM_I]			= &s4_pwm_i_gate.hw,
3459	[CLKID_PWM_J_SEL]		= &s4_pwm_j_mux.hw,
3460	[CLKID_PWM_J_DIV]		= &s4_pwm_j_div.hw,
3461	[CLKID_PWM_J]			= &s4_pwm_j_gate.hw,
3462	[CLKID_SARADC_SEL]		= &s4_saradc_mux.hw,
3463	[CLKID_SARADC_DIV]		= &s4_saradc_div.hw,
3464	[CLKID_SARADC]			= &s4_saradc_gate.hw,
3465	[CLKID_GEN_SEL]			= &s4_gen_clk_sel.hw,
3466	[CLKID_GEN_DIV]			= &s4_gen_clk_div.hw,
3467	[CLKID_GEN]			= &s4_gen_clk.hw,
3468	[CLKID_DDR]			= &s4_ddr.hw,
3469	[CLKID_DOS]			= &s4_dos.hw,
3470	[CLKID_ETHPHY]			= &s4_ethphy.hw,
3471	[CLKID_MALI]			= &s4_mali.hw,
3472	[CLKID_AOCPU]			= &s4_aocpu.hw,
3473	[CLKID_AUCPU]			= &s4_aucpu.hw,
3474	[CLKID_CEC]			= &s4_cec.hw,
3475	[CLKID_SDEMMC_A]		= &s4_sdemmca.hw,
3476	[CLKID_SDEMMC_B]		= &s4_sdemmcb.hw,
3477	[CLKID_NAND]			= &s4_nand.hw,
3478	[CLKID_SMARTCARD]		= &s4_smartcard.hw,
3479	[CLKID_ACODEC]			= &s4_acodec.hw,
3480	[CLKID_SPIFC]			= &s4_spifc.hw,
3481	[CLKID_MSR]			= &s4_msr_clk.hw,
3482	[CLKID_IR_CTRL]			= &s4_ir_ctrl.hw,
3483	[CLKID_AUDIO]			= &s4_audio.hw,
3484	[CLKID_ETH]			= &s4_eth.hw,
3485	[CLKID_UART_A]			= &s4_uart_a.hw,
3486	[CLKID_UART_B]			= &s4_uart_b.hw,
3487	[CLKID_UART_C]			= &s4_uart_c.hw,
3488	[CLKID_UART_D]			= &s4_uart_d.hw,
3489	[CLKID_UART_E]			= &s4_uart_e.hw,
3490	[CLKID_AIFIFO]			= &s4_aififo.hw,
3491	[CLKID_TS_DDR]			= &s4_ts_ddr.hw,
3492	[CLKID_TS_PLL]			= &s4_ts_pll.hw,
3493	[CLKID_G2D]			= &s4_g2d.hw,
3494	[CLKID_SPICC0]			= &s4_spicc0.hw,
3495	[CLKID_USB]			= &s4_usb.hw,
3496	[CLKID_I2C_M_A]			= &s4_i2c_m_a.hw,
3497	[CLKID_I2C_M_B]			= &s4_i2c_m_b.hw,
3498	[CLKID_I2C_M_C]			= &s4_i2c_m_c.hw,
3499	[CLKID_I2C_M_D]			= &s4_i2c_m_d.hw,
3500	[CLKID_I2C_M_E]			= &s4_i2c_m_e.hw,
3501	[CLKID_HDMITX_APB]		= &s4_hdmitx_apb.hw,
3502	[CLKID_I2C_S_A]			= &s4_i2c_s_a.hw,
3503	[CLKID_USB1_TO_DDR]		= &s4_usb1_to_ddr.hw,
3504	[CLKID_HDCP22]			= &s4_hdcp22.hw,
3505	[CLKID_MMC_APB]			= &s4_mmc_apb.hw,
3506	[CLKID_RSA]			= &s4_rsa.hw,
3507	[CLKID_CPU_DEBUG]		= &s4_cpu_debug.hw,
3508	[CLKID_VPU_INTR]		= &s4_vpu_intr.hw,
3509	[CLKID_DEMOD]			= &s4_demod.hw,
3510	[CLKID_SAR_ADC]			= &s4_sar_adc.hw,
3511	[CLKID_GIC]			= &s4_gic.hw,
3512	[CLKID_PWM_AB]			= &s4_pwm_ab.hw,
3513	[CLKID_PWM_CD]			= &s4_pwm_cd.hw,
3514	[CLKID_PWM_EF]			= &s4_pwm_ef.hw,
3515	[CLKID_PWM_GH]			= &s4_pwm_gh.hw,
3516	[CLKID_PWM_IJ]			= &s4_pwm_ij.hw,
3517	[CLKID_HDCP22_ESMCLK_SEL]	= &s4_hdcp22_esmclk_mux.hw,
3518	[CLKID_HDCP22_ESMCLK_DIV]	= &s4_hdcp22_esmclk_div.hw,
3519	[CLKID_HDCP22_ESMCLK]		= &s4_hdcp22_esmclk_gate.hw,
3520	[CLKID_HDCP22_SKPCLK_SEL]	= &s4_hdcp22_skpclk_mux.hw,
3521	[CLKID_HDCP22_SKPCLK_DIV]	= &s4_hdcp22_skpclk_div.hw,
3522	[CLKID_HDCP22_SKPCLK]		= &s4_hdcp22_skpclk_gate.hw,
3523};
3524
3525/* Convenience table to populate regmap in .probe */
3526static struct clk_regmap *const s4_periphs_clk_regmaps[] = {
3527	&s4_rtc_32k_by_oscin_clkin,
3528	&s4_rtc_32k_by_oscin_div,
3529	&s4_rtc_32k_by_oscin_sel,
3530	&s4_rtc_32k_by_oscin,
3531	&s4_rtc_clk,
3532	&s4_sysclk_b_sel,
3533	&s4_sysclk_b_div,
3534	&s4_sysclk_b,
3535	&s4_sysclk_a_sel,
3536	&s4_sysclk_a_div,
3537	&s4_sysclk_a,
3538	&s4_sys_clk,
3539	&s4_ceca_32k_clkin,
3540	&s4_ceca_32k_div,
3541	&s4_ceca_32k_sel_pre,
3542	&s4_ceca_32k_sel,
3543	&s4_ceca_32k_clkout,
3544	&s4_cecb_32k_clkin,
3545	&s4_cecb_32k_div,
3546	&s4_cecb_32k_sel_pre,
3547	&s4_cecb_32k_sel,
3548	&s4_cecb_32k_clkout,
3549	&s4_sc_clk_mux,
3550	&s4_sc_clk_div,
3551	&s4_sc_clk_gate,
3552	&s4_12_24M_clk_gate,
3553	&s4_12_24M_clk,
3554	&s4_vid_pll_div,
3555	&s4_vid_pll_sel,
3556	&s4_vid_pll,
3557	&s4_vclk_sel,
3558	&s4_vclk2_sel,
3559	&s4_vclk_input,
3560	&s4_vclk2_input,
3561	&s4_vclk_div,
3562	&s4_vclk2_div,
3563	&s4_vclk,
3564	&s4_vclk2,
3565	&s4_vclk_div1,
3566	&s4_vclk_div2_en,
3567	&s4_vclk_div4_en,
3568	&s4_vclk_div6_en,
3569	&s4_vclk_div12_en,
3570	&s4_vclk2_div1,
3571	&s4_vclk2_div2_en,
3572	&s4_vclk2_div4_en,
3573	&s4_vclk2_div6_en,
3574	&s4_vclk2_div12_en,
3575	&s4_cts_enci_sel,
3576	&s4_cts_encp_sel,
3577	&s4_cts_vdac_sel,
3578	&s4_hdmi_tx_sel,
3579	&s4_cts_enci,
3580	&s4_cts_encp,
3581	&s4_cts_vdac,
3582	&s4_hdmi_tx,
3583	&s4_hdmi_sel,
3584	&s4_hdmi_div,
3585	&s4_hdmi,
3586	&s4_ts_clk_div,
3587	&s4_ts_clk_gate,
3588	&s4_mali_0_sel,
3589	&s4_mali_0_div,
3590	&s4_mali_0,
3591	&s4_mali_1_sel,
3592	&s4_mali_1_div,
3593	&s4_mali_1,
3594	&s4_mali_mux,
3595	&s4_vdec_p0_mux,
3596	&s4_vdec_p0_div,
3597	&s4_vdec_p0,
3598	&s4_vdec_p1_mux,
3599	&s4_vdec_p1_div,
3600	&s4_vdec_p1,
3601	&s4_vdec_mux,
3602	&s4_hevcf_p0_mux,
3603	&s4_hevcf_p0_div,
3604	&s4_hevcf_p0,
3605	&s4_hevcf_p1_mux,
3606	&s4_hevcf_p1_div,
3607	&s4_hevcf_p1,
3608	&s4_hevcf_mux,
3609	&s4_vpu_0_sel,
3610	&s4_vpu_0_div,
3611	&s4_vpu_0,
3612	&s4_vpu_1_sel,
3613	&s4_vpu_1_div,
3614	&s4_vpu_1,
3615	&s4_vpu,
3616	&s4_vpu_clkb_tmp_mux,
3617	&s4_vpu_clkb_tmp_div,
3618	&s4_vpu_clkb_tmp,
3619	&s4_vpu_clkb_div,
3620	&s4_vpu_clkb,
3621	&s4_vpu_clkc_p0_mux,
3622	&s4_vpu_clkc_p0_div,
3623	&s4_vpu_clkc_p0,
3624	&s4_vpu_clkc_p1_mux,
3625	&s4_vpu_clkc_p1_div,
3626	&s4_vpu_clkc_p1,
3627	&s4_vpu_clkc_mux,
3628	&s4_vapb_0_sel,
3629	&s4_vapb_0_div,
3630	&s4_vapb_0,
3631	&s4_vapb_1_sel,
3632	&s4_vapb_1_div,
3633	&s4_vapb_1,
3634	&s4_vapb,
3635	&s4_ge2d_gate,
3636	&s4_hdcp22_esmclk_mux,
3637	&s4_hdcp22_esmclk_div,
3638	&s4_hdcp22_esmclk_gate,
3639	&s4_hdcp22_skpclk_mux,
3640	&s4_hdcp22_skpclk_div,
3641	&s4_hdcp22_skpclk_gate,
3642	&s4_vdin_meas_mux,
3643	&s4_vdin_meas_div,
3644	&s4_vdin_meas_gate,
3645	&s4_sd_emmc_c_clk0_sel,
3646	&s4_sd_emmc_c_clk0_div,
3647	&s4_sd_emmc_c_clk0,
3648	&s4_sd_emmc_a_clk0_sel,
3649	&s4_sd_emmc_a_clk0_div,
3650	&s4_sd_emmc_a_clk0,
3651	&s4_sd_emmc_b_clk0_sel,
3652	&s4_sd_emmc_b_clk0_div,
3653	&s4_sd_emmc_b_clk0,
3654	&s4_spicc0_mux,
3655	&s4_spicc0_div,
3656	&s4_spicc0_gate,
3657	&s4_pwm_a_mux,
3658	&s4_pwm_a_div,
3659	&s4_pwm_a_gate,
3660	&s4_pwm_b_mux,
3661	&s4_pwm_b_div,
3662	&s4_pwm_b_gate,
3663	&s4_pwm_c_mux,
3664	&s4_pwm_c_div,
3665	&s4_pwm_c_gate,
3666	&s4_pwm_d_mux,
3667	&s4_pwm_d_div,
3668	&s4_pwm_d_gate,
3669	&s4_pwm_e_mux,
3670	&s4_pwm_e_div,
3671	&s4_pwm_e_gate,
3672	&s4_pwm_f_mux,
3673	&s4_pwm_f_div,
3674	&s4_pwm_f_gate,
3675	&s4_pwm_g_mux,
3676	&s4_pwm_g_div,
3677	&s4_pwm_g_gate,
3678	&s4_pwm_h_mux,
3679	&s4_pwm_h_div,
3680	&s4_pwm_h_gate,
3681	&s4_pwm_i_mux,
3682	&s4_pwm_i_div,
3683	&s4_pwm_i_gate,
3684	&s4_pwm_j_mux,
3685	&s4_pwm_j_div,
3686	&s4_pwm_j_gate,
3687	&s4_saradc_mux,
3688	&s4_saradc_div,
3689	&s4_saradc_gate,
3690	&s4_gen_clk_sel,
3691	&s4_gen_clk_div,
3692	&s4_gen_clk,
3693	&s4_ddr,
3694	&s4_dos,
3695	&s4_ethphy,
3696	&s4_mali,
3697	&s4_aocpu,
3698	&s4_aucpu,
3699	&s4_cec,
3700	&s4_sdemmca,
3701	&s4_sdemmcb,
3702	&s4_nand,
3703	&s4_smartcard,
3704	&s4_acodec,
3705	&s4_spifc,
3706	&s4_msr_clk,
3707	&s4_ir_ctrl,
3708	&s4_audio,
3709	&s4_eth,
3710	&s4_uart_a,
3711	&s4_uart_b,
3712	&s4_uart_c,
3713	&s4_uart_d,
3714	&s4_uart_e,
3715	&s4_aififo,
3716	&s4_ts_ddr,
3717	&s4_ts_pll,
3718	&s4_g2d,
3719	&s4_spicc0,
3720	&s4_usb,
3721	&s4_i2c_m_a,
3722	&s4_i2c_m_b,
3723	&s4_i2c_m_c,
3724	&s4_i2c_m_d,
3725	&s4_i2c_m_e,
3726	&s4_hdmitx_apb,
3727	&s4_i2c_s_a,
3728	&s4_usb1_to_ddr,
3729	&s4_hdcp22,
3730	&s4_mmc_apb,
3731	&s4_rsa,
3732	&s4_cpu_debug,
3733	&s4_vpu_intr,
3734	&s4_demod,
3735	&s4_sar_adc,
3736	&s4_gic,
3737	&s4_pwm_ab,
3738	&s4_pwm_cd,
3739	&s4_pwm_ef,
3740	&s4_pwm_gh,
3741	&s4_pwm_ij,
3742	&s4_demod_core_clk_mux,
3743	&s4_demod_core_clk_div,
3744	&s4_demod_core_clk_gate,
3745	&s4_adc_extclk_in_mux,
3746	&s4_adc_extclk_in_div,
3747	&s4_adc_extclk_in_gate,
3748};
3749
3750static struct regmap_config clkc_regmap_config = {
3751	.reg_bits       = 32,
3752	.val_bits       = 32,
3753	.reg_stride     = 4,
3754};
3755
3756static struct meson_clk_hw_data s4_periphs_clks = {
3757	.hws = s4_periphs_hw_clks,
3758	.num = ARRAY_SIZE(s4_periphs_hw_clks),
3759};
3760
3761static int meson_s4_periphs_probe(struct platform_device *pdev)
3762{
3763	struct device *dev = &pdev->dev;
3764	struct regmap *regmap;
3765	void __iomem *base;
3766	int ret, i;
3767
3768	base = devm_platform_ioremap_resource(pdev, 0);
3769	if (IS_ERR(base))
3770		return dev_err_probe(dev, PTR_ERR(base),
3771				     "can't ioremap resource\n");
3772
3773	regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
3774	if (IS_ERR(regmap))
3775		return dev_err_probe(dev, PTR_ERR(regmap),
3776				     "can't init regmap mmio region\n");
3777
3778	/* Populate regmap for the regmap backed clocks */
3779	for (i = 0; i < ARRAY_SIZE(s4_periphs_clk_regmaps); i++)
3780		s4_periphs_clk_regmaps[i]->map = regmap;
3781
3782	for (i = 0; i < s4_periphs_clks.num; i++) {
3783		/* array might be sparse */
3784		if (!s4_periphs_clks.hws[i])
3785			continue;
3786
3787		ret = devm_clk_hw_register(dev, s4_periphs_clks.hws[i]);
3788		if (ret)
3789			return dev_err_probe(dev, ret,
3790					     "clock[%d] registration failed\n", i);
3791	}
3792
3793	return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get, &s4_periphs_clks);
3794}
3795
3796static const struct of_device_id clkc_match_table[] = {
3797	{
3798		.compatible = "amlogic,s4-peripherals-clkc",
3799	},
3800	{}
3801};
3802
3803static struct platform_driver s4_driver = {
3804	.probe		= meson_s4_periphs_probe,
3805	.driver		= {
3806		.name	= "s4-periphs-clkc",
3807		.of_match_table = clkc_match_table,
3808	},
3809};
3810
3811module_platform_driver(s4_driver);
3812MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>");
3813MODULE_LICENSE("GPL");