aboutsummaryrefslogtreecommitdiff
path: root/src/soc/nvidia/tegra124/clock.c
diff options
context:
space:
mode:
authorJulius Werner <jwerner@chromium.org>2013-10-25 17:49:26 -0700
committerIsaac Christensen <isaac.christensen@se-eng.com>2014-09-13 02:00:03 +0200
commitedf6b57f73e3cafaecd67a71fdf7313e75c1b3e8 (patch)
tree9f5e19ff61079502eea47ce321471097248a0d96 /src/soc/nvidia/tegra124/clock.c
parent75c83870e51e6bc48a83114c64177432d3204b1f (diff)
tegra124/nyan: display, clock, and other updates
tegra124: Set Tx FIFO threshold value to recommended setting Reviewed-on: https://chromium-review.googlesource.com/175200 (cherry picked from commit c8f086711c6ae2db70fc8e0d84b54f5952fbe0ad) tegra124: add CLK_X definitions Reviewed-on: https://chromium-review.googlesource.com/175220 (cherry picked from commit 3f8a844bd2f151e06d82d1a7fac4492c6bc9417d) tegra124: fix incorrect struct member in clk_rst.h Reviewed-on: https://chromium-review.googlesource.com/175270 (cherry picked from commit 967193d5984a086c297988caa580b61cb4d0414c) tegra124: add the _x clocks to clock_enable_clear_reset Reviewed-on: https://chromium-review.googlesource.com/175539 (cherry picked from commit df4c515d73b02061e5c98f51efd50e04b10d63f5) tegra124: add clock support code for graphics. Reviewed-on: https://chromium-review.googlesource.com/175162 (cherry picked from commit b8eb6ab4cdc5a583636c10fa05f947a244f94819) tegra124: Clean up some #defines for DMA Reviewed-on: https://chromium-review.googlesource.com/175631 (cherry picked from commit 1a0a900f2d060916c9878781b82113b16a7945d9) tegra124: enable flow control for APBDMA in SPI driver Reviewed-on: https://chromium-review.googlesource.com/175630 (cherry picked from commit 873e6f9e95f6cb0162fa06216682fbc71ab0202d) nyan: move clock setup for the display out of dca_init Reviewed-on: https://chromium-review.googlesource.com/175656 (cherry picked from commit 32dd9947a60298ff9488c911629802c257ed6afc) tegra124: more display PLL setup and clock hardcode removal. Reviewed-on: https://chromium-review.googlesource.com/175732 (cherry picked from commit 80402876b5daa9e9389fd4fab5f539d89c37fa7f) tegra124: move dp.c from tegra to tegra124 Reviewed-on: https://chromium-review.googlesource.com/175830 (cherry picked from commit e98be569b0ba7f4d565ce677343a317db08344e0) tegra124: clean up tabbing; nyan: add a comment and setting to devicetree.cb Reviewed-on: https://chromium-review.googlesource.com/175889 (cherry picked from commit 4e513196b0014c5a82079f3aa87c2efbeb645484) tegra: get rid of struct members that are not used Reviewed-on: https://chromium-review.googlesource.com/176023 (cherry picked from commit 032b8a0c9fe0152ebc27344e93128865ecb918a6) tegra124: Increase SCLK (AVP) to 300MHz Reviewed-on: https://chromium-review.googlesource.com/175489 (cherry picked from commit 7e082f2c2f030950d652f1f87f637e15dee38552) tegra124: Address old main CPU starting review feedback. Reviewed-on: https://chromium-review.googlesource.com/175933 (cherry picked from commit 1d76ac71bd839dff9198e65132ec25212dd55ffd) tegra124: Revise clock source configuration for irregular peripherals. Reviewed-on: https://chromium-review.googlesource.com/176109 (cherry picked from commit 1021c215190602a2b8c1ab97d6c8313d89597d99) nyan: add timestamps in romstage Reviewed-on: https://chromium-review.googlesource.com/176172 (cherry picked from commit cd626aa10b56cd4da6ebda36fe487e44b08f3935) tegra124: Allow enabling clock output for external peripherals. Reviewed-on: https://chromium-review.googlesource.com/176108 (cherry picked from commit ea9fb6393ee80da77c9fbc30f605859c7009c9ed) nyan: Enable and configure clocks for I2S and audio codec. Reviewed-on: https://chromium-review.googlesource.com/176104 (cherry picked from commit 1fb659b3e73285ff8218c0f229734edd3b979ca4) tegra124: Fix typo in pinmux name. Reviewed-on: https://chromium-review.googlesource.com/176215 (cherry picked from commit c7915ad41a3f1d1452aa6d6d287aaa8eb9e85c34) nyan: Add pinmux settings for audio peripherals. Reviewed-on: https://chromium-review.googlesource.com/176212 (cherry picked from commit 37412f3201590e47a06d4678fa833164d370b41c) nyan: De-array-ify the PMIC setup code. Reviewed-on: https://chromium-review.googlesource.com/176903 (cherry picked from commit 86ab1ce9fbf6d5362af1ee37de1394412366f247) nyan: Add a kconfig for building for the original nyans in pixel cases. Reviewed-on: https://chromium-review.googlesource.com/176904 (cherry picked from commit 1d05fd5bc40d727826510ec81496ce4a49e257ed) nyan: Set the CPU voltage differently depending on which PMIC is in use. Reviewed-on: https://chromium-review.googlesource.com/176905 (cherry picked from commit 31507f6a575220737ee5683b312cd162600f89cc) nyan: Increase the CPU voltage to 1.2V. Reviewed-on: https://chromium-review.googlesource.com/176906 (cherry picked from commit fe4795e66b515c2523df09a8800ecac9a3f63557) tegra124: Flesh out/tidy up the flow controller constants. Reviewed-on: https://chromium-review.googlesource.com/177085 (cherry picked from commit b50d315506a5ab9c81b6bbaf8cf580dbb3e78794) tegra124: When leaving the bootblock/AVP, really stop the AVP. Reviewed-on: https://chromium-review.googlesource.com/177086 (cherry picked from commit 06c10df889d4d935bc99792df860d93766ae44dd) nyan: Set SPI4 speed to 33MHz Reviewed-on: https://chromium-review.googlesource.com/177038 (cherry picked from commit c98de65482fabdb5c76944fe3bf762191b3a0a55) nyan: Do console_init() in romstage Reviewed-on: https://chromium-review.googlesource.com/176763 (cherry picked from commit 0bec32e09eab28bc5ea49b7896a8b6f489143b03) nyan: Add a prompt to the CONFIG_NYAN_IN_A_PIXEL option. Reviewed-on: https://chromium-review.googlesource.com/177486 (cherry picked from commit 7cbb801d000dac4b39f76266ebef2585fe48faba) nyan: Separate the SDRAM BCT config for the two nyans, and turn down norrin. Reviewed-on: https://chromium-review.googlesource.com/177487 (cherry picked from commit 6b119685f6626d79d924af9f856ebb90af45a73f) tegra124: Bump up HCLK and PCLK Reviewed-on: https://chromium-review.googlesource.com/177563 (cherry picked from commit c25337dac8c3ecdd8ffe5b4d11acebb216132405) nyan: Add some code for reading the board ID. Reviewed-on: https://chromium-review.googlesource.com/177488 (cherry picked from commit 5fccbce99e7db312e2e3caf806c438c9b04c0a8f) nyan: Use the board ID to decide how to initialize the PMIC. Reviewed-on: https://chromium-review.googlesource.com/177489 (cherry picked from commit 677bdb9df55248da3a0c6be0089098f6d6807d3c) nyan: Create kconfig variables for each SDRAM config. Reviewed-on: https://chromium-review.googlesource.com/177580 (cherry picked from commit d7ddcf262a321f06289c4f2b2a6b43982dd96377) tegra124: Mux some unused pins away from UARTA, and pull up the serial RX line. Reviewed-on: https://chromium-review.googlesource.com/177637 (cherry picked from commit bd533cc109b0acf3495b04fa6622e250ba454fe9) tegra124: Initialize the MCR when setting up the UART. Reviewed-on: https://chromium-review.googlesource.com/177638 (cherry picked from commit 38c84786fc3e8fab913aebca176ac7b038cb0be6) tegra124: fix SPI AHB burst length Reviewed-on: https://chromium-review.googlesource.com/177564 (cherry picked from commit f29235263202c9b4a3dbb65da5727c8eefe44315) tegra124: remove unneeded debug print in SPI code Reviewed-on: https://chromium-review.googlesource.com/177833 (cherry picked from commit 34a50040268dbde1c326d315f8042a3905ddfb06) nyan: Set up the SOC and TPM reset pin. Reviewed-on: https://chromium-review.googlesource.com/177965 (cherry picked from commit b81a5bd15a2979ee009b9f7bc4a39a304e6a759a) tegra124: Allow some time for packets to appear in Rx FIFO Reviewed-on: https://chromium-review.googlesource.com/177832 (cherry picked from commit 8f70a25b1eea865a448525749ac18393f5b9ad84) nyan: PMIC: Slam default init values for SDOs/LDOs in AS3722 Reviewed-on: https://chromium-review.googlesource.com/178226 (cherry picked from commit c536b0d82fd6fffbc0e2448e0d19d3f06df5d86a) nyan: change devicetree for the new display settings. Reviewed-on: https://chromium-review.googlesource.com/177958 (cherry picked from commit 43abed730f222c8a685c250a58c981268994a65d) nyan: Switch USB VBUS GPIOs from outputs to pulled-up inputs Reviewed-on: https://chromium-review.googlesource.com/178914 (cherry picked from commit e47b6a609b9d23694a466b56960d9d14ca5d6242) Tegra124: nyan: Disable VPR Reviewed-on: https://chromium-review.googlesource.com/179327 (cherry picked from commit 441aa276446141f1b92ed8fb98c9578597487f4d) tegra124: norrin: fix display issue Reviewed-on: https://chromium-review.googlesource.com/179745 (cherry picked from commit c1c1ae69f6058ed901f532e2c532d1e6ba1f81fb) tegra124: Add iRAM layout information. Reviewed-on: https://chromium-review.googlesource.com/179814 (cherry picked from commit d00f135c93a52ad4dced2edecb74e2dfc54bb2fa) tegra124: Run bootblock and ROM stage out of DRAM. Reviewed-on: https://chromium-review.googlesource.com/179822 (cherry picked from commit 2d3ec06ec39a489d02e798bb22bce4d7465b20ce) nyan: clean up a comment regarding video Reviewed-on: https://chromium-review.googlesource.com/180161 (cherry picked from commit 03b5e88a66b9c96df2ef3d9ce5ba4a62a8bb2447) tegra124: norrin: the first step to clean up display code Reviewed-on: https://chromium-review.googlesource.com/180135 (cherry picked from commit 9d0c12dfef28a1161604df9b3fcc113049b2747d) Squashed 49 commits for tegra124/nyan. Change-Id: Id67bfee725e703d3e2d8ac17f40844dc193e901d Signed-off-by: Isaac Christensen <isaac.christensen@se-eng.com> Reviewed-on: http://review.coreboot.org/6883 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/soc/nvidia/tegra124/clock.c')
-rw-r--r--src/soc/nvidia/tegra124/clock.c228
1 files changed, 157 insertions, 71 deletions
diff --git a/src/soc/nvidia/tegra124/clock.c b/src/soc/nvidia/tegra124/clock.c
index 5298ce820f..d98da29469 100644
--- a/src/soc/nvidia/tegra124/clock.c
+++ b/src/soc/nvidia/tegra124/clock.c
@@ -20,8 +20,8 @@
#include <soc/clock.h>
#include <stdlib.h>
#include "clk_rst.h"
-#include "cpug.h"
#include "flow.h"
+#include "maincpu.h"
#include "pmc.h"
#include "sysctr.h"
@@ -79,7 +79,8 @@ union __attribute__((transparent_union)) pll_fields {
/* This table defines the frequency dividers for every PLL to turn the external
* OSC clock into the frequencies defined by TEGRA_PLL*_KHZ in soc/clock.h.
* All PLLs have three dividers (N, M and P), with the governing formula for
- * the output frequency being OUT = (IN / m) * N / (2^P). */
+ * the output frequency being OUT = (IN / m) * N / (2^P).
+ * Yes, it really is one equation with three unknowns ... */
struct {
int khz;
struct pllcx_dividers pllx; /* target: 1900 MHz */
@@ -87,62 +88,78 @@ struct {
struct pllcx_dividers pllc; /* target: 600 MHz */
struct pllpad_dividers plld; /* target: 925 MHz */
struct pllu_dividers pllu; /* target; 960 MHz */
+ struct pllcx_dividers plldp; /* target; 270 MHz */
+ struct pllcx_dividers plld2; /* target; 570 MHz */
} static const osc_table[16] = {
[OSC_FREQ_OSC12]{
.khz = 12000,
.pllx = {.n = 158, .m = 1, .p = 0}, /* 1896 MHz */
.pllp = {.n = 34, .m = 1, .p = 0, .cpcon = 2},
.pllc = {.n = 50, .m = 1, .p = 0},
- .plld = {.n = 925, .m = 12, .p = 0, .cpcon = 12},
+ .plld = {.n = 283, .m = 12, .p = 0, .cpcon = 8}, /* 283 MHz */
.pllu = {.n = 80, .m = 1, .p = 0, .cpcon = 3},
+ .plldp = {.n = 90, .m = 1, .p = 3}, /* 270 MHz */
+ .plld2 = {.n = 95, .m = 1, .p = 1}, /* 570 MHz */
},
[OSC_FREQ_OSC13]{
.khz = 13000,
.pllx = {.n = 146, .m = 1, .p = 0}, /* 1898 MHz */
.pllp = {.n = 408, .m = 13, .p = 0, .cpcon = 8},
.pllc = {.n = 231, .m = 5, .p = 0}, /* 600.6 MHz */
- .plld = {.n = 925, .m = 13, .p = 0, .cpcon = 12},
+ .plld = {.n = 283, .m = 13, .p = 0, .cpcon = 8}, /* 283 MHz*/
.pllu = {.n = 960, .m = 13, .p = 0, .cpcon = 12},
+ .plldp = {.n = 83, .m = 1, .p = 3}, /* 269.75 MHz */
+ .plld2 = {.n = 88, .m = 1, .p = 1}, /* 572 MHz */
},
[OSC_FREQ_OSC16P8]{
.khz = 16800,
.pllx = {.n = 113, .m = 1, .p = 0}, /* 1898.4 MHz */
.pllp = {.n = 170, .m = 7, .p = 0, .cpcon = 4},
.pllc = {.n = 250, .m = 7, .p = 0},
- .plld = {.n = 936, .m = 17, .p = 0, .cpcon = 12},/* 924.9 MHz */
+ .plld = {.n = 286, .m = 17, .p = 0, .cpcon = 8}, /* 282.6 MHz*/
.pllu = {.n = 400, .m = 7, .p = 0, .cpcon = 8},
+ .plldp = {.n = 64, .m = 1, .p = 3}, /* 268.8 MHz */
+ .plld2 = {.n = 68, .m = 1, .p = 1}, /* 571.2 MHz */
},
[OSC_FREQ_OSC19P2]{
.khz = 19200,
.pllx = {.n = 98, .m = 1, .p = 0}, /* 1881.6 MHz */
.pllp = {.n = 85, .m = 4, .p = 0, .cpcon = 3},
.pllc = {.n = 125, .m = 4, .p = 0},
- .plld = {.n = 819, .m = 17, .p = 0, .cpcon = 12},/* 924.9 MHz */
+ .plld = {.n = 251, .m = 17, .p = 0, .cpcon = 8}, /* 283.5 MHz */
.pllu = {.n = 50, .m = 1, .p = 0, .cpcon = 2},
+ .plldp = {.n = 56, .m = 1, .p = 3}, /* 270.75 MHz */
+ .plld2 = {.n = 59, .m = 1, .p = 1}, /* 570 MHz */
},
[OSC_FREQ_OSC26]{
.khz = 26000,
.pllx = {.n = 73, .m = 1, .p = 0}, /* 1898 MHz */
.pllp = {.n = 204, .m = 13, .p = 0, .cpcon = 5},
.pllc = {.n = 23, .m = 1, .p = 0}, /* 598 MHz */
- .plld = {.n = 925, .m = 26, .p = 0, .cpcon = 12},
+ .plld = {.n = 283, .m = 26, .p = 0, .cpcon = 8}, /* 283 MHz */
.pllu = {.n = 480, .m = 13, .p = 0, .cpcon = 8},
+ .plldp = {.n = 83, .m = 2, .p = 3}, /* 266.50 MHz */
+ .plld2 = {.n = 88, .m = 2, .p = 1}, /* 570 MHz */
},
[OSC_FREQ_OSC38P4]{
.khz = 38400,
.pllx = {.n = 98, .m = 1, .p = 0}, /* 1881.6 MHz */
.pllp = {.n = 85, .m = 4, .p = 0, .cpcon = 3},
.pllc = {.n = 125, .m = 4, .p = 0},
- .plld = {.n = 819, .m = 17, .p = 0, .cpcon = 12},/* 924.9 MHz */
+ .plld = {.n = 125, .m = 17, .p = 0, .cpcon = 8}, /* 282.4 MHz */
.pllu = {.n = 50, .m = 1, .p = 0, .cpcon = 2},
+ .plldp = {.n = 56, .m = 2, .p = 3}, /* 268 MHz */
+ .plld2 = {.n = 59, .m = 2, .p = 1}, /* 566 MHz */
},
[OSC_FREQ_OSC48]{
.khz = 48000,
.pllx = {.n = 158, .m = 1, .p = 0}, /* 1896 MHz */
.pllp = {.n = 24, .m = 1, .p = 0, .cpcon = 2},
.pllc = {.n = 50, .m = 1, .p = 0},
- .plld = {.n = 925, .m = 12, .p = 0, .cpcon = 12},
+ .plld = {.n = 71, .m = 12, .p = 0, .cpcon = 8}, /* 284 MHz */
.pllu = {.n = 80, .m = 1, .p = 0, .cpcon = 3},
+ .plldp = {.n = 90, .m = 4, .p = 3}, /* 264 MHz */
+ .plld2 = {.n = 95, .m = 4, .p = 1}, /* 570 MHz */
},
};
@@ -174,19 +191,23 @@ void clock_init_arm_generic_timer(void)
write32(cntcr, &sysctr->cntcr);
}
-static void adjust_pllp_out_freqs(void)
+#define SOR0_CLK_SEL0 (1 << 14)
+#define SOR0_CLK_SEL1 (1 << 15)
+
+void sor_clock_stop(void)
+{
+ /* The Serial Output Resource clock has to be off
+ * before we start the plldp. Learned the hard way.
+ * FIXME: this has to be cleaned up a bit more.
+ * Waiting on some new info from Nvidia.
+ */
+ clrbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0 | SOR0_CLK_SEL1);
+}
+
+void sor_clock_start(void)
{
- u32 reg;
- /* Set T30 PLLP_OUT1, 2, 3 & 4 freqs to 9.6, 48, 102 & 204MHz */
- reg = readl(&clk_rst->pllp_outa); // OUTA contains OUT2 / OUT1
- reg |= (IN_408_OUT_48_DIVISOR << PLLP_OUT2_RATIO) | PLLP_OUT2_OVR
- | (IN_408_OUT_9_6_DIVISOR << PLLP_OUT1_RATIO) | PLLP_OUT1_OVR;
- writel(reg, &clk_rst->pllp_outa);
-
- reg = readl(&clk_rst->pllp_outb); // OUTB, contains OUT4 / OUT3
- reg |= (IN_408_OUT_204_DIVISOR << PLLP_OUT4_RATIO) | PLLP_OUT4_OVR
- | (IN_408_OUT_102_DIVISOR << PLLP_OUT3_RATIO) | PLLP_OUT3_OVR;
- writel(reg, &clk_rst->pllp_outb);
+ /* uses PLLP, has a non-standard bit layout. */
+ setbits_le32(&clk_rst->clk_src_sor, SOR0_CLK_SEL0);
}
static void init_pll(u32 *base, u32 *misc, const union pll_fields pll)
@@ -197,7 +218,6 @@ static void init_pll(u32 *base, u32 *misc, const union pll_fields pll)
/* Write dividers but BYPASS the PLL while we're messing with it. */
writel(dividers | PLL_BASE_BYPASS, base);
-
/* Set CPCON field (defaults to 0 if it doesn't exist for this PLL) */
writel(pll.div.cpcon << PLL_MISC_CPCON_SHIFT, misc);
@@ -237,6 +257,41 @@ static void init_utmip_pll(void)
setbits_le32(&clk_rst->utmip_pll_cfg2, 1 << 30); /* PHY_XTAL_CLKEN */
}
+/* Graphics just has to be different. There's a few more bits we
+ * need to set in here, but it makes sense just to restrict all the
+ * special bits to this one function.
+ */
+static void graphics_pll(void)
+{
+ int osc = clock_get_osc_bits();
+ u32 *cfg = &clk_rst->plldp_ss_cfg;
+ /* the vendor code sets the dither bit (28)
+ * an undocumented bit (24)
+ * and clamp while we mess with it (22)
+ * Dither is pretty important to display port
+ * so we really do need to handle these bits.
+ * I'm not willing to not clamp it, even if
+ * it might "mostly work" with it not set,
+ * I don't want to find out in a few months
+ * that it is needed.
+ */
+ u32 scfg = (1<<28) | (1<<24) | (1<<22);
+ writel(scfg, cfg);
+ init_pll(&clk_rst->plldp_base, &clk_rst->plldp_misc, osc_table[osc].plldp);
+ /* leave dither and undoc bits set, release clamp */
+ scfg = (1<<28) | (1<<24);
+ writel(scfg, cfg);
+ /* set lock bit */
+ setbits_le32(&clk_rst->plldp_misc, PLLDPD2_MISC_LOCK_ENABLE);
+
+ /* init clock source for disp1 */
+ /* init plld (the actual output is plld_out0 that is 1/2 of plld. */
+ init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, osc_table[osc].plld);
+ setbits_le32(&clk_rst->plld_misc, PLLUD_MISC_LOCK_ENABLE);
+ setbits_le32(&clk_rst->plld_misc, PLLD_MISC_CLK_ENABLE);
+ udelay(10); /* wait for plld ready */
+}
+
/* Initialize the UART and put it on CLK_M so we can use it during clock_init().
* Will later move it to PLLP in clock_config(). The divisor must be very small
* to accomodate 12KHz OSCs, so we override the 16.0 UART divider with the 15.1
@@ -252,13 +307,36 @@ void clock_early_uart(void)
clrbits_le32(&clk_rst->rst_dev_l, CLK_L_UARTA);
}
+/* Enable output clock (CLK1~3) for external peripherals. */
+void clock_external_output(int clk_id)
+{
+ switch (clk_id) {
+ case 1:
+ setbits_le32(&pmc->clk_out_cntrl, 1 << 2);
+ break;
+ case 2:
+ setbits_le32(&pmc->clk_out_cntrl, 1 << 10);
+ break;
+ case 3:
+ setbits_le32(&pmc->clk_out_cntrl, 1 << 18);
+ break;
+ default:
+ printk(BIOS_CRIT, "ERROR: Unknown output clock id %d\n",
+ clk_id);
+ break;
+ }
+}
+
void clock_cpu0_config_and_reset(void *entry)
{
void * const evp_cpu_reset = (uint8_t *)TEGRA_EVP_BASE + 0x100;
- write32(CONFIG_STACK_TOP, &cpug_stack_pointer);
- write32((uintptr_t)entry, &cpug_entry_point);
- write32((uintptr_t)&cpug_setup, evp_cpu_reset);
+ write32(CONFIG_STACK_TOP, &maincpu_stack_pointer);
+ write32((uintptr_t)entry, &maincpu_entry_point);
+ write32((uintptr_t)&maincpu_setup, evp_cpu_reset);
+
+ /* Set active CPU cluster to G */
+ clrbits_le32(&flow->cluster_control, 1);
// Set up cclk_brst and divider.
write32((CRC_CCLK_BRST_POL_PLLX_OUT0 << 0) |
@@ -296,75 +374,82 @@ void clock_cpu0_config_and_reset(void *entry)
&clk_rst->rst_cpug_cmplx_clr);
}
-/**
- * The T124 requires some special clock initialization, including setting up
- * the DVC I2C, turning on MSELECT and selecting the G CPU cluster
- */
+void clock_halt_avp(void)
+{
+ for (;;) {
+ write32(FLOW_EVENT_JTAG | FLOW_EVENT_LIC_IRQ |
+ FLOW_EVENT_GIC_IRQ | FLOW_MODE_WAITEVENT,
+ &flow->halt_cop_events);
+ }
+}
+
void clock_init(void)
{
- u32 val;
u32 osc = clock_get_osc_bits();
- /*
- * On poweron, AVP clock source (also called system clock) is set to
- * PLLP_out0 with frequency set at 1MHz. Before initializing PLLP, we
- * need to move the system clock's source to CLK_M temporarily. And
- * then switch it to PLLP_out4 (204MHz) at a later time.
- */
- val = (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_FIQ_SOURCE_SHIFT) |
- (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_IRQ_SOURCE_SHIFT) |
- (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_RUN_SOURCE_SHIFT) |
- (SCLK_SOURCE_CLKM << SCLK_SWAKEUP_IDLE_SOURCE_SHIFT) |
- (SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT);
- writel(val, &clk_rst->sclk_brst_pol);
- udelay(2);
+ /* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */
+ writel(0x2b << 17 | 0xb << 9, &clk_rst->pllc_misc2);
- /* Set active CPU cluster to G */
- clrbits_le32(&flow->cluster_control, 1);
+ /* Max out the AVP clock before everything else (need PLLC for that). */
+ init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc, osc_table[osc].pllc);
- /* Change the oscillator drive strength */
- val = readl(&clk_rst->osc_ctrl);
- val &= ~OSC_XOFS_MASK;
- val |= (OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
- writel(val, &clk_rst->osc_ctrl);
+ /* Be more careful with processor clock, wait for the lock. (~10us) */
+ setbits_le32(&clk_rst->pllc_misc, PLLC_MISC_LOCK_ENABLE);
+ while (!(read32(&clk_rst->pllc_base) & PLL_BASE_LOCK)) /* wait */;
+
+ /* Typical ratios are 1:2:2 or 1:2:3 sclk:hclk:pclk (See: APB DMA
+ * features section in the TRM). */
+ write32(1 << HCLK_DIVISOR_SHIFT | 0 << PCLK_DIVISOR_SHIFT,
+ &clk_rst->clk_sys_rate); /* pclk = hclk = sclk/2 */
+ write32(0 << SCLK_DIVIDEND_SHIFT |
+ (CEIL_DIV(TEGRA_PLLC_KHZ, 300000) - 1) << SCLK_DIVISOR_SHIFT
+ | SCLK_DIV_ENB, &clk_rst->super_sclk_div);
+ write32(SCLK_SYS_STATE_RUN << SCLK_SYS_STATE_SHIFT |
+ SCLK_SOURCE_PLLC_OUT0 << SCLK_RUN_SHIFT,
+ &clk_rst->sclk_brst_pol); /* sclk = 300 MHz */
+
+ /* Change the oscillator drive strength (from U-Boot -- why?) */
+ clrsetbits_le32(&clk_rst->osc_ctrl, OSC_XOFS_MASK,
+ OSC_DRIVE_STRENGTH << OSC_XOFS_SHIFT);
- /* Ambiguous quote from u-boot. TODO: what's this mean?
+ /*
+ * Ambiguous quote from u-boot. TODO: what's this mean?
* "should update same value in PMC_OSC_EDPD_OVER XOFS
- field for warmboot "*/
- val = readl(&pmc->osc_edpd_over);
- val &= ~PMC_OSC_EDPD_OVER_XOFS_MASK;
- val |= (OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT);
- writel(val, &pmc->osc_edpd_over);
+ * field for warmboot "
+ */
+ clrsetbits_le32(&pmc->osc_edpd_over, PMC_OSC_EDPD_OVER_XOFS_MASK,
+ OSC_DRIVE_STRENGTH << PMC_OSC_EDPD_OVER_XOFS_SHIFT);
/* Disable IDDQ for PLLX before we set it up (from U-Boot -- why?) */
- val = readl(&clk_rst->pllx_misc3);
- val &= ~PLLX_IDDQ_MASK;
- writel(val, &clk_rst->pllx_misc3);
- udelay(2);
-
- /* Set PLLC dynramp_step A to 0x2b and B to 0xb (from U-Boot -- why? */
- writel(0x2b << 17 | 0xb << 9, &clk_rst->pllc_misc2);
-
- adjust_pllp_out_freqs();
+ clrbits_le32(&clk_rst->pllx_misc3, PLLX_IDDQ_MASK);
+
+ /* Set up PLLP_OUT(1|2|3|4) divisor to generate (9.6|48|102|204)MHz */
+ write32((CLK_DIVIDER(TEGRA_PLLP_KHZ, 9600) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT1_SHIFT |
+ (CLK_DIVIDER(TEGRA_PLLP_KHZ, 48000) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT2_SHIFT,
+ &clk_rst->pllp_outa);
+ write32((CLK_DIVIDER(TEGRA_PLLP_KHZ, 102000) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT3_SHIFT |
+ (CLK_DIVIDER(TEGRA_PLLP_KHZ, 204000) << PLL_OUT_RATIO_SHIFT |
+ PLL_OUT_OVR | PLL_OUT_CLKEN | PLL_OUT_RSTN) << PLL_OUT4_SHIFT,
+ &clk_rst->pllp_outb);
init_pll(&clk_rst->pllx_base, &clk_rst->pllx_misc, osc_table[osc].pllx);
init_pll(&clk_rst->pllp_base, &clk_rst->pllp_misc, osc_table[osc].pllp);
- init_pll(&clk_rst->pllc_base, &clk_rst->pllc_misc, osc_table[osc].pllc);
- init_pll(&clk_rst->plld_base, &clk_rst->plld_misc, osc_table[osc].plld);
init_pll(&clk_rst->pllu_base, &clk_rst->pllu_misc, osc_table[osc].pllu);
init_utmip_pll();
-
- val = (1 << CLK_SYS_RATE_AHB_RATE_SHIFT);
- writel(val, &clk_rst->clk_sys_rate);
+ graphics_pll();
}
-void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w)
+void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w, u32 x)
{
if (l) writel(l, &clk_rst->clk_enb_l_set);
if (h) writel(h, &clk_rst->clk_enb_h_set);
if (u) writel(u, &clk_rst->clk_enb_u_set);
if (v) writel(v, &clk_rst->clk_enb_v_set);
if (w) writel(w, &clk_rst->clk_enb_w_set);
+ if (x) writel(x, &clk_rst->clk_enb_x_set);
/* Give clocks time to stabilize. */
udelay(IO_STABILIZATION_DELAY);
@@ -374,4 +459,5 @@ void clock_enable_clear_reset(u32 l, u32 h, u32 u, u32 v, u32 w)
if (u) writel(u, &clk_rst->rst_dev_u_clr);
if (v) writel(v, &clk_rst->rst_dev_v_clr);
if (w) writel(w, &clk_rst->rst_dev_w_clr);
+ if (x) writel(x, &clk_rst->rst_dev_x_clr);
}