blob: 4c087b8539ca0d23c2a133a255b69d0e7e4677da [file] [log] [blame]
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -07001/*
2 * Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
Gabe Black31785032014-03-03 16:26:11 -08003 * Copyright 2014 Google Inc.
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -07004 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -070013 */
Julius Wernerf0d21ff32014-10-20 13:24:14 -070014#include <arch/clock.h>
15#include <arch/io.h>
Gabe Blackd40be112013-10-09 23:45:07 -070016#include <console/console.h>
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -070017#include <delay.h>
Gabe Blacke97b6832013-10-06 06:13:24 -070018#include <soc/addressmap.h>
Julius Wernerf0d21ff32014-10-20 13:24:14 -070019#include <soc/clk_rst.h>
Gabe Blackd40be112013-10-09 23:45:07 -070020#include <soc/clock.h>
Julius Wernerf0d21ff32014-10-20 13:24:14 -070021#include <soc/flow.h>
22#include <soc/maincpu.h>
23#include <soc/pmc.h>
24#include <soc/sysctr.h>
Hung-Te Lin2fc3b622013-10-21 21:43:03 +080025#include <stdlib.h>
Julius Wernerec5e5e02014-08-20 15:29:56 -070026#include <symbols.h>
Gabe Blacke97b6832013-10-06 06:13:24 -070027
28static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
Gabe Blackd40be112013-10-09 23:45:07 -070029static struct flow_ctlr *flow = (void *)TEGRA_FLOW_BASE;
Hung-Te Lin2fc3b622013-10-21 21:43:03 +080030static struct tegra_pmc_regs *pmc = (void *)TEGRA_PMC_BASE;
31static struct sysctr_regs *sysctr = (void *)TEGRA_SYSCTR0_BASE;
Gabe Blackd40be112013-10-09 23:45:07 -070032
33struct pll_dividers {
34 u32 n : 10;
35 u32 m : 8;
36 u32 p : 4;
Andrew Bresticker25bf7752014-03-04 11:06:13 -080037 u32 cpcon : 4;
38 u32 lfcon : 4;
39 u32 : 2;
Gabe Blackd40be112013-10-09 23:45:07 -070040};
41
42/* Some PLLs have more restrictive divider bit lengths or are missing some
43 * fields. Make sure to use the right struct in the osc_table definition to get
44 * compile-time checking, but keep the bits aligned with struct pll_dividers so
45 * they can be used interchangeably at run time. Add new formats as required. */
46struct pllcx_dividers {
47 u32 n : 8;
48 u32 : 2;
49 u32 m : 8;
50 u32 p : 4;
51 u32 : 10;
52};
53struct pllpad_dividers {
54 u32 n : 10;
55 u32 m : 5;
56 u32 : 3;
57 u32 p : 3;
58 u32 : 1;
59 u32 cpcon : 4;
60 u32 : 6;
61};
62struct pllu_dividers {
63 u32 n : 10;
64 u32 m : 5;
65 u32 : 3;
66 u32 p : 1;
67 u32 : 3;
68 u32 cpcon : 4;
Andrew Bresticker25bf7752014-03-04 11:06:13 -080069 u32 lfcon : 4;
70 u32 : 2;
Gabe Blackd40be112013-10-09 23:45:07 -070071};
72
73union __attribute__((transparent_union)) pll_fields {
74 u32 raw;
75 struct pll_dividers div;
76 struct pllcx_dividers cx;
77 struct pllpad_dividers pad;
78 struct pllu_dividers u;
79};
80
81/* This table defines the frequency dividers for every PLL to turn the external
82 * OSC clock into the frequencies defined by TEGRA_PLL*_KHZ in soc/clock.h.
Julius Wernere57c3032014-04-11 18:23:12 -070083 * All PLLs have three dividers (n, m and p), with the governing formula for
84 * the output frequency being CF = (IN / m), VCO = CF * n and OUT = VCO / (2^p).
85 * All divisor configurations must meet the PLL's constraints for VCO and CF:
86 * PLLX: 12 MHz < CF < 50 MHz, 700 MHz < VCO < 3000 MHz
87 * PLLC: 12 MHz < CF < 50 MHz, 600 MHz < VCO < 1400 MHz
88 * PLLM: 12 MHz < CF < 50 MHz, 400 MHz < VCO < 1066 MHz
89 * PLLP: 1 MHz < CF < 6 MHz, 200 MHz < VCO < 700 MHz
90 * PLLD: 1 MHz < CF < 6 MHz, 500 MHz < VCO < 1000 MHz
91 * PLLU: 1 MHz < CF < 6 MHz, 480 MHz < VCO < 960 MHz
92 * PLLDP: 12 MHz < CF < 38 MHz, 600 MHz < VCO < 1200 MHz
93 * (values taken from Linux' drivers/clk/tegra/clk-tegra124.c). */
Gabe Blackd40be112013-10-09 23:45:07 -070094struct {
95 int khz;
Gabe Black31785032014-03-03 16:26:11 -080096 struct pllcx_dividers pllx; /* target: CONFIG_PLLX_KHZ */
Gabe Blackd40be112013-10-09 23:45:07 -070097 struct pllcx_dividers pllc; /* target: 600 MHz */
Julius Wernere57c3032014-04-11 18:23:12 -070098 /* PLLM is set up dynamically by clock_sdram(). */
99 /* PLLP is hardwired to 408 MHz in HW (unless we set BASE_OVRD). */
Gabe Blackd40be112013-10-09 23:45:07 -0700100 struct pllu_dividers pllu; /* target; 960 MHz */
Julius Werneredf6b572013-10-25 17:49:26 -0700101 struct pllcx_dividers plldp; /* target; 270 MHz */
Julius Wernere57c3032014-04-11 18:23:12 -0700102 /* PLLDP treats p differently (OUT = VCO / (p + 1) for p < 6). */
Gabe Blackd40be112013-10-09 23:45:07 -0700103} static const osc_table[16] = {
Julius Wernere57c3032014-04-11 18:23:12 -0700104 [OSC_FREQ_12]{
Gabe Blackd40be112013-10-09 23:45:07 -0700105 .khz = 12000,
Gabe Black31785032014-03-03 16:26:11 -0800106 .pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
Gabe Blackd40be112013-10-09 23:45:07 -0700107 .pllc = {.n = 50, .m = 1, .p = 0},
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800108 .pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800109 .plldp = {.n = 90, .m = 1, .p = 3},
Gabe Blackd40be112013-10-09 23:45:07 -0700110 },
Julius Wernere57c3032014-04-11 18:23:12 -0700111 [OSC_FREQ_13]{
Gabe Blackd40be112013-10-09 23:45:07 -0700112 .khz = 13000,
Gabe Black31785032014-03-03 16:26:11 -0800113 .pllx = {.n = TEGRA_PLLX_KHZ / 13000, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700114 .pllc = {.n = 46, .m = 1, .p = 0}, /* 598.0 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800115 .pllu = {.n = 960, .m = 13, .p = 0, .cpcon = 12, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700116 .plldp = {.n = 83, .m = 1, .p = 3}, /* 269.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700117 },
Julius Wernere57c3032014-04-11 18:23:12 -0700118 [OSC_FREQ_16P8]{
Gabe Blackd40be112013-10-09 23:45:07 -0700119 .khz = 16800,
Gabe Black31785032014-03-03 16:26:11 -0800120 .pllx = {.n = TEGRA_PLLX_KHZ / 16800, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700121 .pllc = {.n = 71, .m = 1, .p = 1}, /* 596.4 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800122 .pllu = {.n = 400, .m = 7, .p = 0, .cpcon = 5, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700123 .plldp = {.n = 64, .m = 1, .p = 3}, /* 268.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700124 },
Julius Wernere57c3032014-04-11 18:23:12 -0700125 [OSC_FREQ_19P2]{
Gabe Blackd40be112013-10-09 23:45:07 -0700126 .khz = 19200,
Gabe Black31785032014-03-03 16:26:11 -0800127 .pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700128 .pllc = {.n = 62, .m = 1, .p = 1}, /* 595.2 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800129 .pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700130 .plldp = {.n = 56, .m = 1, .p = 3}, /* 268.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700131 },
Julius Wernere57c3032014-04-11 18:23:12 -0700132 [OSC_FREQ_26]{
Gabe Blackd40be112013-10-09 23:45:07 -0700133 .khz = 26000,
Gabe Black31785032014-03-03 16:26:11 -0800134 .pllx = {.n = TEGRA_PLLX_KHZ / 26000, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700135 .pllc = {.n = 23, .m = 1, .p = 0}, /* 598.0 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800136 .pllu = {.n = 960, .m = 26, .p = 0, .cpcon = 12, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700137 .plldp = {.n = 83, .m = 2, .p = 3}, /* 269.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700138 },
Julius Wernere57c3032014-04-11 18:23:12 -0700139 /* These oscillators get predivided as PLL inputs... n/m/p divisors for
140 * 38.4 should always match 19.2, and 48 should always match 12. */
141 [OSC_FREQ_38P4]{
Gabe Blackd40be112013-10-09 23:45:07 -0700142 .khz = 38400,
Gabe Black31785032014-03-03 16:26:11 -0800143 .pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700144 .pllc = {.n = 62, .m = 1, .p = 1}, /* 595.2 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800145 .pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700146 .plldp = {.n = 56, .m = 1, .p = 3}, /* 268.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700147 },
Julius Wernere57c3032014-04-11 18:23:12 -0700148 [OSC_FREQ_48]{
Gabe Blackd40be112013-10-09 23:45:07 -0700149 .khz = 48000,
Gabe Black31785032014-03-03 16:26:11 -0800150 .pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
Gabe Blackd40be112013-10-09 23:45:07 -0700151 .pllc = {.n = 50, .m = 1, .p = 0},
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800152 .pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700153 .plldp = {.n = 90, .m = 1, .p = 3},
Gabe Blackd40be112013-10-09 23:45:07 -0700154 },
155};
156
Gabe Blackd40be112013-10-09 23:45:07 -0700157/* Get the oscillator frequency, from the corresponding hardware
158 * configuration field. This is actually a per-soc thing. Avoid the
159 * temptation to make it common.
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -0700160 */
Gabe Blackd40be112013-10-09 23:45:07 -0700161static u32 clock_get_osc_bits(void)
162{
Julius Werner2f37bd62015-02-19 14:51:15 -0800163 return (read32(&clk_rst->osc_ctrl) & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
Gabe Blackd40be112013-10-09 23:45:07 -0700164}
165
166int clock_get_osc_khz(void)
167{
168 return osc_table[clock_get_osc_bits()].khz;
169}
170
Julius Wernere57c3032014-04-11 18:23:12 -0700171int clock_get_pll_input_khz(void)
172{
Julius Werner2f37bd62015-02-19 14:51:15 -0800173 u32 osc_ctrl = read32(&clk_rst->osc_ctrl);
Julius Wernere57c3032014-04-11 18:23:12 -0700174 u32 osc_bits = (osc_ctrl & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
175 u32 pll_ref_div = (osc_ctrl & OSC_PREDIV_MASK) >> OSC_PREDIV_SHIFT;
176 return osc_table[osc_bits].khz >> pll_ref_div;
177}
178
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800179void clock_init_arm_generic_timer(void)
180{
181 uint32_t freq = clock_get_osc_khz() * 1000;
182 // Set the cntfrq register.
Furquan Shaikhd653ae82014-06-24 15:21:03 -0700183 set_cntfrq(freq);
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800184
185 // Record the system timer frequency.
Julius Werner2f37bd62015-02-19 14:51:15 -0800186 write32(&sysctr->cntfid0, freq);
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800187 // Enable the system counter.
188 uint32_t cntcr = read32(&sysctr->cntcr);
189 cntcr |= SYSCTR_CNTCR_EN | SYSCTR_CNTCR_HDBG;
Julius Werner2f37bd62015-02-19 14:51:15 -0800190 write32(&sysctr->cntcr, cntcr);
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800191}
192
Julius Werneredf6b572013-10-25 17:49:26 -0700193#define SOR0_CLK_SEL0 (1 << 14)
194#define SOR0_CLK_SEL1 (1 << 15)
Gabe Blackd40be112013-10-09 23:45:07 -0700195
Julius Werneredf6b572013-10-25 17:49:26 -0700196void sor_clock_stop(void)
197{
198 /* The Serial Output Resource clock has to be off
199 * before we start the plldp. Learned the hard way.
200 * FIXME: this has to be cleaned up a bit more.
201 * Waiting on some new info from Nvidia.
202 */
203 clrbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0 | SOR0_CLK_SEL1);
204}
205
206void sor_clock_start(void)
207{
208 /* uses PLLP, has a non-standard bit layout. */
209 setbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0);
Gabe Blackd40be112013-10-09 23:45:07 -0700210}
211
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800212static void init_pll(u32 *base, u32 *misc, const union pll_fields pll, u32 lock)
Gabe Blackd40be112013-10-09 23:45:07 -0700213{
214 u32 dividers = pll.div.n << PLL_BASE_DIVN_SHIFT |
215 pll.div.m << PLL_BASE_DIVM_SHIFT |
216 pll.div.p << PLL_BASE_DIVP_SHIFT;
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800217 u32 misc_con = pll.div.cpcon << PLL_MISC_CPCON_SHIFT |
218 pll.div.lfcon << PLL_MISC_LFCON_SHIFT;
Gabe Blackd40be112013-10-09 23:45:07 -0700219
220 /* Write dividers but BYPASS the PLL while we're messing with it. */
Julius Werner2f37bd62015-02-19 14:51:15 -0800221 write32(base, dividers | PLL_BASE_BYPASS);
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800222 /*
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800223 * Set Lock bit, CPCON and LFCON fields (default to 0 if it doesn't
224 * exist for this PLL)
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800225 */
Julius Werner2f37bd62015-02-19 14:51:15 -0800226 write32(misc, lock | misc_con);
Gabe Blackd40be112013-10-09 23:45:07 -0700227
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800228 /* Enable PLL and take it back out of BYPASS */
Julius Werner2f37bd62015-02-19 14:51:15 -0800229 write32(base, dividers | PLL_BASE_ENABLE);
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800230
231 /* Wait for lock ready */
Julius Werner2f37bd62015-02-19 14:51:15 -0800232 while (!(read32(base) & PLL_BASE_LOCK));
Gabe Blackd40be112013-10-09 23:45:07 -0700233}
234
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800235static void init_utmip_pll(void)
236{
Julius Wernere57c3032014-04-11 18:23:12 -0700237 int khz = clock_get_pll_input_khz();
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800238
239 /* Shut off PLL crystal clock while we mess with it */
240 clrbits_le32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
241 udelay(1);
242
Julius Werner94184762015-02-19 20:19:23 -0800243 write32(&clk_rst->utmip_pll_cfg0, /* 960MHz * 1 / 80 == 12 MHz */
244 80 << 16 | /* (rst) phy_divn */
245 1 << 8); /* (rst) phy_divm */
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800246
Julius Werner2f37bd62015-02-19 14:51:15 -0800247 write32(&clk_rst->utmip_pll_cfg1,
Julius Werner94184762015-02-19 20:19:23 -0800248 CEIL_DIV(khz, 8000) << 27 | /* pllu_enbl_cnt / 8 (1us) */
249 0 << 16 | /* PLLU pwrdn */
250 0 << 14 | /* pll_enable pwrdn */
251 0 << 12 | /* pll_active pwrdn */
252 CEIL_DIV(khz, 102) << 0); /* phy_stbl_cnt / 256 (2.5ms) */
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800253
254 /* TODO: TRM can't decide if actv is 5us or 10us, keep an eye on it */
Julius Werner2f37bd62015-02-19 14:51:15 -0800255 write32(&clk_rst->utmip_pll_cfg2,
Julius Werner94184762015-02-19 20:19:23 -0800256 0 << 24 | /* SAMP_D/XDEV pwrdn */
257 CEIL_DIV(khz, 3200) << 18 | /* phy_actv_cnt / 16 (5us) */
258 CEIL_DIV(khz, 256) << 6 | /* pllu_stbl_cnt / 256 (1ms) */
259 0 << 4 | /* SAMP_C/USB3 pwrdn */
260 0 << 2 | /* SAMP_B/XHOST pwrdn */
261 0 << 0); /* SAMP_A/USBD pwrdn */
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800262
263 setbits_le32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
264}
265
Julius Werneredf6b572013-10-25 17:49:26 -0700266/* Graphics just has to be different. There's a few more bits we
267 * need to set in here, but it makes sense just to restrict all the
268 * special bits to this one function.
269 */
270static void graphics_pll(void)
271{
272 int osc = clock_get_osc_bits();
273 u32 *cfg = &clk_rst->plldp_ss_cfg;
274 /* the vendor code sets the dither bit (28)
275 * an undocumented bit (24)
276 * and clamp while we mess with it (22)
277 * Dither is pretty important to display port
278 * so we really do need to handle these bits.
279 * I'm not willing to not clamp it, even if
280 * it might "mostly work" with it not set,
281 * I don't want to find out in a few months
282 * that it is needed.
283 */
284 u32 scfg = (1<<28) | (1<<24) | (1<<22);
Julius Werner2f37bd62015-02-19 14:51:15 -0800285 write32(cfg, scfg);
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800286 init_pll(&clk_rst->plldp_base, &clk_rst->plldp_misc,
287 osc_table[osc].plldp, PLLDPD2_MISC_LOCK_ENABLE);
Julius Werneredf6b572013-10-25 17:49:26 -0700288 /* leave dither and undoc bits set, release clamp */
289 scfg = (1<<28) | (1<<24);
Julius Werner2f37bd62015-02-19 14:51:15 -0800290 write32(cfg, scfg);
Julius Werneredf6b572013-10-25 17:49:26 -0700291
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800292 /* disp1 will be set when panel information (pixel clock) is
293 * retrieved (clock_display).
294 */
295}
296
Vince Hsu1e3679d2014-06-11 17:14:05 +0800297/*
298 * Init PLLD clock source.
299 *
300 * @frequency: the requested plld frequency
301 *
302 * Return the plld frequency if success, otherwise return 0.
303 */
304u32
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800305clock_display(u32 frequency)
306{
307 /**
308 * plld (fo) = vco >> p, where 500MHz < vco < 1000MHz
309 * = (cf * n) >> p, where 1MHz < cf < 6MHz
310 * = ((ref / m) * n) >> p
311 *
Ken Changcbae0de2014-04-18 13:52:48 +0800312 * Iterate the possible values of p (3 bits, 2^7) to find out a minimum
313 * safe vco, then find best (m, n). since m has only 5 bits, we can
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800314 * iterate all possible values. Note Tegra 124 supports 11 bits for n,
315 * but our pll_fields has only 10 bits for n.
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800316 *
317 * Note values undershoot or overshoot target output frequency may not
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800318 * work if the values are not in "safe" range by panel specification.
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800319 */
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800320 struct pllpad_dividers plld = { 0 };
Ken Changcbae0de2014-04-18 13:52:48 +0800321 u32 ref = clock_get_pll_input_khz() * 1000, m, n, p = 0;
Vince Hsu1e3679d2014-06-11 17:14:05 +0800322 u32 cf, vco, rounded_rate = frequency;
Ken Changcbae0de2014-04-18 13:52:48 +0800323 u32 diff, best_diff;
324 const u32 max_m = 1 << 5, max_n = 1 << 10, max_p = 1 << 3,
325 mhz = 1000 * 1000, min_vco = 500 * mhz, max_vco = 1000 * mhz,
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800326 min_cf = 1 * mhz, max_cf = 6 * mhz;
327
Ken Changcbae0de2014-04-18 13:52:48 +0800328 for (vco = frequency; vco < min_vco && p < max_p; p++)
329 vco <<= 1;
330
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800331 if (vco < min_vco || vco > max_vco) {
Ken Changcbae0de2014-04-18 13:52:48 +0800332 printk(BIOS_ERR, "%s: Cannot find out a supported VCO"
333 " for Frequency (%u).\n", __func__, frequency);
Vince Hsu1e3679d2014-06-11 17:14:05 +0800334 return 0;
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800335 }
336
Ken Changcbae0de2014-04-18 13:52:48 +0800337 plld.p = p;
338 best_diff = vco;
339
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800340 for (m = 1; m < max_m && best_diff; m++) {
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800341 cf = ref / m;
342 if (cf < min_cf)
343 break;
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800344 if (cf > max_cf)
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800345 continue;
346
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800347 n = vco / cf;
348 if (n >= max_n)
349 continue;
350
351 diff = vco - n * cf;
352 if (n + 1 < max_n && diff > cf / 2) {
353 n++;
354 diff = cf - diff;
355 }
356
357 if (diff >= best_diff)
358 continue;
359
360 best_diff = diff;
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800361 plld.m = m;
362 plld.n = n;
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800363 }
364
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800365 if (plld.n < 50)
366 plld.cpcon = 2;
367 else if (plld.n < 300)
368 plld.cpcon = 3;
369 else if (plld.n < 600)
370 plld.cpcon = 8;
371 else
372 plld.cpcon = 12;
373
374 if (best_diff) {
Vince Hsu1e3679d2014-06-11 17:14:05 +0800375 printk(BIOS_WARNING, "%s: Failed to match output frequency %u, "
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800376 "best difference is %u.\n", __func__, frequency,
377 best_diff);
Vince Hsu1e3679d2014-06-11 17:14:05 +0800378 rounded_rate = (ref / plld.m * plld.n) >> plld.p;
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800379 }
380
381 printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p/cpcon=%u/%u/%u/%u\n",
Vince Hsu1e3679d2014-06-11 17:14:05 +0800382 __func__, rounded_rate, ref, plld.m, plld.n, plld.p, plld.cpcon);
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800383
384 init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, plld,
385 (PLLUD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE));
Vince Hsu1e3679d2014-06-11 17:14:05 +0800386
387 return rounded_rate;
Julius Werneredf6b572013-10-25 17:49:26 -0700388}
389
Gabe Blackd40be112013-10-09 23:45:07 -0700390/* Initialize the UART and put it on CLK_M so we can use it during clock_init().
391 * Will later move it to PLLP in clock_config(). The divisor must be very small
Martin Roth2ed0aa22016-01-05 20:58:58 -0700392 * to accommodate 12KHz OSCs, so we override the 16.0 UART divider with the 15.1
Gabe Blackd40be112013-10-09 23:45:07 -0700393 * CLK_SOURCE divider to get more precision. (This might still not be enough for
Gabe Blacke5b21272014-04-05 03:54:30 -0700394 * some OSCs... if you use 13KHz, be prepared to have a bad time.) The 1900 has
Gabe Blackd40be112013-10-09 23:45:07 -0700395 * been determined through trial and error (must lead to div 13 at 24MHz). */
396void clock_early_uart(void)
397{
Julius Werner94184762015-02-19 20:19:23 -0800398 write32(&clk_rst->clk_src_uarta, CLK_M << CLK_SOURCE_SHIFT |
399 CLK_UART_DIV_OVERRIDE | CLK_DIVIDER(TEGRA_CLK_M_KHZ, 1900));
Gabe Blackd40be112013-10-09 23:45:07 -0700400 setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_UARTA);
401 udelay(2);
402 clrbits_le32(&clk_rst->rst_dev_l, CLK_L_UARTA);
403}
404
Julius Werneredf6b572013-10-25 17:49:26 -0700405/* Enable output clock (CLK1~3) for external peripherals. */
406void clock_external_output(int clk_id)
407{
408 switch (clk_id) {
409 case 1:
410 setbits_le32(&pmc->clk_out_cntrl, 1 << 2);
411 break;
412 case 2:
413 setbits_le32(&pmc->clk_out_cntrl, 1 << 10);
414 break;
415 case 3:
416 setbits_le32(&pmc->clk_out_cntrl, 1 << 18);
417 break;
418 default:
419 printk(BIOS_CRIT, "ERROR: Unknown output clock id %d\n",
420 clk_id);
421 break;
422 }
423}
424
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800425/* Start PLLM for SDRAM. */
426void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
427 u32 ph135, u32 kvco, u32 kcp, u32 stable_time, u32 emc_source,
428 u32 same_freq)
429{
430 u32 misc1 = ((setup << PLLM_MISC1_SETUP_SHIFT) |
431 (ph45 << PLLM_MISC1_PD_LSHIFT_PH45_SHIFT) |
432 (ph90 << PLLM_MISC1_PD_LSHIFT_PH90_SHIFT) |
433 (ph135 << PLLM_MISC1_PD_LSHIFT_PH135_SHIFT)),
434 misc2 = ((kvco << PLLM_MISC2_KVCO_SHIFT) |
435 (kcp << PLLM_MISC2_KCP_SHIFT)),
436 base;
437
438 if (same_freq)
439 emc_source |= CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
440 else
441 emc_source &= ~CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
442
443 /*
444 * Note PLLM_BASE.PLLM_OUT1_RSTN must be in RESET_ENABLE mode, and
445 * PLLM_BASE.ENABLE must be in DISABLE state (both are the default
446 * values after coldboot reset).
447 */
448
Julius Werner2f37bd62015-02-19 14:51:15 -0800449 write32(&clk_rst->pllm_misc1, misc1);
450 write32(&clk_rst->pllm_misc2, misc2);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800451
452 /* PLLM.BASE needs BYPASS=0, different from general init_pll */
Julius Werner2f37bd62015-02-19 14:51:15 -0800453 base = read32(&clk_rst->pllm_base);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800454 base &= ~(PLLCMX_BASE_DIVN_MASK | PLLCMX_BASE_DIVM_MASK |
455 PLLM_BASE_DIVP_MASK | PLL_BASE_BYPASS);
456 base |= ((m << PLL_BASE_DIVM_SHIFT) | (n << PLL_BASE_DIVN_SHIFT) |
457 (p << PLL_BASE_DIVP_SHIFT));
Julius Werner2f37bd62015-02-19 14:51:15 -0800458 write32(&clk_rst->pllm_base, base);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800459
460 setbits_le32(&clk_rst->pllm_base, PLL_BASE_ENABLE);
461 /* stable_time is required, before we can start to check lock. */
462 udelay(stable_time);
463
Julius Werner2f37bd62015-02-19 14:51:15 -0800464 while (!(read32(&clk_rst->pllm_base) & PLL_BASE_LOCK)) {
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800465 udelay(1);
466 }
467 /*
468 * After PLLM reports being locked, we have to delay 10us before
469 * enabling PLLM_OUT.
470 */
471 udelay(10);
472
473 /* Put OUT1 out of reset state (start to output). */
474 setbits_le32(&clk_rst->pllm_out, PLLM_OUT1_RSTN_RESET_DISABLE);
475
476 /* Enable and start MEM(MC) and EMC. */
477 clock_enable_clear_reset(0, CLK_H_MEM | CLK_H_EMC, 0, 0, 0, 0);
Julius Werner2f37bd62015-02-19 14:51:15 -0800478 write32(&clk_rst->clk_src_emc, emc_source);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800479 udelay(IO_STABILIZATION_DELAY);
480}
481
Jimmy Zhangb3655302014-07-02 17:45:18 -0700482void clock_cpu0_config(void *entry)
Gabe Blackd40be112013-10-09 23:45:07 -0700483{
484 void * const evp_cpu_reset = (uint8_t *)TEGRA_EVP_BASE + 0x100;
485
Julius Werner2f37bd62015-02-19 14:51:15 -0800486 write32(&maincpu_stack_pointer, (uintptr_t)_estack);
487 write32(&maincpu_entry_point, (uintptr_t)entry);
488 write32(evp_cpu_reset, (uintptr_t)&maincpu_setup);
Julius Werneredf6b572013-10-25 17:49:26 -0700489
490 /* Set active CPU cluster to G */
491 clrbits_le32(&flow->cluster_control, 1);
Gabe Blackd40be112013-10-09 23:45:07 -0700492
493 // Set up cclk_brst and divider.
Julius Werner2f37bd62015-02-19 14:51:15 -0800494 write32(&clk_rst->cclk_brst_pol,
Julius Werner94184762015-02-19 20:19:23 -0800495 (CRC_CCLK_BRST_POL_PLLX_OUT0 << 0) |
496 (CRC_CCLK_BRST_POL_PLLX_OUT0 << 4) |
497 (CRC_CCLK_BRST_POL_PLLX_OUT0 << 8) |
498 (CRC_CCLK_BRST_POL_PLLX_OUT0 << 12) |
499 (CRC_CCLK_BRST_POL_CPU_STATE_RUN << 28));
Julius Werner2f37bd62015-02-19 14:51:15 -0800500 write32(&clk_rst->super_cclk_div,
501 CRC_SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB);
Gabe Blackd40be112013-10-09 23:45:07 -0700502
503 // Enable the clocks for CPUs 0-3.
504 uint32_t cpu_cmplx_clr = read32(&clk_rst->clk_cpu_cmplx_clr);
505 cpu_cmplx_clr |= CRC_CLK_CLR_CPU0_STP | CRC_CLK_CLR_CPU1_STP |
506 CRC_CLK_CLR_CPU2_STP | CRC_CLK_CLR_CPU3_STP;
Julius Werner2f37bd62015-02-19 14:51:15 -0800507 write32(&clk_rst->clk_cpu_cmplx_clr, cpu_cmplx_clr);
Gabe Blackd40be112013-10-09 23:45:07 -0700508
509 // Enable other CPU related clocks.
510 setbits_le32(&clk_rst->clk_out_enb_l, CLK_L_CPU);
511 setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_CPUG);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800512 setbits_le32(&clk_rst->clk_out_enb_v, CLK_V_CPULP);
Jimmy Zhangb3655302014-07-02 17:45:18 -0700513}
Gabe Blackd40be112013-10-09 23:45:07 -0700514
Jimmy Zhangb3655302014-07-02 17:45:18 -0700515void clock_cpu0_remove_reset(void)
516{
Gabe Blackd40be112013-10-09 23:45:07 -0700517 // Disable the reset on the non-CPU parts of the fast cluster.
Julius Werner2f37bd62015-02-19 14:51:15 -0800518 write32(&clk_rst->rst_cpug_cmplx_clr, CRC_RST_CPUG_CLR_NONCPU);
Gabe Blackd40be112013-10-09 23:45:07 -0700519 // Disable the various resets on the CPUs.
Julius Werner2f37bd62015-02-19 14:51:15 -0800520 write32(&clk_rst->rst_cpug_cmplx_clr,
Julius Werner94184762015-02-19 20:19:23 -0800521 CRC_RST_CPUG_CLR_CPU0 | CRC_RST_CPUG_CLR_CPU1 |
522 CRC_RST_CPUG_CLR_CPU2 | CRC_RST_CPUG_CLR_CPU3 |
523 CRC_RST_CPUG_CLR_DBG0 | CRC_RST_CPUG_CLR_DBG1 |
524 CRC_RST_CPUG_CLR_DBG2 | CRC_RST_CPUG_CLR_DBG3 |
525 CRC_RST_CPUG_CLR_CORE0 | CRC_RST_CPUG_CLR_CORE1 |
526 CRC_RST_CPUG_CLR_CORE2 | CRC_RST_CPUG_CLR_CORE3 |
527 CRC_RST_CPUG_CLR_CX0 | CRC_RST_CPUG_CLR_CX1 |
528 CRC_RST_CPUG_CLR_CX2 | CRC_RST_CPUG_CLR_CX3 |
529 CRC_RST_CPUG_CLR_L2 | CRC_RST_CPUG_CLR_PDBG);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800530
531 // Disable the reset on the non-CPU parts of the slow cluster.
Julius Werner2f37bd62015-02-19 14:51:15 -0800532 write32(&clk_rst->rst_cpulp_cmplx_clr, CRC_RST_CPULP_CLR_NONCPU);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800533 // Disable the various resets on the LP CPU.
Julius Werner2f37bd62015-02-19 14:51:15 -0800534 write32(&clk_rst->rst_cpulp_cmplx_clr,
Julius Werner94184762015-02-19 20:19:23 -0800535 CRC_RST_CPULP_CLR_CPU0 | CRC_RST_CPULP_CLR_DBG0 |
536 CRC_RST_CPULP_CLR_CORE0 | CRC_RST_CPULP_CLR_CX0 |
537 CRC_RST_CPULP_CLR_L2 | CRC_RST_CPULP_CLR_PDBG);
Gabe Blackd40be112013-10-09 23:45:07 -0700538}
539
Julius Werneredf6b572013-10-25 17:49:26 -0700540void clock_halt_avp(void)
541{
542 for (;;) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800543 write32(&flow->halt_cop_events,
Julius Werner94184762015-02-19 20:19:23 -0800544 FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ |
545 FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT);
Julius Werneredf6b572013-10-25 17:49:26 -0700546 }
547}
548
Gabe Blackd40be112013-10-09 23:45:07 -0700549void clock_init(void)
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -0700550{
Gabe Blackd40be112013-10-09 23:45:07 -0700551 u32 osc = clock_get_osc_bits();
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -0700552
Gabe Blackd40be112013-10-09 23:45:07 -0700553 /* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */
Julius Werner2f37bd62015-02-19 14:51:15 -0800554 write32(&clk_rst->pllc_misc2, 0x2b << 17 | 0xb << 9);
Gabe Blackd40be112013-10-09 23:45:07 -0700555
Julius Werneredf6b572013-10-25 17:49:26 -0700556 /* Max out the AVP clock before everything else (need PLLC for that). */
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800557 init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc,
558 osc_table[osc].pllc, PLLC_MISC_LOCK_ENABLE);
Julius Werneredf6b572013-10-25 17:49:26 -0700559
560 /* Typical ratios are 1:2:2 or 1:2:3 sclk:hclk:pclk (See: APB DMA
561 * features section in the TRM). */
Julius Werner2f37bd62015-02-19 14:51:15 -0800562 write32(&clk_rst->clk_sys_rate,
Julius Werner94184762015-02-19 20:19:23 -0800563 TEGRA_HCLK_RATIO << HCLK_DIVISOR_SHIFT |
564 TEGRA_PCLK_RATIO << PCLK_DIVISOR_SHIFT);
565 write32(&clk_rst->pllc_out, CLK_DIVIDER(TEGRA_PLLC_KHZ, TEGRA_SCLK_KHZ)
566 << PLL_OUT_RATIO_SHIFT | PLL_OUT_CLKEN | PLL_OUT_RSTN);
567 write32(&clk_rst->sclk_brst_pol, /* sclk = 300 MHz */
568 SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT |
569 SCLK_SOURCE_PLLC_OUT1 << SCLK_RUN_SHIFT);
Julius Werneredf6b572013-10-25 17:49:26 -0700570
571 /* Change the oscillator drive strength (from U-Boot -- why?) */
572 clrsetbits_le32(&clk_rst->osc_ctrl, OSC_XOFS_MASK,
573 OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
574
575 /*
576 * Ambiguous quote from u-boot. TODO: what's this mean?
577 * "should update same value in PMC_OSC_EDPD_OVER XOFS
578 * field for warmboot "
579 */
580 clrsetbits_le32(&pmc->osc_edpd_over, PMC_OSC_EDPD_OVER_XOFS_MASK,
581 OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT);
582
583 /* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */
584 clrbits_le32(&clk_rst->pllx_misc3, PLLX_IDDQ_MASK);
585
586 /* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */
Julius Werner2f37bd62015-02-19 14:51:15 -0800587 write32(&clk_rst->pllp_outa,
Julius Werner94184762015-02-19 20:19:23 -0800588 (CLK_DIVIDER(TEGRA_PLLP_KHZ, 9600) << PLL_OUT_RATIO_SHIFT |
589 PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT1_SHIFT |
590 (CLK_DIVIDER(TEGRA_PLLP_KHZ, 48000) << PLL_OUT_RATIO_SHIFT |
591 PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT2_SHIFT);
Julius Werner2f37bd62015-02-19 14:51:15 -0800592 write32(&clk_rst->pllp_outb,
Julius Werner94184762015-02-19 20:19:23 -0800593 (CLK_DIVIDER(TEGRA_PLLP_KHZ, 102000) << PLL_OUT_RATIO_SHIFT |
594 PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT3_SHIFT |
595 (CLK_DIVIDER(TEGRA_PLLP_KHZ, 204000) << PLL_OUT_RATIO_SHIFT |
596 PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT4_SHIFT);
Gabe Blackd40be112013-10-09 23:45:07 -0700597
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800598 /* init pllx */
599 init_pll(&clk_rst->pllx_base, &clk_rst->pllx_misc,
600 osc_table[osc].pllx, PLLPAXS_MISC_LOCK_ENABLE);
601
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800602 /* init pllu */
603 init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc,
604 osc_table[osc].pllu, PLLUD_MISC_LOCK_ENABLE);
605
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800606 init_utmip_pll();
Julius Werneredf6b572013-10-25 17:49:26 -0700607 graphics_pll();
Gabe Blackd40be112013-10-09 23:45:07 -0700608}
609
Julius Werneredf6b572013-10-25 17:49:26 -0700610void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x)
Gabe Blackd40be112013-10-09 23:45:07 -0700611{
Julius Werner2f37bd62015-02-19 14:51:15 -0800612 if (l) write32(&clk_rst->clk_enb_l_set, l);
613 if (h) write32(&clk_rst->clk_enb_h_set, h);
614 if (u) write32(&clk_rst->clk_enb_u_set, u);
615 if (v) write32(&clk_rst->clk_enb_v_set, v);
616 if (w) write32(&clk_rst->clk_enb_w_set, w);
617 if (x) write32(&clk_rst->clk_enb_x_set, x);
Gabe Blackd40be112013-10-09 23:45:07 -0700618
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800619 /* Give clocks time to stabilize. */
Gabe Blackd40be112013-10-09 23:45:07 -0700620 udelay(IO_STABILIZATION_DELAY);
621
Julius Werner2f37bd62015-02-19 14:51:15 -0800622 if (l) write32(&clk_rst->rst_dev_l_clr, l);
623 if (h) write32(&clk_rst->rst_dev_h_clr, h);
624 if (u) write32(&clk_rst->rst_dev_u_clr, u);
625 if (v) write32(&clk_rst->rst_dev_v_clr, v);
626 if (w) write32(&clk_rst->rst_dev_w_clr, w);
627 if (x) write32(&clk_rst->rst_dev_x_clr, x);
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -0700628}
Gabe Blackbab78962014-03-26 21:29:45 -0700629
630void clock_reset_l(u32 bit)
631{
Julius Werner2f37bd62015-02-19 14:51:15 -0800632 write32(&clk_rst->rst_dev_l_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700633 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800634 write32(&clk_rst->rst_dev_l_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700635}
636
637void clock_reset_h(u32 bit)
638{
Julius Werner2f37bd62015-02-19 14:51:15 -0800639 write32(&clk_rst->rst_dev_h_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700640 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800641 write32(&clk_rst->rst_dev_h_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700642}
643
644void clock_reset_u(u32 bit)
645{
Julius Werner2f37bd62015-02-19 14:51:15 -0800646 write32(&clk_rst->rst_dev_u_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700647 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800648 write32(&clk_rst->rst_dev_u_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700649}
650
651void clock_reset_v(u32 bit)
652{
Julius Werner2f37bd62015-02-19 14:51:15 -0800653 write32(&clk_rst->rst_dev_v_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700654 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800655 write32(&clk_rst->rst_dev_v_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700656}
657
658void clock_reset_w(u32 bit)
659{
Julius Werner2f37bd62015-02-19 14:51:15 -0800660 write32(&clk_rst->rst_dev_w_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700661 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800662 write32(&clk_rst->rst_dev_w_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700663}
664
665void clock_reset_x(u32 bit)
666{
Julius Werner2f37bd62015-02-19 14:51:15 -0800667 write32(&clk_rst->rst_dev_x_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700668 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800669 write32(&clk_rst->rst_dev_x_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700670}