summaryrefslogblamecommitdiff
path: root/drivers/clk/meson/g12a.c
blob: e0e295645c9e2f661334691477cf19870d55aa97 (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
4322
4323
4324
4325
4326
4327
4328
4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
4350
4351
4352
4353
4354
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365
4366
4367
4368
4369
4370
4371
4372
4373
4374
4375
4376
4377
4378
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4466
4467
4468
4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
4504
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
4561
4562
4563
4564
4565
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610
4611
4612
4613
4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657
4658
4659
4660
4661
4662
4663
4664
4665
4666
4667
4668
4669
4670
4671
4672
4673
4674
4675
4676
4677
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748
4749
4750
4751
4752
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809
4810
4811
4812
4813
4814
4815
4816
4817
4818
4819
4820
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831
4832
4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
4859
4860
4861
4862
4863
4864
4865
4866
4867
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878
4879
4880
4881
4882
4883
4884
4885
4886
4887
4888
4889
4890
4891
4892
4893
4894
4895
4896
4897
4898
4899
4900
4901
4902
4903
4904
4905
4906
4907
4908
4909
4910
4911
4912
4913
4914
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925
4926
4927
4928
4929
4930
4931
4932
4933
4934
4935
4936
4937
4938
4939
4940
4941
4942
4943
4944
4945
4946
4947
4948
4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974














                                                      
                                  
                      
                         
 


                       
                           
                        
                        

                 





































                                                     


                                                                













                                                  


                                                         







                                                             


                                                              




























                                                     
                                                  


                                           
                                          


                                                                
                                 

                                                                  











                                                  
                                               


                                                         
                                 
                                             


          


























                                                      
                                                  


                                           
                                          


                                                                
                                 

                                                                  











                                                  
                                               


                                                         
                                 
                                             


          







                                                  
                                                                             







                                                                







                                                   


                                                         







                                                                





                                                     


                                                         



                                 





                                                      





























                                                                               










                                                                               









                                                                               



                                 
























                                                                               





                                                 
                                               


                                           
                                           





                                                                  
                                             











                                                 
                                           




                                                                  
                                 

                                                           




                                                    










                                                         


                                           
                                                 


                                                         
                                 
                                             








                                                  
                                               


                                           
                                           



                                                         
                                 
                                             


          









                                                    


                                                         












                                                  
                                           



                                                         
                                 

                                                           








                                                       
                                               


                                           
                                           



                                                         
                                 
                                             








                                                   
                                               


                                           
                                           



                                                         
                                 
                                             


          





                                                   
                                               


                                           
                                           



                                                         
                                 
                                             








                                                  
                                               


                                            
                                           




                                                                  
                                 
                                             




                                                    










                                                         


                                            
                                                 


                                                         
                                 
                                             








                                                   
                                               


                                           
                                           



                                                         
                                 
                                             











                                                  
                                           




                                                                  
                                 

                                                           












                                                    


                                                         












                                                   
                                           



                                                         
                                 

                                                           








                                                       
                                               


                                           
                                           



                                                         
                                 
                                             








                                                   
                                               


                                           
                                           



                                                         
                                 
                                             


          



















































































































































                                                                  





















































                                                                       

















                                                                


















































































































































































































                                                                              







                                                  


                                                         







                                                                







                                                   


                                                         







                                                                





                                                     


                                                         



                                 





                                                      


                                                         



                                 









                                                  
                                                                             











                                                


                                                         

















                                                             
                                                                             



                                 







                                                


                                                         

















                                                             
                                                                             











                                                


                                                         

















                                                             










                                                                              











                                                


                                                         













                                                             


                                                         









                                                     


                                                         









                                                     


                                                         









                                                     


                                                         









                                                     


                                                         









                                                     


                                                         









                                                     


                                                         














                                                      








                                                         












                                                 


                                                         

















                                                             








                                                         




                                              
                                               
                                                 
                              
                                                 

                                            
                                       
                                               


                                                         







                                                             



                                                  
                           
                                        

                                           

                                              








                                                         
                                 


          
                                              
                                               
                                                 
                              
                                                 

                                            
                                       
                                               


                                                         







                                                             



                                                    
                            
                                        

                                           

                                              








                                                         
                                 


          
                                                
                                               
                                                 
                              
                                                 

                                            
                                         
                                               


                                                         







                                                             
                                                              
                   





















































                                                             


                                                                














                                                     


                                                         




                                             






























































                                                                  



















































                                                              


                                                                














                                                     


                                                         




                                             
































































                                                                            


                                                                









                                                         


                                                         
















                                                    


                                                         










                                                


                                                         




                                             



































                                                      


                                                                


















                                                                                


                                                         














                                                                    


                                                         














                                                                    


                                                         




                                                                    





                                                     
                                                                               











                                               


                                                         









                                                     
                                                                               











                                               


                                                         









                                                     
                                                                               











                                               


                                                         









                                                       


                                                         











                                               


                                                         









                                                    


                                                         












                                              



                                                                  









                                                   


                                                         



                                 



                                                            






















                                                  

                                                               



                                           


                                                         











                                               
                                                                               




                                             



                                                            






















                                                  

                                                               



                                           


                                                         











                                               
                                                                               




                                             



                                                            






















                                                  

                                                               



                                           


                                                         











                                               
                                                                               




                                             



                                                            






















                                                  

                                                               



                                           


                                                         











                                               
                                                                               





                                                          







                                                           











                                              

                                                             











                                               


                                                         












                                               


                                                         




                                                                 





                                                                       

















                                                                               

                                                                         












                                                    


                                                         












                                                


                                                         














                                                    

                                                                         












                                                    


                                                         












                                                


                                                         














                                                    

                                                                         












                                                    


                                                         












                                                


                                                         




                                             































































                                                                              

               








                                                     




                                              
                            




                                           

                                                               












                                                  
                                                                               












                                               
                                                                               







                                                                 
                            




                                           

                                                               












                                                  
                                                                               












                                               
                                                                               

















                                                                 



                                                         




                                                  

                 







                                                      











                                               

                                                                













                                                   


                                                         












                                               


                                                         














                                                

                                                                













                                                   


                                                         












                                               


                                                         














                                               

                                                                













                                                   


                                                         












                                               


                                                         




                                             

                








                                                      










                                              

                                                                












                                                  


                                                         












                                               


                                                         













                                                                 

                                                                












                                                  


                                                         












                                               


                                                         

















                                                                 



                                                         












                                                  
                                                                              




                                                                 








                                                      










                                              

                                                                












                                                                         

                                                                











                                                                         
                                                                              












                                                                 
                                                                               













                                                                 


                                                         













                                               


                                                         












                                               
                                                                              












                                                                 
                                                                               












                                                                 
                                                                          












                                                                 
                                                                          












                                                                 
                                                                          












                                                                 
                                                                          












                                                                 
                                                                          












                                                                 
                                                                           












                                                                 
                                                                           












                                                                 
                                                                           












                                                                 
                                                                           












                                                                 
                                                                           










                                                                 


                                                         









                                                 


                                                         









                                                 


                                                         









                                                  


                                                         









                                                  


                                                         









                                                  


                                                         









                                                  


                                                         









                                                   


                                                         




                                                                     










                                                     











                                              

                                                               













                                                                         

                                                               













                                                                         

                                                               





                                                                         










                                                             











                                               

                                                                       











                                                                         


                                                         












                                                                 


                                                         












                                                                 


                                                         












                                                                 


                                                         




                                                                 





























































                                                                          

                 




                                                               











                                               

                                                                 












                                                                         
                                                                              












                                               
                                                                              






                                                                     


                                                                     
   








                                                                   










                                              
                                                         
                                 






                                                                       











                                               


                                                         
                                 
                                             










                                               


                                                         
                                 
                                                                 











                                              
                                                         
                                 






                                                                       











                                               


                                                         
                                 
                                             










                                               


                                                         
                                 
                                                                 


          


                                                      










                                              
                                                   
                                 
                                             


          








                                                  


                                                                











                                               


                                                         



                                 








































































































                                                                  










































































































                                                               





                                                        











































































                                                                    























































































































































































































































































































































































































































































































































































































































































































































                                                                      

  












































                                                      
                    





















































































































                                 

















                                

                           








                             

                     




















                                 

                         








                              


                      





                              





                              


                                 

  



                                                            


                                                           

                                                            







                                                                          

                                                                          

                                                                            
                  
                                                                                   



                                                      

                                                                     

                                                               
                  
                                                                              







                                                              
                                           
                                        



                                 
                                                     





                                                                          

                                                                 

                                                               
                  
                                                                          



                                               

                                                                  

                                                                            
                  
                                                                           






                                                        

                                                                           

                                                                             
                  
                                                                                    



                                                       
                                                                               

                                                               
                  
                                                                               



                                                   
                                                                                

                                                               
                  
                                                                           



                                              
                                                                               

                                                                            
                  
                                                                          







                                                              
                                           
                                        


                                 
                                                     



                                                  
                                                                               

                                                           
                  
                                                                          



                                              
                                                                               

                                                                   
                  
                                                                          





































                                                                     



                                                        









                                                               



                                                        

                                            

  



                                                               



                                                       



                                            
                                                       







                                                   



                                                  

          
                                          
 
                                             
                                           





                                                   

                                    
// SPDX-License-Identifier: GPL-2.0+
/*
 * Amlogic Meson-G12A Clock Controller Driver
 *
 * Copyright (c) 2016 Baylibre SAS.
 * Author: Michael Turquette <mturquette@baylibre.com>
 *
 * Copyright (c) 2018 Amlogic, inc.
 * Author: Qiufang Dai <qiufang.dai@amlogic.com>
 * Author: Jian Hu <jian.hu@amlogic.com>
 */

#include <linux/clk-provider.h>
#include <linux/init.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/module.h>

#include "clk-mpll.h"
#include "clk-pll.h"
#include "clk-regmap.h"
#include "clk-cpu-dyndiv.h"
#include "vid-pll-div.h"
#include "meson-eeclk.h"
#include "g12a.h"

static DEFINE_SPINLOCK(meson_clk_lock);

static struct clk_regmap g12a_fixed_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_FIX_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_FIX_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_FIX_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.frac = {
			.reg_off = HHI_FIX_PLL_CNTL1,
			.shift   = 0,
			.width   = 17,
		},
		.l = {
			.reg_off = HHI_FIX_PLL_CNTL0,
			.shift   = 31,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_FIX_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
	},
	.hw.init = &(struct clk_init_data){
		.name = "fixed_pll_dco",
		.ops = &meson_clk_pll_ro_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_fixed_pll = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_FIX_PLL_CNTL0,
		.shift = 16,
		.width = 2,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "fixed_pll",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fixed_pll_dco.hw
		},
		.num_parents = 1,
		/*
		 * This clock won't ever change at runtime so
		 * CLK_SET_RATE_PARENT is not required
		 */
	},
};

static const struct pll_mult_range g12a_sys_pll_mult_range = {
	.min = 128,
	.max = 250,
};

static struct clk_regmap g12a_sys_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_SYS_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_SYS_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_SYS_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.l = {
			.reg_off = HHI_SYS_PLL_CNTL0,
			.shift   = 31,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_SYS_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
		.range = &g12a_sys_pll_mult_range,
	},
	.hw.init = &(struct clk_init_data){
		.name = "sys_pll_dco",
		.ops = &meson_clk_pll_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
		/* This clock feeds the CPU, avoid disabling it */
		.flags = CLK_IS_CRITICAL,
	},
};

static struct clk_regmap g12a_sys_pll = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_PLL_CNTL0,
		.shift = 16,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "sys_pll",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_sys_pll_dco.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12b_sys1_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_SYS1_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_SYS1_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_SYS1_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.l = {
			.reg_off = HHI_SYS1_PLL_CNTL0,
			.shift   = 31,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_SYS1_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
		.range = &g12a_sys_pll_mult_range,
	},
	.hw.init = &(struct clk_init_data){
		.name = "sys1_pll_dco",
		.ops = &meson_clk_pll_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
		/* This clock feeds the CPU, avoid disabling it */
		.flags = CLK_IS_CRITICAL,
	},
};

static struct clk_regmap g12b_sys1_pll = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS1_PLL_CNTL0,
		.shift = 16,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "sys1_pll",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_sys1_pll_dco.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_sys_pll_div16_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sys_pll_div16_en",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_sys_pll.hw },
		.num_parents = 1,
		/*
		 * This clock is used to debug the sys_pll range
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12b_sys1_pll_div16_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sys1_pll_div16_en",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_sys1_pll.hw
		},
		.num_parents = 1,
		/*
		 * This clock is used to debug the sys_pll range
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_fixed_factor g12a_sys_pll_div16 = {
	.mult = 1,
	.div = 16,
	.hw.init = &(struct clk_init_data){
		.name = "sys_pll_div16",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_sys_pll_div16_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12b_sys1_pll_div16 = {
	.mult = 1,
	.div = 16,
	.hw.init = &(struct clk_init_data){
		.name = "sys1_pll_div16",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_sys1_pll_div16_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_fclk_div2_div = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div2_div",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_fclk_div2 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_FIX_PLL_CNTL1,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div2",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fclk_div2_div.hw
		},
		.num_parents = 1,
		/*
		 * Similar to fclk_div3, it seems that this clock is used by
		 * the resident firmware and is required by the platform to
		 * operate correctly.
		 * Until the following condition are met, we need this clock to
		 * be marked as critical:
		 * a) Mark the clock used by a firmware resource, if possible
		 * b) CCF has a clock hand-off mechanism to make the sure the
		 *    clock stays on until the proper driver comes along
		 */
		.flags = CLK_IS_CRITICAL,
	},
};

static struct clk_fixed_factor g12a_fclk_div3_div = {
	.mult = 1,
	.div = 3,
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div3_div",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_fclk_div3 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_FIX_PLL_CNTL1,
		.bit_idx = 20,
	},
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div3",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fclk_div3_div.hw
		},
		.num_parents = 1,
		/*
		 * This clock is used by the resident firmware and is required
		 * by the platform to operate correctly.
		 * Until the following condition are met, we need this clock to
		 * be marked as critical:
		 * a) Mark the clock used by a firmware resource, if possible
		 * b) CCF has a clock hand-off mechanism to make the sure the
		 *    clock stays on until the proper driver comes along
		 */
		.flags = CLK_IS_CRITICAL,
	},
};

/* Datasheet names this field as "premux0" */
static struct clk_regmap g12a_cpu_clk_premux0 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x3,
		.shift = 0,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn0_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = (const struct clk_parent_data []) {
			{ .fw_name = "xtal", },
			{ .hw = &g12a_fclk_div2.hw },
			{ .hw = &g12a_fclk_div3.hw },
		},
		.num_parents = 3,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "premux1" */
static struct clk_regmap g12a_cpu_clk_premux1 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x3,
		.shift = 16,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn1_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = (const struct clk_parent_data []) {
			{ .fw_name = "xtal", },
			{ .hw = &g12a_fclk_div2.hw },
			{ .hw = &g12a_fclk_div3.hw },
		},
		.num_parents = 3,
		/* This sub-tree is used a parking clock */
		.flags = CLK_SET_RATE_NO_REPARENT
	},
};

/* Datasheet names this field as "mux0_divn_tcnt" */
static struct clk_regmap g12a_cpu_clk_mux0_div = {
	.data = &(struct meson_clk_cpu_dyndiv_data){
		.div = {
			.reg_off = HHI_SYS_CPU_CLK_CNTL0,
			.shift = 4,
			.width = 6,
		},
		.dyn = {
			.reg_off = HHI_SYS_CPU_CLK_CNTL0,
			.shift = 26,
			.width = 1,
		},
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn0_div",
		.ops = &meson_clk_cpu_dyndiv_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_premux0.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "postmux0" */
static struct clk_regmap g12a_cpu_clk_postmux0 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 2,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn0",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_premux0.hw,
			&g12a_cpu_clk_mux0_div.hw,
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "Mux1_divn_tcnt" */
static struct clk_regmap g12a_cpu_clk_mux1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.shift = 20,
		.width = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn1_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_premux1.hw
		},
		.num_parents = 1,
	},
};

/* Datasheet names this field as "postmux1" */
static struct clk_regmap g12a_cpu_clk_postmux1 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 18,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn1",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_premux1.hw,
			&g12a_cpu_clk_mux1_div.hw,
		},
		.num_parents = 2,
		/* This sub-tree is used a parking clock */
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

/* Datasheet names this field as "Final_dyn_mux_sel" */
static struct clk_regmap g12a_cpu_clk_dyn = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 10,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_dyn",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_postmux0.hw,
			&g12a_cpu_clk_postmux1.hw,
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "Final_mux_sel" */
static struct clk_regmap g12a_cpu_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 11,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_dyn.hw,
			&g12a_sys_pll.hw,
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "Final_mux_sel" */
static struct clk_regmap g12b_cpu_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL0,
		.mask = 0x1,
		.shift = 11,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_dyn.hw,
			&g12b_sys1_pll.hw
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "premux0" */
static struct clk_regmap g12b_cpub_clk_premux0 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL,
		.mask = 0x3,
		.shift = 0,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_dyn0_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = (const struct clk_parent_data []) {
			{ .fw_name = "xtal", },
			{ .hw = &g12a_fclk_div2.hw },
			{ .hw = &g12a_fclk_div3.hw },
		},
		.num_parents = 3,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "mux0_divn_tcnt" */
static struct clk_regmap g12b_cpub_clk_mux0_div = {
	.data = &(struct meson_clk_cpu_dyndiv_data){
		.div = {
			.reg_off = HHI_SYS_CPUB_CLK_CNTL,
			.shift = 4,
			.width = 6,
		},
		.dyn = {
			.reg_off = HHI_SYS_CPUB_CLK_CNTL,
			.shift = 26,
			.width = 1,
		},
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_dyn0_div",
		.ops = &meson_clk_cpu_dyndiv_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_premux0.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "postmux0" */
static struct clk_regmap g12b_cpub_clk_postmux0 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL,
		.mask = 0x1,
		.shift = 2,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_dyn0",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_premux0.hw,
			&g12b_cpub_clk_mux0_div.hw
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "premux1" */
static struct clk_regmap g12b_cpub_clk_premux1 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL,
		.mask = 0x3,
		.shift = 16,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_dyn1_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = (const struct clk_parent_data []) {
			{ .fw_name = "xtal", },
			{ .hw = &g12a_fclk_div2.hw },
			{ .hw = &g12a_fclk_div3.hw },
		},
		.num_parents = 3,
		/* This sub-tree is used a parking clock */
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

/* Datasheet names this field as "Mux1_divn_tcnt" */
static struct clk_regmap g12b_cpub_clk_mux1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL,
		.shift = 20,
		.width = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_dyn1_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_premux1.hw
		},
		.num_parents = 1,
	},
};

/* Datasheet names this field as "postmux1" */
static struct clk_regmap g12b_cpub_clk_postmux1 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL,
		.mask = 0x1,
		.shift = 18,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_dyn1",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_premux1.hw,
			&g12b_cpub_clk_mux1_div.hw
		},
		.num_parents = 2,
		/* This sub-tree is used a parking clock */
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

/* Datasheet names this field as "Final_dyn_mux_sel" */
static struct clk_regmap g12b_cpub_clk_dyn = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL,
		.mask = 0x1,
		.shift = 10,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_dyn",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_postmux0.hw,
			&g12b_cpub_clk_postmux1.hw
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Datasheet names this field as "Final_mux_sel" */
static struct clk_regmap g12b_cpub_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL,
		.mask = 0x1,
		.shift = 11,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_dyn.hw,
			&g12a_sys_pll.hw
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap sm1_gp1_pll;

/* Datasheet names this field as "premux0" */
static struct clk_regmap sm1_dsu_clk_premux0 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL5,
		.mask = 0x3,
		.shift = 0,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk_dyn0_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_data = (const struct clk_parent_data []) {
			{ .fw_name = "xtal", },
			{ .hw = &g12a_fclk_div2.hw },
			{ .hw = &g12a_fclk_div3.hw },
			{ .hw = &sm1_gp1_pll.hw },
		},
		.num_parents = 4,
	},
};

/* Datasheet names this field as "premux1" */
static struct clk_regmap sm1_dsu_clk_premux1 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL5,
		.mask = 0x3,
		.shift = 16,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk_dyn1_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_data = (const struct clk_parent_data []) {
			{ .fw_name = "xtal", },
			{ .hw = &g12a_fclk_div2.hw },
			{ .hw = &g12a_fclk_div3.hw },
			{ .hw = &sm1_gp1_pll.hw },
		},
		.num_parents = 4,
	},
};

