forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathclk-tegra210.c
3595 lines (3133 loc) · 117 KB
/
clk-tegra210.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright (c) 2012-2014 NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/io.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/mutex.h>
#include <linux/clk/tegra.h>
#include <dt-bindings/clock/tegra210-car.h>
#include <dt-bindings/reset/tegra210-car.h>
#include <linux/iopoll.h>
#include <linux/sizes.h>
#include <soc/tegra/pmc.h>
#include "clk.h"
#include "clk-id.h"
/*
* TEGRA210_CAR_BANK_COUNT: the number of peripheral clock register
* banks present in the Tegra210 CAR IP block. The banks are
* identified by single letters, e.g.: L, H, U, V, W, X, Y. See
* periph_regs[] in drivers/clk/tegra/clk.c
*/
#define TEGRA210_CAR_BANK_COUNT 7
#define CLK_SOURCE_CSITE 0x1d4
#define CLK_SOURCE_EMC 0x19c
#define CLK_SOURCE_SOR1 0x410
#define CLK_SOURCE_LA 0x1f8
#define CLK_SOURCE_SDMMC2 0x154
#define CLK_SOURCE_SDMMC4 0x164
#define PLLC_BASE 0x80
#define PLLC_OUT 0x84
#define PLLC_MISC0 0x88
#define PLLC_MISC1 0x8c
#define PLLC_MISC2 0x5d0
#define PLLC_MISC3 0x5d4
#define PLLC2_BASE 0x4e8
#define PLLC2_MISC0 0x4ec
#define PLLC2_MISC1 0x4f0
#define PLLC2_MISC2 0x4f4
#define PLLC2_MISC3 0x4f8
#define PLLC3_BASE 0x4fc
#define PLLC3_MISC0 0x500
#define PLLC3_MISC1 0x504
#define PLLC3_MISC2 0x508
#define PLLC3_MISC3 0x50c
#define PLLM_BASE 0x90
#define PLLM_MISC1 0x98
#define PLLM_MISC2 0x9c
#define PLLP_BASE 0xa0
#define PLLP_MISC0 0xac
#define PLLP_MISC1 0x680
#define PLLA_BASE 0xb0
#define PLLA_MISC0 0xbc
#define PLLA_MISC1 0xb8
#define PLLA_MISC2 0x5d8
#define PLLD_BASE 0xd0
#define PLLD_MISC0 0xdc
#define PLLD_MISC1 0xd8
#define PLLU_BASE 0xc0
#define PLLU_OUTA 0xc4
#define PLLU_MISC0 0xcc
#define PLLU_MISC1 0xc8
#define PLLX_BASE 0xe0
#define PLLX_MISC0 0xe4
#define PLLX_MISC1 0x510
#define PLLX_MISC2 0x514
#define PLLX_MISC3 0x518
#define PLLX_MISC4 0x5f0
#define PLLX_MISC5 0x5f4
#define PLLE_BASE 0xe8
#define PLLE_MISC0 0xec
#define PLLD2_BASE 0x4b8
#define PLLD2_MISC0 0x4bc
#define PLLD2_MISC1 0x570
#define PLLD2_MISC2 0x574
#define PLLD2_MISC3 0x578
#define PLLE_AUX 0x48c
#define PLLRE_BASE 0x4c4
#define PLLRE_MISC0 0x4c8
#define PLLRE_OUT1 0x4cc
#define PLLDP_BASE 0x590
#define PLLDP_MISC 0x594
#define PLLC4_BASE 0x5a4
#define PLLC4_MISC0 0x5a8
#define PLLC4_OUT 0x5e4
#define PLLMB_BASE 0x5e8
#define PLLMB_MISC1 0x5ec
#define PLLA1_BASE 0x6a4
#define PLLA1_MISC0 0x6a8
#define PLLA1_MISC1 0x6ac
#define PLLA1_MISC2 0x6b0
#define PLLA1_MISC3 0x6b4
#define PLLU_IDDQ_BIT 31
#define PLLCX_IDDQ_BIT 27
#define PLLRE_IDDQ_BIT 24
#define PLLA_IDDQ_BIT 25
#define PLLD_IDDQ_BIT 20
#define PLLSS_IDDQ_BIT 18
#define PLLM_IDDQ_BIT 5
#define PLLMB_IDDQ_BIT 17
#define PLLXP_IDDQ_BIT 3
#define PLLCX_RESET_BIT 30
#define PLL_BASE_LOCK BIT(27)
#define PLLCX_BASE_LOCK BIT(26)
#define PLLE_MISC_LOCK BIT(11)
#define PLLRE_MISC_LOCK BIT(27)
#define PLL_MISC_LOCK_ENABLE 18
#define PLLC_MISC_LOCK_ENABLE 24
#define PLLDU_MISC_LOCK_ENABLE 22
#define PLLU_MISC_LOCK_ENABLE 29
#define PLLE_MISC_LOCK_ENABLE 9
#define PLLRE_MISC_LOCK_ENABLE 30
#define PLLSS_MISC_LOCK_ENABLE 30
#define PLLP_MISC_LOCK_ENABLE 18
#define PLLM_MISC_LOCK_ENABLE 4
#define PLLMB_MISC_LOCK_ENABLE 16
#define PLLA_MISC_LOCK_ENABLE 28
#define PLLU_MISC_LOCK_ENABLE 29
#define PLLD_MISC_LOCK_ENABLE 18
#define PLLA_SDM_DIN_MASK 0xffff
#define PLLA_SDM_EN_MASK BIT(26)
#define PLLD_SDM_EN_MASK BIT(16)
#define PLLD2_SDM_EN_MASK BIT(31)
#define PLLD2_SSC_EN_MASK 0
#define PLLDP_SS_CFG 0x598
#define PLLDP_SDM_EN_MASK BIT(31)
#define PLLDP_SSC_EN_MASK BIT(30)
#define PLLDP_SS_CTRL1 0x59c
#define PLLDP_SS_CTRL2 0x5a0
#define PMC_PLLM_WB0_OVERRIDE 0x1dc
#define PMC_PLLM_WB0_OVERRIDE_2 0x2b0
#define UTMIP_PLL_CFG2 0x488
#define UTMIP_PLL_CFG2_STABLE_COUNT(x) (((x) & 0xfff) << 6)
#define UTMIP_PLL_CFG2_ACTIVE_DLY_COUNT(x) (((x) & 0x3f) << 18)
#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERDOWN BIT(0)
#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_A_POWERUP BIT(1)
#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERDOWN BIT(2)
#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_B_POWERUP BIT(3)
#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERDOWN BIT(4)
#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_C_POWERUP BIT(5)
#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_D_POWERDOWN BIT(24)
#define UTMIP_PLL_CFG2_FORCE_PD_SAMP_D_POWERUP BIT(25)
#define UTMIP_PLL_CFG1 0x484
#define UTMIP_PLL_CFG1_ENABLE_DLY_COUNT(x) (((x) & 0x1f) << 27)
#define UTMIP_PLL_CFG1_XTAL_FREQ_COUNT(x) (((x) & 0xfff) << 0)
#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERUP BIT(17)
#define UTMIP_PLL_CFG1_FORCE_PLLU_POWERDOWN BIT(16)
#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERUP BIT(15)
#define UTMIP_PLL_CFG1_FORCE_PLL_ENABLE_POWERDOWN BIT(14)
#define UTMIP_PLL_CFG1_FORCE_PLL_ACTIVE_POWERDOWN BIT(12)
#define SATA_PLL_CFG0 0x490
#define SATA_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
#define SATA_PLL_CFG0_PADPLL_USE_LOCKDET BIT(2)
#define SATA_PLL_CFG0_SATA_SEQ_IN_SWCTL BIT(4)
#define SATA_PLL_CFG0_SATA_SEQ_RESET_INPUT_VALUE BIT(5)
#define SATA_PLL_CFG0_SATA_SEQ_LANE_PD_INPUT_VALUE BIT(6)
#define SATA_PLL_CFG0_SATA_SEQ_PADPLL_PD_INPUT_VALUE BIT(7)
#define SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13)
#define SATA_PLL_CFG0_SEQ_ENABLE BIT(24)
#define XUSBIO_PLL_CFG0 0x51c
#define XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL BIT(0)
#define XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL BIT(2)
#define XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET BIT(6)
#define XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ BIT(13)
#define XUSBIO_PLL_CFG0_SEQ_ENABLE BIT(24)
#define UTMIPLL_HW_PWRDN_CFG0 0x52c
#define UTMIPLL_HW_PWRDN_CFG0_UTMIPLL_LOCK BIT(31)
#define UTMIPLL_HW_PWRDN_CFG0_SEQ_START_STATE BIT(25)
#define UTMIPLL_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24)
#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE BIT(7)
#define UTMIPLL_HW_PWRDN_CFG0_USE_LOCKDET BIT(6)
#define UTMIPLL_HW_PWRDN_CFG0_SEQ_RESET_INPUT_VALUE BIT(5)
#define UTMIPLL_HW_PWRDN_CFG0_SEQ_IN_SWCTL BIT(4)
#define UTMIPLL_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2)
#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_OVERRIDE BIT(1)
#define UTMIPLL_HW_PWRDN_CFG0_IDDQ_SWCTL BIT(0)
#define PLLU_HW_PWRDN_CFG0 0x530
#define PLLU_HW_PWRDN_CFG0_IDDQ_PD_INCLUDE BIT(28)
#define PLLU_HW_PWRDN_CFG0_SEQ_ENABLE BIT(24)
#define PLLU_HW_PWRDN_CFG0_USE_SWITCH_DETECT BIT(7)
#define PLLU_HW_PWRDN_CFG0_USE_LOCKDET BIT(6)
#define PLLU_HW_PWRDN_CFG0_CLK_ENABLE_SWCTL BIT(2)
#define PLLU_HW_PWRDN_CFG0_CLK_SWITCH_SWCTL BIT(0)
#define XUSB_PLL_CFG0 0x534
#define XUSB_PLL_CFG0_UTMIPLL_LOCK_DLY 0x3ff
#define XUSB_PLL_CFG0_PLLU_LOCK_DLY_MASK (0x3ff << 14)
#define SPARE_REG0 0x55c
#define CLK_M_DIVISOR_SHIFT 2
#define CLK_M_DIVISOR_MASK 0x3
#define RST_DFLL_DVCO 0x2f4
#define DVFS_DFLL_RESET_SHIFT 0
#define CLK_RST_CONTROLLER_RST_DEV_Y_SET 0x2a8
#define CLK_RST_CONTROLLER_RST_DEV_Y_CLR 0x2ac
#define LVL2_CLK_GATE_OVRA 0xf8
#define LVL2_CLK_GATE_OVRC 0x3a0
#define LVL2_CLK_GATE_OVRD 0x3a4
#define LVL2_CLK_GATE_OVRE 0x554
/* I2S registers to handle during APE MBIST WAR */
#define TEGRA210_I2S_BASE 0x1000
#define TEGRA210_I2S_SIZE 0x100
#define TEGRA210_I2S_CTRLS 5
#define TEGRA210_I2S_CG 0x88
#define TEGRA210_I2S_CTRL 0xa0
/* DISPA registers to handle during MBIST WAR */
#define DC_CMD_DISPLAY_COMMAND 0xc8
#define DC_COM_DSC_TOP_CTL 0xcf8
/* VIC register to handle during MBIST WAR */
#define NV_PVIC_THI_SLCG_OVERRIDE_LOW 0x8c
/* APE, DISPA and VIC base addesses needed for MBIST WAR */
#define TEGRA210_AHUB_BASE 0x702d0000
#define TEGRA210_DISPA_BASE 0x54200000
#define TEGRA210_VIC_BASE 0x54340000
/*
* SDM fractional divisor is 16-bit 2's complement signed number within
* (-2^12 ... 2^12-1) range. Represented in PLL data structure as unsigned
* 16-bit value, with "0" divisor mapped to 0xFFFF. Data "0" is used to
* indicate that SDM is disabled.
*
* Effective ndiv value when SDM is enabled: ndiv + 1/2 + sdm_din/2^13
*/
#define PLL_SDM_COEFF BIT(13)
#define sdin_din_to_data(din) ((u16)((din) ? : 0xFFFFU))
#define sdin_data_to_din(dat) (((dat) == 0xFFFFU) ? 0 : (s16)dat)
/* This macro returns ndiv effective scaled to SDM range */
#define sdin_get_n_eff(cfg) ((cfg)->n * PLL_SDM_COEFF + ((cfg)->sdm_data ? \
(PLL_SDM_COEFF/2 + sdin_data_to_din((cfg)->sdm_data)) : 0))
/* Tegra CPU clock and reset control regs */
#define CLK_RST_CONTROLLER_CPU_CMPLX_STATUS 0x470
#ifdef CONFIG_PM_SLEEP
static struct cpu_clk_suspend_context {
u32 clk_csite_src;
} tegra210_cpu_clk_sctx;
#endif
struct tegra210_domain_mbist_war {
void (*handle_lvl2_ovr)(struct tegra210_domain_mbist_war *mbist);
const u32 lvl2_offset;
const u32 lvl2_mask;
const unsigned int num_clks;
const unsigned int *clk_init_data;
struct clk_bulk_data *clks;
};
static struct clk **clks;
static void __iomem *clk_base;
static void __iomem *pmc_base;
static void __iomem *ahub_base;
static void __iomem *dispa_base;
static void __iomem *vic_base;
static unsigned long osc_freq;
static unsigned long pll_ref_freq;
static DEFINE_SPINLOCK(pll_d_lock);
static DEFINE_SPINLOCK(pll_e_lock);
static DEFINE_SPINLOCK(pll_re_lock);
static DEFINE_SPINLOCK(pll_u_lock);
static DEFINE_SPINLOCK(sor1_lock);
static DEFINE_SPINLOCK(emc_lock);
static DEFINE_MUTEX(lvl2_ovr_lock);
/* possible OSC frequencies in Hz */
static unsigned long tegra210_input_freq[] = {
[5] = 38400000,
[8] = 12000000,
};
static const char *mux_pllmcp_clkm[] = {
"pll_m", "pll_c", "pll_p", "clk_m", "pll_m_ud", "pll_mb", "pll_mb",
"pll_p",
};
#define mux_pllmcp_clkm_idx NULL
#define PLL_ENABLE (1 << 30)
#define PLLCX_MISC1_IDDQ (1 << 27)
#define PLLCX_MISC0_RESET (1 << 30)
#define PLLCX_MISC0_DEFAULT_VALUE 0x40080000
#define PLLCX_MISC0_WRITE_MASK 0x400ffffb
#define PLLCX_MISC1_DEFAULT_VALUE 0x08000000
#define PLLCX_MISC1_WRITE_MASK 0x08003cff
#define PLLCX_MISC2_DEFAULT_VALUE 0x1f720f05
#define PLLCX_MISC2_WRITE_MASK 0xffffff17
#define PLLCX_MISC3_DEFAULT_VALUE 0x000000c4
#define PLLCX_MISC3_WRITE_MASK 0x00ffffff
/* PLLA */
#define PLLA_BASE_IDDQ (1 << 25)
#define PLLA_BASE_LOCK (1 << 27)
#define PLLA_MISC0_LOCK_ENABLE (1 << 28)
#define PLLA_MISC0_LOCK_OVERRIDE (1 << 27)
#define PLLA_MISC2_EN_SDM (1 << 26)
#define PLLA_MISC2_EN_DYNRAMP (1 << 25)
#define PLLA_MISC0_DEFAULT_VALUE 0x12000020
#define PLLA_MISC0_WRITE_MASK 0x7fffffff
#define PLLA_MISC2_DEFAULT_VALUE 0x0
#define PLLA_MISC2_WRITE_MASK 0x06ffffff
/* PLLD */
#define PLLD_BASE_CSI_CLKSOURCE (1 << 23)
#define PLLD_MISC0_EN_SDM (1 << 16)
#define PLLD_MISC0_LOCK_OVERRIDE (1 << 17)
#define PLLD_MISC0_LOCK_ENABLE (1 << 18)
#define PLLD_MISC0_IDDQ (1 << 20)
#define PLLD_MISC0_DSI_CLKENABLE (1 << 21)
#define PLLD_MISC0_DEFAULT_VALUE 0x00140000
#define PLLD_MISC0_WRITE_MASK 0x3ff7ffff
#define PLLD_MISC1_DEFAULT_VALUE 0x20
#define PLLD_MISC1_WRITE_MASK 0x00ffffff
/* PLLD2 and PLLDP and PLLC4 */
#define PLLDSS_BASE_LOCK (1 << 27)
#define PLLDSS_BASE_LOCK_OVERRIDE (1 << 24)
#define PLLDSS_BASE_IDDQ (1 << 18)
#define PLLDSS_BASE_REF_SEL_SHIFT 25
#define PLLDSS_BASE_REF_SEL_MASK (0x3 << PLLDSS_BASE_REF_SEL_SHIFT)
#define PLLDSS_MISC0_LOCK_ENABLE (1 << 30)
#define PLLDSS_MISC1_CFG_EN_SDM (1 << 31)
#define PLLDSS_MISC1_CFG_EN_SSC (1 << 30)
#define PLLD2_MISC0_DEFAULT_VALUE 0x40000020
#define PLLD2_MISC1_CFG_DEFAULT_VALUE 0x10000000
#define PLLD2_MISC2_CTRL1_DEFAULT_VALUE 0x0
#define PLLD2_MISC3_CTRL2_DEFAULT_VALUE 0x0
#define PLLDP_MISC0_DEFAULT_VALUE 0x40000020
#define PLLDP_MISC1_CFG_DEFAULT_VALUE 0xc0000000
#define PLLDP_MISC2_CTRL1_DEFAULT_VALUE 0xf400f0da
#define PLLDP_MISC3_CTRL2_DEFAULT_VALUE 0x2004f400
#define PLLDSS_MISC0_WRITE_MASK 0x47ffffff
#define PLLDSS_MISC1_CFG_WRITE_MASK 0xf8000000
#define PLLDSS_MISC2_CTRL1_WRITE_MASK 0xffffffff
#define PLLDSS_MISC3_CTRL2_WRITE_MASK 0xffffffff
#define PLLC4_MISC0_DEFAULT_VALUE 0x40000000
/* PLLRE */
#define PLLRE_MISC0_LOCK_ENABLE (1 << 30)
#define PLLRE_MISC0_LOCK_OVERRIDE (1 << 29)
#define PLLRE_MISC0_LOCK (1 << 27)
#define PLLRE_MISC0_IDDQ (1 << 24)
#define PLLRE_BASE_DEFAULT_VALUE 0x0
#define PLLRE_MISC0_DEFAULT_VALUE 0x41000000
#define PLLRE_BASE_DEFAULT_MASK 0x1c000000
#define PLLRE_MISC0_WRITE_MASK 0x67ffffff
/* PLLX */
#define PLLX_USE_DYN_RAMP 1
#define PLLX_BASE_LOCK (1 << 27)
#define PLLX_MISC0_FO_G_DISABLE (0x1 << 28)
#define PLLX_MISC0_LOCK_ENABLE (0x1 << 18)
#define PLLX_MISC2_DYNRAMP_STEPB_SHIFT 24
#define PLLX_MISC2_DYNRAMP_STEPB_MASK (0xFF << PLLX_MISC2_DYNRAMP_STEPB_SHIFT)
#define PLLX_MISC2_DYNRAMP_STEPA_SHIFT 16
#define PLLX_MISC2_DYNRAMP_STEPA_MASK (0xFF << PLLX_MISC2_DYNRAMP_STEPA_SHIFT)
#define PLLX_MISC2_NDIV_NEW_SHIFT 8
#define PLLX_MISC2_NDIV_NEW_MASK (0xFF << PLLX_MISC2_NDIV_NEW_SHIFT)
#define PLLX_MISC2_LOCK_OVERRIDE (0x1 << 4)
#define PLLX_MISC2_DYNRAMP_DONE (0x1 << 2)
#define PLLX_MISC2_EN_DYNRAMP (0x1 << 0)
#define PLLX_MISC3_IDDQ (0x1 << 3)
#define PLLX_MISC0_DEFAULT_VALUE PLLX_MISC0_LOCK_ENABLE
#define PLLX_MISC0_WRITE_MASK 0x10c40000
#define PLLX_MISC1_DEFAULT_VALUE 0x20
#define PLLX_MISC1_WRITE_MASK 0x00ffffff
#define PLLX_MISC2_DEFAULT_VALUE 0x0
#define PLLX_MISC2_WRITE_MASK 0xffffff11
#define PLLX_MISC3_DEFAULT_VALUE PLLX_MISC3_IDDQ
#define PLLX_MISC3_WRITE_MASK 0x01ff0f0f
#define PLLX_MISC4_DEFAULT_VALUE 0x0
#define PLLX_MISC4_WRITE_MASK 0x8000ffff
#define PLLX_MISC5_DEFAULT_VALUE 0x0
#define PLLX_MISC5_WRITE_MASK 0x0000ffff
#define PLLX_HW_CTRL_CFG 0x548
#define PLLX_HW_CTRL_CFG_SWCTRL (0x1 << 0)
/* PLLMB */
#define PLLMB_BASE_LOCK (1 << 27)
#define PLLMB_MISC1_LOCK_OVERRIDE (1 << 18)
#define PLLMB_MISC1_IDDQ (1 << 17)
#define PLLMB_MISC1_LOCK_ENABLE (1 << 16)
#define PLLMB_MISC1_DEFAULT_VALUE 0x00030000
#define PLLMB_MISC1_WRITE_MASK 0x0007ffff
/* PLLP */
#define PLLP_BASE_OVERRIDE (1 << 28)
#define PLLP_BASE_LOCK (1 << 27)
#define PLLP_MISC0_LOCK_ENABLE (1 << 18)
#define PLLP_MISC0_LOCK_OVERRIDE (1 << 17)
#define PLLP_MISC0_IDDQ (1 << 3)
#define PLLP_MISC1_HSIO_EN_SHIFT 29
#define PLLP_MISC1_HSIO_EN (1 << PLLP_MISC1_HSIO_EN_SHIFT)
#define PLLP_MISC1_XUSB_EN_SHIFT 28
#define PLLP_MISC1_XUSB_EN (1 << PLLP_MISC1_XUSB_EN_SHIFT)
#define PLLP_MISC0_DEFAULT_VALUE 0x00040008
#define PLLP_MISC1_DEFAULT_VALUE 0x0
#define PLLP_MISC0_WRITE_MASK 0xdc6000f
#define PLLP_MISC1_WRITE_MASK 0x70ffffff
/* PLLU */
#define PLLU_BASE_LOCK (1 << 27)
#define PLLU_BASE_OVERRIDE (1 << 24)
#define PLLU_BASE_CLKENABLE_USB (1 << 21)
#define PLLU_BASE_CLKENABLE_HSIC (1 << 22)
#define PLLU_BASE_CLKENABLE_ICUSB (1 << 23)
#define PLLU_BASE_CLKENABLE_48M (1 << 25)
#define PLLU_BASE_CLKENABLE_ALL (PLLU_BASE_CLKENABLE_USB |\
PLLU_BASE_CLKENABLE_HSIC |\
PLLU_BASE_CLKENABLE_ICUSB |\
PLLU_BASE_CLKENABLE_48M)
#define PLLU_MISC0_IDDQ (1 << 31)
#define PLLU_MISC0_LOCK_ENABLE (1 << 29)
#define PLLU_MISC1_LOCK_OVERRIDE (1 << 0)
#define PLLU_MISC0_DEFAULT_VALUE 0xa0000000
#define PLLU_MISC1_DEFAULT_VALUE 0x0
#define PLLU_MISC0_WRITE_MASK 0xbfffffff
#define PLLU_MISC1_WRITE_MASK 0x00000007
void tegra210_xusb_pll_hw_control_enable(void)
{
u32 val;
val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0);
val &= ~(XUSBIO_PLL_CFG0_CLK_ENABLE_SWCTL |
XUSBIO_PLL_CFG0_PADPLL_RESET_SWCTL);
val |= XUSBIO_PLL_CFG0_PADPLL_USE_LOCKDET |
XUSBIO_PLL_CFG0_PADPLL_SLEEP_IDDQ;
writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0);
}
EXPORT_SYMBOL_GPL(tegra210_xusb_pll_hw_control_enable);
void tegra210_xusb_pll_hw_sequence_start(void)
{
u32 val;
val = readl_relaxed(clk_base + XUSBIO_PLL_CFG0);
val |= XUSBIO_PLL_CFG0_SEQ_ENABLE;
writel_relaxed(val, clk_base + XUSBIO_PLL_CFG0);
}
EXPORT_SYMBOL_GPL(tegra210_xusb_pll_hw_sequence_start);
void tegra210_sata_pll_hw_control_enable(void)
{
u32 val;
val = readl_relaxed(clk_base + SATA_PLL_CFG0);
val &= ~SATA_PLL_CFG0_PADPLL_RESET_SWCTL;
val |= SATA_PLL_CFG0_PADPLL_USE_LOCKDET |
SATA_PLL_CFG0_PADPLL_SLEEP_IDDQ;
writel_relaxed(val, clk_base + SATA_PLL_CFG0);
}
EXPORT_SYMBOL_GPL(tegra210_sata_pll_hw_control_enable);
void tegra210_sata_pll_hw_sequence_start(void)
{
u32 val;
val = readl_relaxed(clk_base + SATA_PLL_CFG0);
val |= SATA_PLL_CFG0_SEQ_ENABLE;
writel_relaxed(val, clk_base + SATA_PLL_CFG0);
}
EXPORT_SYMBOL_GPL(tegra210_sata_pll_hw_sequence_start);
void tegra210_set_sata_pll_seq_sw(bool state)
{
u32 val;
val = readl_relaxed(clk_base + SATA_PLL_CFG0);
if (state) {
val |= SATA_PLL_CFG0_SATA_SEQ_IN_SWCTL;
val |= SATA_PLL_CFG0_SATA_SEQ_RESET_INPUT_VALUE;
val |= SATA_PLL_CFG0_SATA_SEQ_LANE_PD_INPUT_VALUE;
val |= SATA_PLL_CFG0_SATA_SEQ_PADPLL_PD_INPUT_VALUE;
} else {
val &= ~SATA_PLL_CFG0_SATA_SEQ_IN_SWCTL;
val &= ~SATA_PLL_CFG0_SATA_SEQ_RESET_INPUT_VALUE;
val &= ~SATA_PLL_CFG0_SATA_SEQ_LANE_PD_INPUT_VALUE;
val &= ~SATA_PLL_CFG0_SATA_SEQ_PADPLL_PD_INPUT_VALUE;
}
writel_relaxed(val, clk_base + SATA_PLL_CFG0);
}
EXPORT_SYMBOL_GPL(tegra210_set_sata_pll_seq_sw);
static void tegra210_generic_mbist_war(struct tegra210_domain_mbist_war *mbist)
{
u32 val;
val = readl_relaxed(clk_base + mbist->lvl2_offset);
writel_relaxed(val | mbist->lvl2_mask, clk_base + mbist->lvl2_offset);
fence_udelay(1, clk_base);
writel_relaxed(val, clk_base + mbist->lvl2_offset);
fence_udelay(1, clk_base);
}
static void tegra210_venc_mbist_war(struct tegra210_domain_mbist_war *mbist)
{
u32 csi_src, ovra, ovre;
unsigned long flags = 0;
spin_lock_irqsave(&pll_d_lock, flags);
csi_src = readl_relaxed(clk_base + PLLD_BASE);
writel_relaxed(csi_src | PLLD_BASE_CSI_CLKSOURCE, clk_base + PLLD_BASE);
fence_udelay(1, clk_base);
ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA);
writel_relaxed(ovra | BIT(15), clk_base + LVL2_CLK_GATE_OVRA);
ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
writel_relaxed(ovre | BIT(3), clk_base + LVL2_CLK_GATE_OVRE);
fence_udelay(1, clk_base);
writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA);
writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
writel_relaxed(csi_src, clk_base + PLLD_BASE);
fence_udelay(1, clk_base);
spin_unlock_irqrestore(&pll_d_lock, flags);
}
static void tegra210_disp_mbist_war(struct tegra210_domain_mbist_war *mbist)
{
u32 ovra, dsc_top_ctrl;
ovra = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRA);
writel_relaxed(ovra | BIT(1), clk_base + LVL2_CLK_GATE_OVRA);
fence_udelay(1, clk_base);
dsc_top_ctrl = readl_relaxed(dispa_base + DC_COM_DSC_TOP_CTL);
writel_relaxed(dsc_top_ctrl | BIT(2), dispa_base + DC_COM_DSC_TOP_CTL);
readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND);
writel_relaxed(dsc_top_ctrl, dispa_base + DC_COM_DSC_TOP_CTL);
readl_relaxed(dispa_base + DC_CMD_DISPLAY_COMMAND);
writel_relaxed(ovra, clk_base + LVL2_CLK_GATE_OVRA);
fence_udelay(1, clk_base);
}
static void tegra210_vic_mbist_war(struct tegra210_domain_mbist_war *mbist)
{
u32 ovre, val;
ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
writel_relaxed(ovre | BIT(5), clk_base + LVL2_CLK_GATE_OVRE);
fence_udelay(1, clk_base);
val = readl_relaxed(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
writel_relaxed(val | BIT(0) | GENMASK(7, 2) | BIT(24),
vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
fence_udelay(1, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
writel_relaxed(val, vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
readl(vic_base + NV_PVIC_THI_SLCG_OVERRIDE_LOW);
writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
fence_udelay(1, clk_base);
}
static void tegra210_ape_mbist_war(struct tegra210_domain_mbist_war *mbist)
{
void __iomem *i2s_base;
unsigned int i;
u32 ovrc, ovre;
ovrc = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRC);
ovre = readl_relaxed(clk_base + LVL2_CLK_GATE_OVRE);
writel_relaxed(ovrc | BIT(1), clk_base + LVL2_CLK_GATE_OVRC);
writel_relaxed(ovre | BIT(10) | BIT(11),
clk_base + LVL2_CLK_GATE_OVRE);
fence_udelay(1, clk_base);
i2s_base = ahub_base + TEGRA210_I2S_BASE;
for (i = 0; i < TEGRA210_I2S_CTRLS; i++) {
u32 i2s_ctrl;
i2s_ctrl = readl_relaxed(i2s_base + TEGRA210_I2S_CTRL);
writel_relaxed(i2s_ctrl | BIT(10),
i2s_base + TEGRA210_I2S_CTRL);
writel_relaxed(0, i2s_base + TEGRA210_I2S_CG);
readl(i2s_base + TEGRA210_I2S_CG);
writel_relaxed(1, i2s_base + TEGRA210_I2S_CG);
writel_relaxed(i2s_ctrl, i2s_base + TEGRA210_I2S_CTRL);
readl(i2s_base + TEGRA210_I2S_CTRL);
i2s_base += TEGRA210_I2S_SIZE;
}
writel_relaxed(ovrc, clk_base + LVL2_CLK_GATE_OVRC);
writel_relaxed(ovre, clk_base + LVL2_CLK_GATE_OVRE);
fence_udelay(1, clk_base);
}
static inline void _pll_misc_chk_default(void __iomem *base,
struct tegra_clk_pll_params *params,
u8 misc_num, u32 default_val, u32 mask)
{
u32 boot_val = readl_relaxed(base + params->ext_misc_reg[misc_num]);
boot_val &= mask;
default_val &= mask;
if (boot_val != default_val) {
pr_warn("boot misc%d 0x%x: expected 0x%x\n",
misc_num, boot_val, default_val);
pr_warn(" (comparison mask = 0x%x)\n", mask);
params->defaults_set = false;
}
}
/*
* PLLCX: PLLC, PLLC2, PLLC3, PLLA1
* Hybrid PLLs with dynamic ramp. Dynamic ramp is allowed for any transition
* that changes NDIV only, while PLL is already locked.
*/
static void pllcx_check_defaults(struct tegra_clk_pll_params *params)
{
u32 default_val;
default_val = PLLCX_MISC0_DEFAULT_VALUE & (~PLLCX_MISC0_RESET);
_pll_misc_chk_default(clk_base, params, 0, default_val,
PLLCX_MISC0_WRITE_MASK);
default_val = PLLCX_MISC1_DEFAULT_VALUE & (~PLLCX_MISC1_IDDQ);
_pll_misc_chk_default(clk_base, params, 1, default_val,
PLLCX_MISC1_WRITE_MASK);
default_val = PLLCX_MISC2_DEFAULT_VALUE;
_pll_misc_chk_default(clk_base, params, 2, default_val,
PLLCX_MISC2_WRITE_MASK);
default_val = PLLCX_MISC3_DEFAULT_VALUE;
_pll_misc_chk_default(clk_base, params, 3, default_val,
PLLCX_MISC3_WRITE_MASK);
}
static void tegra210_pllcx_set_defaults(const char *name,
struct tegra_clk_pll *pllcx)
{
pllcx->params->defaults_set = true;
if (readl_relaxed(clk_base + pllcx->params->base_reg) & PLL_ENABLE) {
/* PLL is ON: only check if defaults already set */
pllcx_check_defaults(pllcx->params);
if (!pllcx->params->defaults_set)
pr_warn("%s already enabled. Postponing set full defaults\n",
name);
return;
}
/* Defaults assert PLL reset, and set IDDQ */
writel_relaxed(PLLCX_MISC0_DEFAULT_VALUE,
clk_base + pllcx->params->ext_misc_reg[0]);
writel_relaxed(PLLCX_MISC1_DEFAULT_VALUE,
clk_base + pllcx->params->ext_misc_reg[1]);
writel_relaxed(PLLCX_MISC2_DEFAULT_VALUE,
clk_base + pllcx->params->ext_misc_reg[2]);
writel_relaxed(PLLCX_MISC3_DEFAULT_VALUE,
clk_base + pllcx->params->ext_misc_reg[3]);
udelay(1);
}
static void _pllc_set_defaults(struct tegra_clk_pll *pllcx)
{
tegra210_pllcx_set_defaults("PLL_C", pllcx);
}
static void _pllc2_set_defaults(struct tegra_clk_pll *pllcx)
{
tegra210_pllcx_set_defaults("PLL_C2", pllcx);
}
static void _pllc3_set_defaults(struct tegra_clk_pll *pllcx)
{
tegra210_pllcx_set_defaults("PLL_C3", pllcx);
}
static void _plla1_set_defaults(struct tegra_clk_pll *pllcx)
{
tegra210_pllcx_set_defaults("PLL_A1", pllcx);
}
/*
* PLLA
* PLL with dynamic ramp and fractional SDM. Dynamic ramp is not used.
* Fractional SDM is allowed to provide exact audio rates.
*/
static void tegra210_plla_set_defaults(struct tegra_clk_pll *plla)
{
u32 mask;
u32 val = readl_relaxed(clk_base + plla->params->base_reg);
plla->params->defaults_set = true;
if (val & PLL_ENABLE) {
/*
* PLL is ON: check if defaults already set, then set those
* that can be updated in flight.
*/
if (val & PLLA_BASE_IDDQ) {
pr_warn("PLL_A boot enabled with IDDQ set\n");
plla->params->defaults_set = false;
}
pr_warn("PLL_A already enabled. Postponing set full defaults\n");
val = PLLA_MISC0_DEFAULT_VALUE; /* ignore lock enable */
mask = PLLA_MISC0_LOCK_ENABLE | PLLA_MISC0_LOCK_OVERRIDE;
_pll_misc_chk_default(clk_base, plla->params, 0, val,
~mask & PLLA_MISC0_WRITE_MASK);
val = PLLA_MISC2_DEFAULT_VALUE; /* ignore all but control bit */
_pll_misc_chk_default(clk_base, plla->params, 2, val,
PLLA_MISC2_EN_DYNRAMP);
/* Enable lock detect */
val = readl_relaxed(clk_base + plla->params->ext_misc_reg[0]);
val &= ~mask;
val |= PLLA_MISC0_DEFAULT_VALUE & mask;
writel_relaxed(val, clk_base + plla->params->ext_misc_reg[0]);
udelay(1);
return;
}
/* set IDDQ, enable lock detect, disable dynamic ramp and SDM */
val |= PLLA_BASE_IDDQ;
writel_relaxed(val, clk_base + plla->params->base_reg);
writel_relaxed(PLLA_MISC0_DEFAULT_VALUE,
clk_base + plla->params->ext_misc_reg[0]);
writel_relaxed(PLLA_MISC2_DEFAULT_VALUE,
clk_base + plla->params->ext_misc_reg[2]);
udelay(1);
}
/*
* PLLD
* PLL with fractional SDM.
*/
static void tegra210_plld_set_defaults(struct tegra_clk_pll *plld)
{
u32 val;
u32 mask = 0xffff;
plld->params->defaults_set = true;
if (readl_relaxed(clk_base + plld->params->base_reg) &
PLL_ENABLE) {
/*
* PLL is ON: check if defaults already set, then set those
* that can be updated in flight.
*/
val = PLLD_MISC1_DEFAULT_VALUE;
_pll_misc_chk_default(clk_base, plld->params, 1,
val, PLLD_MISC1_WRITE_MASK);
/* ignore lock, DSI and SDM controls, make sure IDDQ not set */
val = PLLD_MISC0_DEFAULT_VALUE & (~PLLD_MISC0_IDDQ);
mask |= PLLD_MISC0_DSI_CLKENABLE | PLLD_MISC0_LOCK_ENABLE |
PLLD_MISC0_LOCK_OVERRIDE | PLLD_MISC0_EN_SDM;
_pll_misc_chk_default(clk_base, plld->params, 0, val,
~mask & PLLD_MISC0_WRITE_MASK);
if (!plld->params->defaults_set)
pr_warn("PLL_D already enabled. Postponing set full defaults\n");
/* Enable lock detect */
mask = PLLD_MISC0_LOCK_ENABLE | PLLD_MISC0_LOCK_OVERRIDE;
val = readl_relaxed(clk_base + plld->params->ext_misc_reg[0]);
val &= ~mask;
val |= PLLD_MISC0_DEFAULT_VALUE & mask;
writel_relaxed(val, clk_base + plld->params->ext_misc_reg[0]);
udelay(1);
return;
}
val = readl_relaxed(clk_base + plld->params->ext_misc_reg[0]);
val &= PLLD_MISC0_DSI_CLKENABLE;
val |= PLLD_MISC0_DEFAULT_VALUE;
/* set IDDQ, enable lock detect, disable SDM */
writel_relaxed(val, clk_base + plld->params->ext_misc_reg[0]);
writel_relaxed(PLLD_MISC1_DEFAULT_VALUE, clk_base +
plld->params->ext_misc_reg[1]);
udelay(1);
}
/*
* PLLD2, PLLDP
* PLL with fractional SDM and Spread Spectrum (SDM is a must if SSC is used).
*/
static void plldss_defaults(const char *pll_name, struct tegra_clk_pll *plldss,
u32 misc0_val, u32 misc1_val, u32 misc2_val, u32 misc3_val)
{
u32 default_val;
u32 val = readl_relaxed(clk_base + plldss->params->base_reg);
plldss->params->defaults_set = true;
if (val & PLL_ENABLE) {
/*
* PLL is ON: check if defaults already set, then set those
* that can be updated in flight.
*/
if (val & PLLDSS_BASE_IDDQ) {
pr_warn("plldss boot enabled with IDDQ set\n");
plldss->params->defaults_set = false;
}
/* ignore lock enable */
default_val = misc0_val;
_pll_misc_chk_default(clk_base, plldss->params, 0, default_val,
PLLDSS_MISC0_WRITE_MASK &
(~PLLDSS_MISC0_LOCK_ENABLE));
/*
* If SSC is used, check all settings, otherwise just confirm
* that SSC is not used on boot as well. Do nothing when using
* this function for PLLC4 that has only MISC0.
*/
if (plldss->params->ssc_ctrl_en_mask) {
default_val = misc1_val;
_pll_misc_chk_default(clk_base, plldss->params, 1,
default_val, PLLDSS_MISC1_CFG_WRITE_MASK);
default_val = misc2_val;
_pll_misc_chk_default(clk_base, plldss->params, 2,
default_val, PLLDSS_MISC2_CTRL1_WRITE_MASK);
default_val = misc3_val;
_pll_misc_chk_default(clk_base, plldss->params, 3,
default_val, PLLDSS_MISC3_CTRL2_WRITE_MASK);
} else if (plldss->params->ext_misc_reg[1]) {
default_val = misc1_val;
_pll_misc_chk_default(clk_base, plldss->params, 1,
default_val, PLLDSS_MISC1_CFG_WRITE_MASK &
(~PLLDSS_MISC1_CFG_EN_SDM));
}
if (!plldss->params->defaults_set)
pr_warn("%s already enabled. Postponing set full defaults\n",
pll_name);
/* Enable lock detect */
if (val & PLLDSS_BASE_LOCK_OVERRIDE) {
val &= ~PLLDSS_BASE_LOCK_OVERRIDE;
writel_relaxed(val, clk_base +
plldss->params->base_reg);
}
val = readl_relaxed(clk_base + plldss->params->ext_misc_reg[0]);
val &= ~PLLDSS_MISC0_LOCK_ENABLE;
val |= misc0_val & PLLDSS_MISC0_LOCK_ENABLE;
writel_relaxed(val, clk_base + plldss->params->ext_misc_reg[0]);
udelay(1);
return;
}
/* set IDDQ, enable lock detect, configure SDM/SSC */
val |= PLLDSS_BASE_IDDQ;
val &= ~PLLDSS_BASE_LOCK_OVERRIDE;
writel_relaxed(val, clk_base + plldss->params->base_reg);
/* When using this function for PLLC4 exit here */
if (!plldss->params->ext_misc_reg[1]) {
writel_relaxed(misc0_val, clk_base +
plldss->params->ext_misc_reg[0]);
udelay(1);
return;
}
writel_relaxed(misc0_val, clk_base +
plldss->params->ext_misc_reg[0]);
/* if SSC used set by 1st enable */
writel_relaxed(misc1_val & (~PLLDSS_MISC1_CFG_EN_SSC),
clk_base + plldss->params->ext_misc_reg[1]);
writel_relaxed(misc2_val, clk_base + plldss->params->ext_misc_reg[2]);
writel_relaxed(misc3_val, clk_base + plldss->params->ext_misc_reg[3]);
udelay(1);
}
static void tegra210_plld2_set_defaults(struct tegra_clk_pll *plld2)
{
plldss_defaults("PLL_D2", plld2, PLLD2_MISC0_DEFAULT_VALUE,
PLLD2_MISC1_CFG_DEFAULT_VALUE,
PLLD2_MISC2_CTRL1_DEFAULT_VALUE,
PLLD2_MISC3_CTRL2_DEFAULT_VALUE);
}
static void tegra210_plldp_set_defaults(struct tegra_clk_pll *plldp)
{
plldss_defaults("PLL_DP", plldp, PLLDP_MISC0_DEFAULT_VALUE,
PLLDP_MISC1_CFG_DEFAULT_VALUE,
PLLDP_MISC2_CTRL1_DEFAULT_VALUE,
PLLDP_MISC3_CTRL2_DEFAULT_VALUE);
}
/*
* PLLC4
* Base and misc0 layout is the same as PLLD2/PLLDP, but no SDM/SSC support.
* VCO is exposed to the clock tree via fixed 1/3 and 1/5 dividers.
*/
static void tegra210_pllc4_set_defaults(struct tegra_clk_pll *pllc4)
{
plldss_defaults("PLL_C4", pllc4, PLLC4_MISC0_DEFAULT_VALUE, 0, 0, 0);
}
/*
* PLLRE
* VCO is exposed to the clock tree directly along with post-divider output
*/
static void tegra210_pllre_set_defaults(struct tegra_clk_pll *pllre)
{
u32 mask;
u32 val = readl_relaxed(clk_base + pllre->params->base_reg);
pllre->params->defaults_set = true;
if (val & PLL_ENABLE) {
pr_warn("PLL_RE already enabled. Postponing set full defaults\n");
/*