blob: f8a232f875faa0bcf8de1896774986bb1b344e87 [file] [log] [blame]
Angel Ponsa2ee7612020-04-04 18:51:15 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Angel Ponsa2ee7612020-04-04 18:51:15 +02002
Jacob Garber693c55c2019-07-25 12:06:28 -06003#include <assert.h>
Julius Wernerf0d21ff32014-10-20 13:24:14 -07004#include <arch/clock.h>
Kyösti Mälkki13f66502019-03-03 08:01:05 +02005#include <device/mmio.h>
Gabe Blackd40be112013-10-09 23:45:07 -07006#include <console/console.h>
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -07007#include <delay.h>
Gabe Blacke97b6832013-10-06 06:13:24 -07008#include <soc/addressmap.h>
Julius Wernerf0d21ff32014-10-20 13:24:14 -07009#include <soc/clk_rst.h>
Gabe Blackd40be112013-10-09 23:45:07 -070010#include <soc/clock.h>
Julius Wernerf0d21ff32014-10-20 13:24:14 -070011#include <soc/flow.h>
12#include <soc/maincpu.h>
13#include <soc/pmc.h>
14#include <soc/sysctr.h>
Julius Wernerec5e5e02014-08-20 15:29:56 -070015#include <symbols.h>
Gabe Blacke97b6832013-10-06 06:13:24 -070016
17static struct clk_rst_ctlr *clk_rst = (void *)TEGRA_CLK_RST_BASE;
Gabe Blackd40be112013-10-09 23:45:07 -070018static struct flow_ctlr *flow = (void *)TEGRA_FLOW_BASE;
Hung-Te Lin2fc3b622013-10-21 21:43:03 +080019static struct tegra_pmc_regs *pmc = (void *)TEGRA_PMC_BASE;
20static struct sysctr_regs *sysctr = (void *)TEGRA_SYSCTR0_BASE;
Gabe Blackd40be112013-10-09 23:45:07 -070021
22struct pll_dividers {
23 u32 n : 10;
24 u32 m : 8;
25 u32 p : 4;
Andrew Bresticker25bf7752014-03-04 11:06:13 -080026 u32 cpcon : 4;
27 u32 lfcon : 4;
28 u32 : 2;
Gabe Blackd40be112013-10-09 23:45:07 -070029};
30
31/* Some PLLs have more restrictive divider bit lengths or are missing some
32 * fields. Make sure to use the right struct in the osc_table definition to get
33 * compile-time checking, but keep the bits aligned with struct pll_dividers so
34 * they can be used interchangeably at run time. Add new formats as required. */
35struct pllcx_dividers {
36 u32 n : 8;
37 u32 : 2;
38 u32 m : 8;
39 u32 p : 4;
40 u32 : 10;
41};
42struct pllpad_dividers {
43 u32 n : 10;
44 u32 m : 5;
45 u32 : 3;
46 u32 p : 3;
47 u32 : 1;
48 u32 cpcon : 4;
49 u32 : 6;
50};
51struct pllu_dividers {
52 u32 n : 10;
53 u32 m : 5;
54 u32 : 3;
55 u32 p : 1;
56 u32 : 3;
57 u32 cpcon : 4;
Andrew Bresticker25bf7752014-03-04 11:06:13 -080058 u32 lfcon : 4;
59 u32 : 2;
Gabe Blackd40be112013-10-09 23:45:07 -070060};
61
62union __attribute__((transparent_union)) pll_fields {
63 u32 raw;
64 struct pll_dividers div;
65 struct pllcx_dividers cx;
66 struct pllpad_dividers pad;
67 struct pllu_dividers u;
68};
69
70/* This table defines the frequency dividers for every PLL to turn the external
71 * OSC clock into the frequencies defined by TEGRA_PLL*_KHZ in soc/clock.h.
Julius Wernere57c3032014-04-11 18:23:12 -070072 * All PLLs have three dividers (n, m and p), with the governing formula for
73 * the output frequency being CF = (IN / m), VCO = CF * n and OUT = VCO / (2^p).
74 * All divisor configurations must meet the PLL's constraints for VCO and CF:
75 * PLLX: 12 MHz < CF < 50 MHz, 700 MHz < VCO < 3000 MHz
76 * PLLC: 12 MHz < CF < 50 MHz, 600 MHz < VCO < 1400 MHz
77 * PLLM: 12 MHz < CF < 50 MHz, 400 MHz < VCO < 1066 MHz
78 * PLLP: 1 MHz < CF < 6 MHz, 200 MHz < VCO < 700 MHz
79 * PLLD: 1 MHz < CF < 6 MHz, 500 MHz < VCO < 1000 MHz
80 * PLLU: 1 MHz < CF < 6 MHz, 480 MHz < VCO < 960 MHz
81 * PLLDP: 12 MHz < CF < 38 MHz, 600 MHz < VCO < 1200 MHz
82 * (values taken from Linux' drivers/clk/tegra/clk-tegra124.c). */
Gabe Blackd40be112013-10-09 23:45:07 -070083struct {
84 int khz;
Gabe Black31785032014-03-03 16:26:11 -080085 struct pllcx_dividers pllx; /* target: CONFIG_PLLX_KHZ */
Gabe Blackd40be112013-10-09 23:45:07 -070086 struct pllcx_dividers pllc; /* target: 600 MHz */
Julius Wernere57c3032014-04-11 18:23:12 -070087 /* PLLM is set up dynamically by clock_sdram(). */
88 /* PLLP is hardwired to 408 MHz in HW (unless we set BASE_OVRD). */
Gabe Blackd40be112013-10-09 23:45:07 -070089 struct pllu_dividers pllu; /* target; 960 MHz */
Julius Werneredf6b572013-10-25 17:49:26 -070090 struct pllcx_dividers plldp; /* target; 270 MHz */
Julius Wernere57c3032014-04-11 18:23:12 -070091 /* PLLDP treats p differently (OUT = VCO / (p + 1) for p < 6). */
Gabe Blackd40be112013-10-09 23:45:07 -070092} static const osc_table[16] = {
Arthur Heymans961e09c2022-03-24 00:11:07 +010093 [OSC_FREQ_12] = {
Gabe Blackd40be112013-10-09 23:45:07 -070094 .khz = 12000,
Gabe Black31785032014-03-03 16:26:11 -080095 .pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
Gabe Blackd40be112013-10-09 23:45:07 -070096 .pllc = {.n = 50, .m = 1, .p = 0},
Andrew Bresticker25bf7752014-03-04 11:06:13 -080097 .pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
Jimmy Zhangc225e4c2014-02-28 17:35:48 -080098 .plldp = {.n = 90, .m = 1, .p = 3},
Gabe Blackd40be112013-10-09 23:45:07 -070099 },
Arthur Heymans961e09c2022-03-24 00:11:07 +0100100 [OSC_FREQ_13] = {
Gabe Blackd40be112013-10-09 23:45:07 -0700101 .khz = 13000,
Gabe Black31785032014-03-03 16:26:11 -0800102 .pllx = {.n = TEGRA_PLLX_KHZ / 13000, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700103 .pllc = {.n = 46, .m = 1, .p = 0}, /* 598.0 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800104 .pllu = {.n = 960, .m = 13, .p = 0, .cpcon = 12, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700105 .plldp = {.n = 83, .m = 1, .p = 3}, /* 269.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700106 },
Arthur Heymans961e09c2022-03-24 00:11:07 +0100107 [OSC_FREQ_16P8] = {
Gabe Blackd40be112013-10-09 23:45:07 -0700108 .khz = 16800,
Gabe Black31785032014-03-03 16:26:11 -0800109 .pllx = {.n = TEGRA_PLLX_KHZ / 16800, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700110 .pllc = {.n = 71, .m = 1, .p = 1}, /* 596.4 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800111 .pllu = {.n = 400, .m = 7, .p = 0, .cpcon = 5, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700112 .plldp = {.n = 64, .m = 1, .p = 3}, /* 268.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700113 },
Arthur Heymans961e09c2022-03-24 00:11:07 +0100114 [OSC_FREQ_19P2] = {
Gabe Blackd40be112013-10-09 23:45:07 -0700115 .khz = 19200,
Gabe Black31785032014-03-03 16:26:11 -0800116 .pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700117 .pllc = {.n = 62, .m = 1, .p = 1}, /* 595.2 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800118 .pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700119 .plldp = {.n = 56, .m = 1, .p = 3}, /* 268.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700120 },
Arthur Heymans961e09c2022-03-24 00:11:07 +0100121 [OSC_FREQ_26] = {
Gabe Blackd40be112013-10-09 23:45:07 -0700122 .khz = 26000,
Gabe Black31785032014-03-03 16:26:11 -0800123 .pllx = {.n = TEGRA_PLLX_KHZ / 26000, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700124 .pllc = {.n = 23, .m = 1, .p = 0}, /* 598.0 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800125 .pllu = {.n = 960, .m = 26, .p = 0, .cpcon = 12, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700126 .plldp = {.n = 83, .m = 2, .p = 3}, /* 269.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700127 },
Julius Wernere57c3032014-04-11 18:23:12 -0700128 /* These oscillators get predivided as PLL inputs... n/m/p divisors for
129 * 38.4 should always match 19.2, and 48 should always match 12. */
Arthur Heymans961e09c2022-03-24 00:11:07 +0100130 [OSC_FREQ_38P4] = {
Gabe Blackd40be112013-10-09 23:45:07 -0700131 .khz = 38400,
Gabe Black31785032014-03-03 16:26:11 -0800132 .pllx = {.n = TEGRA_PLLX_KHZ / 19200, .m = 1, .p = 0},
Julius Wernere57c3032014-04-11 18:23:12 -0700133 .pllc = {.n = 62, .m = 1, .p = 1}, /* 595.2 MHz */
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800134 .pllu = {.n = 200, .m = 4, .p = 0, .cpcon = 3, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700135 .plldp = {.n = 56, .m = 1, .p = 3}, /* 268.8 MHz */
Gabe Blackd40be112013-10-09 23:45:07 -0700136 },
Arthur Heymans961e09c2022-03-24 00:11:07 +0100137 [OSC_FREQ_48] = {
Gabe Blackd40be112013-10-09 23:45:07 -0700138 .khz = 48000,
Gabe Black31785032014-03-03 16:26:11 -0800139 .pllx = {.n = TEGRA_PLLX_KHZ / 12000, .m = 1, .p = 0},
Gabe Blackd40be112013-10-09 23:45:07 -0700140 .pllc = {.n = 50, .m = 1, .p = 0},
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800141 .pllu = {.n = 960, .m = 12, .p = 0, .cpcon = 12, .lfcon = 2},
Julius Wernere57c3032014-04-11 18:23:12 -0700142 .plldp = {.n = 90, .m = 1, .p = 3},
Gabe Blackd40be112013-10-09 23:45:07 -0700143 },
144};
145
Gabe Blackd40be112013-10-09 23:45:07 -0700146/* Get the oscillator frequency, from the corresponding hardware
147 * configuration field. This is actually a per-soc thing. Avoid the
148 * temptation to make it common.
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -0700149 */
Gabe Blackd40be112013-10-09 23:45:07 -0700150static u32 clock_get_osc_bits(void)
151{
Julius Werner2f37bd62015-02-19 14:51:15 -0800152 return (read32(&clk_rst->osc_ctrl) & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
Gabe Blackd40be112013-10-09 23:45:07 -0700153}
154
155int clock_get_osc_khz(void)
156{
157 return osc_table[clock_get_osc_bits()].khz;
158}
159
Julius Wernere57c3032014-04-11 18:23:12 -0700160int clock_get_pll_input_khz(void)
161{
Julius Werner2f37bd62015-02-19 14:51:15 -0800162 u32 osc_ctrl = read32(&clk_rst->osc_ctrl);
Julius Wernere57c3032014-04-11 18:23:12 -0700163 u32 osc_bits = (osc_ctrl & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT;
164 u32 pll_ref_div = (osc_ctrl & OSC_PREDIV_MASK) >> OSC_PREDIV_SHIFT;
165 return osc_table[osc_bits].khz >> pll_ref_div;
166}
167
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800168void clock_init_arm_generic_timer(void)
169{
170 uint32_t freq = clock_get_osc_khz() * 1000;
171 // Set the cntfrq register.
Furquan Shaikhd653ae82014-06-24 15:21:03 -0700172 set_cntfrq(freq);
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800173
174 // Record the system timer frequency.
Julius Werner2f37bd62015-02-19 14:51:15 -0800175 write32(&sysctr->cntfid0, freq);
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800176 // Enable the system counter.
177 uint32_t cntcr = read32(&sysctr->cntcr);
178 cntcr |= SYSCTR_CNTCR_EN | SYSCTR_CNTCR_HDBG;
Julius Werner2f37bd62015-02-19 14:51:15 -0800179 write32(&sysctr->cntcr, cntcr);
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800180}
181
Julius Werneredf6b572013-10-25 17:49:26 -0700182#define SOR0_CLK_SEL0 (1 << 14)
183#define SOR0_CLK_SEL1 (1 << 15)
Gabe Blackd40be112013-10-09 23:45:07 -0700184
Julius Werneredf6b572013-10-25 17:49:26 -0700185void sor_clock_stop(void)
186{
187 /* The Serial Output Resource clock has to be off
188 * before we start the plldp. Learned the hard way.
189 * FIXME: this has to be cleaned up a bit more.
190 * Waiting on some new info from Nvidia.
191 */
Julius Werner55009af2019-12-02 22:03:27 -0800192 clrbits32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0 | SOR0_CLK_SEL1);
Julius Werneredf6b572013-10-25 17:49:26 -0700193}
194
195void sor_clock_start(void)
196{
197 /* uses PLLP, has a non-standard bit layout. */
Julius Werner55009af2019-12-02 22:03:27 -0800198 setbits32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0);
Gabe Blackd40be112013-10-09 23:45:07 -0700199}
200
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800201static void init_pll(u32 *base, u32 *misc, const union pll_fields pll, u32 lock)
Gabe Blackd40be112013-10-09 23:45:07 -0700202{
203 u32 dividers = pll.div.n << PLL_BASE_DIVN_SHIFT |
204 pll.div.m << PLL_BASE_DIVM_SHIFT |
205 pll.div.p << PLL_BASE_DIVP_SHIFT;
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800206 u32 misc_con = pll.div.cpcon << PLL_MISC_CPCON_SHIFT |
207 pll.div.lfcon << PLL_MISC_LFCON_SHIFT;
Gabe Blackd40be112013-10-09 23:45:07 -0700208
209 /* Write dividers but BYPASS the PLL while we're messing with it. */
Julius Werner2f37bd62015-02-19 14:51:15 -0800210 write32(base, dividers | PLL_BASE_BYPASS);
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800211 /*
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800212 * Set Lock bit, CPCON and LFCON fields (default to 0 if it doesn't
213 * exist for this PLL)
Andrew Bresticker25bf7752014-03-04 11:06:13 -0800214 */
Julius Werner2f37bd62015-02-19 14:51:15 -0800215 write32(misc, lock | misc_con);
Gabe Blackd40be112013-10-09 23:45:07 -0700216
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800217 /* Enable PLL and take it back out of BYPASS */
Julius Werner2f37bd62015-02-19 14:51:15 -0800218 write32(base, dividers | PLL_BASE_ENABLE);
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800219
220 /* Wait for lock ready */
Julius Werner2f37bd62015-02-19 14:51:15 -0800221 while (!(read32(base) & PLL_BASE_LOCK));
Gabe Blackd40be112013-10-09 23:45:07 -0700222}
223
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800224static void init_utmip_pll(void)
225{
Julius Wernere57c3032014-04-11 18:23:12 -0700226 int khz = clock_get_pll_input_khz();
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800227
228 /* Shut off PLL crystal clock while we mess with it */
Julius Werner55009af2019-12-02 22:03:27 -0800229 clrbits32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800230 udelay(1);
231
Julius Werner94184762015-02-19 20:19:23 -0800232 write32(&clk_rst->utmip_pll_cfg0, /* 960MHz * 1 / 80 == 12 MHz */
233 80 << 16 | /* (rst) phy_divn */
234 1 << 8); /* (rst) phy_divm */
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800235
Julius Werner2f37bd62015-02-19 14:51:15 -0800236 write32(&clk_rst->utmip_pll_cfg1,
Elyes HAOUAS6df3b642018-11-26 22:53:49 +0100237 DIV_ROUND_UP(khz, 8000) << 27 | /* pllu_enbl_cnt / 8 (1us) */
Julius Werner94184762015-02-19 20:19:23 -0800238 0 << 16 | /* PLLU pwrdn */
239 0 << 14 | /* pll_enable pwrdn */
240 0 << 12 | /* pll_active pwrdn */
Elyes HAOUAS6df3b642018-11-26 22:53:49 +0100241 DIV_ROUND_UP(khz, 102) << 0); /* phy_stbl_cnt / 256 (2.5ms) */
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800242
243 /* TODO: TRM can't decide if actv is 5us or 10us, keep an eye on it */
Julius Werner2f37bd62015-02-19 14:51:15 -0800244 write32(&clk_rst->utmip_pll_cfg2,
Julius Werner94184762015-02-19 20:19:23 -0800245 0 << 24 | /* SAMP_D/XDEV pwrdn */
Elyes HAOUAS6df3b642018-11-26 22:53:49 +0100246 DIV_ROUND_UP(khz, 3200) << 18 | /* phy_actv_cnt / 16 (5us) */
247 DIV_ROUND_UP(khz, 256) << 6 | /* pllu_stbl_cnt / 256 (1ms) */
Julius Werner94184762015-02-19 20:19:23 -0800248 0 << 4 | /* SAMP_C/USB3 pwrdn */
249 0 << 2 | /* SAMP_B/XHOST pwrdn */
250 0 << 0); /* SAMP_A/USBD pwrdn */
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800251
Julius Werner55009af2019-12-02 22:03:27 -0800252 setbits32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800253}
254
Julius Werneredf6b572013-10-25 17:49:26 -0700255/* Graphics just has to be different. There's a few more bits we
256 * need to set in here, but it makes sense just to restrict all the
257 * special bits to this one function.
258 */
259static void graphics_pll(void)
260{
261 int osc = clock_get_osc_bits();
262 u32 *cfg = &clk_rst->plldp_ss_cfg;
263 /* the vendor code sets the dither bit (28)
264 * an undocumented bit (24)
265 * and clamp while we mess with it (22)
266 * Dither is pretty important to display port
267 * so we really do need to handle these bits.
268 * I'm not willing to not clamp it, even if
269 * it might "mostly work" with it not set,
270 * I don't want to find out in a few months
271 * that it is needed.
272 */
273 u32 scfg = (1<<28) | (1<<24) | (1<<22);
Julius Werner2f37bd62015-02-19 14:51:15 -0800274 write32(cfg, scfg);
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800275 init_pll(&clk_rst->plldp_base, &clk_rst->plldp_misc,
276 osc_table[osc].plldp, PLLDPD2_MISC_LOCK_ENABLE);
Julius Werneredf6b572013-10-25 17:49:26 -0700277 /* leave dither and undoc bits set, release clamp */
278 scfg = (1<<28) | (1<<24);
Julius Werner2f37bd62015-02-19 14:51:15 -0800279 write32(cfg, scfg);
Julius Werneredf6b572013-10-25 17:49:26 -0700280
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800281 /* disp1 will be set when panel information (pixel clock) is
282 * retrieved (clock_display).
283 */
284}
285
Vince Hsu1e3679d2014-06-11 17:14:05 +0800286/*
287 * Init PLLD clock source.
288 *
289 * @frequency: the requested plld frequency
290 *
291 * Return the plld frequency if success, otherwise return 0.
292 */
293u32
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800294clock_display(u32 frequency)
295{
296 /**
297 * plld (fo) = vco >> p, where 500MHz < vco < 1000MHz
298 * = (cf * n) >> p, where 1MHz < cf < 6MHz
299 * = ((ref / m) * n) >> p
300 *
Ken Changcbae0de2014-04-18 13:52:48 +0800301 * Iterate the possible values of p (3 bits, 2^7) to find out a minimum
302 * safe vco, then find best (m, n). since m has only 5 bits, we can
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800303 * iterate all possible values. Note Tegra 124 supports 11 bits for n,
304 * but our pll_fields has only 10 bits for n.
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800305 *
306 * Note values undershoot or overshoot target output frequency may not
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800307 * work if the values are not in "safe" range by panel specification.
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800308 */
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800309 struct pllpad_dividers plld = { 0 };
Ken Changcbae0de2014-04-18 13:52:48 +0800310 u32 ref = clock_get_pll_input_khz() * 1000, m, n, p = 0;
Vince Hsu1e3679d2014-06-11 17:14:05 +0800311 u32 cf, vco, rounded_rate = frequency;
Ken Changcbae0de2014-04-18 13:52:48 +0800312 u32 diff, best_diff;
313 const u32 max_m = 1 << 5, max_n = 1 << 10, max_p = 1 << 3,
314 mhz = 1000 * 1000, min_vco = 500 * mhz, max_vco = 1000 * mhz,
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800315 min_cf = 1 * mhz, max_cf = 6 * mhz;
316
Ken Changcbae0de2014-04-18 13:52:48 +0800317 for (vco = frequency; vco < min_vco && p < max_p; p++)
318 vco <<= 1;
319
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800320 if (vco < min_vco || vco > max_vco) {
Ken Changcbae0de2014-04-18 13:52:48 +0800321 printk(BIOS_ERR, "%s: Cannot find out a supported VCO"
322 " for Frequency (%u).\n", __func__, frequency);
Vince Hsu1e3679d2014-06-11 17:14:05 +0800323 return 0;
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800324 }
325
Ken Changcbae0de2014-04-18 13:52:48 +0800326 plld.p = p;
327 best_diff = vco;
328
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800329 for (m = 1; m < max_m && best_diff; m++) {
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800330 cf = ref / m;
331 if (cf < min_cf)
332 break;
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800333 if (cf > max_cf)
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800334 continue;
335
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800336 n = vco / cf;
337 if (n >= max_n)
338 continue;
339
340 diff = vco - n * cf;
341 if (n + 1 < max_n && diff > cf / 2) {
342 n++;
343 diff = cf - diff;
344 }
345
346 if (diff >= best_diff)
347 continue;
348
349 best_diff = diff;
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800350 plld.m = m;
351 plld.n = n;
Hung-Te Lin1a8e0af2014-04-08 20:03:40 +0800352 }
353
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800354 if (plld.n < 50)
355 plld.cpcon = 2;
356 else if (plld.n < 300)
357 plld.cpcon = 3;
358 else if (plld.n < 600)
359 plld.cpcon = 8;
360 else
361 plld.cpcon = 12;
362
363 if (best_diff) {
Vince Hsu1e3679d2014-06-11 17:14:05 +0800364 printk(BIOS_WARNING, "%s: Failed to match output frequency %u, "
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800365 "best difference is %u.\n", __func__, frequency,
366 best_diff);
Jacob Garber693c55c2019-07-25 12:06:28 -0600367 assert(plld.m != 0);
Vince Hsu1e3679d2014-06-11 17:14:05 +0800368 rounded_rate = (ref / plld.m * plld.n) >> plld.p;
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800369 }
370
371 printk(BIOS_DEBUG, "%s: PLLD=%u ref=%u, m/n/p/cpcon=%u/%u/%u/%u\n",
Vince Hsu1e3679d2014-06-11 17:14:05 +0800372 __func__, rounded_rate, ref, plld.m, plld.n, plld.p, plld.cpcon);
Hung-Te Lin0cbba822014-04-17 08:20:04 +0800373
374 init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, plld,
375 (PLLUD_MISC_LOCK_ENABLE | PLLD_MISC_CLK_ENABLE));
Vince Hsu1e3679d2014-06-11 17:14:05 +0800376
377 return rounded_rate;
Julius Werneredf6b572013-10-25 17:49:26 -0700378}
379
Gabe Blackd40be112013-10-09 23:45:07 -0700380/* Initialize the UART and put it on CLK_M so we can use it during clock_init().
381 * Will later move it to PLLP in clock_config(). The divisor must be very small
Martin Roth2ed0aa22016-01-05 20:58:58 -0700382 * to accommodate 12KHz OSCs, so we override the 16.0 UART divider with the 15.1
Gabe Blackd40be112013-10-09 23:45:07 -0700383 * CLK_SOURCE divider to get more precision. (This might still not be enough for
Gabe Blacke5b21272014-04-05 03:54:30 -0700384 * some OSCs... if you use 13KHz, be prepared to have a bad time.) The 1900 has
Gabe Blackd40be112013-10-09 23:45:07 -0700385 * been determined through trial and error (must lead to div 13 at 24MHz). */
386void clock_early_uart(void)
387{
Julius Werner94184762015-02-19 20:19:23 -0800388 write32(&clk_rst->clk_src_uarta, CLK_M << CLK_SOURCE_SHIFT |
389 CLK_UART_DIV_OVERRIDE | CLK_DIVIDER(TEGRA_CLK_M_KHZ, 1900));
Julius Werner55009af2019-12-02 22:03:27 -0800390 setbits32(&clk_rst->clk_out_enb_l, CLK_L_UARTA);
Gabe Blackd40be112013-10-09 23:45:07 -0700391 udelay(2);
Julius Werner55009af2019-12-02 22:03:27 -0800392 clrbits32(&clk_rst->rst_dev_l, CLK_L_UARTA);
Gabe Blackd40be112013-10-09 23:45:07 -0700393}
394
Julius Werneredf6b572013-10-25 17:49:26 -0700395/* Enable output clock (CLK1~3) for external peripherals. */
396void clock_external_output(int clk_id)
397{
398 switch (clk_id) {
399 case 1:
Julius Werner55009af2019-12-02 22:03:27 -0800400 setbits32(&pmc->clk_out_cntrl, 1 << 2);
Julius Werneredf6b572013-10-25 17:49:26 -0700401 break;
402 case 2:
Julius Werner55009af2019-12-02 22:03:27 -0800403 setbits32(&pmc->clk_out_cntrl, 1 << 10);
Julius Werneredf6b572013-10-25 17:49:26 -0700404 break;
405 case 3:
Julius Werner55009af2019-12-02 22:03:27 -0800406 setbits32(&pmc->clk_out_cntrl, 1 << 18);
Julius Werneredf6b572013-10-25 17:49:26 -0700407 break;
408 default:
409 printk(BIOS_CRIT, "ERROR: Unknown output clock id %d\n",
410 clk_id);
411 break;
412 }
413}
414
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800415/* Start PLLM for SDRAM. */
416void clock_sdram(u32 m, u32 n, u32 p, u32 setup, u32 ph45, u32 ph90,
417 u32 ph135, u32 kvco, u32 kcp, u32 stable_time, u32 emc_source,
418 u32 same_freq)
419{
420 u32 misc1 = ((setup << PLLM_MISC1_SETUP_SHIFT) |
421 (ph45 << PLLM_MISC1_PD_LSHIFT_PH45_SHIFT) |
422 (ph90 << PLLM_MISC1_PD_LSHIFT_PH90_SHIFT) |
423 (ph135 << PLLM_MISC1_PD_LSHIFT_PH135_SHIFT)),
424 misc2 = ((kvco << PLLM_MISC2_KVCO_SHIFT) |
425 (kcp << PLLM_MISC2_KCP_SHIFT)),
426 base;
427
428 if (same_freq)
429 emc_source |= CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
430 else
431 emc_source &= ~CLK_SOURCE_EMC_MC_EMC_SAME_FREQ;
432
433 /*
434 * Note PLLM_BASE.PLLM_OUT1_RSTN must be in RESET_ENABLE mode, and
435 * PLLM_BASE.ENABLE must be in DISABLE state (both are the default
436 * values after coldboot reset).
437 */
438
Julius Werner2f37bd62015-02-19 14:51:15 -0800439 write32(&clk_rst->pllm_misc1, misc1);
440 write32(&clk_rst->pllm_misc2, misc2);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800441
442 /* PLLM.BASE needs BYPASS=0, different from general init_pll */
Julius Werner2f37bd62015-02-19 14:51:15 -0800443 base = read32(&clk_rst->pllm_base);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800444 base &= ~(PLLCMX_BASE_DIVN_MASK | PLLCMX_BASE_DIVM_MASK |
445 PLLM_BASE_DIVP_MASK | PLL_BASE_BYPASS);
446 base |= ((m << PLL_BASE_DIVM_SHIFT) | (n << PLL_BASE_DIVN_SHIFT) |
447 (p << PLL_BASE_DIVP_SHIFT));
Julius Werner2f37bd62015-02-19 14:51:15 -0800448 write32(&clk_rst->pllm_base, base);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800449
Julius Werner55009af2019-12-02 22:03:27 -0800450 setbits32(&clk_rst->pllm_base, PLL_BASE_ENABLE);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800451 /* stable_time is required, before we can start to check lock. */
452 udelay(stable_time);
453
Julius Werner2f37bd62015-02-19 14:51:15 -0800454 while (!(read32(&clk_rst->pllm_base) & PLL_BASE_LOCK)) {
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800455 udelay(1);
456 }
457 /*
458 * After PLLM reports being locked, we have to delay 10us before
459 * enabling PLLM_OUT.
460 */
461 udelay(10);
462
463 /* Put OUT1 out of reset state (start to output). */
Julius Werner55009af2019-12-02 22:03:27 -0800464 setbits32(&clk_rst->pllm_out, PLLM_OUT1_RSTN_RESET_DISABLE);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800465
466 /* Enable and start MEM(MC) and EMC. */
467 clock_enable_clear_reset(0, CLK_H_MEM | CLK_H_EMC, 0, 0, 0, 0);
Julius Werner2f37bd62015-02-19 14:51:15 -0800468 write32(&clk_rst->clk_src_emc, emc_source);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800469 udelay(IO_STABILIZATION_DELAY);
470}
471
Jimmy Zhangb3655302014-07-02 17:45:18 -0700472void clock_cpu0_config(void *entry)
Gabe Blackd40be112013-10-09 23:45:07 -0700473{
Elyes HAOUAS39303d52018-07-08 12:40:45 +0200474 void *const evp_cpu_reset = (uint8_t *)TEGRA_EVP_BASE + 0x100;
Gabe Blackd40be112013-10-09 23:45:07 -0700475
Julius Werner2f37bd62015-02-19 14:51:15 -0800476 write32(&maincpu_stack_pointer, (uintptr_t)_estack);
477 write32(&maincpu_entry_point, (uintptr_t)entry);
478 write32(evp_cpu_reset, (uintptr_t)&maincpu_setup);
Julius Werneredf6b572013-10-25 17:49:26 -0700479
480 /* Set active CPU cluster to G */
Julius Werner55009af2019-12-02 22:03:27 -0800481 clrbits32(&flow->cluster_control, 1);
Gabe Blackd40be112013-10-09 23:45:07 -0700482
483 // Set up cclk_brst and divider.
Julius Werner2f37bd62015-02-19 14:51:15 -0800484 write32(&clk_rst->cclk_brst_pol,
Julius Werner94184762015-02-19 20:19:23 -0800485 (CRC_CCLK_BRST_POL_PLLX_OUT0 << 0) |
486 (CRC_CCLK_BRST_POL_PLLX_OUT0 << 4) |
487 (CRC_CCLK_BRST_POL_PLLX_OUT0 << 8) |
488 (CRC_CCLK_BRST_POL_PLLX_OUT0 << 12) |
489 (CRC_CCLK_BRST_POL_CPU_STATE_RUN << 28));
Julius Werner2f37bd62015-02-19 14:51:15 -0800490 write32(&clk_rst->super_cclk_div,
491 CRC_SUPER_CCLK_DIVIDER_SUPER_CDIV_ENB);
Gabe Blackd40be112013-10-09 23:45:07 -0700492
493 // Enable the clocks for CPUs 0-3.
494 uint32_t cpu_cmplx_clr = read32(&clk_rst->clk_cpu_cmplx_clr);
495 cpu_cmplx_clr |= CRC_CLK_CLR_CPU0_STP | CRC_CLK_CLR_CPU1_STP |
496 CRC_CLK_CLR_CPU2_STP | CRC_CLK_CLR_CPU3_STP;
Julius Werner2f37bd62015-02-19 14:51:15 -0800497 write32(&clk_rst->clk_cpu_cmplx_clr, cpu_cmplx_clr);
Gabe Blackd40be112013-10-09 23:45:07 -0700498
499 // Enable other CPU related clocks.
Julius Werner55009af2019-12-02 22:03:27 -0800500 setbits32(&clk_rst->clk_out_enb_l, CLK_L_CPU);
501 setbits32(&clk_rst->clk_out_enb_v, CLK_V_CPUG);
502 setbits32(&clk_rst->clk_out_enb_v, CLK_V_CPULP);
Jimmy Zhangb3655302014-07-02 17:45:18 -0700503}
Gabe Blackd40be112013-10-09 23:45:07 -0700504
Jimmy Zhangb3655302014-07-02 17:45:18 -0700505void clock_cpu0_remove_reset(void)
506{
Gabe Blackd40be112013-10-09 23:45:07 -0700507 // Disable the reset on the non-CPU parts of the fast cluster.
Julius Werner2f37bd62015-02-19 14:51:15 -0800508 write32(&clk_rst->rst_cpug_cmplx_clr, CRC_RST_CPUG_CLR_NONCPU);
Gabe Blackd40be112013-10-09 23:45:07 -0700509 // Disable the various resets on the CPUs.
Julius Werner2f37bd62015-02-19 14:51:15 -0800510 write32(&clk_rst->rst_cpug_cmplx_clr,
Julius Werner94184762015-02-19 20:19:23 -0800511 CRC_RST_CPUG_CLR_CPU0 | CRC_RST_CPUG_CLR_CPU1 |
512 CRC_RST_CPUG_CLR_CPU2 | CRC_RST_CPUG_CLR_CPU3 |
513 CRC_RST_CPUG_CLR_DBG0 | CRC_RST_CPUG_CLR_DBG1 |
514 CRC_RST_CPUG_CLR_DBG2 | CRC_RST_CPUG_CLR_DBG3 |
515 CRC_RST_CPUG_CLR_CORE0 | CRC_RST_CPUG_CLR_CORE1 |
516 CRC_RST_CPUG_CLR_CORE2 | CRC_RST_CPUG_CLR_CORE3 |
517 CRC_RST_CPUG_CLR_CX0 | CRC_RST_CPUG_CLR_CX1 |
518 CRC_RST_CPUG_CLR_CX2 | CRC_RST_CPUG_CLR_CX3 |
519 CRC_RST_CPUG_CLR_L2 | CRC_RST_CPUG_CLR_PDBG);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800520
521 // Disable the reset on the non-CPU parts of the slow cluster.
Julius Werner2f37bd62015-02-19 14:51:15 -0800522 write32(&clk_rst->rst_cpulp_cmplx_clr, CRC_RST_CPULP_CLR_NONCPU);
Andrew Bresticker24d4f7f2013-12-18 22:41:34 -0800523 // Disable the various resets on the LP CPU.
Julius Werner2f37bd62015-02-19 14:51:15 -0800524 write32(&clk_rst->rst_cpulp_cmplx_clr,
Julius Werner94184762015-02-19 20:19:23 -0800525 CRC_RST_CPULP_CLR_CPU0 | CRC_RST_CPULP_CLR_DBG0 |
526 CRC_RST_CPULP_CLR_CORE0 | CRC_RST_CPULP_CLR_CX0 |
527 CRC_RST_CPULP_CLR_L2 | CRC_RST_CPULP_CLR_PDBG);
Gabe Blackd40be112013-10-09 23:45:07 -0700528}
529
Julius Werneredf6b572013-10-25 17:49:26 -0700530void clock_halt_avp(void)
531{
532 for (;;) {
Julius Werner2f37bd62015-02-19 14:51:15 -0800533 write32(&flow->halt_cop_events,
Julius Werner94184762015-02-19 20:19:23 -0800534 FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ |
535 FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT);
Julius Werneredf6b572013-10-25 17:49:26 -0700536 }
537}
538
Gabe Blackd40be112013-10-09 23:45:07 -0700539void clock_init(void)
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -0700540{
Gabe Blackd40be112013-10-09 23:45:07 -0700541 u32 osc = clock_get_osc_bits();
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -0700542
Gabe Blackd40be112013-10-09 23:45:07 -0700543 /* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */
Julius Werner2f37bd62015-02-19 14:51:15 -0800544 write32(&clk_rst->pllc_misc2, 0x2b << 17 | 0xb << 9);
Gabe Blackd40be112013-10-09 23:45:07 -0700545
Julius Werneredf6b572013-10-25 17:49:26 -0700546 /* Max out the AVP clock before everything else (need PLLC for that). */
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800547 init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc,
548 osc_table[osc].pllc, PLLC_MISC_LOCK_ENABLE);
Julius Werneredf6b572013-10-25 17:49:26 -0700549
550 /* Typical ratios are 1:2:2 or 1:2:3 sclk:hclk:pclk (See: APB DMA
551 * features section in the TRM). */
Julius Werner2f37bd62015-02-19 14:51:15 -0800552 write32(&clk_rst->clk_sys_rate,
Julius Werner94184762015-02-19 20:19:23 -0800553 TEGRA_HCLK_RATIO << HCLK_DIVISOR_SHIFT |
554 TEGRA_PCLK_RATIO << PCLK_DIVISOR_SHIFT);
555 write32(&clk_rst->pllc_out, CLK_DIVIDER(TEGRA_PLLC_KHZ, TEGRA_SCLK_KHZ)
556 << PLL_OUT_RATIO_SHIFT | PLL_OUT_CLKEN | PLL_OUT_RSTN);
557 write32(&clk_rst->sclk_brst_pol, /* sclk = 300 MHz */
558 SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT |
559 SCLK_SOURCE_PLLC_OUT1 << SCLK_RUN_SHIFT);
Julius Werneredf6b572013-10-25 17:49:26 -0700560
561 /* Change the oscillator drive strength (from U-Boot -- why?) */
Julius Werner55009af2019-12-02 22:03:27 -0800562 clrsetbits32(&clk_rst->osc_ctrl, OSC_XOFS_MASK,
Julius Werneredf6b572013-10-25 17:49:26 -0700563 OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
564
565 /*
566 * Ambiguous quote from u-boot. TODO: what's this mean?
567 * "should update same value in PMC_OSC_EDPD_OVER XOFS
568 * field for warmboot "
569 */
Julius Werner55009af2019-12-02 22:03:27 -0800570 clrsetbits32(&pmc->osc_edpd_over, PMC_OSC_EDPD_OVER_XOFS_MASK,
Julius Werneredf6b572013-10-25 17:49:26 -0700571 OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT);
572
573 /* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */
Julius Werner55009af2019-12-02 22:03:27 -0800574 clrbits32(&clk_rst->pllx_misc3, PLLX_IDDQ_MASK);
Julius Werneredf6b572013-10-25 17:49:26 -0700575
576 /* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */
Julius Werner2f37bd62015-02-19 14:51:15 -0800577 write32(&clk_rst->pllp_outa,
Julius Werner94184762015-02-19 20:19:23 -0800578 (CLK_DIVIDER(TEGRA_PLLP_KHZ, 9600) << PLL_OUT_RATIO_SHIFT |
579 PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT1_SHIFT |
580 (CLK_DIVIDER(TEGRA_PLLP_KHZ, 48000) << PLL_OUT_RATIO_SHIFT |
581 PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT2_SHIFT);
Julius Werner2f37bd62015-02-19 14:51:15 -0800582 write32(&clk_rst->pllp_outb,
Julius Werner94184762015-02-19 20:19:23 -0800583 (CLK_DIVIDER(TEGRA_PLLP_KHZ, 102000) << PLL_OUT_RATIO_SHIFT |
584 PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT3_SHIFT |
585 (CLK_DIVIDER(TEGRA_PLLP_KHZ, 204000) << PLL_OUT_RATIO_SHIFT |
586 PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT4_SHIFT);
Gabe Blackd40be112013-10-09 23:45:07 -0700587
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800588 /* init pllx */
589 init_pll(&clk_rst->pllx_base, &clk_rst->pllx_misc,
590 osc_table[osc].pllx, PLLPAXS_MISC_LOCK_ENABLE);
591
Jimmy Zhangc225e4c2014-02-28 17:35:48 -0800592 /* init pllu */
593 init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc,
594 osc_table[osc].pllu, PLLUD_MISC_LOCK_ENABLE);
595
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800596 init_utmip_pll();
Julius Werneredf6b572013-10-25 17:49:26 -0700597 graphics_pll();
Gabe Blackd40be112013-10-09 23:45:07 -0700598}
599
Julius Werneredf6b572013-10-25 17:49:26 -0700600void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x)
Gabe Blackd40be112013-10-09 23:45:07 -0700601{
Julius Werner2f37bd62015-02-19 14:51:15 -0800602 if (l) write32(&clk_rst->clk_enb_l_set, l);
603 if (h) write32(&clk_rst->clk_enb_h_set, h);
604 if (u) write32(&clk_rst->clk_enb_u_set, u);
605 if (v) write32(&clk_rst->clk_enb_v_set, v);
606 if (w) write32(&clk_rst->clk_enb_w_set, w);
607 if (x) write32(&clk_rst->clk_enb_x_set, x);
Gabe Blackd40be112013-10-09 23:45:07 -0700608
Hung-Te Lin2fc3b622013-10-21 21:43:03 +0800609 /* Give clocks time to stabilize. */
Gabe Blackd40be112013-10-09 23:45:07 -0700610 udelay(IO_STABILIZATION_DELAY);
611
Julius Werner2f37bd62015-02-19 14:51:15 -0800612 if (l) write32(&clk_rst->rst_dev_l_clr, l);
613 if (h) write32(&clk_rst->rst_dev_h_clr, h);
614 if (u) write32(&clk_rst->rst_dev_u_clr, u);
615 if (v) write32(&clk_rst->rst_dev_v_clr, v);
616 if (w) write32(&clk_rst->rst_dev_w_clr, w);
617 if (x) write32(&clk_rst->rst_dev_x_clr, x);
Ronald G. Minnich3eab7ed2013-10-03 17:05:55 -0700618}
Gabe Blackbab78962014-03-26 21:29:45 -0700619
620void clock_reset_l(u32 bit)
621{
Julius Werner2f37bd62015-02-19 14:51:15 -0800622 write32(&clk_rst->rst_dev_l_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700623 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800624 write32(&clk_rst->rst_dev_l_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700625}
626
627void clock_reset_h(u32 bit)
628{
Julius Werner2f37bd62015-02-19 14:51:15 -0800629 write32(&clk_rst->rst_dev_h_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700630 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800631 write32(&clk_rst->rst_dev_h_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700632}
633
634void clock_reset_u(u32 bit)
635{
Julius Werner2f37bd62015-02-19 14:51:15 -0800636 write32(&clk_rst->rst_dev_u_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700637 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800638 write32(&clk_rst->rst_dev_u_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700639}
640
641void clock_reset_v(u32 bit)
642{
Julius Werner2f37bd62015-02-19 14:51:15 -0800643 write32(&clk_rst->rst_dev_v_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700644 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800645 write32(&clk_rst->rst_dev_v_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700646}
647
648void clock_reset_w(u32 bit)
649{
Julius Werner2f37bd62015-02-19 14:51:15 -0800650 write32(&clk_rst->rst_dev_w_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700651 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800652 write32(&clk_rst->rst_dev_w_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700653}
654
655void clock_reset_x(u32 bit)
656{
Julius Werner2f37bd62015-02-19 14:51:15 -0800657 write32(&clk_rst->rst_dev_x_set, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700658 udelay(1);
Julius Werner2f37bd62015-02-19 14:51:15 -0800659 write32(&clk_rst->rst_dev_x_clr, bit);
Gabe Blackbab78962014-03-26 21:29:45 -0700660}