/* Datasheet names this field as "Mux0_divn_tcnt" */
static struct clk_regmap sm1_dsu_clk_mux0_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL5,
		.shift = 4,
		.width = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk_dyn0_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_dsu_clk_premux0.hw
		},
		.num_parents = 1,
	},
};

/* Datasheet names this field as "postmux0" */
static struct clk_regmap sm1_dsu_clk_postmux0 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL5,
		.mask = 0x1,
		.shift = 2,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk_dyn0",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_dsu_clk_premux0.hw,
			&sm1_dsu_clk_mux0_div.hw,
		},
		.num_parents = 2,
	},
};

/* Datasheet names this field as "Mux1_divn_tcnt" */
static struct clk_regmap sm1_dsu_clk_mux1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL5,
		.shift = 20,
		.width = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk_dyn1_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_dsu_clk_premux1.hw
		},
		.num_parents = 1,
	},
};

/* Datasheet names this field as "postmux1" */
static struct clk_regmap sm1_dsu_clk_postmux1 = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL5,
		.mask = 0x1,
		.shift = 18,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk_dyn1",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_dsu_clk_premux1.hw,
			&sm1_dsu_clk_mux1_div.hw,
		},
		.num_parents = 2,
	},
};

/* Datasheet names this field as "Final_dyn_mux_sel" */
static struct clk_regmap sm1_dsu_clk_dyn = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL5,
		.mask = 0x1,
		.shift = 10,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk_dyn",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_dsu_clk_postmux0.hw,
			&sm1_dsu_clk_postmux1.hw,
		},
		.num_parents = 2,
	},
};

/* Datasheet names this field as "Final_mux_sel" */
static struct clk_regmap sm1_dsu_final_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL5,
		.mask = 0x1,
		.shift = 11,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk_final",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_dsu_clk_dyn.hw,
			&g12a_sys_pll.hw,
		},
		.num_parents = 2,
	},
};

/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 0 */
static struct clk_regmap sm1_cpu1_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL6,
		.mask = 0x1,
		.shift = 24,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu1_clk",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk.hw,
			/* This CPU also have a dedicated clock tree */
		},
		.num_parents = 1,
	},
};

/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 1 */
static struct clk_regmap sm1_cpu2_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL6,
		.mask = 0x1,
		.shift = 25,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu2_clk",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk.hw,
			/* This CPU also have a dedicated clock tree */
		},
		.num_parents = 1,
	},
};

/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 2 */
static struct clk_regmap sm1_cpu3_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL6,
		.mask = 0x1,
		.shift = 26,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu3_clk",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk.hw,
			/* This CPU also have a dedicated clock tree */
		},
		.num_parents = 1,
	},
};

/* Datasheet names this field as "Cpu_clk_sync_mux_sel" bit 4 */
static struct clk_regmap sm1_dsu_clk = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPU_CLK_CNTL6,
		.mask = 0x1,
		.shift = 27,
	},
	.hw.init = &(struct clk_init_data){
		.name = "dsu_clk",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk.hw,
			&sm1_dsu_final_clk.hw,
		},
		.num_parents = 2,
	},
};

static int g12a_cpu_clk_mux_notifier_cb(struct notifier_block *nb,
					unsigned long event, void *data)
{
	if (event == POST_RATE_CHANGE || event == PRE_RATE_CHANGE) {
		/* Wait for clock propagation before/after changing the mux */
		udelay(100);
		return NOTIFY_OK;
	}

	return NOTIFY_DONE;
}

static struct notifier_block g12a_cpu_clk_mux_nb = {
	.notifier_call = g12a_cpu_clk_mux_notifier_cb,
};

struct g12a_cpu_clk_postmux_nb_data {
	struct notifier_block nb;
	struct clk_hw *xtal;
	struct clk_hw *cpu_clk_dyn;
	struct clk_hw *cpu_clk_postmux0;
	struct clk_hw *cpu_clk_postmux1;
	struct clk_hw *cpu_clk_premux1;
};

static int g12a_cpu_clk_postmux_notifier_cb(struct notifier_block *nb,
					    unsigned long event, void *data)
{
	struct g12a_cpu_clk_postmux_nb_data *nb_data =
		container_of(nb, struct g12a_cpu_clk_postmux_nb_data, nb);

	switch (event) {
	case PRE_RATE_CHANGE:
		/*
		 * This notifier means cpu_clk_postmux0 clock will be changed
		 * to feed cpu_clk, this is the current path :
		 * cpu_clk
		 *    \- cpu_clk_dyn
		 *          \- cpu_clk_postmux0
		 *                \- cpu_clk_muxX_div
		 *                      \- cpu_clk_premux0
		 *				\- fclk_div3 or fclk_div2
		 *		OR
		 *                \- cpu_clk_premux0
		 *			\- fclk_div3 or fclk_div2
		 */

		/* Setup cpu_clk_premux1 to xtal */
		clk_hw_set_parent(nb_data->cpu_clk_premux1,
				  nb_data->xtal);

		/* Setup cpu_clk_postmux1 to bypass divider */
		clk_hw_set_parent(nb_data->cpu_clk_postmux1,
				  nb_data->cpu_clk_premux1);

		/* Switch to parking clk on cpu_clk_postmux1 */
		clk_hw_set_parent(nb_data->cpu_clk_dyn,
				  nb_data->cpu_clk_postmux1);

		/*
		 * Now, cpu_clk is 24MHz in the current path :
		 * cpu_clk
		 *    \- cpu_clk_dyn
		 *          \- cpu_clk_postmux1
		 *                \- cpu_clk_premux1
		 *                      \- xtal
		 */

		udelay(100);

		return NOTIFY_OK;

	case POST_RATE_CHANGE:
		/*
		 * The cpu_clk_postmux0 has ben updated, now switch back
		 * cpu_clk_dyn to cpu_clk_postmux0 and take the changes
		 * in account.
		 */

		/* Configure cpu_clk_dyn back to cpu_clk_postmux0 */
		clk_hw_set_parent(nb_data->cpu_clk_dyn,
				  nb_data->cpu_clk_postmux0);

		/*
		 * new path :
		 * cpu_clk
		 *    \- cpu_clk_dyn
		 *          \- cpu_clk_postmux0
		 *                \- cpu_clk_muxX_div
		 *                      \- cpu_clk_premux0
		 *				\- fclk_div3 or fclk_div2
		 *		OR
		 *                \- cpu_clk_premux0
		 *			\- fclk_div3 or fclk_div2
		 */

		udelay(100);

		return NOTIFY_OK;

	default:
		return NOTIFY_DONE;
	}
}

static struct g12a_cpu_clk_postmux_nb_data g12a_cpu_clk_postmux0_nb_data = {
	.cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
	.cpu_clk_postmux0 = &g12a_cpu_clk_postmux0.hw,
	.cpu_clk_postmux1 = &g12a_cpu_clk_postmux1.hw,
	.cpu_clk_premux1 = &g12a_cpu_clk_premux1.hw,
	.nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
};

static struct g12a_cpu_clk_postmux_nb_data g12b_cpub_clk_postmux0_nb_data = {
	.cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
	.cpu_clk_postmux0 = &g12b_cpub_clk_postmux0.hw,
	.cpu_clk_postmux1 = &g12b_cpub_clk_postmux1.hw,
	.cpu_clk_premux1 = &g12b_cpub_clk_premux1.hw,
	.nb.notifier_call = g12a_cpu_clk_postmux_notifier_cb,
};

struct g12a_sys_pll_nb_data {
	struct notifier_block nb;
	struct clk_hw *sys_pll;
	struct clk_hw *cpu_clk;
	struct clk_hw *cpu_clk_dyn;
};

static int g12a_sys_pll_notifier_cb(struct notifier_block *nb,
				    unsigned long event, void *data)
{
	struct g12a_sys_pll_nb_data *nb_data =
		container_of(nb, struct g12a_sys_pll_nb_data, nb);

	switch (event) {
	case PRE_RATE_CHANGE:
		/*
		 * This notifier means sys_pll clock will be changed
		 * to feed cpu_clk, this the current path :
		 * cpu_clk
		 *    \- sys_pll
		 *          \- sys_pll_dco
		 */

		/* Configure cpu_clk to use cpu_clk_dyn */
		clk_hw_set_parent(nb_data->cpu_clk,
				  nb_data->cpu_clk_dyn);

		/*
		 * Now, cpu_clk uses the dyn path
		 * cpu_clk
		 *    \- cpu_clk_dyn
		 *          \- cpu_clk_dynX
		 *                \- cpu_clk_dynX_sel
		 *		     \- cpu_clk_dynX_div
		 *                      \- xtal/fclk_div2/fclk_div3
		 *                   \- xtal/fclk_div2/fclk_div3
		 */

		udelay(100);

		return NOTIFY_OK;

	case POST_RATE_CHANGE:
		/*
		 * The sys_pll has ben updated, now switch back cpu_clk to
		 * sys_pll
		 */

		/* Configure cpu_clk to use sys_pll */
		clk_hw_set_parent(nb_data->cpu_clk,
				  nb_data->sys_pll);

		udelay(100);

		/* new path :
		 * cpu_clk
		 *    \- sys_pll
		 *          \- sys_pll_dco
		 */

		return NOTIFY_OK;

	default:
		return NOTIFY_DONE;
	}
}

static struct g12a_sys_pll_nb_data g12a_sys_pll_nb_data = {
	.sys_pll = &g12a_sys_pll.hw,
	.cpu_clk = &g12a_cpu_clk.hw,
	.cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
	.nb.notifier_call = g12a_sys_pll_notifier_cb,
};

/* G12B first CPU cluster uses sys1_pll */
static struct g12a_sys_pll_nb_data g12b_cpu_clk_sys1_pll_nb_data = {
	.sys_pll = &g12b_sys1_pll.hw,
	.cpu_clk = &g12b_cpu_clk.hw,
	.cpu_clk_dyn = &g12a_cpu_clk_dyn.hw,
	.nb.notifier_call = g12a_sys_pll_notifier_cb,
};

/* G12B second CPU cluster uses sys_pll */
static struct g12a_sys_pll_nb_data g12b_cpub_clk_sys_pll_nb_data = {
	.sys_pll = &g12a_sys_pll.hw,
	.cpu_clk = &g12b_cpub_clk.hw,
	.cpu_clk_dyn = &g12b_cpub_clk_dyn.hw,
	.nb.notifier_call = g12a_sys_pll_notifier_cb,
};

static struct clk_regmap g12a_cpu_clk_div16_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 1,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_div16_en",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk.hw
		},
		.num_parents = 1,
		/*
		 * This clock is used to debug the cpu_clk range
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12b_cpub_clk_div16_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.bit_idx = 1,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpub_clk_div16_en",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk.hw
		},
		.num_parents = 1,
		/*
		 * This clock is used to debug the cpu_clk range
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_fixed_factor g12a_cpu_clk_div16 = {
	.mult = 1,
	.div = 16,
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_div16",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_div16_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12b_cpub_clk_div16 = {
	.mult = 1,
	.div = 16,
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_div16",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_div16_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_apb_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.shift = 3,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_apb_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_apb = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 1,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_apb",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_apb_div.hw
		},
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12a_cpu_clk_atb_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.shift = 6,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_atb_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_atb = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 17,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_atb",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_atb_div.hw
		},
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12a_cpu_clk_axi_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.shift = 9,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_axi_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_cpu_clk.hw },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_axi = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 18,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_axi",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_axi_div.hw
		},
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12a_cpu_clk_trace_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.shift = 20,
		.width = 3,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpu_clk_trace_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_data = &(const struct clk_parent_data) {
			/*
			 * Note:
			 * G12A and G12B have different cpu_clks (with
			 * different struct clk_hw). We fallback to the global
			 * naming string mechanism so cpu_clk_trace_div picks
			 * up the appropriate one.
			 */
			.name = "cpu_clk",
			.index = -1,
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_cpu_clk_trace = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPU_CLK_CNTL1,
		.bit_idx = 23,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpu_clk_trace",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cpu_clk_trace_div.hw
		},
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_fixed_factor g12b_cpub_clk_div2 = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_div2",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12b_cpub_clk_div3 = {
	.mult = 1,
	.div = 3,
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_div3",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12b_cpub_clk_div4 = {
	.mult = 1,
	.div = 4,
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_div4",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12b_cpub_clk_div5 = {
	.mult = 1,
	.div = 5,
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_div5",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12b_cpub_clk_div6 = {
	.mult = 1,
	.div = 6,
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_div6",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12b_cpub_clk_div7 = {
	.mult = 1,
	.div = 7,
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_div7",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12b_cpub_clk_div8 = {
	.mult = 1,
	.div = 8,
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_div8",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk.hw
		},
		.num_parents = 1,
	},
};

static u32 mux_table_cpub[] = { 1, 2, 3, 4, 5, 6, 7 };
static struct clk_regmap g12b_cpub_clk_apb_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.mask = 7,
		.shift = 3,
		.table = mux_table_cpub,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_apb_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_div2.hw,
			&g12b_cpub_clk_div3.hw,
			&g12b_cpub_clk_div4.hw,
			&g12b_cpub_clk_div5.hw,
			&g12b_cpub_clk_div6.hw,
			&g12b_cpub_clk_div7.hw,
			&g12b_cpub_clk_div8.hw
		},
		.num_parents = 7,
	},
};

static struct clk_regmap g12b_cpub_clk_apb = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.bit_idx = 16,
		.flags = CLK_GATE_SET_TO_DISABLE,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpub_clk_apb",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_apb_sel.hw
		},
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12b_cpub_clk_atb_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.mask = 7,
		.shift = 6,
		.table = mux_table_cpub,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_atb_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_div2.hw,
			&g12b_cpub_clk_div3.hw,
			&g12b_cpub_clk_div4.hw,
			&g12b_cpub_clk_div5.hw,
			&g12b_cpub_clk_div6.hw,
			&g12b_cpub_clk_div7.hw,
			&g12b_cpub_clk_div8.hw
		},
		.num_parents = 7,
	},
};

static struct clk_regmap g12b_cpub_clk_atb = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.bit_idx = 17,
		.flags = CLK_GATE_SET_TO_DISABLE,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpub_clk_atb",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_atb_sel.hw
		},
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12b_cpub_clk_axi_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.mask = 7,
		.shift = 9,
		.table = mux_table_cpub,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_axi_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_div2.hw,
			&g12b_cpub_clk_div3.hw,
			&g12b_cpub_clk_div4.hw,
			&g12b_cpub_clk_div5.hw,
			&g12b_cpub_clk_div6.hw,
			&g12b_cpub_clk_div7.hw,
			&g12b_cpub_clk_div8.hw
		},
		.num_parents = 7,
	},
};

static struct clk_regmap g12b_cpub_clk_axi = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.bit_idx = 18,
		.flags = CLK_GATE_SET_TO_DISABLE,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpub_clk_axi",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_axi_sel.hw
		},
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static struct clk_regmap g12b_cpub_clk_trace_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.mask = 7,
		.shift = 20,
		.table = mux_table_cpub,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cpub_clk_trace_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_div2.hw,
			&g12b_cpub_clk_div3.hw,
			&g12b_cpub_clk_div4.hw,
			&g12b_cpub_clk_div5.hw,
			&g12b_cpub_clk_div6.hw,
			&g12b_cpub_clk_div7.hw,
			&g12b_cpub_clk_div8.hw
		},
		.num_parents = 7,
	},
};

static struct clk_regmap g12b_cpub_clk_trace = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SYS_CPUB_CLK_CNTL1,
		.bit_idx = 23,
		.flags = CLK_GATE_SET_TO_DISABLE,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cpub_clk_trace",
		.ops = &clk_regmap_gate_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12b_cpub_clk_trace_sel.hw
		},
		.num_parents = 1,
		/*
		 * This clock is set by the ROM monitor code,
		 * Linux should not change it at runtime
		 */
	},
};

static const struct pll_mult_range g12a_gp0_pll_mult_range = {
	.min = 125,
	.max = 255,
};

/*
 * Internal gp0 pll emulation configuration parameters
 */
static const struct reg_sequence g12a_gp0_init_regs[] = {
	{ .reg = HHI_GP0_PLL_CNTL1,	.def = 0x00000000 },
	{ .reg = HHI_GP0_PLL_CNTL2,	.def = 0x00000000 },
	{ .reg = HHI_GP0_PLL_CNTL3,	.def = 0x48681c00 },
	{ .reg = HHI_GP0_PLL_CNTL4,	.def = 0x33771290 },
	{ .reg = HHI_GP0_PLL_CNTL5,	.def = 0x39272000 },
	{ .reg = HHI_GP0_PLL_CNTL6,	.def = 0x56540000 },
};

static struct clk_regmap g12a_gp0_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_GP0_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_GP0_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_GP0_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.frac = {
			.reg_off = HHI_GP0_PLL_CNTL1,
			.shift   = 0,
			.width   = 17,
		},
		.l = {
			.reg_off = HHI_GP0_PLL_CNTL0,
			.shift   = 31,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_GP0_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
		.range = &g12a_gp0_pll_mult_range,
		.init_regs = g12a_gp0_init_regs,
		.init_count = ARRAY_SIZE(g12a_gp0_init_regs),
	},
	.hw.init = &(struct clk_init_data){
		.name = "gp0_pll_dco",
		.ops = &meson_clk_pll_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_gp0_pll = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_GP0_PLL_CNTL0,
		.shift = 16,
		.width = 3,
		.flags = (CLK_DIVIDER_POWER_OF_TWO |
			  CLK_DIVIDER_ROUND_CLOSEST),
	},
	.hw.init = &(struct clk_init_data){
		.name = "gp0_pll",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_gp0_pll_dco.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap sm1_gp1_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_GP1_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_GP1_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_GP1_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.frac = {
			.reg_off = HHI_GP1_PLL_CNTL1,
			.shift   = 0,
			.width   = 17,
		},
		.l = {
			.reg_off = HHI_GP1_PLL_CNTL0,
			.shift   = 31,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_GP1_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
	},
	.hw.init = &(struct clk_init_data){
		.name = "gp1_pll_dco",
		.ops = &meson_clk_pll_ro_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
		/* This clock feeds the DSU, avoid disabling it */
		.flags = CLK_IS_CRITICAL,
	},
};

static struct clk_regmap sm1_gp1_pll = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_GP1_PLL_CNTL0,
		.shift = 16,
		.width = 3,
		.flags = (CLK_DIVIDER_POWER_OF_TWO |
			  CLK_DIVIDER_ROUND_CLOSEST),
	},
	.hw.init = &(struct clk_init_data){
		.name = "gp1_pll",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_gp1_pll_dco.hw
		},
		.num_parents = 1,
	},
};

/*
 * Internal hifi pll emulation configuration parameters
 */
static const struct reg_sequence g12a_hifi_init_regs[] = {
	{ .reg = HHI_HIFI_PLL_CNTL1,	.def = 0x00000000 },
	{ .reg = HHI_HIFI_PLL_CNTL2,	.def = 0x00000000 },
	{ .reg = HHI_HIFI_PLL_CNTL3,	.def = 0x6a285c00 },
	{ .reg = HHI_HIFI_PLL_CNTL4,	.def = 0x65771290 },
	{ .reg = HHI_HIFI_PLL_CNTL5,	.def = 0x39272000 },
	{ .reg = HHI_HIFI_PLL_CNTL6,	.def = 0x56540000 },
};

