2 * Copyright (c) 2010-2015, NVIDIA CORPORATION. All rights reserved.
4 * SPDX-License-Identifier: GPL-2.0
7 /* Tegra SoC common clock control functions */
12 #include <asm/arch/clock.h>
13 #include <asm/arch/tegra.h>
14 #include <asm/arch-tegra/ap.h>
15 #include <asm/arch-tegra/clk_rst.h>
16 #include <asm/arch-tegra/pmc.h>
17 #include <asm/arch-tegra/timer.h>
22 * This is our record of the current clock rate of each clock. We don't
23 * fill all of these in since we are only really interested in clocks which
26 static unsigned pll_rate
[CLOCK_ID_COUNT
];
29 * The oscillator frequency is fixed to one of four set values. Based on this
30 * the other clocks are set up appropriately.
32 static unsigned osc_freq
[CLOCK_OSC_FREQ_COUNT
] = {
41 /* return 1 if a peripheral ID is in range */
42 #define clock_type_id_isvalid(id) ((id) >= 0 && \
43 (id) < CLOCK_TYPE_COUNT)
45 char pllp_valid
= 1; /* PLLP is set up correctly */
47 /* return 1 if a periphc_internal_id is in range */
48 #define periphc_internal_id_isvalid(id) ((id) >= 0 && \
51 /* number of clock outputs of a PLL */
52 static const u8 pll_num_clkouts
[] = {
61 int clock_get_osc_bypass(void)
63 struct clk_rst_ctlr
*clkrst
=
64 (struct clk_rst_ctlr
*)NV_PA_CLK_RST_BASE
;
67 reg
= readl(&clkrst
->crc_osc_ctrl
);
68 return (reg
& OSC_XOBP_MASK
) >> OSC_XOBP_SHIFT
;
71 /* Returns a pointer to the registers of the given pll */
72 static struct clk_pll
*get_pll(enum clock_id clkid
)
74 struct clk_rst_ctlr
*clkrst
=
75 (struct clk_rst_ctlr
*)NV_PA_CLK_RST_BASE
;
77 assert(clock_id_is_pll(clkid
));
78 if (clkid
>= (enum clock_id
)TEGRA_CLK_PLLS
) {
79 debug("%s: Invalid PLL %d\n", __func__
, clkid
);
82 return &clkrst
->crc_pll
[clkid
];
85 __weak
struct clk_pll_simple
*clock_get_simple_pll(enum clock_id clkid
)
90 int clock_ll_read_pll(enum clock_id clkid
, u32
*divm
, u32
*divn
,
91 u32
*divp
, u32
*cpcon
, u32
*lfcon
)
93 struct clk_pll
*pll
= get_pll(clkid
);
94 struct clk_pll_info
*pllinfo
= &tegra_pll_info_table
[clkid
];
97 assert(clkid
!= CLOCK_ID_USB
);
99 /* Safety check, adds to code size but is small */
100 if (!clock_id_is_pll(clkid
) || clkid
== CLOCK_ID_USB
)
102 data
= readl(&pll
->pll_base
);
103 *divm
= (data
>> pllinfo
->m_shift
) & pllinfo
->m_mask
;
104 *divn
= (data
>> pllinfo
->n_shift
) & pllinfo
->n_mask
;
105 *divp
= (data
>> pllinfo
->p_shift
) & pllinfo
->p_mask
;
106 data
= readl(&pll
->pll_misc
);
107 /* NOTE: On T210, cpcon/lfcon no longer exist, moved to KCP/KVCO */
108 *cpcon
= (data
>> pllinfo
->kcp_shift
) & pllinfo
->kcp_mask
;
109 *lfcon
= (data
>> pllinfo
->kvco_shift
) & pllinfo
->kvco_mask
;
114 unsigned long clock_start_pll(enum clock_id clkid
, u32 divm
, u32 divn
,
115 u32 divp
, u32 cpcon
, u32 lfcon
)
117 struct clk_pll
*pll
= NULL
;
118 struct clk_pll_info
*pllinfo
= &tegra_pll_info_table
[clkid
];
119 struct clk_pll_simple
*simple_pll
= NULL
;
122 if (clkid
< (enum clock_id
)TEGRA_CLK_PLLS
) {
123 pll
= get_pll(clkid
);
125 simple_pll
= clock_get_simple_pll(clkid
);
127 debug("%s: Uknown simple PLL %d\n", __func__
, clkid
);
133 * pllinfo has the m/n/p and kcp/kvco mask and shift
134 * values for all of the PLLs used in U-Boot, with any
135 * SoC differences accounted for.
137 * Preserve EN_LOCKDET, etc.
140 misc_data
= readl(&pll
->pll_misc
);
142 misc_data
= readl(&simple_pll
->pll_misc
);
143 misc_data
&= ~(pllinfo
->kcp_mask
<< pllinfo
->kcp_shift
);
144 misc_data
|= cpcon
<< pllinfo
->kcp_shift
;
145 misc_data
&= ~(pllinfo
->kvco_mask
<< pllinfo
->kvco_shift
);
146 misc_data
|= lfcon
<< pllinfo
->kvco_shift
;
148 data
= (divm
<< pllinfo
->m_shift
) | (divn
<< pllinfo
->n_shift
);
149 data
|= divp
<< pllinfo
->p_shift
;
150 data
|= (1 << PLL_ENABLE_SHIFT
); /* BYPASS s/b 0 already */
153 writel(misc_data
, &pll
->pll_misc
);
154 writel(data
, &pll
->pll_base
);
156 writel(misc_data
, &simple_pll
->pll_misc
);
157 writel(data
, &simple_pll
->pll_base
);
160 /* calculate the stable time */
161 return timer_get_us() + CLOCK_PLL_STABLE_DELAY_US
;
164 void clock_ll_set_source_divisor(enum periph_id periph_id
, unsigned source
,
167 u32
*reg
= get_periph_source_reg(periph_id
);
172 value
&= ~OUT_CLK_SOURCE_31_30_MASK
;
173 value
|= source
<< OUT_CLK_SOURCE_31_30_SHIFT
;
175 value
&= ~OUT_CLK_DIVISOR_MASK
;
176 value
|= divisor
<< OUT_CLK_DIVISOR_SHIFT
;
181 int clock_ll_set_source_bits(enum periph_id periph_id
, int mux_bits
,
184 u32
*reg
= get_periph_source_reg(periph_id
);
187 case MASK_BITS_31_30
:
188 clrsetbits_le32(reg
, OUT_CLK_SOURCE_31_30_MASK
,
189 source
<< OUT_CLK_SOURCE_31_30_SHIFT
);
192 case MASK_BITS_31_29
:
193 clrsetbits_le32(reg
, OUT_CLK_SOURCE_31_29_MASK
,
194 source
<< OUT_CLK_SOURCE_31_29_SHIFT
);
197 case MASK_BITS_31_28
:
198 clrsetbits_le32(reg
, OUT_CLK_SOURCE_31_28_MASK
,
199 source
<< OUT_CLK_SOURCE_31_28_SHIFT
);
209 void clock_ll_set_source(enum periph_id periph_id
, unsigned source
)
211 clock_ll_set_source_bits(periph_id
, MASK_BITS_31_30
, source
);
215 * Given the parent's rate and the required rate for the children, this works
216 * out the peripheral clock divider to use, in 7.1 binary format.
218 * @param divider_bits number of divider bits (8 or 16)
219 * @param parent_rate clock rate of parent clock in Hz
220 * @param rate required clock rate for this clock
221 * @return divider which should be used
223 static int clk_get_divider(unsigned divider_bits
, unsigned long parent_rate
,
226 u64 divider
= parent_rate
* 2;
227 unsigned max_divider
= 1 << divider_bits
;
230 do_div(divider
, rate
);
232 if ((s64
)divider
- 2 < 0)
235 if ((s64
)divider
- 2 >= max_divider
)
241 int clock_set_pllout(enum clock_id clkid
, enum pll_out_id pllout
, unsigned rate
)
243 struct clk_pll
*pll
= get_pll(clkid
);
244 int data
= 0, div
= 0, offset
= 0;
246 if (!clock_id_is_pll(clkid
))
249 if (pllout
+ 1 > pll_num_clkouts
[clkid
])
252 div
= clk_get_divider(8, pll_rate
[clkid
], rate
);
257 /* out2 and out4 are in the high part of the register */
258 if (pllout
== PLL_OUT2
|| pllout
== PLL_OUT4
)
261 data
= (div
<< PLL_OUT_RATIO_SHIFT
) |
262 PLL_OUT_OVRRIDE
| PLL_OUT_CLKEN
| PLL_OUT_RSTN
;
263 clrsetbits_le32(&pll
->pll_out
[pllout
>> 1],
264 PLL_OUT_RATIO_MASK
<< offset
, data
<< offset
);
270 * Given the parent's rate and the divider in 7.1 format, this works out the
271 * resulting peripheral clock rate.
273 * @param parent_rate clock rate of parent clock in Hz
274 * @param divider which should be used in 7.1 format
275 * @return effective clock rate of peripheral
277 static unsigned long get_rate_from_divider(unsigned long parent_rate
,
282 rate
= (u64
)parent_rate
* 2;
283 do_div(rate
, divider
+ 2);
287 unsigned long clock_get_periph_rate(enum periph_id periph_id
,
288 enum clock_id parent
)
290 u32
*reg
= get_periph_source_reg(periph_id
);
292 return get_rate_from_divider(pll_rate
[parent
],
293 (readl(reg
) & OUT_CLK_DIVISOR_MASK
) >> OUT_CLK_DIVISOR_SHIFT
);
297 * Find the best available 7.1 format divisor given a parent clock rate and
298 * required child clock rate. This function assumes that a second-stage
299 * divisor is available which can divide by powers of 2 from 1 to 256.
301 * @param divider_bits number of divider bits (8 or 16)
302 * @param parent_rate clock rate of parent clock in Hz
303 * @param rate required clock rate for this clock
304 * @param extra_div value for the second-stage divisor (not set if this
305 * function returns -1.
306 * @return divider which should be used, or -1 if nothing is valid
309 static int find_best_divider(unsigned divider_bits
, unsigned long parent_rate
,
310 unsigned long rate
, int *extra_div
)
313 int best_divider
= -1;
314 int best_error
= rate
;
316 /* try dividers from 1 to 256 and find closest match */
317 for (shift
= 0; shift
<= 8 && best_error
> 0; shift
++) {
318 unsigned divided_parent
= parent_rate
>> shift
;
319 int divider
= clk_get_divider(divider_bits
, divided_parent
,
321 unsigned effective_rate
= get_rate_from_divider(divided_parent
,
323 int error
= rate
- effective_rate
;
325 /* Given a valid divider, look for the lowest error */
326 if (divider
!= -1 && error
< best_error
) {
328 *extra_div
= 1 << shift
;
329 best_divider
= divider
;
333 /* return what we found - *extra_div will already be set */
338 * Adjust peripheral PLL to use the given divider and source.
340 * @param periph_id peripheral to adjust
341 * @param source Source number (0-3 or 0-7)
342 * @param mux_bits Number of mux bits (2 or 4)
343 * @param divider Required divider in 7.1 or 15.1 format
344 * @return 0 if ok, -1 on error (requesting a parent clock which is not valid
345 * for this peripheral)
347 static int adjust_periph_pll(enum periph_id periph_id
, int source
,
348 int mux_bits
, unsigned divider
)
350 u32
*reg
= get_periph_source_reg(periph_id
);
352 clrsetbits_le32(reg
, OUT_CLK_DIVISOR_MASK
,
353 divider
<< OUT_CLK_DIVISOR_SHIFT
);
356 /* work out the source clock and set it */
360 clock_ll_set_source_bits(periph_id
, mux_bits
, source
);
366 unsigned clock_adjust_periph_pll_div(enum periph_id periph_id
,
367 enum clock_id parent
, unsigned rate
, int *extra_div
)
369 unsigned effective_rate
;
370 int mux_bits
, divider_bits
, source
;
374 /* work out the source clock and set it */
375 source
= get_periph_clock_source(periph_id
, parent
, &mux_bits
,
378 divider
= find_best_divider(divider_bits
, pll_rate
[parent
],
383 assert(divider
>= 0);
384 if (adjust_periph_pll(periph_id
, source
, mux_bits
, divider
))
386 debug("periph %d, rate=%d, reg=%p = %x\n", periph_id
, rate
,
387 get_periph_source_reg(periph_id
),
388 readl(get_periph_source_reg(periph_id
)));
390 /* Check what we ended up with. This shouldn't matter though */
391 effective_rate
= clock_get_periph_rate(periph_id
, parent
);
393 effective_rate
/= *extra_div
;
394 if (rate
!= effective_rate
)
395 debug("Requested clock rate %u not honored (got %u)\n",
396 rate
, effective_rate
);
397 return effective_rate
;
400 unsigned clock_start_periph_pll(enum periph_id periph_id
,
401 enum clock_id parent
, unsigned rate
)
403 unsigned effective_rate
;
405 reset_set_enable(periph_id
, 1);
406 clock_enable(periph_id
);
408 effective_rate
= clock_adjust_periph_pll_div(periph_id
, parent
, rate
,
411 reset_set_enable(periph_id
, 0);
412 return effective_rate
;
415 void clock_enable(enum periph_id clkid
)
417 clock_set_enable(clkid
, 1);
420 void clock_disable(enum periph_id clkid
)
422 clock_set_enable(clkid
, 0);
425 void reset_periph(enum periph_id periph_id
, int us_delay
)
427 /* Put peripheral into reset */
428 reset_set_enable(periph_id
, 1);
432 reset_set_enable(periph_id
, 0);
437 void reset_cmplx_set_enable(int cpu
, int which
, int reset
)
439 struct clk_rst_ctlr
*clkrst
=
440 (struct clk_rst_ctlr
*)NV_PA_CLK_RST_BASE
;
443 /* Form the mask, which depends on the cpu chosen (2 or 4) */
444 assert(cpu
>= 0 && cpu
< MAX_NUM_CPU
);
447 /* either enable or disable those reset for that CPU */
449 writel(mask
, &clkrst
->crc_cpu_cmplx_set
);
451 writel(mask
, &clkrst
->crc_cpu_cmplx_clr
);
454 unsigned int __weak
clk_m_get_rate(unsigned int parent_rate
)
459 unsigned clock_get_rate(enum clock_id clkid
)
463 u64 parent_rate
, rate
;
464 struct clk_pll_info
*pllinfo
= &tegra_pll_info_table
[clkid
];
466 parent_rate
= osc_freq
[clock_get_osc_freq()];
467 if (clkid
== CLOCK_ID_OSC
)
470 if (clkid
== CLOCK_ID_CLK_M
)
471 return clk_m_get_rate(parent_rate
);
473 pll
= get_pll(clkid
);
476 base
= readl(&pll
->pll_base
);
478 rate
= parent_rate
* ((base
>> pllinfo
->n_shift
) & pllinfo
->n_mask
);
479 divm
= (base
>> pllinfo
->m_shift
) & pllinfo
->m_mask
;
481 * PLLU uses p_mask/p_shift for VCO on all but T210,
482 * T210 uses normal DIVP. Handled in pllinfo table.
484 #ifdef CONFIG_TEGRA210
486 * PLLP's primary output (pllP_out0) on T210 is the VCO, and divp is
487 * not applied. pllP_out2 does have divp applied. All other pllP_outN
488 * are divided down from pllP_out0. We only support pllP_out0 in
489 * U-Boot at the time of writing this comment.
491 if (clkid
!= CLOCK_ID_PERIPH
)
493 divm
<<= (base
>> pllinfo
->p_shift
) & pllinfo
->p_mask
;
499 * Set the output frequency you want for each PLL clock.
500 * PLL output frequencies are programmed by setting their N, M and P values.
501 * The governing equations are:
502 * VCO = (Fi / m) * n, Fo = VCO / (2^p)
503 * where Fo is the output frequency from the PLL.
504 * Example: Set the output frequency to 216Mhz(Fo) with 12Mhz OSC(Fi)
505 * 216Mhz = ((12Mhz / m) * n) / (2^p) so n=432,m=12,p=1
506 * Please see Tegra TRM section 5.3 to get the detail for PLL Programming
508 * @param n PLL feedback divider(DIVN)
509 * @param m PLL input divider(DIVN)
510 * @param p post divider(DIVP)
511 * @param cpcon base PLL charge pump(CPCON)
512 * @return 0 if ok, -1 on error (the requested PLL is incorrect and cannot
513 * be overriden), 1 if PLL is already correct
515 int clock_set_rate(enum clock_id clkid
, u32 n
, u32 m
, u32 p
, u32 cpcon
)
517 u32 base_reg
, misc_reg
;
519 struct clk_pll_info
*pllinfo
= &tegra_pll_info_table
[clkid
];
521 pll
= get_pll(clkid
);
523 base_reg
= readl(&pll
->pll_base
);
525 /* Set BYPASS, m, n and p to PLL_BASE */
526 base_reg
&= ~(pllinfo
->m_mask
<< pllinfo
->m_shift
);
527 base_reg
|= m
<< pllinfo
->m_shift
;
529 base_reg
&= ~(pllinfo
->n_mask
<< pllinfo
->n_shift
);
530 base_reg
|= n
<< pllinfo
->n_shift
;
532 base_reg
&= ~(pllinfo
->p_mask
<< pllinfo
->p_shift
);
533 base_reg
|= p
<< pllinfo
->p_shift
;
535 if (clkid
== CLOCK_ID_PERIPH
) {
537 * If the PLL is already set up, check that it is correct
538 * and record this info for clock_verify() to check.
540 if (base_reg
& PLL_BASE_OVRRIDE_MASK
) {
541 base_reg
|= PLL_ENABLE_MASK
;
542 if (base_reg
!= readl(&pll
->pll_base
))
544 return pllp_valid
? 1 : -1;
546 base_reg
|= PLL_BASE_OVRRIDE_MASK
;
549 base_reg
|= PLL_BYPASS_MASK
;
550 writel(base_reg
, &pll
->pll_base
);
552 /* Set cpcon (KCP) to PLL_MISC */
553 misc_reg
= readl(&pll
->pll_misc
);
554 misc_reg
&= ~(pllinfo
->kcp_mask
<< pllinfo
->kcp_shift
);
555 misc_reg
|= cpcon
<< pllinfo
->kcp_shift
;
556 writel(misc_reg
, &pll
->pll_misc
);
559 base_reg
|= PLL_ENABLE_MASK
;
560 writel(base_reg
, &pll
->pll_base
);
563 base_reg
&= ~PLL_BYPASS_MASK
;
564 writel(base_reg
, &pll
->pll_base
);
569 void clock_ll_start_uart(enum periph_id periph_id
)
571 /* Assert UART reset and enable clock */
572 reset_set_enable(periph_id
, 1);
573 clock_enable(periph_id
);
574 clock_ll_set_source(periph_id
, 0); /* UARTx_CLK_SRC = 00, PLLP_OUT0 */
579 /* De-assert reset to UART */
580 reset_set_enable(periph_id
, 0);
583 #if CONFIG_IS_ENABLED(OF_CONTROL)
584 int clock_decode_periph_id(const void *blob
, int node
)
590 err
= fdtdec_get_int_array(blob
, node
, "clocks", cell
,
594 id
= clk_id_to_periph_id(cell
[1]);
595 assert(clock_periph_id_isvalid(id
));
598 #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */
600 int clock_verify(void)
602 struct clk_pll
*pll
= get_pll(CLOCK_ID_PERIPH
);
603 u32 reg
= readl(&pll
->pll_base
);
606 printf("Warning: PLLP %x is not correct\n", reg
);
609 debug("PLLP %x is correct\n", reg
);
613 void clock_init(void)
615 pll_rate
[CLOCK_ID_CGENERAL
] = clock_get_rate(CLOCK_ID_CGENERAL
);
616 pll_rate
[CLOCK_ID_MEMORY
] = clock_get_rate(CLOCK_ID_MEMORY
);
617 pll_rate
[CLOCK_ID_PERIPH
] = clock_get_rate(CLOCK_ID_PERIPH
);
618 pll_rate
[CLOCK_ID_USB
] = clock_get_rate(CLOCK_ID_USB
);
619 pll_rate
[CLOCK_ID_DISPLAY
] = clock_get_rate(CLOCK_ID_DISPLAY
);
620 pll_rate
[CLOCK_ID_XCPU
] = clock_get_rate(CLOCK_ID_XCPU
);
621 pll_rate
[CLOCK_ID_SFROM32KHZ
] = 32768;
622 pll_rate
[CLOCK_ID_OSC
] = clock_get_rate(CLOCK_ID_OSC
);
623 pll_rate
[CLOCK_ID_CLK_M
] = clock_get_rate(CLOCK_ID_CLK_M
);
625 debug("Osc = %d\n", pll_rate
[CLOCK_ID_OSC
]);
626 debug("CLKM = %d\n", pll_rate
[CLOCK_ID_CLK_M
]);
627 debug("PLLC = %d\n", pll_rate
[CLOCK_ID_CGENERAL
]);
628 debug("PLLM = %d\n", pll_rate
[CLOCK_ID_MEMORY
]);
629 debug("PLLP = %d\n", pll_rate
[CLOCK_ID_PERIPH
]);
630 debug("PLLU = %d\n", pll_rate
[CLOCK_ID_USB
]);
631 debug("PLLD = %d\n", pll_rate
[CLOCK_ID_DISPLAY
]);
632 debug("PLLX = %d\n", pll_rate
[CLOCK_ID_XCPU
]);
635 static void set_avp_clock_source(u32 src
)
637 struct clk_rst_ctlr
*clkrst
=
638 (struct clk_rst_ctlr
*)NV_PA_CLK_RST_BASE
;
641 val
= (src
<< SCLK_SWAKEUP_FIQ_SOURCE_SHIFT
) |
642 (src
<< SCLK_SWAKEUP_IRQ_SOURCE_SHIFT
) |
643 (src
<< SCLK_SWAKEUP_RUN_SOURCE_SHIFT
) |
644 (src
<< SCLK_SWAKEUP_IDLE_SOURCE_SHIFT
) |
645 (SCLK_SYS_STATE_RUN
<< SCLK_SYS_STATE_SHIFT
);
646 writel(val
, &clkrst
->crc_sclk_brst_pol
);
651 * This function is useful on Tegra30, and any later SoCs that have compatible
652 * PLLP configuration registers.
653 * NOTE: Not used on Tegra210 - see tegra210_setup_pllp in T210 clock.c
655 void tegra30_set_up_pllp(void)
657 struct clk_rst_ctlr
*clkrst
= (struct clk_rst_ctlr
*)NV_PA_CLK_RST_BASE
;
661 * Based on the Tegra TRM, the system clock (which is the AVP clock) can
662 * run up to 275MHz. On power on, the default sytem clock source is set
663 * to PLLP_OUT0. This function sets PLLP's (hence PLLP_OUT0's) rate to
664 * 408MHz which is beyond system clock's upper limit.
666 * The fix is to set the system clock to CLK_M before initializing PLLP,
667 * and then switch back to PLLP_OUT4, which has an appropriate divider
668 * configured, after PLLP has been configured
670 set_avp_clock_source(SCLK_SOURCE_CLKM
);
673 * PLLP output frequency set to 408Mhz
674 * PLLC output frequency set to 228Mhz
676 switch (clock_get_osc_freq()) {
677 case CLOCK_OSC_FREQ_12_0
: /* OSC is 12Mhz */
678 clock_set_rate(CLOCK_ID_PERIPH
, 408, 12, 0, 8);
679 clock_set_rate(CLOCK_ID_CGENERAL
, 456, 12, 1, 8);
682 case CLOCK_OSC_FREQ_26_0
: /* OSC is 26Mhz */
683 clock_set_rate(CLOCK_ID_PERIPH
, 408, 26, 0, 8);
684 clock_set_rate(CLOCK_ID_CGENERAL
, 600, 26, 0, 8);
687 case CLOCK_OSC_FREQ_13_0
: /* OSC is 13Mhz */
688 clock_set_rate(CLOCK_ID_PERIPH
, 408, 13, 0, 8);
689 clock_set_rate(CLOCK_ID_CGENERAL
, 600, 13, 0, 8);
691 case CLOCK_OSC_FREQ_19_2
:
694 * These are not supported. It is too early to print a
695 * message and the UART likely won't work anyway due to the
696 * oscillator being wrong.
701 /* Set PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
704 /* Assert RSTN before enable */
705 reg
= PLLP_OUT2_RSTN_EN
| PLLP_OUT1_RSTN_EN
;
706 writel(reg
, &clkrst
->crc_pll
[CLOCK_ID_PERIPH
].pll_out
[0]);
707 /* Set divisor and reenable */
708 reg
= (IN_408_OUT_48_DIVISOR
<< PLLP_OUT2_RATIO
)
709 | PLLP_OUT2_OVR
| PLLP_OUT2_CLKEN
| PLLP_OUT2_RSTN_DIS
710 | (IN_408_OUT_9_6_DIVISOR
<< PLLP_OUT1_RATIO
)
711 | PLLP_OUT1_OVR
| PLLP_OUT1_CLKEN
| PLLP_OUT1_RSTN_DIS
;
712 writel(reg
, &clkrst
->crc_pll
[CLOCK_ID_PERIPH
].pll_out
[0]);
715 /* Assert RSTN before enable */
716 reg
= PLLP_OUT4_RSTN_EN
| PLLP_OUT3_RSTN_EN
;
717 writel(reg
, &clkrst
->crc_pll
[CLOCK_ID_PERIPH
].pll_out
[1]);
718 /* Set divisor and reenable */
719 reg
= (IN_408_OUT_204_DIVISOR
<< PLLP_OUT4_RATIO
)
720 | PLLP_OUT4_OVR
| PLLP_OUT4_CLKEN
| PLLP_OUT4_RSTN_DIS
721 | (IN_408_OUT_102_DIVISOR
<< PLLP_OUT3_RATIO
)
722 | PLLP_OUT3_OVR
| PLLP_OUT3_CLKEN
| PLLP_OUT3_RSTN_DIS
;
723 writel(reg
, &clkrst
->crc_pll
[CLOCK_ID_PERIPH
].pll_out
[1]);
725 set_avp_clock_source(SCLK_SOURCE_PLLP_OUT4
);
728 int clock_external_output(int clk_id
)
730 struct pmc_ctlr
*pmc
= (struct pmc_ctlr
*)NV_PA_PMC_BASE
;
732 if (clk_id
>= 1 && clk_id
<= 3) {
733 setbits_le32(&pmc
->pmc_clk_out_cntrl
,
734 1 << (2 + (clk_id
- 1) * 8));
736 printf("%s: Unknown output clock id %d\n", __func__
, clk_id
);