From edf6b57f73e3cafaecd67a71fdf7313e75c1b3e8 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Fri, 25 Oct 2013 17:49:26 -0700 Subject: 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 Reviewed-on: http://review.coreboot.org/6883 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/soc/nvidia/tegra124/clock.c | 228 +++++++++++++++++++++++++++------------- 1 file changed, 157 insertions(+), 71 deletions(-) (limited to 'src/soc/nvidia/tegra124/clock.c') 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 #include #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); } -- cgit v1.2.3