static struct clk_regmap g12a_hifi_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_HIFI_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_HIFI_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_HIFI_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.frac = {
			.reg_off = HHI_HIFI_PLL_CNTL1,
			.shift   = 0,
			.width   = 17,
		},
		.l = {
			.reg_off = HHI_HIFI_PLL_CNTL0,
			.shift   = 31,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_HIFI_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
		.range = &g12a_gp0_pll_mult_range,
		.init_regs = g12a_hifi_init_regs,
		.init_count = ARRAY_SIZE(g12a_hifi_init_regs),
		.flags = CLK_MESON_PLL_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "hifi_pll_dco",
		.ops = &meson_clk_pll_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_hifi_pll = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_HIFI_PLL_CNTL0,
		.shift = 16,
		.width = 2,
		.flags = (CLK_DIVIDER_POWER_OF_TWO |
			  CLK_DIVIDER_ROUND_CLOSEST),
	},
	.hw.init = &(struct clk_init_data){
		.name = "hifi_pll",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_hifi_pll_dco.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/*
 * The Meson G12A PCIE PLL is fined tuned to deliver a very precise
 * 100MHz reference clock for the PCIe Analog PHY, and thus requires
 * a strict register sequence to enable the PLL.
 */
static const struct reg_sequence g12a_pcie_pll_init_regs[] = {
	{ .reg = HHI_PCIE_PLL_CNTL0,	.def = 0x20090496 },
	{ .reg = HHI_PCIE_PLL_CNTL0,	.def = 0x30090496 },
	{ .reg = HHI_PCIE_PLL_CNTL1,	.def = 0x00000000 },
	{ .reg = HHI_PCIE_PLL_CNTL2,	.def = 0x00001100 },
	{ .reg = HHI_PCIE_PLL_CNTL3,	.def = 0x10058e00 },
	{ .reg = HHI_PCIE_PLL_CNTL4,	.def = 0x000100c0 },
	{ .reg = HHI_PCIE_PLL_CNTL5,	.def = 0x68000048 },
	{ .reg = HHI_PCIE_PLL_CNTL5,	.def = 0x68000068, .delay_us = 20 },
	{ .reg = HHI_PCIE_PLL_CNTL4,	.def = 0x008100c0, .delay_us = 10 },
	{ .reg = HHI_PCIE_PLL_CNTL0,	.def = 0x34090496 },
	{ .reg = HHI_PCIE_PLL_CNTL0,	.def = 0x14090496, .delay_us = 10 },
	{ .reg = HHI_PCIE_PLL_CNTL2,	.def = 0x00001000 },
};

/* Keep a single entry table for recalc/round_rate() ops */
static const struct pll_params_table g12a_pcie_pll_table[] = {
	PLL_PARAMS(150, 1),
	{0, 0},
};

static struct clk_regmap g12a_pcie_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.frac = {
			.reg_off = HHI_PCIE_PLL_CNTL1,
			.shift   = 0,
			.width   = 12,
		},
		.l = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 31,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_PCIE_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
		.table = g12a_pcie_pll_table,
		.init_regs = g12a_pcie_pll_init_regs,
		.init_count = ARRAY_SIZE(g12a_pcie_pll_init_regs),
	},
	.hw.init = &(struct clk_init_data){
		.name = "pcie_pll_dco",
		.ops = &meson_clk_pcie_pll_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_pcie_pll_dco_div2 = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "pcie_pll_dco_div2",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_pcie_pll_dco.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_pcie_pll_od = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_PCIE_PLL_CNTL0,
		.shift = 16,
		.width = 5,
		.flags = CLK_DIVIDER_ROUND_CLOSEST |
			 CLK_DIVIDER_ONE_BASED |
			 CLK_DIVIDER_ALLOW_ZERO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "pcie_pll_od",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_pcie_pll_dco_div2.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_fixed_factor g12a_pcie_pll = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "pcie_pll_pll",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_pcie_pll_od.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_hdmi_pll_dco = {
	.data = &(struct meson_clk_pll_data){
		.en = {
			.reg_off = HHI_HDMI_PLL_CNTL0,
			.shift   = 28,
			.width   = 1,
		},
		.m = {
			.reg_off = HHI_HDMI_PLL_CNTL0,
			.shift   = 0,
			.width   = 8,
		},
		.n = {
			.reg_off = HHI_HDMI_PLL_CNTL0,
			.shift   = 10,
			.width   = 5,
		},
		.frac = {
			.reg_off = HHI_HDMI_PLL_CNTL1,
			.shift   = 0,
			.width   = 16,
		},
		.l = {
			.reg_off = HHI_HDMI_PLL_CNTL0,
			.shift   = 30,
			.width   = 1,
		},
		.rst = {
			.reg_off = HHI_HDMI_PLL_CNTL0,
			.shift   = 29,
			.width   = 1,
		},
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_pll_dco",
		.ops = &meson_clk_pll_ro_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
		/*
		 * Display directly handle hdmi pll registers ATM, we need
		 * NOCACHE to keep our view of the clock as accurate as possible
		 */
		.flags = CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_hdmi_pll_od = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_HDMI_PLL_CNTL0,
		.shift = 16,
		.width = 2,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_pll_od",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_hdmi_pll_dco.hw
		},
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_hdmi_pll_od2 = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_HDMI_PLL_CNTL0,
		.shift = 18,
		.width = 2,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_pll_od2",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_hdmi_pll_od.hw
		},
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_hdmi_pll = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_HDMI_PLL_CNTL0,
		.shift = 20,
		.width = 2,
		.flags = CLK_DIVIDER_POWER_OF_TWO,
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_pll",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_hdmi_pll_od2.hw
		},
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT,
	},
};

static struct clk_fixed_factor g12a_fclk_div4_div = {
	.mult = 1,
	.div = 4,
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div4_div",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_fclk_div4 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_FIX_PLL_CNTL1,
		.bit_idx = 21,
	},
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div4",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fclk_div4_div.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_fclk_div5_div = {
	.mult = 1,
	.div = 5,
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div5_div",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_fclk_div5 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_FIX_PLL_CNTL1,
		.bit_idx = 22,
	},
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div5",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fclk_div5_div.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_fclk_div7_div = {
	.mult = 1,
	.div = 7,
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div7_div",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_fixed_pll.hw },
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_fclk_div7 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_FIX_PLL_CNTL1,
		.bit_idx = 23,
	},
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div7",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fclk_div7_div.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_fclk_div2p5_div = {
	.mult = 1,
	.div = 5,
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div2p5_div",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fixed_pll_dco.hw
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_fclk_div2p5 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_FIX_PLL_CNTL1,
		.bit_idx = 25,
	},
	.hw.init = &(struct clk_init_data){
		.name = "fclk_div2p5",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fclk_div2p5_div.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_mpll_50m_div = {
	.mult = 1,
	.div = 80,
	.hw.init = &(struct clk_init_data){
		.name = "mpll_50m_div",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fixed_pll_dco.hw
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_mpll_50m = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_FIX_PLL_CNTL3,
		.mask = 0x1,
		.shift = 5,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll_50m",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_data = (const struct clk_parent_data []) {
			{ .fw_name = "xtal", },
			{ .hw = &g12a_mpll_50m_div.hw },
		},
		.num_parents = 2,
	},
};

static struct clk_fixed_factor g12a_mpll_prediv = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "mpll_prediv",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_fixed_pll_dco.hw
		},
		.num_parents = 1,
	},
};

static const struct reg_sequence g12a_mpll0_init_regs[] = {
	{ .reg = HHI_MPLL_CNTL2,	.def = 0x40000033 },
};

static struct clk_regmap g12a_mpll0_div = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL1,
			.shift   = 0,
			.width   = 14,
		},
		.sdm_en = {
			.reg_off = HHI_MPLL_CNTL1,
			.shift   = 30,
			.width	 = 1,
		},
		.n2 = {
			.reg_off = HHI_MPLL_CNTL1,
			.shift   = 20,
			.width   = 9,
		},
		.ssen = {
			.reg_off = HHI_MPLL_CNTL1,
			.shift   = 29,
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
		.init_regs = g12a_mpll0_init_regs,
		.init_count = ARRAY_SIZE(g12a_mpll0_init_regs),
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll0_div",
		.ops = &meson_clk_mpll_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mpll_prediv.hw
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_mpll0 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_MPLL_CNTL1,
		.bit_idx = 31,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll0",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_mpll0_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static const struct reg_sequence g12a_mpll1_init_regs[] = {
	{ .reg = HHI_MPLL_CNTL4,	.def = 0x40000033 },
};

static struct clk_regmap g12a_mpll1_div = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL3,
			.shift   = 0,
			.width   = 14,
		},
		.sdm_en = {
			.reg_off = HHI_MPLL_CNTL3,
			.shift   = 30,
			.width	 = 1,
		},
		.n2 = {
			.reg_off = HHI_MPLL_CNTL3,
			.shift   = 20,
			.width   = 9,
		},
		.ssen = {
			.reg_off = HHI_MPLL_CNTL3,
			.shift   = 29,
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
		.init_regs = g12a_mpll1_init_regs,
		.init_count = ARRAY_SIZE(g12a_mpll1_init_regs),
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll1_div",
		.ops = &meson_clk_mpll_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mpll_prediv.hw
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_mpll1 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_MPLL_CNTL3,
		.bit_idx = 31,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll1",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_mpll1_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static const struct reg_sequence g12a_mpll2_init_regs[] = {
	{ .reg = HHI_MPLL_CNTL6,	.def = 0x40000033 },
};

static struct clk_regmap g12a_mpll2_div = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL5,
			.shift   = 0,
			.width   = 14,
		},
		.sdm_en = {
			.reg_off = HHI_MPLL_CNTL5,
			.shift   = 30,
			.width	 = 1,
		},
		.n2 = {
			.reg_off = HHI_MPLL_CNTL5,
			.shift   = 20,
			.width   = 9,
		},
		.ssen = {
			.reg_off = HHI_MPLL_CNTL5,
			.shift   = 29,
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
		.init_regs = g12a_mpll2_init_regs,
		.init_count = ARRAY_SIZE(g12a_mpll2_init_regs),
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll2_div",
		.ops = &meson_clk_mpll_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mpll_prediv.hw
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_mpll2 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_MPLL_CNTL5,
		.bit_idx = 31,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll2",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_mpll2_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static const struct reg_sequence g12a_mpll3_init_regs[] = {
	{ .reg = HHI_MPLL_CNTL8,	.def = 0x40000033 },
};

static struct clk_regmap g12a_mpll3_div = {
	.data = &(struct meson_clk_mpll_data){
		.sdm = {
			.reg_off = HHI_MPLL_CNTL7,
			.shift   = 0,
			.width   = 14,
		},
		.sdm_en = {
			.reg_off = HHI_MPLL_CNTL7,
			.shift   = 30,
			.width	 = 1,
		},
		.n2 = {
			.reg_off = HHI_MPLL_CNTL7,
			.shift   = 20,
			.width   = 9,
		},
		.ssen = {
			.reg_off = HHI_MPLL_CNTL7,
			.shift   = 29,
			.width	 = 1,
		},
		.lock = &meson_clk_lock,
		.init_regs = g12a_mpll3_init_regs,
		.init_count = ARRAY_SIZE(g12a_mpll3_init_regs),
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll3_div",
		.ops = &meson_clk_mpll_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mpll_prediv.hw
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_mpll3 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_MPLL_CNTL7,
		.bit_idx = 31,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpll3",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_mpll3_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static u32 mux_table_clk81[]	= { 0, 2, 3, 4, 5, 6, 7 };
static const struct clk_parent_data clk81_parent_data[] = {
	{ .fw_name = "xtal", },
	{ .hw = &g12a_fclk_div7.hw },
	{ .hw = &g12a_mpll1.hw },
	{ .hw = &g12a_mpll2.hw },
	{ .hw = &g12a_fclk_div4.hw },
	{ .hw = &g12a_fclk_div3.hw },
	{ .hw = &g12a_fclk_div5.hw },
};

static struct clk_regmap g12a_mpeg_clk_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_MPEG_CLK_CNTL,
		.mask = 0x7,
		.shift = 12,
		.table = mux_table_clk81,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpeg_clk_sel",
		.ops = &clk_regmap_mux_ro_ops,
		.parent_data = clk81_parent_data,
		.num_parents = ARRAY_SIZE(clk81_parent_data),
	},
};

static struct clk_regmap g12a_mpeg_clk_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_MPEG_CLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mpeg_clk_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mpeg_clk_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_clk81 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_MPEG_CLK_CNTL,
		.bit_idx = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "clk81",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mpeg_clk_div.hw
		},
		.num_parents = 1,
		.flags = (CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
	},
};

static const struct clk_parent_data g12a_sd_emmc_clk0_parent_data[] = {
	{ .fw_name = "xtal", },
	{ .hw = &g12a_fclk_div2.hw },
	{ .hw = &g12a_fclk_div3.hw },
	{ .hw = &g12a_fclk_div5.hw },
	{ .hw = &g12a_fclk_div7.hw },
	/*
	 * Following these parent clocks, we should also have had mpll2, mpll3
	 * and gp0_pll but these clocks are too precious to be used here. All
	 * the necessary rates for MMC and NAND operation can be acheived using
	 * g12a_ee_core or fclk_div clocks
	 */
};

/* SDIO clock */
static struct clk_regmap g12a_sd_emmc_a_clk0_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SD_EMMC_CLK_CNTL,
		.mask = 0x7,
		.shift = 9,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sd_emmc_a_clk0_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = g12a_sd_emmc_clk0_parent_data,
		.num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_sd_emmc_a_clk0_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SD_EMMC_CLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sd_emmc_a_clk0_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_sd_emmc_a_clk0_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_sd_emmc_a_clk0 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SD_EMMC_CLK_CNTL,
		.bit_idx = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "sd_emmc_a_clk0",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_sd_emmc_a_clk0_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* SDcard clock */
static struct clk_regmap g12a_sd_emmc_b_clk0_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SD_EMMC_CLK_CNTL,
		.mask = 0x7,
		.shift = 25,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sd_emmc_b_clk0_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = g12a_sd_emmc_clk0_parent_data,
		.num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_sd_emmc_b_clk0_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SD_EMMC_CLK_CNTL,
		.shift = 16,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sd_emmc_b_clk0_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_sd_emmc_b_clk0_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_sd_emmc_b_clk0 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SD_EMMC_CLK_CNTL,
		.bit_idx = 23,
	},
	.hw.init = &(struct clk_init_data){
		.name = "sd_emmc_b_clk0",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_sd_emmc_b_clk0_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* EMMC/NAND clock */
static struct clk_regmap g12a_sd_emmc_c_clk0_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_NAND_CLK_CNTL,
		.mask = 0x7,
		.shift = 9,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sd_emmc_c_clk0_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = g12a_sd_emmc_clk0_parent_data,
		.num_parents = ARRAY_SIZE(g12a_sd_emmc_clk0_parent_data),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_sd_emmc_c_clk0_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_NAND_CLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "sd_emmc_c_clk0_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_sd_emmc_c_clk0_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_sd_emmc_c_clk0 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_NAND_CLK_CNTL,
		.bit_idx = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "sd_emmc_c_clk0",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_sd_emmc_c_clk0_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Video Clocks */

static struct clk_regmap g12a_vid_pll_div = {
	.data = &(struct meson_vid_pll_div_data){
		.val = {
			.reg_off = HHI_VID_PLL_CLK_DIV,
			.shift   = 0,
			.width   = 15,
		},
		.sel = {
			.reg_off = HHI_VID_PLL_CLK_DIV,
			.shift   = 16,
			.width   = 2,
		},
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vid_pll_div",
		.ops = &meson_vid_pll_div_ro_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_pll.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_GET_RATE_NOCACHE,
	},
};

static const struct clk_hw *g12a_vid_pll_parent_hws[] = {
	&g12a_vid_pll_div.hw,
	&g12a_hdmi_pll.hw,
};

static struct clk_regmap g12a_vid_pll_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VID_PLL_CLK_DIV,
		.mask = 0x1,
		.shift = 18,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vid_pll_sel",
		.ops = &clk_regmap_mux_ops,
		/*
		 * bit 18 selects from 2 possible parents:
		 * vid_pll_div or hdmi_pll
		 */
		.parent_hws = g12a_vid_pll_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vid_pll_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_vid_pll = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_PLL_CLK_DIV,
		.bit_idx = 19,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vid_pll",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vid_pll_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

/* VPU Clock */

static const struct clk_hw *g12a_vpu_parent_hws[] = {
	&g12a_fclk_div3.hw,
	&g12a_fclk_div4.hw,
	&g12a_fclk_div5.hw,
	&g12a_fclk_div7.hw,
	&g12a_mpll1.hw,
	&g12a_vid_pll.hw,
	&g12a_hifi_pll.hw,
	&g12a_gp0_pll.hw,
};

static struct clk_regmap g12a_vpu_0_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VPU_CLK_CNTL,
		.mask = 0x7,
		.shift = 9,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vpu_0_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vpu_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vpu_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

static struct clk_regmap g12a_vpu_0_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VPU_CLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vpu_0_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_sel.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vpu_0 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VPU_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vpu_0",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vpu_0_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vpu_1_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VPU_CLK_CNTL,
		.mask = 0x7,
		.shift = 25,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vpu_1_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vpu_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vpu_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

static struct clk_regmap g12a_vpu_1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VPU_CLK_CNTL,
		.shift = 16,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vpu_1_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_sel.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vpu_1 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VPU_CLK_CNTL,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vpu_1",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vpu_1_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vpu = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VPU_CLK_CNTL,
		.mask = 1,
		.shift = 31,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vpu",
		.ops = &clk_regmap_mux_ops,
		/*
		 * bit 31 selects from 2 possible parents:
		 * vpu_0 or vpu_1
		 */
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vpu_0.hw,
			&g12a_vpu_1.hw,
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

/* VDEC clocks */

static const struct clk_hw *g12a_vdec_parent_hws[] = {
	&g12a_fclk_div2p5.hw,
	&g12a_fclk_div3.hw,
	&g12a_fclk_div4.hw,
	&g12a_fclk_div5.hw,
	&g12a_fclk_div7.hw,
	&g12a_hifi_pll.hw,
	&g12a_gp0_pll.hw,
};

static struct clk_regmap g12a_vdec_1_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VDEC_CLK_CNTL,
		.mask = 0x7,
		.shift = 9,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_1_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vdec_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VDEC_CLK_CNTL,
		.shift = 0,
		.width = 7,
		.flags = CLK_DIVIDER_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_1_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vdec_1_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_1 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VDEC_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vdec_1",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vdec_1_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevcf_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.mask = 0x7,
		.shift = 9,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_hevcf_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vdec_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevcf_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.shift = 0,
		.width = 7,
		.flags = CLK_DIVIDER_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_hevcf_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vdec_hevcf_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevcf = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vdec_hevcf",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vdec_hevcf_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevc_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.mask = 0x7,
		.shift = 25,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_hevc_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vdec_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vdec_parent_hws),
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevc_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.shift = 16,
		.width = 7,
		.flags = CLK_DIVIDER_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vdec_hevc_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vdec_hevc_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vdec_hevc = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VDEC2_CLK_CNTL,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vdec_hevc",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vdec_hevc_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* VAPB Clock */

static const struct clk_hw *g12a_vapb_parent_hws[] = {
	&g12a_fclk_div4.hw,
	&g12a_fclk_div3.hw,
	&g12a_fclk_div5.hw,
	&g12a_fclk_div7.hw,
	&g12a_mpll1.hw,
	&g12a_vid_pll.hw,
	&g12a_mpll2.hw,
	&g12a_fclk_div2p5.hw,
};

static struct clk_regmap g12a_vapb_0_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VAPBCLK_CNTL,
		.mask = 0x3,
		.shift = 9,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vapb_0_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vapb_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vapb_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

static struct clk_regmap g12a_vapb_0_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VAPBCLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vapb_0_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vapb_0_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vapb_0 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VAPBCLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vapb_0",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vapb_0_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vapb_1_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VAPBCLK_CNTL,
		.mask = 0x3,
		.shift = 25,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vapb_1_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vapb_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vapb_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

static struct clk_regmap g12a_vapb_1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VAPBCLK_CNTL,
		.shift = 16,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vapb_1_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vapb_1_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_vapb_1 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VAPBCLK_CNTL,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vapb_1",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vapb_1_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vapb_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VAPBCLK_CNTL,
		.mask = 1,
		.shift = 31,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vapb_sel",
		.ops = &clk_regmap_mux_ops,
		/*
		 * bit 31 selects from 2 possible parents:
		 * vapb_0 or vapb_1
		 */
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vapb_0.hw,
			&g12a_vapb_1.hw,
		},
		.num_parents = 2,
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

static struct clk_regmap g12a_vapb = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VAPBCLK_CNTL,
		.bit_idx = 30,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vapb",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vapb_sel.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static const struct clk_hw *g12a_vclk_parent_hws[] = {
	&g12a_vid_pll.hw,
	&g12a_gp0_pll.hw,
	&g12a_hifi_pll.hw,
	&g12a_mpll1.hw,
	&g12a_fclk_div3.hw,
	&g12a_fclk_div4.hw,
	&g12a_fclk_div5.hw,
	&g12a_fclk_div7.hw,
};

static struct clk_regmap g12a_vclk_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VID_CLK_CNTL,
		.mask = 0x7,
		.shift = 16,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vclk_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vclk_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vclk_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_vclk2_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VIID_CLK_CNTL,
		.mask = 0x7,
		.shift = 16,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vclk2_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_vclk_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_vclk_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_vclk_input = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_DIV,
		.bit_idx = 16,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk_input",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk_sel.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk2_input = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VIID_CLK_DIV,
		.bit_idx = 16,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk2_input",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_sel.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VID_CLK_DIV,
		.shift = 0,
		.width = 8,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vclk_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk_input.hw
		},
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_vclk2_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_VIID_CLK_DIV,
		.shift = 0,
		.width = 8,
	},
	.hw.init = &(struct clk_init_data){
		.name = "vclk2_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk2_input.hw
		},
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_vclk = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 19,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk2 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VIID_CLK_CNTL,
		.bit_idx = 19,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk2",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk_div1 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 0,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk_div1",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk_div2_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 1,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk_div2_en",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk_div4_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 2,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk_div4_en",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk_div6_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 3,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk_div6_en",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk_div12_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL,
		.bit_idx = 4,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk_div12_en",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk2_div1 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VIID_CLK_CNTL,
		.bit_idx = 0,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk2_div1",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk2_div2_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VIID_CLK_CNTL,
		.bit_idx = 1,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk2_div2_en",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk2_div4_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VIID_CLK_CNTL,
		.bit_idx = 2,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk2_div4_en",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk2_div6_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VIID_CLK_CNTL,
		.bit_idx = 3,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk2_div6_en",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_vclk2_div12_en = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VIID_CLK_CNTL,
		.bit_idx = 4,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "vclk2_div12_en",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_vclk2.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_fixed_factor g12a_vclk_div2 = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "vclk_div2",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk_div2_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_vclk_div4 = {
	.mult = 1,
	.div = 4,
	.hw.init = &(struct clk_init_data){
		.name = "vclk_div4",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk_div4_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_vclk_div6 = {
	.mult = 1,
	.div = 6,
	.hw.init = &(struct clk_init_data){
		.name = "vclk_div6",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk_div6_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_vclk_div12 = {
	.mult = 1,
	.div = 12,
	.hw.init = &(struct clk_init_data){
		.name = "vclk_div12",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk_div12_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_vclk2_div2 = {
	.mult = 1,
	.div = 2,
	.hw.init = &(struct clk_init_data){
		.name = "vclk2_div2",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk2_div2_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_vclk2_div4 = {
	.mult = 1,
	.div = 4,
	.hw.init = &(struct clk_init_data){
		.name = "vclk2_div4",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk2_div4_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_vclk2_div6 = {
	.mult = 1,
	.div = 6,
	.hw.init = &(struct clk_init_data){
		.name = "vclk2_div6",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk2_div6_en.hw
		},
		.num_parents = 1,
	},
};

static struct clk_fixed_factor g12a_vclk2_div12 = {
	.mult = 1,
	.div = 12,
	.hw.init = &(struct clk_init_data){
		.name = "vclk2_div12",
		.ops = &clk_fixed_factor_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_vclk2_div12_en.hw
		},
		.num_parents = 1,
	},
};

static u32 mux_table_cts_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
static const struct clk_hw *g12a_cts_parent_hws[] = {
	&g12a_vclk_div1.hw,
	&g12a_vclk_div2.hw,
	&g12a_vclk_div4.hw,
	&g12a_vclk_div6.hw,
	&g12a_vclk_div12.hw,
	&g12a_vclk2_div1.hw,
	&g12a_vclk2_div2.hw,
	&g12a_vclk2_div4.hw,
	&g12a_vclk2_div6.hw,
	&g12a_vclk2_div12.hw,
};

static struct clk_regmap g12a_cts_enci_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VID_CLK_DIV,
		.mask = 0xf,
		.shift = 28,
		.table = mux_table_cts_sel,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cts_enci_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_cts_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_cts_encp_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VID_CLK_DIV,
		.mask = 0xf,
		.shift = 20,
		.table = mux_table_cts_sel,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cts_encp_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_cts_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_cts_vdac_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_VIID_CLK_DIV,
		.mask = 0xf,
		.shift = 28,
		.table = mux_table_cts_sel,
	},
	.hw.init = &(struct clk_init_data){
		.name = "cts_vdac_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_cts_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
	},
};

/* TOFIX: add support for cts_tcon */
static u32 mux_table_hdmi_tx_sel[] = { 0, 1, 2, 3, 4, 8, 9, 10, 11, 12 };
static const struct clk_hw *g12a_cts_hdmi_tx_parent_hws[] = {
	&g12a_vclk_div1.hw,
	&g12a_vclk_div2.hw,
	&g12a_vclk_div4.hw,
	&g12a_vclk_div6.hw,
	&g12a_vclk_div12.hw,
	&g12a_vclk2_div1.hw,
	&g12a_vclk2_div2.hw,
	&g12a_vclk2_div4.hw,
	&g12a_vclk2_div6.hw,
	&g12a_vclk2_div12.hw,
};

static struct clk_regmap g12a_hdmi_tx_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_HDMI_CLK_CNTL,
		.mask = 0xf,
		.shift = 16,
		.table = mux_table_hdmi_tx_sel,
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_tx_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_cts_hdmi_tx_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_cts_hdmi_tx_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_cts_enci = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL2,
		.bit_idx = 0,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cts_enci",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cts_enci_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_cts_encp = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL2,
		.bit_idx = 2,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cts_encp",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cts_encp_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_cts_vdac = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL2,
		.bit_idx = 4,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "cts_vdac",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_cts_vdac_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

static struct clk_regmap g12a_hdmi_tx = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_VID_CLK_CNTL2,
		.bit_idx = 5,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "hdmi_tx",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_hdmi_tx_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

/* MIPI DSI Host Clocks */

static const struct clk_hw *g12a_mipi_dsi_pxclk_parent_hws[] = {
	&g12a_vid_pll.hw,
	&g12a_gp0_pll.hw,
	&g12a_hifi_pll.hw,
	&g12a_mpll1.hw,
	&g12a_fclk_div2.hw,
	&g12a_fclk_div2p5.hw,
	&g12a_fclk_div3.hw,
	&g12a_fclk_div7.hw,
};

static struct clk_regmap g12a_mipi_dsi_pxclk_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_MIPIDSI_PHY_CLK_CNTL,
		.mask = 0x7,
		.shift = 12,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mipi_dsi_pxclk_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_mipi_dsi_pxclk_parent_hws,
		.num_parents = ARRAY_SIZE(g12a_mipi_dsi_pxclk_parent_hws),
		.flags = CLK_SET_RATE_NO_REPARENT,
	},
};

static struct clk_regmap g12a_mipi_dsi_pxclk_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_MIPIDSI_PHY_CLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mipi_dsi_pxclk_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mipi_dsi_pxclk_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_mipi_dsi_pxclk = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_MIPIDSI_PHY_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "mipi_dsi_pxclk",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mipi_dsi_pxclk_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* HDMI Clocks */

static const struct clk_parent_data g12a_hdmi_parent_data[] = {
	{ .fw_name = "xtal", },
	{ .hw = &g12a_fclk_div4.hw },
	{ .hw = &g12a_fclk_div3.hw },
	{ .hw = &g12a_fclk_div5.hw },
};

static struct clk_regmap g12a_hdmi_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_HDMI_CLK_CNTL,
		.mask = 0x3,
		.shift = 9,
		.flags = CLK_MUX_ROUND_CLOSEST,
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = g12a_hdmi_parent_data,
		.num_parents = ARRAY_SIZE(g12a_hdmi_parent_data),
		.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_hdmi_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_HDMI_CLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "hdmi_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_sel.hw },
		.num_parents = 1,
		.flags = CLK_GET_RATE_NOCACHE,
	},
};

static struct clk_regmap g12a_hdmi = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_HDMI_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data) {
		.name = "hdmi",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) { &g12a_hdmi_div.hw },
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
	},
};

/*
 * The MALI IP is clocked by two identical clocks (mali_0 and mali_1)
 * muxed by a glitch-free switch. The CCF can manage this glitch-free
 * mux because it does top-to-bottom updates the each clock tree and
 * switches to the "inactive" one when CLK_SET_RATE_GATE is set.
 */
static const struct clk_parent_data g12a_mali_0_1_parent_data[] = {
	{ .fw_name = "xtal", },
	{ .hw = &g12a_gp0_pll.hw },
	{ .hw = &g12a_hifi_pll.hw },
	{ .hw = &g12a_fclk_div2p5.hw },
	{ .hw = &g12a_fclk_div3.hw },
	{ .hw = &g12a_fclk_div4.hw },
	{ .hw = &g12a_fclk_div5.hw },
	{ .hw = &g12a_fclk_div7.hw },
};

static struct clk_regmap g12a_mali_0_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_MALI_CLK_CNTL,
		.mask = 0x7,
		.shift = 9,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mali_0_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = g12a_mali_0_1_parent_data,
		.num_parents = 8,
		/*
		 * Don't request the parent to change the rate because
		 * all GPU frequencies can be derived from the fclk_*
		 * clocks and one special GP0_PLL setting. This is
		 * important because we need the MPLL clocks for audio.
		 */
		.flags = 0,
	},
};

static struct clk_regmap g12a_mali_0_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_MALI_CLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mali_0_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mali_0_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_mali_0 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_MALI_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mali_0",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mali_0_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_mali_1_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_MALI_CLK_CNTL,
		.mask = 0x7,
		.shift = 25,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mali_1_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = g12a_mali_0_1_parent_data,
		.num_parents = 8,
		/*
		 * Don't request the parent to change the rate because
		 * all GPU frequencies can be derived from the fclk_*
		 * clocks and one special GP0_PLL setting. This is
		 * important because we need the MPLL clocks for audio.
		 */
		.flags = 0,
	},
};

static struct clk_regmap g12a_mali_1_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_MALI_CLK_CNTL,
		.shift = 16,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mali_1_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mali_1_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_mali_1 = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_MALI_CLK_CNTL,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mali_1",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_mali_1_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_GATE | CLK_SET_RATE_PARENT,
	},
};

static const struct clk_hw *g12a_mali_parent_hws[] = {
	&g12a_mali_0.hw,
	&g12a_mali_1.hw,
};

static struct clk_regmap g12a_mali = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_MALI_CLK_CNTL,
		.mask = 1,
		.shift = 31,
	},
	.hw.init = &(struct clk_init_data){
		.name = "mali",
		.ops = &clk_regmap_mux_ops,
		.parent_hws = g12a_mali_parent_hws,
		.num_parents = 2,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_ts_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_TS_CLK_CNTL,
		.shift = 0,
		.width = 8,
	},
	.hw.init = &(struct clk_init_data){
		.name = "ts_div",
		.ops = &clk_regmap_divider_ro_ops,
		.parent_data = &(const struct clk_parent_data) {
			.fw_name = "xtal",
		},
		.num_parents = 1,
	},
};

static struct clk_regmap g12a_ts = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_TS_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data){
		.name = "ts",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_ts_div.hw
		},
		.num_parents = 1,
	},
};

/* SPICC SCLK source clock */

static const struct clk_parent_data spicc_sclk_parent_data[] = {
	{ .fw_name = "xtal", },
	{ .hw = &g12a_clk81.hw },
	{ .hw = &g12a_fclk_div4.hw },
	{ .hw = &g12a_fclk_div3.hw },
	{ .hw = &g12a_fclk_div5.hw },
	{ .hw = &g12a_fclk_div7.hw },
};

static struct clk_regmap g12a_spicc0_sclk_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SPICC_CLK_CNTL,
		.mask = 7,
		.shift = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "spicc0_sclk_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = spicc_sclk_parent_data,
		.num_parents = ARRAY_SIZE(spicc_sclk_parent_data),
	},
};

static struct clk_regmap g12a_spicc0_sclk_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SPICC_CLK_CNTL,
		.shift = 0,
		.width = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "spicc0_sclk_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_spicc0_sclk_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_spicc0_sclk = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SPICC_CLK_CNTL,
		.bit_idx = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "spicc0_sclk",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_spicc0_sclk_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_spicc1_sclk_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_SPICC_CLK_CNTL,
		.mask = 7,
		.shift = 23,
	},
	.hw.init = &(struct clk_init_data){
		.name = "spicc1_sclk_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = spicc_sclk_parent_data,
		.num_parents = ARRAY_SIZE(spicc_sclk_parent_data),
	},
};

static struct clk_regmap g12a_spicc1_sclk_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_SPICC_CLK_CNTL,
		.shift = 16,
		.width = 6,
	},
	.hw.init = &(struct clk_init_data){
		.name = "spicc1_sclk_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_spicc1_sclk_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap g12a_spicc1_sclk = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_SPICC_CLK_CNTL,
		.bit_idx = 22,
	},
	.hw.init = &(struct clk_init_data){
		.name = "spicc1_sclk",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&g12a_spicc1_sclk_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

/* Neural Network Accelerator source clock */

static const struct clk_parent_data nna_clk_parent_data[] = {
	{ .fw_name = "xtal", },
	{ .hw = &g12a_gp0_pll.hw, },
	{ .hw = &g12a_hifi_pll.hw, },
	{ .hw = &g12a_fclk_div2p5.hw, },
	{ .hw = &g12a_fclk_div3.hw, },
	{ .hw = &g12a_fclk_div4.hw, },
	{ .hw = &g12a_fclk_div5.hw, },
	{ .hw = &g12a_fclk_div7.hw },
};

static struct clk_regmap sm1_nna_axi_clk_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_NNA_CLK_CNTL,
		.mask = 7,
		.shift = 9,
	},
	.hw.init = &(struct clk_init_data){
		.name = "nna_axi_clk_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = nna_clk_parent_data,
		.num_parents = ARRAY_SIZE(nna_clk_parent_data),
	},
};

static struct clk_regmap sm1_nna_axi_clk_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_NNA_CLK_CNTL,
		.shift = 0,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "nna_axi_clk_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_nna_axi_clk_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap sm1_nna_axi_clk = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_NNA_CLK_CNTL,
		.bit_idx = 8,
	},
	.hw.init = &(struct clk_init_data){
		.name = "nna_axi_clk",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_nna_axi_clk_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap sm1_nna_core_clk_sel = {
	.data = &(struct clk_regmap_mux_data){
		.offset = HHI_NNA_CLK_CNTL,
		.mask = 7,
		.shift = 25,
	},
	.hw.init = &(struct clk_init_data){
		.name = "nna_core_clk_sel",
		.ops = &clk_regmap_mux_ops,
		.parent_data = nna_clk_parent_data,
		.num_parents = ARRAY_SIZE(nna_clk_parent_data),
	},
};

static struct clk_regmap sm1_nna_core_clk_div = {
	.data = &(struct clk_regmap_div_data){
		.offset = HHI_NNA_CLK_CNTL,
		.shift = 16,
		.width = 7,
	},
	.hw.init = &(struct clk_init_data){
		.name = "nna_core_clk_div",
		.ops = &clk_regmap_divider_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_nna_core_clk_sel.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

static struct clk_regmap sm1_nna_core_clk = {
	.data = &(struct clk_regmap_gate_data){
		.offset = HHI_NNA_CLK_CNTL,
		.bit_idx = 24,
	},
	.hw.init = &(struct clk_init_data){
		.name = "nna_core_clk",
		.ops = &clk_regmap_gate_ops,
		.parent_hws = (const struct clk_hw *[]) {
			&sm1_nna_core_clk_div.hw
		},
		.num_parents = 1,
		.flags = CLK_SET_RATE_PARENT,
	},
};

#define MESON_GATE(_name, _reg, _bit) \
	MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw)

#define MESON_GATE_RO(_name, _reg, _bit) \
	MESON_PCLK_RO(_name, _reg, _bit, &g12a_clk81.hw)

/* Everything Else (EE) domain gates */
static MESON_GATE(g12a_ddr,			HHI_GCLK_MPEG0,	0);
static MESON_GATE(g12a_dos,			HHI_GCLK_MPEG0,	1);
static MESON_GATE(g12a_audio_locker,		HHI_GCLK_MPEG0,	2);
static MESON_GATE(g12a_mipi_dsi_host,		HHI_GCLK_MPEG0,	3);
static MESON_GATE(g12a_eth_phy,			HHI_GCLK_MPEG0,	4);
static MESON_GATE(g12a_isa,			HHI_GCLK_MPEG0,	5);
static MESON_GATE(g12a_pl301,			HHI_GCLK_MPEG0,	6);
static MESON_GATE(g12a_periphs,			HHI_GCLK_MPEG0,	7);
static MESON_GATE(g12a_spicc_0,			HHI_GCLK_MPEG0,	8);
static MESON_GATE(g12a_i2c,			HHI_GCLK_MPEG0,	9);
static MESON_GATE(g12a_sana,			HHI_GCLK_MPEG0,	10);
static MESON_GATE(g12a_sd,			HHI_GCLK_MPEG0,	11);
static MESON_GATE(g12a_rng0,			HHI_GCLK_MPEG0,	12);
static MESON_GATE(g12a_uart0,			HHI_GCLK_MPEG0,	13);
static MESON_GATE(g12a_spicc_1,			HHI_GCLK_MPEG0,	14);
static MESON_GATE(g12a_hiu_reg,			HHI_GCLK_MPEG0,	19);
static MESON_GATE(g12a_mipi_dsi_phy,		HHI_GCLK_MPEG0,	20);
static MESON_GATE(g12a_assist_misc,		HHI_GCLK_MPEG0,	23);
static MESON_GATE(g12a_emmc_a,			HHI_GCLK_MPEG0,	4);
static MESON_GATE(g12a_emmc_b,			HHI_GCLK_MPEG0,	25);
static MESON_GATE(g12a_emmc_c,			HHI_GCLK_MPEG0,	26);
static MESON_GATE(g12a_audio_codec,		HHI_GCLK_MPEG0,	28);

static MESON_GATE(g12a_audio,			HHI_GCLK_MPEG1,	0);
static MESON_GATE(g12a_eth_core,		HHI_GCLK_MPEG1,	3);
static MESON_GATE(g12a_demux,			HHI_GCLK_MPEG1,	4);
static MESON_GATE(g12a_audio_ififo,		HHI_GCLK_MPEG1,	11);
static MESON_GATE(g12a_adc,			HHI_GCLK_MPEG1,	13);
static MESON_GATE(g12a_uart1,			HHI_GCLK_MPEG1,	16);
static MESON_GATE(g12a_g2d,			HHI_GCLK_MPEG1,	20);
static MESON_GATE(g12a_reset,			HHI_GCLK_MPEG1,	23);
static MESON_GATE(g12a_pcie_comb,		HHI_GCLK_MPEG1,	24);
static MESON_GATE(g12a_parser,			HHI_GCLK_MPEG1,	25);
static MESON_GATE(g12a_usb_general,		HHI_GCLK_MPEG1,	26);
static MESON_GATE(g12a_pcie_phy,		HHI_GCLK_MPEG1,	27);
static MESON_GATE(g12a_ahb_arb0,		HHI_GCLK_MPEG1,	29);

static MESON_GATE(g12a_ahb_data_bus,		HHI_GCLK_MPEG2,	1);
static MESON_GATE(g12a_ahb_ctrl_bus,		HHI_GCLK_MPEG2,	2);
static MESON_GATE(g12a_htx_hdcp22,		HHI_GCLK_MPEG2,	3);
static MESON_GATE(g12a_htx_pclk,		HHI_GCLK_MPEG2,	4);
static MESON_GATE(g12a_bt656,			HHI_GCLK_MPEG2,	6);
static MESON_GATE(g12a_usb1_to_ddr,		HHI_GCLK_MPEG2,	8);
static MESON_GATE(g12a_mmc_pclk,		HHI_GCLK_MPEG2,	11);
static MESON_GATE(g12a_uart2,			HHI_GCLK_MPEG2,	15);
static MESON_GATE(g12a_vpu_intr,		HHI_GCLK_MPEG2,	25);
static MESON_GATE(g12a_gic,			HHI_GCLK_MPEG2,	30);

static MESON_GATE(g12a_vclk2_venci0,		HHI_GCLK_OTHER,	1);
static MESON_GATE(g12a_vclk2_venci1,		HHI_GCLK_OTHER,	2);
static MESON_GATE(g12a_vclk2_vencp0,		HHI_GCLK_OTHER,	3);
static MESON_GATE(g12a_vclk2_vencp1,		HHI_GCLK_OTHER,	4);
static MESON_GATE(g12a_vclk2_venct0,		HHI_GCLK_OTHER,	5);
static MESON_GATE(g12a_vclk2_venct1,		HHI_GCLK_OTHER,	6);
static MESON_GATE(g12a_vclk2_other,		HHI_GCLK_OTHER,	7);
static MESON_GATE(g12a_vclk2_enci,		HHI_GCLK_OTHER,	8);
static MESON_GATE(g12a_vclk2_encp,		HHI_GCLK_OTHER,	9);
static MESON_GATE(g12a_dac_clk,			HHI_GCLK_OTHER,	10);
static MESON_GATE(g12a_aoclk_gate,		HHI_GCLK_OTHER,	14);
static MESON_GATE(g12a_iec958_gate,		HHI_GCLK_OTHER,	16);
static MESON_GATE(g12a_enc480p,			HHI_GCLK_OTHER,	20);
static MESON_GATE(g12a_rng1,			HHI_GCLK_OTHER,	21);
static MESON_GATE(g12a_vclk2_enct,		HHI_GCLK_OTHER,	22);
static MESON_GATE(g12a_vclk2_encl,		HHI_GCLK_OTHER,	23);
static MESON_GATE(g12a_vclk2_venclmmc,		HHI_GCLK_OTHER,	24);
static MESON_GATE(g12a_vclk2_vencl,		HHI_GCLK_OTHER,	25);
static MESON_GATE(g12a_vclk2_other1,		HHI_GCLK_OTHER,	26);

static MESON_GATE_RO(g12a_dma,			HHI_GCLK_OTHER2, 0);
static MESON_GATE_RO(g12a_efuse,		HHI_GCLK_OTHER2, 1);
static MESON_GATE_RO(g12a_rom_boot,		HHI_GCLK_OTHER2, 2);
static MESON_GATE_RO(g12a_reset_sec,		HHI_GCLK_OTHER2, 3);
static MESON_GATE_RO(g12a_sec_ahb_apb3,		HHI_GCLK_OTHER2, 4);

/* Array of all clocks provided by this provider */
static struct clk_hw *g12a_hw_clks[] = {
	[CLKID_SYS_PLL]			= &g12a_sys_pll.hw,
	[CLKID_FIXED_PLL]		= &g12a_fixed_pll.hw,
	[CLKID_FCLK_DIV2]		= &g12a_fclk_div2.hw,
	[CLKID_FCLK_DIV3]		= &g12a_fclk_div3.hw,
	[CLKID_FCLK_DIV4]		= &g12a_fclk_div4.hw,
	[CLKID_FCLK_DIV5]		= &g12a_fclk_div5.hw,
	[CLKID_FCLK_DIV7]		= &g12a_fclk_div7.hw,
	[CLKID_FCLK_DIV2P5]		= &g12a_fclk_div2p5.hw,
	[CLKID_GP0_PLL]			= &g12a_gp0_pll.hw,
	[CLKID_MPEG_SEL]		= &g12a_mpeg_clk_sel.hw,
	[CLKID_MPEG_DIV]		= &g12a_mpeg_clk_div.hw,
	[CLKID_CLK81]			= &g12a_clk81.hw,
	[CLKID_MPLL0]			= &g12a_mpll0.hw,
	[CLKID_MPLL1]			= &g12a_mpll1.hw,
	[CLKID_MPLL2]			= &g12a_mpll2.hw,
	[CLKID_MPLL3]			= &g12a_mpll3.hw,
	[CLKID_DDR]			= &g12a_ddr.hw,
	[CLKID_DOS]			= &g12a_dos.hw,
	[CLKID_AUDIO_LOCKER]		= &g12a_audio_locker.hw,
	[CLKID_MIPI_DSI_HOST]		= &g12a_mipi_dsi_host.hw,
	[CLKID_ETH_PHY]			= &g12a_eth_phy.hw,
	[CLKID_ISA]			= &g12a_isa.hw,
	[CLKID_PL301]			= &g12a_pl301.hw,
	[CLKID_PERIPHS]			= &g12a_periphs.hw,
	[CLKID_SPICC0]			= &g12a_spicc_0.hw,
	[CLKID_I2C]			= &g12a_i2c.hw,
	[CLKID_SANA]			= &g12a_sana.hw,
	[CLKID_SD]			= &g12a_sd.hw,
	[CLKID_RNG0]			= &g12a_rng0.hw,
	[CLKID_UART0]			= &g12a_uart0.hw,
	[CLKID_SPICC1]			= &g12a_spicc_1.hw,
	[CLKID_HIU_IFACE]		= &g12a_hiu_reg.hw,
	[CLKID_MIPI_DSI_PHY]		= &g12a_mipi_dsi_phy.hw,
	[CLKID_ASSIST_MISC]		= &g12a_assist_misc.hw,
	[CLKID_SD_EMMC_A]		= &g12a_emmc_a.hw,
	[CLKID_SD_EMMC_B]		= &g12a_emmc_b.hw,
	[CLKID_SD_EMMC_C]		= &g12a_emmc_c.hw,
	[CLKID_AUDIO_CODEC]		= &g12a_audio_codec.hw,
	[CLKID_AUDIO]			= &g12a_audio.hw,
	[CLKID_ETH]			= &g12a_eth_core.hw,
	[CLKID_DEMUX]			= &g12a_demux.hw,
	[CLKID_AUDIO_IFIFO]		= &g12a_audio_ififo.hw,
	[CLKID_ADC]			= &g12a_adc.hw,
	[CLKID_UART1]			= &g12a_uart1.hw,
	[CLKID_G2D]			= &g12a_g2d.hw,
	[CLKID_RESET]			= &g12a_reset.hw,
	[CLKID_PCIE_COMB]		= &g12a_pcie_comb.hw,
	[CLKID_PARSER]			= &g12a_parser.hw,
	[CLKID_USB]			= &g12a_usb_general.hw,
	[CLKID_PCIE_PHY]		= &g12a_pcie_phy.hw,
	[CLKID_AHB_ARB0]		= &g12a_ahb_arb0.hw,
	[CLKID_AHB_DATA_BUS]		= &g12a_ahb_data_bus.hw,
	[CLKID_AHB_CTRL_BUS]		= &g12a_ahb_ctrl_bus.hw,
	[CLKID_HTX_HDCP22]		= &g12a_htx_hdcp22.hw,
	[CLKID_HTX_PCLK]		= &g12a_htx_pclk.hw,
	[CLKID_BT656]			= &g12a_bt656.hw,
	[CLKID_USB1_DDR_BRIDGE]		= &g12a_usb1_to_ddr.hw,
	[CLKID_MMC_PCLK]		= &g12a_mmc_pclk.hw,
	[CLKID_UART2]			= &g12a_uart2.hw,
	[CLKID_VPU_INTR]		= &g12a_vpu_intr.hw,
	[CLKID_GIC]			= &g12a_gic.hw,
	[CLKID_SD_EMMC_A_CLK0_SEL]	= &g12a_sd_emmc_a_clk0_sel.hw,
	[CLKID_SD_EMMC_A_CLK0_DIV]	= &g12a_sd_emmc_a_clk0_div.hw,
	[CLKID_SD_EMMC_A_CLK0]		= &g12a_sd_emmc_a_clk0.hw,
	[CLKID_SD_EMMC_B_CLK0_SEL]	= &g12a_sd_emmc_b_clk0_sel.hw,
	[CLKID_SD_EMMC_B_CLK0_DIV]	= &g12a_sd_emmc_b_clk0_div.hw,
	[CLKID_SD_EMMC_B_CLK0]		= &g12a_sd_emmc_b_clk0.hw,
	[CLKID_SD_EMMC_C_CLK0_SEL]	= &g12a_sd_emmc_c_clk0_sel.hw,
	[CLKID_SD_EMMC_C_CLK0_DIV]	= &g12a_sd_emmc_c_clk0_div.hw,
	[CLKID_SD_EMMC_C_CLK0]		= &g12a_sd_emmc_c_clk0.hw,
	[CLKID_MPLL0_DIV]		= &g12a_mpll0_div.hw,
	[CLKID_MPLL1_DIV]		= &g12a_mpll1_div.hw,
	[CLKID_MPLL2_DIV]		= &g12a_mpll2_div.hw,
	[CLKID_MPLL3_DIV]		= &g12a_mpll3_div.hw,
	[CLKID_FCLK_DIV2_DIV]		= &g12a_fclk_div2_div.hw,
	[CLKID_FCLK_DIV3_DIV]		= &g12a_fclk_div3_div.hw,
	[CLKID_FCLK_DIV4_DIV]		= &g12a_fclk_div4_div.hw,
	[CLKID_FCLK_DIV5_DIV]		= &g12a_fclk_div5_div.hw,
	[CLKID_FCLK_DIV7_DIV]		= &g12a_fclk_div7_div.hw,
	[CLKID_FCLK_DIV2P5_DIV]		= &g12a_fclk_div2p5_div.hw,
	[CLKID_HIFI_PLL]		= &g12a_hifi_pll.hw,
	[CLKID_VCLK2_VENCI0]		= &g12a_vclk2_venci0.hw,
	[CLKID_VCLK2_VENCI1]		= &g12a_vclk2_venci1.hw,
	[CLKID_VCLK2_VENCP0]		= &g12a_vclk2_vencp0.hw,
	[CLKID_VCLK2_VENCP1]		= &g12a_vclk2_vencp1.hw,
	[CLKID_VCLK2_VENCT0]		= &g12a_vclk2_venct0.hw,
	[CLKID_VCLK2_VENCT1]		= &g12a_vclk2_venct1.hw,
	[CLKID_VCLK2_OTHER]		= &g12a_vclk2_other.hw,
	[CLKID_VCLK2_ENCI]		= &g12a_vclk2_enci.hw,
	[CLKID_VCLK2_ENCP]		= &g12a_vclk2_encp.hw,
	[CLKID_DAC_CLK]			= &g12a_dac_clk.hw,
	[CLKID_AOCLK]			= &g12a_aoclk_gate.hw,
	[CLKID_IEC958]			= &g12a_iec958_gate.hw,
	[CLKID_ENC480P]			= &g12a_enc480p.hw,
	[CLKID_RNG1]			= &g12a_rng1.hw,
	[CLKID_VCLK2_ENCT]		= &g12a_vclk2_enct.hw,
	[CLKID_VCLK2_ENCL]		= &g12a_vclk2_encl.hw,
	[CLKID_VCLK2_VENCLMMC]		= &g12a_vclk2_venclmmc.hw,
	[CLKID_VCLK2_VENCL]		= &g12a_vclk2_vencl.hw,
	[CLKID_VCLK2_OTHER1]		= &g12a_vclk2_other1.hw,
	[CLKID_FIXED_PLL_DCO]		= &g12a_fixed_pll_dco.hw,
	[CLKID_SYS_PLL_DCO]		= &g12a_sys_pll_dco.hw,
	[CLKID_GP0_PLL_DCO]		= &g12a_gp0_pll_dco.hw,
	[CLKID_HIFI_PLL_DCO]		= &g12a_hifi_pll_dco.hw,
	[CLKID_DMA]			= &g12a_dma.hw,
	[CLKID_EFUSE]			= &g12a_efuse.hw,
	[CLKID_ROM_BOOT]		= &g12a_rom_boot.hw,
	[CLKID_RESET_SEC]		= &g12a_reset_sec.hw,
	[CLKID_SEC_AHB_APB3]		= &g12a_sec_ahb_apb3.hw,
	[CLKID_MPLL_PREDIV]		= &g12a_mpll_prediv.hw,
	[CLKID_VPU_0_SEL]		= &g12a_vpu_0_sel.hw,
	[CLKID_VPU_0_DIV]		= &g12a_vpu_0_div.hw,
	[CLKID_VPU_0]			= &g12a_vpu_0.hw,
	[CLKID_VPU_1_SEL]		= &g12a_vpu_1_sel.hw,
	[CLKID_VPU_1_DIV]		= &g12a_vpu_1_div.hw,
	[CLKID_VPU_1]			= &g12a_vpu_1.hw,
	[CLKID_VPU]			= &g12a_vpu.hw,
	[CLKID_VAPB_0_SEL]		= &g12a_vapb_0_sel.hw,
	[CLKID_VAPB_0_DIV]		= &g12a_vapb_0_div.hw,
	[CLKID_VAPB_0]			= &g12a_vapb_0.hw,
	[CLKID_VAPB_1_SEL]		= &g12a_vapb_1_sel.hw,
	[CLKID_VAPB_1_DIV]		= &g12a_vapb_1_div.hw,
	[CLKID_VAPB_1]			= &g12a_vapb_1.hw,
	[CLKID_VAPB_SEL]		= &g12a_vapb_sel.hw,
	[CLKID_VAPB]			= &g12a_vapb.hw,
	[CLKID_HDMI_PLL_DCO]		= &g12a_hdmi_pll_dco.hw,
	[CLKID_HDMI_PLL_OD]		= &g12a_hdmi_pll_od.hw,
	[CLKID_HDMI_PLL_OD2]		= &g12a_hdmi_pll_od2.hw,
	[CLKID_HDMI_PLL]		= &g12a_hdmi_pll.hw,
	[CLKID_VID_PLL]			= &g12a_vid_pll_div.hw,
	[CLKID_VID_PLL_SEL]		= &g12a_vid_pll_sel.hw,
	[CLKID_VID_PLL_DIV]		= &g12a_vid_pll.hw,
	[CLKID_VCLK_SEL]		= &g12a_vclk_sel.hw,
	[CLKID_VCLK2_SEL]		= &g12a_vclk2_sel.hw,
	[CLKID_VCLK_INPUT]		= &g12a_vclk_input.hw,
	[CLKID_VCLK2_INPUT]		= &g12a_vclk2_input.hw,
	[CLKID_VCLK_DIV]		= &g12a_vclk_div.hw,
	[CLKID_VCLK2_DIV]		= &g12a_vclk2_div.hw,
	[CLKID_VCLK]			= &g12a_vclk.hw,
	[CLKID_VCLK2]			= &g12a_vclk2.hw,
	[CLKID_VCLK_DIV1]		= &g12a_vclk_div1.hw,
	[CLKID_VCLK_DIV2_EN]		= &g12a_vclk_div2_en.hw,
	[CLKID_VCLK_DIV4_EN]		= &g12a_vclk_div4_en.hw,
	[CLKID_VCLK_DIV6_EN]		= &g12a_vclk_div6_en.hw,
	[CLKID_VCLK_DIV12_EN]		= &g12a_vclk_div12_en.hw,
	[CLKID_VCLK2_DIV1]		= &g12a_vclk2_div1.hw,
	[CLKID_VCLK2_DIV2_EN]		= &g12a_vclk2_div2_en.hw,
	[CLKID_VCLK2_DIV4_EN]		= &g12a_vclk2_div4_en.hw,
	[CLKID_VCLK2_DIV6_EN]		= &g12a_vclk2_div6_en.hw,
	[CLKID_VCLK2_DIV12_EN]		= &g12a_vclk2_div12_en.hw,
	[CLKID_VCLK_DIV2]		= &g12a_vclk_div2.hw,
	[CLKID_VCLK_DIV4]		= &g12a_vclk_div4.hw,
	[CLKID_VCLK_DIV6]		= &g12a_vclk_div6.hw,
	[CLKID_VCLK_DIV12]		= &g12a_vclk_div12.hw,
	[CLKID_VCLK2_DIV2]		= &g12a_vclk2_div2.hw,
	[CLKID_VCLK2_DIV4]		= &g12a_vclk2_div4.hw,
	[CLKID_VCLK2_DIV6]		= &g12a_vclk2_div6.hw,
	[CLKID_VCLK2_DIV12]		= &g12a_vclk2_div12.hw,
	[CLKID_CTS_ENCI_SEL]		= &g12a_cts_enci_sel.hw,
	[CLKID_CTS_ENCP_SEL]		= &g12a_cts_encp_sel.hw,
	[CLKID_CTS_VDAC_SEL]		= &g12a_cts_vdac_sel.hw,
	[CLKID_HDMI_TX_SEL]		= &g12a_hdmi_tx_sel.hw,
	[CLKID_CTS_ENCI]		= &g12a_cts_enci.hw,
	[CLKID_CTS_ENCP]		= &g12a_cts_encp.hw,
	[CLKID_CTS_VDAC]		= &g12a_cts_vdac.hw,
	[CLKID_HDMI_TX]			= &g12a_hdmi_tx.hw,
	[CLKID_HDMI_SEL]		= &g12a_hdmi_sel.hw,
	[CLKID_HDMI_DIV]		= &g12a_hdmi_div.hw,
	[CLKID_HDMI]			= &g12a_hdmi.hw,
	[CLKID_MALI_0_SEL]		= &g12a_mali_0_sel.hw,
	[CLKID_MALI_0_DIV]		= &g12a_mali_0_div.hw,
	[CLKID_MALI_0]			= &g12a_mali_0.hw,
	[CLKID_MALI_1_SEL]		= &g12a_mali_1_sel.hw,
	[CLKID_MALI_1_DIV]		= &g12a_mali_1_div.hw,
	[CLKID_MALI_1]			= &g12a_mali_1.hw,
	[CLKID_MALI]			= &g12a_mali.hw,
	[CLKID_MPLL_50M_DIV]		= &g12a_mpll_50m_div.hw,
	[CLKID_MPLL_50M]		= &g12a_mpll_50m.hw,
	[CLKID_SYS_PLL_DIV16_EN]	= &g12a_sys_pll_div16_en.hw,
	[CLKID_SYS_PLL_DIV16]		= &g12a_sys_pll_div16.hw,
	[CLKID_CPU_CLK_DYN0_SEL]	= &g12a_cpu_clk_premux0.hw,
	[CLKID_CPU_CLK_DYN0_DIV]	= &g12a_cpu_clk_mux0_div.hw,
	[CLKID_CPU_CLK_DYN0]		= &g12a_cpu_clk_postmux0.hw,
	[CLKID_CPU_CLK_DYN1_SEL]	= &g12a_cpu_clk_premux1.hw,
	[CLKID_CPU_CLK_DYN1_DIV]	= &g12a_cpu_clk_mux1_div.hw,
	[CLKID_CPU_CLK_DYN1]		= &g12a_cpu_clk_postmux1.hw,
	[CLKID_CPU_CLK_DYN]		= &g12a_cpu_clk_dyn.hw,
	[CLKID_CPU_CLK]			= &g12a_cpu_clk.hw,
	[CLKID_CPU_CLK_DIV16_EN]	= &g12a_cpu_clk_div16_en.hw,
	[CLKID_CPU_CLK_DIV16]		= &g12a_cpu_clk_div16.hw,
	[CLKID_CPU_CLK_APB_DIV]		= &g12a_cpu_clk_apb_div.hw,
	[CLKID_CPU_CLK_APB]		= &g12a_cpu_clk_apb.hw,
	[CLKID_CPU_CLK_ATB_DIV]		= &g12a_cpu_clk_atb_div.hw,
	[CLKID_CPU_CLK_ATB]		= &g12a_cpu_clk_atb.hw,
	[CLKID_CPU_CLK_AXI_DIV]		= &g12a_cpu_clk_axi_div.hw,
	[CLKID_CPU_CLK_AXI]		= &g12a_cpu_clk_axi.hw,
	[CLKID_CPU_CLK_TRACE_DIV]	= &g12a_cpu_clk_trace_div.hw,
	[CLKID_CPU_CLK_TRACE]		= &g12a_cpu_clk_trace.hw,
	[CLKID_PCIE_PLL_DCO]		= &g12a_pcie_pll_dco.hw,
	[CLKID_PCIE_PLL_DCO_DIV2]	= &g12a_pcie_pll_dco_div2.hw,
	[CLKID_PCIE_PLL_OD]		= &g12a_pcie_pll_od.hw,
	[CLKID_PCIE_PLL]		= &g12a_pcie_pll.hw,
	[CLKID_VDEC_1_SEL]		= &g12a_vdec_1_sel.hw,
	[CLKID_VDEC_1_DIV]		= &g12a_vdec_1_div.hw,
	[CLKID_VDEC_1]			= &g12a_vdec_1.hw,
	[CLKID_VDEC_HEVC_SEL]		= &g12a_vdec_hevc_sel.hw,
	[CLKID_VDEC_HEVC_DIV]		= &g12a_vdec_hevc_div.hw,
	[CLKID_VDEC_HEVC]		= &g12a_vdec_hevc.hw,
	[CLKID_VDEC_HEVCF_SEL]		= &g12a_vdec_hevcf_sel.hw,
	[CLKID_VDEC_HEVCF_DIV]		= &g12a_vdec_hevcf_div.hw,
	[CLKID_VDEC_HEVCF]		= &g12a_vdec_hevcf.hw,
	[CLKID_TS_DIV]			= &g12a_ts_div.hw,
	[CLKID_TS]			= &g12a_ts.hw,
	[CLKID_SPICC0_SCLK_SEL]		= &g12a_spicc0_sclk_sel.hw,
	[CLKID_SPICC0_SCLK_DIV]		= &g12a_spicc0_sclk_div.hw,
	[CLKID_SPICC0_SCLK]		= &g12a_spicc0_sclk.hw,
	[CLKID_SPICC1_SCLK_SEL]		= &g12a_spicc1_sclk_sel.hw,
	[CLKID_SPICC1_SCLK_DIV]		= &g12a_spicc1_sclk_div.hw,
	[CLKID_SPICC1_SCLK]		= &g12a_spicc1_sclk.hw,
	[CLKID_MIPI_DSI_PXCLK_SEL]	= &g12a_mipi_dsi_pxclk_sel.hw,
	[CLKID_MIPI_DSI_PXCLK_DIV]	= &g12a_mipi_dsi_pxclk_div.hw,
	[CLKID_MIPI_DSI_PXCLK]		= &g12a_mipi_dsi_pxclk.hw,
};

static struct clk_hw *g12b_hw_clks[] = {
	[CLKID_SYS_PLL]			= &g12a_sys_pll.hw,
	[CLKID_FIXED_PLL]		= &g12a_fixed_pll.hw,
	[CLKID_FCLK_DIV2]		= &g12a_fclk_div2.hw,
	[CLKID_FCLK_DIV3]		= &g12a_fclk_div3.hw,
	[CLKID_FCLK_DIV4]		= &g12a_fclk_div4.hw,
	[CLKID_FCLK_DIV5]		= &g12a_fclk_div5.hw,
	[CLKID_FCLK_DIV7]		= &g12a_fclk_div7.hw,
	[CLKID_FCLK_DIV2P5]		= &g12a_fclk_div2p5.hw,
	[CLKID_GP0_PLL]			= &g12a_gp0_pll.hw,
	[CLKID_MPEG_SEL]		= &g12a_mpeg_clk_sel.hw,
	[CLKID_MPEG_DIV]		= &g12a_mpeg_clk_div.hw,
	[CLKID_CLK81]			= &g12a_clk81.hw,
	[CLKID_MPLL0]			= &g12a_mpll0.hw,
	[CLKID_MPLL1]			= &g12a_mpll1.hw,
	[CLKID_MPLL2]			= &g12a_mpll2.hw,
	[CLKID_MPLL3]			= &g12a_mpll3.hw,
	[CLKID_DDR]			= &g12a_ddr.hw,
	[CLKID_DOS]			= &g12a_dos.hw,
	[CLKID_AUDIO_LOCKER]		= &g12a_audio_locker.hw,
	[CLKID_MIPI_DSI_HOST]		= &g12a_mipi_dsi_host.hw,
	[CLKID_ETH_PHY]			= &g12a_eth_phy.hw,
	[CLKID_ISA]			= &g12a_isa.hw,
	[CLKID_PL301]			= &g12a_pl301.hw,
	[CLKID_PERIPHS]			= &g12a_periphs.hw,
	[CLKID_SPICC0]			= &g12a_spicc_0.hw,
	[CLKID_I2C]			= &g12a_i2c.hw,
	[CLKID_SANA]			= &g12a_sana.hw,
	[CLKID_SD]			= &g12a_sd.hw,
	[CLKID_RNG0]			= &g12a_rng0.hw,
	[CLKID_UART0]			= &g12a_uart0.hw,
	[CLKID_SPICC1]			= &g12a_spicc_1.hw,
	[CLKID_HIU_IFACE]		= &g12a_hiu_reg.hw,
	[CLKID_MIPI_DSI_PHY]		= &g12a_mipi_dsi_phy.hw,
	[CLKID_ASSIST_MISC]		= &g12a_assist_misc.hw,
	[CLKID_SD_EMMC_A]		= &g12a_emmc_a.hw,
	[CLKID_SD_EMMC_B]		= &g12a_emmc_b.hw,
	[CLKID_SD_EMMC_C]		= &g12a_emmc_c.hw,
	[CLKID_AUDIO_CODEC]		= &g12a_audio_codec.hw,
	[CLKID_AUDIO]			= &g12a_audio.hw,
	[CLKID_ETH]			= &g12a_eth_core.hw,
	[CLKID_DEMUX]			= &g12a_demux.hw,
	[CLKID_AUDIO_IFIFO]		= &g12a_audio_ififo.hw,
	[CLKID_ADC]			= &g12a_adc.hw,
	[CLKID_UART1]			= &g12a_uart1.hw,
	[CLKID_G2D]			= &g12a_g2d.hw,
	[CLKID_RESET]			= &g12a_reset.hw,
	[CLKID_PCIE_COMB]		= &g12a_pcie_comb.hw,
	[CLKID_PARSER]			= &g12a_parser.hw,
	[CLKID_USB]			= &g12a_usb_general.hw,
	[CLKID_PCIE_PHY]		= &g12a_pcie_phy.hw,
	[CLKID_AHB_ARB0]		= &g12a_ahb_arb0.hw,
	[CLKID_AHB_DATA_BUS]		= &g12a_ahb_data_bus.hw,
	[CLKID_AHB_CTRL_BUS]		= &g12a_ahb_ctrl_bus.hw,
	[CLKID_HTX_HDCP22]		= &g12a_htx_hdcp22.hw,
	[CLKID_HTX_PCLK]		= &g12a_htx_pclk.hw,
	[CLKID_BT656]			= &g12a_bt656.hw,
	[CLKID_USB1_DDR_BRIDGE]		= &g12a_usb1_to_ddr.hw,
	[CLKID_MMC_PCLK]		= &g12a_mmc_pclk.hw,
	[CLKID_UART2]			= &g12a_uart2.hw,
	[CLKID_VPU_INTR]		= &g12a_vpu_intr.hw,
	[CLKID_GIC]			= &g12a_gic.hw,
	[CLKID_SD_EMMC_A_CLK0_SEL]	= &g12a_sd_emmc_a_clk0_sel.hw,
	[CLKID_SD_EMMC_A_CLK0_DIV]	= &g12a_sd_emmc_a_clk0_div.hw,
	[CLKID_SD_EMMC_A_CLK0]		= &g12a_sd_emmc_a_clk0.hw,
	[CLKID_SD_EMMC_B_CLK0_SEL]	= &g12a_sd_emmc_b_clk0_sel.hw,
	[CLKID_SD_EMMC_B_CLK0_DIV]	= &g12a_sd_emmc_b_clk0_div.hw,
	[CLKID_SD_EMMC_B_CLK0]		= &g12a_sd_emmc_b_clk0.hw,
	[CLKID_SD_EMMC_C_CLK0_SEL]	= &g12a_sd_emmc_c_clk0_sel.hw,
	[CLKID_SD_EMMC_C_CLK0_DIV]	= &g12a_sd_emmc_c_clk0_div.hw,
	[CLKID_SD_EMMC_C_CLK0]		= &g12a_sd_emmc_c_clk0.hw,
	[CLKID_MPLL0_DIV]		= &g12a_mpll0_div.hw,
	[CLKID_MPLL1_DIV]		= &g12a_mpll1_div.hw,
	[CLKID_MPLL2_DIV]		= &g12a_mpll2_div.hw,
	[CLKID_MPLL3_DIV]		= &g12a_mpll3_div.hw,
	[CLKID_FCLK_DIV2_DIV]		= &g12a_fclk_div2_div.hw,
	[CLKID_FCLK_DIV3_DIV]		= &g12a_fclk_div3_div.hw,
	[CLKID_FCLK_DIV4_DIV]		= &g12a_fclk_div4_div.hw,
	[CLKID_FCLK_DIV5_DIV]		= &g12a_fclk_div5_div.hw,
	[CLKID_FCLK_DIV7_DIV]		= &g12a_fclk_div7_div.hw,
	[CLKID_FCLK_DIV2P5_DIV]		= &g12a_fclk_div2p5_div.hw,
	[CLKID_HIFI_PLL]		= &g12a_hifi_pll.hw,
	[CLKID_VCLK2_VENCI0]		= &g12a_vclk2_venci0.hw,
	[CLKID_VCLK2_VENCI1]		= &g12a_vclk2_venci1.hw,
	[CLKID_VCLK2_VENCP0]		= &g12a_vclk2_vencp0.hw,
	[CLKID_VCLK2_VENCP1]		= &g12a_vclk2_vencp1.hw,
	[CLKID_VCLK2_VENCT0]		= &g12a_vclk2_venct0.hw,
	[CLKID_VCLK2_VENCT1]		= &g12a_vclk2_venct1.hw,
	[CLKID_VCLK2_OTHER]		= &g12a_vclk2_other.hw,
	[CLKID_VCLK2_ENCI]		= &g12a_vclk2_enci.hw,
	[CLKID_VCLK2_ENCP]		= &g12a_vclk2_encp.hw,
	[CLKID_DAC_CLK]			= &g12a_dac_clk.hw,
	[CLKID_AOCLK]			= &g12a_aoclk_gate.hw,
	[CLKID_IEC958]			= &g12a_iec958_gate.hw,
	[CLKID_ENC480P]			= &g12a_enc480p.hw,
	[CLKID_RNG1]			= &g12a_rng1.hw,
	[CLKID_VCLK2_ENCT]		= &g12a_vclk2_enct.hw,
	[CLKID_VCLK2_ENCL]		= &g12a_vclk2_encl.hw,
	[CLKID_VCLK2_VENCLMMC]		= &g12a_vclk2_venclmmc.hw,
	[CLKID_VCLK2_VENCL]		= &g12a_vclk2_vencl.hw,
	[CLKID_VCLK2_OTHER1]		= &g12a_vclk2_other1.hw,
	[CLKID_FIXED_PLL_DCO]		= &g12a_fixed_pll_dco.hw,
	[CLKID_SYS_PLL_DCO]		= &g12a_sys_pll_dco.hw,
	[CLKID_GP0_PLL_DCO]		= &g12a_gp0_pll_dco.hw,
	[CLKID_HIFI_PLL_DCO]		= &g12a_hifi_pll_dco.hw,
	[CLKID_DMA]			= &g12a_dma.hw,
	[CLKID_EFUSE]			= &g12a_efuse.hw,
	[CLKID_ROM_BOOT]		= &g12a_rom_boot.hw,
	[CLKID_RESET_SEC]		= &g12a_reset_sec.hw,
	[CLKID_SEC_AHB_APB3]		= &g12a_sec_ahb_apb3.hw,
	[CLKID_MPLL_PREDIV]		= &g12a_mpll_prediv.hw,
	[CLKID_VPU_0_SEL]		= &g12a_vpu_0_sel.hw,
	[CLKID_VPU_0_DIV]		= &g12a_vpu_0_div.hw,
	[CLKID_VPU_0]			= &g12a_vpu_0.hw,
	[CLKID_VPU_1_SEL]		= &g12a_vpu_1_sel.hw,
	[CLKID_VPU_1_DIV]		= &g12a_vpu_1_div.hw,
	[CLKID_VPU_1]			= &g12a_vpu_1.hw,
	[CLKID_VPU]			= &g12a_vpu.hw,
	[CLKID_VAPB_0_SEL]		= &g12a_vapb_0_sel.hw,
	[CLKID_VAPB_0_DIV]		= &g12a_vapb_0_div.hw,
	[CLKID_VAPB_0]			= &g12a_vapb_0.hw,
	[CLKID_VAPB_1_SEL]		= &g12a_vapb_1_sel.hw,
	[CLKID_VAPB_1_DIV]		= &g12a_vapb_1_div.hw,
	[CLKID_VAPB_1]			= &g12a_vapb_1.hw,
	[CLKID_VAPB_SEL]		= &g12a_vapb_sel.hw,
	[CLKID_VAPB]			= &g12a_vapb.hw,
	[CLKID_HDMI_PLL_DCO]		= &g12a_hdmi_pll_dco.hw,
	[CLKID_HDMI_PLL_OD]		= &g12a_hdmi_pll_od.hw,
	[CLKID_HDMI_PLL_OD2]		= &g12a_hdmi_pll_od2.hw,
	[CLKID_HDMI_PLL]		= &g12a_hdmi_pll.hw,
	[CLKID_VID_PLL]			= &g12a_vid_pll_div.hw,
	[CLKID_VID_PLL_SEL]		= &g12a_vid_pll_sel.hw,
	[CLKID_VID_PLL_DIV]		= &g12a_vid_pll.hw,
	[CLKID_VCLK_SEL]		= &g12a_vclk_sel.hw,
	[CLKID_VCLK2_SEL]		= &g12a_vclk2_sel.hw,
	[CLKID_VCLK_INPUT]		= &g12a_vclk_input.hw,
	[CLKID_VCLK2_INPUT]		= &g12a_vclk2_input.hw,
	[CLKID_VCLK_DIV]		= &g12a_vclk_div.hw,
	[CLKID_VCLK2_DIV]		= &g12a_vclk2_div.hw,
	[CLKID_VCLK]			= &g12a_vclk.hw,
	[CLKID_VCLK2]			= &g12a_vclk2.hw,
	[CLKID_VCLK_DIV1]		= &g12a_vclk_div1.hw,
	[CLKID_VCLK_DIV2_EN]		= &g12a_vclk_div2_en.hw,
	[CLKID_VCLK_DIV4_EN]		= &g12a_vclk_div4_en.hw,
	[CLKID_VCLK_DIV6_EN]		= &g12a_vclk_div6_en.hw,
	[CLKID_VCLK_DIV12_EN]		= &g12a_vclk_div12_en.hw,
	[CLKID_VCLK2_DIV1]		= &g12a_vclk2_div1.hw,
	[CLKID_VCLK2_DIV2_EN]		= &g12a_vclk2_div2_en.hw,
	[CLKID_VCLK2_DIV4_EN]		= &g12a_vclk2_div4_en.hw,
	[CLKID_VCLK2_DIV6_EN]		= &g12a_vclk2_div6_en.hw,
	[CLKID_VCLK2_DIV12_EN]		= &g12a_vclk2_div12_en.hw,
	[CLKID_VCLK_DIV2]		= &g12a_vclk_div2.hw,
	[CLKID_VCLK_DIV4]		= &g12a_vclk_div4.hw,
	[CLKID_VCLK_DIV6]		= &g12a_vclk_div6.hw,
	[CLKID_VCLK_DIV12]		= &g12a_vclk_div12.hw,
	[CLKID_VCLK2_DIV2]		= &g12a_vclk2_div2.hw,
	[CLKID_VCLK2_DIV4]		= &g12a_vclk2_div4.hw,
	[CLKID_VCLK2_DIV6]		= &g12a_vclk2_div6.hw,
	[CLKID_VCLK2_DIV12]		= &g12a_vclk2_div12.hw,
	[CLKID_CTS_ENCI_SEL]		= &g12a_cts_enci_sel.hw,
	[CLKID_CTS_ENCP_SEL]		= &g12a_cts_encp_sel.hw,
	[CLKID_CTS_VDAC_SEL]		= &g12a_cts_vdac_sel.hw,
	[CLKID_HDMI_TX_SEL]		= &g12a_hdmi_tx_sel.hw,
	[CLKID_CTS_ENCI]		= &g12a_cts_enci.hw,
	[CLKID_CTS_ENCP]		= &g12a_cts_encp.hw,
	[CLKID_CTS_VDAC]		= &g12a_cts_vdac.hw,
	[CLKID_HDMI_TX]			= &g12a_hdmi_tx.hw,
	[CLKID_HDMI_SEL]		= &g12a_hdmi_sel.hw,
	[CLKID_HDMI_DIV]		= &g12a_hdmi_div.hw,
	[CLKID_HDMI]			= &g12a_hdmi.hw,
	[CLKID_MALI_0_SEL]		= &g12a_mali_0_sel.hw,
	[CLKID_MALI_0_DIV]		= &g12a_mali_0_div.hw,
	[CLKID_MALI_0]			= &g12a_mali_0.hw,
	[CLKID_MALI_1_SEL]		= &g12a_mali_1_sel.hw,
	[CLKID_MALI_1_DIV]		= &g12a_mali_1_div.hw,
	[CLKID_MALI_1]			= &g12a_mali_1.hw,
	[CLKID_MALI]			= &g12a_mali.hw,
	[CLKID_MPLL_50M_DIV]		= &g12a_mpll_50m_div.hw,
	[CLKID_MPLL_50M]		= &g12a_mpll_50m.hw,
	[CLKID_SYS_PLL_DIV16_EN]	= &g12a_sys_pll_div16_en.hw,
	[CLKID_SYS_PLL_DIV16]		= &g12a_sys_pll_div16.hw,
	[CLKID_CPU_CLK_DYN0_SEL]	= &g12a_cpu_clk_premux0.hw,
	[CLKID_CPU_CLK_DYN0_DIV]	= &g12a_cpu_clk_mux0_div.hw,
	[CLKID_CPU_CLK_DYN0]		= &g12a_cpu_clk_postmux0.hw,
	[CLKID_CPU_CLK_DYN1_SEL]	= &g12a_cpu_clk_premux1.hw,
	[CLKID_CPU_CLK_DYN1_DIV]	= &g12a_cpu_clk_mux1_div.hw,
	[CLKID_CPU_CLK_DYN1]		= &g12a_cpu_clk_postmux1.hw,
	[CLKID_CPU_CLK_DYN]		= &g12a_cpu_clk_dyn.hw,
	[CLKID_CPU_CLK]			= &g12b_cpu_clk.hw,
	[CLKID_CPU_CLK_DIV16_EN]	= &g12a_cpu_clk_div16_en.hw,
	[CLKID_CPU_CLK_DIV16]		= &g12a_cpu_clk_div16.hw,
	[CLKID_CPU_CLK_APB_DIV]		= &g12a_cpu_clk_apb_div.hw,
	[CLKID_CPU_CLK_APB]		= &g12a_cpu_clk_apb.hw,
	[CLKID_CPU_CLK_ATB_DIV]		= &g12a_cpu_clk_atb_div.hw,
	[CLKID_CPU_CLK_ATB]		= &g12a_cpu_clk_atb.hw,
	[CLKID_CPU_CLK_AXI_DIV]		= &g12a_cpu_clk_axi_div.hw,
	[CLKID_CPU_CLK_AXI]		= &g12a_cpu_clk_axi.hw,
	[CLKID_CPU_CLK_TRACE_DIV]	= &g12a_cpu_clk_trace_div.hw,
	[CLKID_CPU_CLK_TRACE]		= &g12a_cpu_clk_trace.hw,
	[CLKID_PCIE_PLL_DCO]		= &g12a_pcie_pll_dco.hw,
	[CLKID_PCIE_PLL_DCO_DIV2]	= &g12a_pcie_pll_dco_div2.hw,
	[CLKID_PCIE_PLL_OD]		= &g12a_pcie_pll_od.hw,
	[CLKID_PCIE_PLL]		= &g12a_pcie_pll.hw,
	[CLKID_VDEC_1_SEL]		= &g12a_vdec_1_sel.hw,
	[CLKID_VDEC_1_DIV]		= &g12a_vdec_1_div.hw,
	[CLKID_VDEC_1]			= &g12a_vdec_1.hw,
	[CLKID_VDEC_HEVC_SEL]		= &g12a_vdec_hevc_sel.hw,
	[CLKID_VDEC_HEVC_DIV]		= &g12a_vdec_hevc_div.hw,
	[CLKID_VDEC_HEVC]		= &g12a_vdec_hevc.hw,
	[CLKID_VDEC_HEVCF_SEL]		= &g12a_vdec_hevcf_sel.hw,
	[CLKID_VDEC_HEVCF_DIV]		= &g12a_vdec_hevcf_div.hw,
	[CLKID_VDEC_HEVCF]		= &g12a_vdec_hevcf.hw,
	[CLKID_TS_DIV]			= &g12a_ts_div.hw,
	[CLKID_TS]			= &g12a_ts.hw,
	[CLKID_SYS1_PLL_DCO]		= &g12b_sys1_pll_dco.hw,
	[CLKID_SYS1_PLL]		= &g12b_sys1_pll.hw,
	[CLKID_SYS1_PLL_DIV16_EN]	= &g12b_sys1_pll_div16_en.hw,
	[CLKID_SYS1_PLL_DIV16]		= &g12b_sys1_pll_div16.hw,
	[CLKID_CPUB_CLK_DYN0_SEL]	= &g12b_cpub_clk_premux0.hw,
	[CLKID_CPUB_CLK_DYN0_DIV]	= &g12b_cpub_clk_mux0_div.hw,
	[CLKID_CPUB_CLK_DYN0]		= &g12b_cpub_clk_postmux0.hw,
	[CLKID_CPUB_CLK_DYN1_SEL]	= &g12b_cpub_clk_premux1.hw,
	[CLKID_CPUB_CLK_DYN1_DIV]	= &g12b_cpub_clk_mux1_div.hw,
	[CLKID_CPUB_CLK_DYN1]		= &g12b_cpub_clk_postmux1.hw,
	[CLKID_CPUB_CLK_DYN]		= &g12b_cpub_clk_dyn.hw,
	[CLKID_CPUB_CLK]		= &g12b_cpub_clk.hw,
	[CLKID_CPUB_CLK_DIV16_EN]	= &g12b_cpub_clk_div16_en.hw,
	[CLKID_CPUB_CLK_DIV16]		= &g12b_cpub_clk_div16.hw,
	[CLKID_CPUB_CLK_DIV2]		= &g12b_cpub_clk_div2.hw,
	[CLKID_CPUB_CLK_DIV3]		= &g12b_cpub_clk_div3.hw,
	[CLKID_CPUB_CLK_DIV4]		= &g12b_cpub_clk_div4.hw,
	[CLKID_CPUB_CLK_DIV5]		= &g12b_cpub_clk_div5.hw,
	[CLKID_CPUB_CLK_DIV6]		= &g12b_cpub_clk_div6.hw,
	[CLKID_CPUB_CLK_DIV7]		= &g12b_cpub_clk_div7.hw,
	[CLKID_CPUB_CLK_DIV8]		= &g12b_cpub_clk_div8.hw,
	[CLKID_CPUB_CLK_APB_SEL]	= &g12b_cpub_clk_apb_sel.hw,
	[CLKID_CPUB_CLK_APB]		= &g12b_cpub_clk_apb.hw,
	[CLKID_CPUB_CLK_ATB_SEL]	= &g12b_cpub_clk_atb_sel.hw,
	[CLKID_CPUB_CLK_ATB]		= &g12b_cpub_clk_atb.hw,
	[CLKID_CPUB_CLK_AXI_SEL]	= &g12b_cpub_clk_axi_sel.hw,
	[CLKID_CPUB_CLK_AXI]		= &g12b_cpub_clk_axi.hw,
	[CLKID_CPUB_CLK_TRACE_SEL]	= &g12b_cpub_clk_trace_sel.hw,
	[CLKID_CPUB_CLK_TRACE]		= &g12b_cpub_clk_trace.hw,
	[CLKID_SPICC0_SCLK_SEL]		= &g12a_spicc0_sclk_sel.hw,
	[CLKID_SPICC0_SCLK_DIV]		= &g12a_spicc0_sclk_div.hw,
	[CLKID_SPICC0_SCLK]		= &g12a_spicc0_sclk.hw,
	[CLKID_SPICC1_SCLK_SEL]		= &g12a_spicc1_sclk_sel.hw,
	[CLKID_SPICC1_SCLK_DIV]		= &g12a_spicc1_sclk_div.hw,
	[CLKID_SPICC1_SCLK]		= &g12a_spicc1_sclk.hw,
	[CLKID_NNA_AXI_CLK_SEL]		= &sm1_nna_axi_clk_sel.hw,
	[CLKID_NNA_AXI_CLK_DIV]		= &sm1_nna_axi_clk_div.hw,
	[CLKID_NNA_AXI_CLK]		= &sm1_nna_axi_clk.hw,
	[CLKID_NNA_CORE_CLK_SEL]	= &sm1_nna_core_clk_sel.hw,
	[CLKID_NNA_CORE_CLK_DIV]	= &sm1_nna_core_clk_div.hw,
	[CLKID_NNA_CORE_CLK]		= &sm1_nna_core_clk.hw,
	[CLKID_MIPI_DSI_PXCLK_SEL]	= &g12a_mipi_dsi_pxclk_sel.hw,
	[CLKID_MIPI_DSI_PXCLK_DIV]	= &g12a_mipi_dsi_pxclk_div.hw,
	[CLKID_MIPI_DSI_PXCLK]		= &g12a_mipi_dsi_pxclk.hw,
};

static struct clk_hw *sm1_hw_clks[] = {
	[CLKID_SYS_PLL]			= &g12a_sys_pll.hw,
	[CLKID_FIXED_PLL]		= &g12a_fixed_pll.hw,
	[CLKID_FCLK_DIV2]		= &g12a_fclk_div2.hw,
	[CLKID_FCLK_DIV3]		= &g12a_fclk_div3.hw,
	[CLKID_FCLK_DIV4]		= &g12a_fclk_div4.hw,
	[CLKID_FCLK_DIV5]		= &g12a_fclk_div5.hw,
	[CLKID_FCLK_DIV7]		= &g12a_fclk_div7.hw,
	[CLKID_FCLK_DIV2P5]		= &g12a_fclk_div2p5.hw,
	[CLKID_GP0_PLL]			= &g12a_gp0_pll.hw,
	[CLKID_MPEG_SEL]		= &g12a_mpeg_clk_sel.hw,
	[CLKID_MPEG_DIV]		= &g12a_mpeg_clk_div.hw,
	[CLKID_CLK81]			= &g12a_clk81.hw,
	[CLKID_MPLL0]			= &g12a_mpll0.hw,
	[CLKID_MPLL1]			= &g12a_mpll1.hw,
	[CLKID_MPLL2]			= &g12a_mpll2.hw,
	[CLKID_MPLL3]			= &g12a_mpll3.hw,
	[CLKID_DDR]			= &g12a_ddr.hw,
	[CLKID_DOS]			= &g12a_dos.hw,
	[CLKID_AUDIO_LOCKER]		= &g12a_audio_locker.hw,
	[CLKID_MIPI_DSI_HOST]		= &g12a_mipi_dsi_host.hw,
	[CLKID_ETH_PHY]			= &g12a_eth_phy.hw,
	[CLKID_ISA]			= &g12a_isa.hw,
	[CLKID_PL301]			= &g12a_pl301.hw,
	[CLKID_PERIPHS]			= &g12a_periphs.hw,
	[CLKID_SPICC0]			= &g12a_spicc_0.hw,
	[CLKID_I2C]			= &g12a_i2c.hw,
	[CLKID_SANA]			= &g12a_sana.hw,
	[CLKID_SD]			= &g12a_sd.hw,
	[CLKID_RNG0]			= &g12a_rng0.hw,
	[CLKID_UART0]			= &g12a_uart0.hw,
	[CLKID_SPICC1]			= &g12a_spicc_1.hw,
	[CLKID_HIU_IFACE]		= &g12a_hiu_reg.hw,
	[CLKID_MIPI_DSI_PHY]		= &g12a_mipi_dsi_phy.hw,
	[CLKID_ASSIST_MISC]		= &g12a_assist_misc.hw,
	[CLKID_SD_EMMC_A]		= &g12a_emmc_a.hw,
	[CLKID_SD_EMMC_B]		= &g12a_emmc_b.hw,
	[CLKID_SD_EMMC_C]		= &g12a_emmc_c.hw,
	[CLKID_AUDIO_CODEC]		= &g12a_audio_codec.hw,
	[CLKID_AUDIO]			= &g12a_audio.hw,
	[CLKID_ETH]			= &g12a_eth_core.hw,
	[CLKID_DEMUX]			= &g12a_demux.hw,
	[CLKID_AUDIO_IFIFO]		= &g12a_audio_ififo.hw,
	[CLKID_ADC]			= &g12a_adc.hw,
	[CLKID_UART1]			= &g12a_uart1.hw,
	[CLKID_G2D]			= &g12a_g2d.hw,
	[CLKID_RESET]			= &g12a_reset.hw,
	[CLKID_PCIE_COMB]		= &g12a_pcie_comb.hw,
	[CLKID_PARSER]			= &g12a_parser.hw,
	[CLKID_USB]			= &g12a_usb_general.hw,
	[CLKID_PCIE_PHY]		= &g12a_pcie_phy.hw,
	[CLKID_AHB_ARB0]		= &g12a_ahb_arb0.hw,
	[CLKID_AHB_DATA_BUS]		= &g12a_ahb_data_bus.hw,
	[CLKID_AHB_CTRL_BUS]		= &g12a_ahb_ctrl_bus.hw,
	[CLKID_HTX_HDCP22]		= &g12a_htx_hdcp22.hw,
	[CLKID_HTX_PCLK]		= &g12a_htx_pclk.hw,
	[CLKID_BT656]			= &g12a_bt656.hw,
	[CLKID_USB1_DDR_BRIDGE]		= &g12a_usb1_to_ddr.hw,
	[CLKID_MMC_PCLK]		= &g12a_mmc_pclk.hw,
	[CLKID_UART2]			= &g12a_uart2.hw,
	[CLKID_VPU_INTR]		= &g12a_vpu_intr.hw,
	[CLKID_GIC]			= &g12a_gic.hw,
	[CLKID_SD_EMMC_A_CLK0_SEL]	= &g12a_sd_emmc_a_clk0_sel.hw,
	[CLKID_SD_EMMC_A_CLK0_DIV]	= &g12a_sd_emmc_a_clk0_div.hw,
	[CLKID_SD_EMMC_A_CLK0]		= &g12a_sd_emmc_a_clk0.hw,
	[CLKID_SD_EMMC_B_CLK0_SEL]	= &g12a_sd_emmc_b_clk0_sel.hw,
	[CLKID_SD_EMMC_B_CLK0_DIV]	= &g12a_sd_emmc_b_clk0_div.hw,
	[CLKID_SD_EMMC_B_CLK0]		= &g12a_sd_emmc_b_clk0.hw,
	[CLKID_SD_EMMC_C_CLK0_SEL]	= &g12a_sd_emmc_c_clk0_sel.hw,
	[CLKID_SD_EMMC_C_CLK0_DIV]	= &g12a_sd_emmc_c_clk0_div.hw,
	[CLKID_SD_EMMC_C_CLK0]		= &g12a_sd_emmc_c_clk0.hw,
	[CLKID_MPLL0_DIV]		= &g12a_mpll0_div.hw,
	[CLKID_MPLL1_DIV]		= &g12a_mpll1_div.hw,
	[CLKID_MPLL2_DIV]		= &g12a_mpll2_div.hw,
	[CLKID_MPLL3_DIV]		= &g12a_mpll3_div.hw,
	[CLKID_FCLK_DIV2_DIV]		= &g12a_fclk_div2_div.hw,
	[CLKID_FCLK_DIV3_DIV]		= &g12a_fclk_div3_div.hw,
	[CLKID_FCLK_DIV4_DIV]		= &g12a_fclk_div4_div.hw,
	[CLKID_FCLK_DIV5_DIV]		= &g12a_fclk_div5_div.hw,
	[CLKID_FCLK_DIV7_DIV]		= &g12a_fclk_div7_div.hw,
	[CLKID_FCLK_DIV2P5_DIV]		= &g12a_fclk_div2p5_div.hw,
	[CLKID_HIFI_PLL]		= &g12a_hifi_pll.hw,
	[CLKID_VCLK2_VENCI0]		= &g12a_vclk2_venci0.hw,
	[CLKID_VCLK2_VENCI1]		= &g12a_vclk2_venci1.hw,
	[CLKID_VCLK2_VENCP0]		= &g12a_vclk2_vencp0.hw,
	[CLKID_VCLK2_VENCP1]		= &g12a_vclk2_vencp1.hw,
	[CLKID_VCLK2_VENCT0]		= &g12a_vclk2_venct0.hw,
	[CLKID_VCLK2_VENCT1]		= &g12a_vclk2_venct1.hw,
	[CLKID_VCLK2_OTHER]		= &g12a_vclk2_other.hw,
	[CLKID_VCLK2_ENCI]		= &g12a_vclk2_enci.hw,
	[CLKID_VCLK2_ENCP]		= &g12a_vclk2_encp.hw,
	[CLKID_DAC_CLK]			= &g12a_dac_clk.hw,
	[CLKID_AOCLK]			= &g12a_aoclk_gate.hw,
	[CLKID_IEC958]			= &g12a_iec958_gate.hw,
	[CLKID_ENC480P]			= &g12a_enc480p.hw,
	[CLKID_RNG1]			= &g12a_rng1.hw,
	[CLKID_VCLK2_ENCT]		= &g12a_vclk2_enct.hw,
	[CLKID_VCLK2_ENCL]		= &g12a_vclk2_encl.hw,
	[CLKID_VCLK2_VENCLMMC]		= &g12a_vclk2_venclmmc.hw,
	[CLKID_VCLK2_VENCL]		= &g12a_vclk2_vencl.hw,
	[CLKID_VCLK2_OTHER1]		= &g12a_vclk2_other1.hw,
	[CLKID_FIXED_PLL_DCO]		= &g12a_fixed_pll_dco.hw,
	[CLKID_SYS_PLL_DCO]		= &g12a_sys_pll_dco.hw,
	[CLKID_GP0_PLL_DCO]		= &g12a_gp0_pll_dco.hw,
	[CLKID_HIFI_PLL_DCO]		= &g12a_hifi_pll_dco.hw,
	[CLKID_DMA]			= &g12a_dma.hw,
	[CLKID_EFUSE]			= &g12a_efuse.hw,
	[CLKID_ROM_BOOT]		= &g12a_rom_boot.hw,
	[CLKID_RESET_SEC]		= &g12a_reset_sec.hw,
	[CLKID_SEC_AHB_APB3]		= &g12a_sec_ahb_apb3.hw,
	[CLKID_MPLL_PREDIV]		= &g12a_mpll_prediv.hw,
	[CLKID_VPU_0_SEL]		= &g12a_vpu_0_sel.hw,
	[CLKID_VPU_0_DIV]		= &g12a_vpu_0_div.hw,
	[CLKID_VPU_0]			= &g12a_vpu_0.hw,
	[CLKID_VPU_1_SEL]		= &g12a_vpu_1_sel.hw,
	[CLKID_VPU_1_DIV]		= &g12a_vpu_1_div.hw,
	[CLKID_VPU_1]			= &g12a_vpu_1.hw,
	[CLKID_VPU]			= &g12a_vpu.hw,
	[CLKID_VAPB_0_SEL]		= &g12a_vapb_0_sel.hw,
	[CLKID_VAPB_0_DIV]		= &g12a_vapb_0_div.hw,
	[CLKID_VAPB_0]			= &g12a_vapb_0.hw,
	[CLKID_VAPB_1_SEL]		= &g12a_vapb_1_sel.hw,
	[CLKID_VAPB_1_DIV]		= &g12a_vapb_1_div.hw,
	[CLKID_VAPB_1]			= &g12a_vapb_1.hw,
	[CLKID_VAPB_SEL]		= &g12a_vapb_sel.hw,
	[CLKID_VAPB]			= &g12a_vapb.hw,
	[CLKID_HDMI_PLL_DCO]		= &g12a_hdmi_pll_dco.hw,
	[CLKID_HDMI_PLL_OD]		= &g12a_hdmi_pll_od.hw,
	[CLKID_HDMI_PLL_OD2]		= &g12a_hdmi_pll_od2.hw,
	[CLKID_HDMI_PLL]		= &g12a_hdmi_pll.hw,
	[CLKID_VID_PLL]			= &g12a_vid_pll_div.hw,
	[CLKID_VID_PLL_SEL]		= &g12a_vid_pll_sel.hw,
	[CLKID_VID_PLL_DIV]		= &g12a_vid_pll.hw,
	[CLKID_VCLK_SEL]		= &g12a_vclk_sel.hw,
	[CLKID_VCLK2_SEL]		= &g12a_vclk2_sel.hw,
	[CLKID_VCLK_INPUT]		= &g12a_vclk_input.hw,
	[CLKID_VCLK2_INPUT]		= &g12a_vclk2_input.hw,
	[CLKID_VCLK_DIV]		= &g12a_vclk_div.hw,
	[CLKID_VCLK2_DIV]		= &g12a_vclk2_div.hw,
	[CLKID_VCLK]			= &g12a_vclk.hw,
	[CLKID_VCLK2]			= &g12a_vclk2.hw,
	[CLKID_VCLK_DIV1]		= &g12a_vclk_div1.hw,
	[CLKID_VCLK_DIV2_EN]		= &g12a_vclk_div2_en.hw,
	[CLKID_VCLK_DIV4_EN]		= &g12a_vclk_div4_en.hw,
	[CLKID_VCLK_DIV6_EN]		= &g12a_vclk_div6_en.hw,
	[CLKID_VCLK_DIV12_EN]		= &g12a_vclk_div12_en.hw,
	[CLKID_VCLK2_DIV1]		= &g12a_vclk2_div1.hw,
	[CLKID_VCLK2_DIV2_EN]		= &g12a_vclk2_div2_en.hw,
	[CLKID_VCLK2_DIV4_EN]		= &g12a_vclk2_div4_en.hw,
	[CLKID_VCLK2_DIV6_EN]		= &g12a_vclk2_div6_en.hw,
	[CLKID_VCLK2_DIV12_EN]		= &g12a_vclk2_div12_en.hw,
	[CLKID_VCLK_DIV2]		= &g12a_vclk_div2.hw,
	[CLKID_VCLK_DIV4]		= &g12a_vclk_div4.hw,
	[CLKID_VCLK_DIV6]		= &g12a_vclk_div6.hw,
	[CLKID_VCLK_DIV12]		= &g12a_vclk_div12.hw,
	[CLKID_VCLK2_DIV2]		= &g12a_vclk2_div2.hw,
	[CLKID_VCLK2_DIV4]		= &g12a_vclk2_div4.hw,
	[CLKID_VCLK2_DIV6]		= &g12a_vclk2_div6.hw,
	[CLKID_VCLK2_DIV12]		= &g12a_vclk2_div12.hw,
	[CLKID_CTS_ENCI_SEL]		= &g12a_cts_enci_sel.hw,
	[CLKID_CTS_ENCP_SEL]		= &g12a_cts_encp_sel.hw,
	[CLKID_CTS_VDAC_SEL]		= &g12a_cts_vdac_sel.hw,
	[CLKID_HDMI_TX_SEL]		= &g12a_hdmi_tx_sel.hw,
	[CLKID_CTS_ENCI]		= &g12a_cts_enci.hw,
	[CLKID_CTS_ENCP]		= &g12a_cts_encp.hw,
	[CLKID_CTS_VDAC]		= &g12a_cts_vdac.hw,
	[CLKID_HDMI_TX]			= &g12a_hdmi_tx.hw,
	[CLKID_HDMI_SEL]		= &g12a_hdmi_sel.hw,
	[CLKID_HDMI_DIV]		= &g12a_hdmi_div.hw,
	[CLKID_HDMI]			= &g12a_hdmi.hw,
	[CLKID_MALI_0_SEL]		= &g12a_mali_0_sel.hw,
	[CLKID_MALI_0_DIV]		= &g12a_mali_0_div.hw,
	[CLKID_MALI_0]			= &g12a_mali_0.hw,
	[CLKID_MALI_1_SEL]		= &g12a_mali_1_sel.hw,
	[CLKID_MALI_1_DIV]		= &g12a_mali_1_div.hw,
	[CLKID_MALI_1]			= &g12a_mali_1.hw,
	[CLKID_MALI]			= &g12a_mali.hw,
	[CLKID_MPLL_50M_DIV]		= &g12a_mpll_50m_div.hw,
	[CLKID_MPLL_50M]		= &g12a_mpll_50m.hw,
	[CLKID_SYS_PLL_DIV16_EN]	= &g12a_sys_pll_div16_en.hw,
	[CLKID_SYS_PLL_DIV16]		= &g12a_sys_pll_div16.hw,
	[CLKID_CPU_CLK_DYN0_SEL]	= &g12a_cpu_clk_premux0.hw,
	[CLKID_CPU_CLK_DYN0_DIV]	= &g12a_cpu_clk_mux0_div.hw,
	[CLKID_CPU_CLK_DYN0]		= &g12a_cpu_clk_postmux0.hw,
	[CLKID_CPU_CLK_DYN1_SEL]	= &g12a_cpu_clk_premux1.hw,
	[CLKID_CPU_CLK_DYN1_DIV]	= &g12a_cpu_clk_mux1_div.hw,
	[CLKID_CPU_CLK_DYN1]		= &g12a_cpu_clk_postmux1.hw,
	[CLKID_CPU_CLK_DYN]		= &g12a_cpu_clk_dyn.hw,
	[CLKID_CPU_CLK]			= &g12a_cpu_clk.hw,
	[CLKID_CPU_CLK_DIV16_EN]	= &g12a_cpu_clk_div16_en.hw,
	[CLKID_CPU_CLK_DIV16]		= &g12a_cpu_clk_div16.hw,
	[CLKID_CPU_CLK_APB_DIV]		= &g12a_cpu_clk_apb_div.hw,
	[CLKID_CPU_CLK_APB]		= &g12a_cpu_clk_apb.hw,
	[CLKID_CPU_CLK_ATB_DIV]		= &g12a_cpu_clk_atb_div.hw,
	[CLKID_CPU_CLK_ATB]		= &g12a_cpu_clk_atb.hw,
	[CLKID_CPU_CLK_AXI_DIV]		= &g12a_cpu_clk_axi_div.hw,
	[CLKID_CPU_CLK_AXI]		= &g12a_cpu_clk_axi.hw,
	[CLKID_CPU_CLK_TRACE_DIV]	= &g12a_cpu_clk_trace_div.hw,
	[CLKID_CPU_CLK_TRACE]		= &g12a_cpu_clk_trace.hw,
	[CLKID_PCIE_PLL_DCO]		= &g12a_pcie_pll_dco.hw,
	[CLKID_PCIE_PLL_DCO_DIV2]	= &g12a_pcie_pll_dco_div2.hw,
	[CLKID_PCIE_PLL_OD]		= &g12a_pcie_pll_od.hw,
	[CLKID_PCIE_PLL]		= &g12a_pcie_pll.hw,
	[CLKID_VDEC_1_SEL]		= &g12a_vdec_1_sel.hw,
	[CLKID_VDEC_1_DIV]		= &g12a_vdec_1_div.hw,
	[CLKID_VDEC_1]			= &g12a_vdec_1.hw,
	[CLKID_VDEC_HEVC_SEL]		= &g12a_vdec_hevc_sel.hw,
	[CLKID_VDEC_HEVC_DIV]		= &g12a_vdec_hevc_div.hw,
	[CLKID_VDEC_HEVC]		= &g12a_vdec_hevc.hw,
	[CLKID_VDEC_HEVCF_SEL]		= &g12a_vdec_hevcf_sel.hw,
	[CLKID_VDEC_HEVCF_DIV]		= &g12a_vdec_hevcf_div.hw,
	[CLKID_VDEC_HEVCF]		= &g12a_vdec_hevcf.hw,
	[CLKID_TS_DIV]			= &g12a_ts_div.hw,
	[CLKID_TS]			= &g12a_ts.hw,
	[CLKID_GP1_PLL_DCO]		= &sm1_gp1_pll_dco.hw,
	[CLKID_GP1_PLL]			= &sm1_gp1_pll.hw,
	[CLKID_DSU_CLK_DYN0_SEL]	= &sm1_dsu_clk_premux0.hw,
	[CLKID_DSU_CLK_DYN0_DIV]	= &sm1_dsu_clk_premux1.hw,
	[CLKID_DSU_CLK_DYN0]		= &sm1_dsu_clk_mux0_div.hw,
	[CLKID_DSU_CLK_DYN1_SEL]	= &sm1_dsu_clk_postmux0.hw,
	[CLKID_DSU_CLK_DYN1_DIV]	= &sm1_dsu_clk_mux1_div.hw,
	[CLKID_DSU_CLK_DYN1]		= &sm1_dsu_clk_postmux1.hw,
	[CLKID_DSU_CLK_DYN]		= &sm1_dsu_clk_dyn.hw,
	[CLKID_DSU_CLK_FINAL]		= &sm1_dsu_final_clk.hw,
	[CLKID_DSU_CLK]			= &sm1_dsu_clk.hw,
	[CLKID_CPU1_CLK]		= &sm1_cpu1_clk.hw,
	[CLKID_CPU2_CLK]		= &sm1_cpu2_clk.hw,
	[CLKID_CPU3_CLK]		= &sm1_cpu3_clk.hw,
	[CLKID_SPICC0_SCLK_SEL]		= &g12a_spicc0_sclk_sel.hw,
	[CLKID_SPICC0_SCLK_DIV]		= &g12a_spicc0_sclk_div.hw,
	[CLKID_SPICC0_SCLK]		= &g12a_spicc0_sclk.hw,
	[CLKID_SPICC1_SCLK_SEL]		= &g12a_spicc1_sclk_sel.hw,
	[CLKID_SPICC1_SCLK_DIV]		= &g12a_spicc1_sclk_div.hw,
	[CLKID_SPICC1_SCLK]		= &g12a_spicc1_sclk.hw,
	[CLKID_NNA_AXI_CLK_SEL]		= &sm1_nna_axi_clk_sel.hw,
	[CLKID_NNA_AXI_CLK_DIV]		= &sm1_nna_axi_clk_div.hw,
	[CLKID_NNA_AXI_CLK]		= &sm1_nna_axi_clk.hw,
	[CLKID_NNA_CORE_CLK_SEL]	= &sm1_nna_core_clk_sel.hw,
	[CLKID_NNA_CORE_CLK_DIV]	= &sm1_nna_core_clk_div.hw,
	[CLKID_NNA_CORE_CLK]		= &sm1_nna_core_clk.hw,
	[CLKID_MIPI_DSI_PXCLK_SEL]	= &g12a_mipi_dsi_pxclk_sel.hw,
	[CLKID_MIPI_DSI_PXCLK_DIV]	= &g12a_mipi_dsi_pxclk_div.hw,
	[CLKID_MIPI_DSI_PXCLK]		= &g12a_mipi_dsi_pxclk.hw,
};

/* Convenience table to populate regmap in .probe */
static struct clk_regmap *const g12a_clk_regmaps[] = {
	&g12a_clk81,
	&g12a_dos,
	&g12a_ddr,
	&g12a_audio_locker,
	&g12a_mipi_dsi_host,
	&g12a_eth_phy,
	&g12a_isa,
	&g12a_pl301,
	&g12a_periphs,
	&g12a_spicc_0,
	&g12a_i2c,
	&g12a_sana,
	&g12a_sd,
	&g12a_rng0,
	&g12a_uart0,
	&g12a_spicc_1,
	&g12a_hiu_reg,
	&g12a_mipi_dsi_phy,
	&g12a_assist_misc,
	&g12a_emmc_a,
	&g12a_emmc_b,
	&g12a_emmc_c,
	&g12a_audio_codec,
	&g12a_audio,
	&g12a_eth_core,
	&g12a_demux,
	&g12a_audio_ififo,
	&g12a_adc,
	&g12a_uart1,
	&g12a_g2d,
	&g12a_reset,
	&g12a_pcie_comb,
	&g12a_parser,
	&g12a_usb_general,
	&g12a_pcie_phy,
	&g12a_ahb_arb0,
	&g12a_ahb_data_bus,
	&g12a_ahb_ctrl_bus,
	&g12a_htx_hdcp22,
	&g12a_htx_pclk,
	&g12a_bt656,
	&g12a_usb1_to_ddr,
	&g12a_mmc_pclk,
	&g12a_uart2,
	&g12a_vpu_intr,
	&g12a_gic,
	&g12a_sd_emmc_a_clk0,
	&g12a_sd_emmc_b_clk0,
	&g12a_sd_emmc_c_clk0,
	&g12a_mpeg_clk_div,
	&g12a_sd_emmc_a_clk0_div,
	&g12a_sd_emmc_b_clk0_div,
	&g12a_sd_emmc_c_clk0_div,
	&g12a_mpeg_clk_sel,
	&g12a_sd_emmc_a_clk0_sel,
	&g12a_sd_emmc_b_clk0_sel,
	&g12a_sd_emmc_c_clk0_sel,
	&g12a_mpll0,
	&g12a_mpll1,
	&g12a_mpll2,
	&g12a_mpll3,
	&g12a_mpll0_div,
	&g12a_mpll1_div,
	&g12a_mpll2_div,
	&g12a_mpll3_div,
	&g12a_fixed_pll,
	&g12a_sys_pll,
	&g12a_gp0_pll,
	&g12a_hifi_pll,
	&g12a_vclk2_venci0,
	&g12a_vclk2_venci1,
	&g12a_vclk2_vencp0,
	&g12a_vclk2_vencp1,
	&g12a_vclk2_venct0,
	&g12a_vclk2_venct1,
	&g12a_vclk2_other,
	&g12a_vclk2_enci,
	&g12a_vclk2_encp,
	&g12a_dac_clk,
	&g12a_aoclk_gate,
	&g12a_iec958_gate,
	&g12a_enc480p,
	&g12a_rng1,
	&g12a_vclk2_enct,
	&g12a_vclk2_encl,
	&g12a_vclk2_venclmmc,
	&g12a_vclk2_vencl,
	&g12a_vclk2_other1,
	&g12a_fixed_pll_dco,
	&g12a_sys_pll_dco,
	&g12a_gp0_pll_dco,
	&g12a_hifi_pll_dco,
	&g12a_fclk_div2,
	&g12a_fclk_div3,
	&g12a_fclk_div4,
	&g12a_fclk_div5,
	&g12a_fclk_div7,
	&g12a_fclk_div2p5,
	&g12a_dma,
	&g12a_efuse,
	&g12a_rom_boot,
	&g12a_reset_sec,
	&g12a_sec_ahb_apb3,
	&g12a_vpu_0_sel,
	&g12a_vpu_0_div,
	&g12a_vpu_0,
	&g12a_vpu_1_sel,
	&g12a_vpu_1_div,
	&g12a_vpu_1,
	&g12a_vpu,
	&g12a_vapb_0_sel,
	&g12a_vapb_0_div,
	&g12a_vapb_0,
	&g12a_vapb_1_sel,
	&g12a_vapb_1_div,
	&g12a_vapb_1,
	&g12a_vapb_sel,
	&g12a_vapb,
	&g12a_hdmi_pll_dco,
	&g12a_hdmi_pll_od,
	&g12a_hdmi_pll_od2,
	&g12a_hdmi_pll,
	&g12a_vid_pll_div,
	&g12a_vid_pll_sel,
	&g12a_vid_pll,
	&g12a_vclk_sel,
	&g12a_vclk2_sel,
	&g12a_vclk_input,
	&g12a_vclk2_input,
	&g12a_vclk_div,
	&g12a_vclk2_div,
	&g12a_vclk,
	&g12a_vclk2,
	&g12a_vclk_div1,
	&g12a_vclk_div2_en,
	&g12a_vclk_div4_en,
	&g12a_vclk_div6_en,
	&g12a_vclk_div12_en,
	&g12a_vclk2_div1,
	&g12a_vclk2_div2_en,
	&g12a_vclk2_div4_en,
	&g12a_vclk2_div6_en,
	&g12a_vclk2_div12_en,
	&g12a_cts_enci_sel,
	&g12a_cts_encp_sel,
	&g12a_cts_vdac_sel,
	&g12a_hdmi_tx_sel,
	&g12a_cts_enci,
	&g12a_cts_encp,
	&g12a_cts_vdac,
	&g12a_hdmi_tx,
	&g12a_hdmi_sel,
	&g12a_hdmi_div,
	&g12a_hdmi,
	&g12a_mali_0_sel,
	&g12a_mali_0_div,
	&g12a_mali_0,
	&g12a_mali_1_sel,
	&g12a_mali_1_div,
	&g12a_mali_1,
	&g12a_mali,
	&g12a_mpll_50m,
	&g12a_sys_pll_div16_en,
	&g12a_cpu_clk_premux0,
	&g12a_cpu_clk_mux0_div,
	&g12a_cpu_clk_postmux0,
	&g12a_cpu_clk_premux1,
	&g12a_cpu_clk_mux1_div,
	&g12a_cpu_clk_postmux1,
	&g12a_cpu_clk_dyn,
	&g12a_cpu_clk,
	&g12a_cpu_clk_div16_en,
	&g12a_cpu_clk_apb_div,
	&g12a_cpu_clk_apb,
	&g12a_cpu_clk_atb_div,
	&g12a_cpu_clk_atb,
	&g12a_cpu_clk_axi_div,
	&g12a_cpu_clk_axi,
	&g12a_cpu_clk_trace_div,
	&g12a_cpu_clk_trace,
	&g12a_pcie_pll_od,
	&g12a_pcie_pll_dco,
	&g12a_vdec_1_sel,
	&g12a_vdec_1_div,
	&g12a_vdec_1,
	&g12a_vdec_hevc_sel,
	&g12a_vdec_hevc_div,
	&g12a_vdec_hevc,
	&g12a_vdec_hevcf_sel,
	&g12a_vdec_hevcf_div,
	&g12a_vdec_hevcf,
	&g12a_ts_div,
	&g12a_ts,
	&g12b_cpu_clk,
	&g12b_sys1_pll_dco,
	&g12b_sys1_pll,
	&g12b_sys1_pll_div16_en,
	&g12b_cpub_clk_premux0,
	&g12b_cpub_clk_mux0_div,
	&g12b_cpub_clk_postmux0,
	&g12b_cpub_clk_premux1,
	&g12b_cpub_clk_mux1_div,
	&g12b_cpub_clk_postmux1,
	&g12b_cpub_clk_dyn,
	&g12b_cpub_clk,
	&g12b_cpub_clk_div16_en,
	&g12b_cpub_clk_apb_sel,
	&g12b_cpub_clk_apb,
	&g12b_cpub_clk_atb_sel,
	&g12b_cpub_clk_atb,
	&g12b_cpub_clk_axi_sel,
	&g12b_cpub_clk_axi,
	&g12b_cpub_clk_trace_sel,
	&g12b_cpub_clk_trace,
	&sm1_gp1_pll_dco,
	&sm1_gp1_pll,
	&sm1_dsu_clk_premux0,
	&sm1_dsu_clk_premux1,
	&sm1_dsu_clk_mux0_div,
	&sm1_dsu_clk_postmux0,
	&sm1_dsu_clk_mux1_div,
	&sm1_dsu_clk_postmux1,
	&sm1_dsu_clk_dyn,
	&sm1_dsu_final_clk,
	&sm1_dsu_clk,
	&sm1_cpu1_clk,
	&sm1_cpu2_clk,
	&sm1_cpu3_clk,
	&g12a_spicc0_sclk_sel,
	&g12a_spicc0_sclk_div,
	&g12a_spicc0_sclk,
	&g12a_spicc1_sclk_sel,
	&g12a_spicc1_sclk_div,
	&g12a_spicc1_sclk,
	&sm1_nna_axi_clk_sel,
	&sm1_nna_axi_clk_div,
	&sm1_nna_axi_clk,
	&sm1_nna_core_clk_sel,
	&sm1_nna_core_clk_div,
	&sm1_nna_core_clk,
	&g12a_mipi_dsi_pxclk_sel,
	&g12a_mipi_dsi_pxclk_div,
	&g12a_mipi_dsi_pxclk,
};

static const struct reg_sequence g12a_init_regs[] = {
	{ .reg = HHI_MPLL_CNTL0,	.def = 0x00000543 },
};

#define DVFS_CON_ID "dvfs"

static int meson_g12a_dvfs_setup_common(struct device *dev,
					struct clk_hw **hws)
{
	struct clk *notifier_clk;
	struct clk_hw *xtal;
	int ret;

	xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);

	/* Setup clock notifier for cpu_clk_postmux0 */
	g12a_cpu_clk_postmux0_nb_data.xtal = xtal;
	notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk_postmux0.hw,
					   DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12a_cpu_clk_postmux0_nb_data.nb);
	if (ret) {
		dev_err(dev, "failed to register the cpu_clk_postmux0 notifier\n");
		return ret;
	}

	/* Setup clock notifier for cpu_clk_dyn mux */
	notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk_dyn.hw,
					   DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12a_cpu_clk_mux_nb);
	if (ret) {
		dev_err(dev, "failed to register the cpu_clk_dyn notifier\n");
		return ret;
	}

	return 0;
}

static int meson_g12b_dvfs_setup(struct platform_device *pdev)
{
	struct clk_hw **hws = g12b_hw_clks;
	struct device *dev = &pdev->dev;
	struct clk *notifier_clk;
	struct clk_hw *xtal;
	int ret;

	ret = meson_g12a_dvfs_setup_common(dev, hws);
	if (ret)
		return ret;

	xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);

	/* Setup clock notifier for cpu_clk mux */
	notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpu_clk.hw,
					   DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12a_cpu_clk_mux_nb);
	if (ret) {
		dev_err(dev, "failed to register the cpu_clk notifier\n");
		return ret;
	}

	/* Setup clock notifier for sys1_pll */
	notifier_clk = devm_clk_hw_get_clk(dev, &g12b_sys1_pll.hw,
					   DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12b_cpu_clk_sys1_pll_nb_data.nb);
	if (ret) {
		dev_err(dev, "failed to register the sys1_pll notifier\n");
		return ret;
	}

	/* Add notifiers for the second CPU cluster */

	/* Setup clock notifier for cpub_clk_postmux0 */
	g12b_cpub_clk_postmux0_nb_data.xtal = xtal;
	notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_postmux0.hw,
					   DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12b_cpub_clk_postmux0_nb_data.nb);
	if (ret) {
		dev_err(dev, "failed to register the cpub_clk_postmux0 notifier\n");
		return ret;
	}

	/* Setup clock notifier for cpub_clk_dyn mux */
	notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_dyn.hw, "dvfs");
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12a_cpu_clk_mux_nb);
	if (ret) {
		dev_err(dev, "failed to register the cpub_clk_dyn notifier\n");
		return ret;
	}

	/* Setup clock notifier for cpub_clk mux */
	notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk.hw, DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12a_cpu_clk_mux_nb);
	if (ret) {
		dev_err(dev, "failed to register the cpub_clk notifier\n");
		return ret;
	}

	/* Setup clock notifier for sys_pll */
	notifier_clk = devm_clk_hw_get_clk(dev, &g12a_sys_pll.hw, DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12b_cpub_clk_sys_pll_nb_data.nb);
	if (ret) {
		dev_err(dev, "failed to register the sys_pll notifier\n");
		return ret;
	}

	return 0;
}

static int meson_g12a_dvfs_setup(struct platform_device *pdev)
{
	struct clk_hw **hws = g12a_hw_clks;
	struct device *dev = &pdev->dev;
	struct clk *notifier_clk;
	int ret;

	ret = meson_g12a_dvfs_setup_common(dev, hws);
	if (ret)
		return ret;

	/* Setup clock notifier for cpu_clk mux */
	notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk.hw, DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
				    &g12a_cpu_clk_mux_nb);
	if (ret) {
		dev_err(dev, "failed to register the cpu_clk notifier\n");
		return ret;
	}

	/* Setup clock notifier for sys_pll */
	notifier_clk = devm_clk_hw_get_clk(dev, &g12a_sys_pll.hw, DVFS_CON_ID);
	ret = devm_clk_notifier_register(dev, notifier_clk,
					 &g12a_sys_pll_nb_data.nb);
	if (ret) {
		dev_err(dev, "failed to register the sys_pll notifier\n");
		return ret;
	}

	return 0;
}

struct meson_g12a_data {
	const struct meson_eeclkc_data eeclkc_data;
	int (*dvfs_setup)(struct platform_device *pdev);
};

static int meson_g12a_probe(struct platform_device *pdev)
{
	const struct meson_eeclkc_data *eeclkc_data;
	const struct meson_g12a_data *g12a_data;
	int ret;

	eeclkc_data = of_device_get_match_data(&pdev->dev);
	if (!eeclkc_data)
		return -EINVAL;

	ret = meson_eeclkc_probe(pdev);
	if (ret)
		return ret;

	g12a_data = container_of(eeclkc_data, struct meson_g12a_data,
				 eeclkc_data);

	if (g12a_data->dvfs_setup)
		return g12a_data->dvfs_setup(pdev);

	return 0;
}

static const struct meson_g12a_data g12a_clkc_data = {
	.eeclkc_data = {
		.regmap_clks = g12a_clk_regmaps,
		.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
		.hw_clks = {
			.hws = g12a_hw_clks,
			.num = ARRAY_SIZE(g12a_hw_clks),
		},
		.init_regs = g12a_init_regs,
		.init_count = ARRAY_SIZE(g12a_init_regs),
	},
	.dvfs_setup = meson_g12a_dvfs_setup,
};

static const struct meson_g12a_data g12b_clkc_data = {
	.eeclkc_data = {
		.regmap_clks = g12a_clk_regmaps,
		.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
		.hw_clks = {
			.hws = g12b_hw_clks,
			.num = ARRAY_SIZE(g12b_hw_clks),
		},
	},
	.dvfs_setup = meson_g12b_dvfs_setup,
};

static const struct meson_g12a_data sm1_clkc_data = {
	.eeclkc_data = {
		.regmap_clks = g12a_clk_regmaps,
		.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
		.hw_clks = {
			.hws = sm1_hw_clks,
			.num = ARRAY_SIZE(sm1_hw_clks),
		},
	},
	.dvfs_setup = meson_g12a_dvfs_setup,
};

static const struct of_device_id clkc_match_table[] = {
	{
		.compatible = "amlogic,g12a-clkc",
		.data = &g12a_clkc_data.eeclkc_data
	},
	{
		.compatible = "amlogic,g12b-clkc",
		.data = &g12b_clkc_data.eeclkc_data
	},
	{
		.compatible = "amlogic,sm1-clkc",
		.data = &sm1_clkc_data.eeclkc_data
	},
	{}
};
MODULE_DEVICE_TABLE(of, clkc_match_table);

static struct platform_driver g12a_driver = {
	.probe		= meson_g12a_probe,
	.driver		= {
		.name	= "g12a-clkc",
		.of_match_table = clkc_match_table,
	},
};

module_platform_driver(g12a_driver);
MODULE_LICENSE("GPL v2");