109f455dcSMasahiro Yamada /* 209f455dcSMasahiro Yamada * Copyright (c) 2011 The Chromium OS Authors. 3722e000cSTom Warren * (C) Copyright 2010-2015 4722e000cSTom Warren * NVIDIA Corporation <www.nvidia.com> 509f455dcSMasahiro Yamada * 609f455dcSMasahiro Yamada * SPDX-License-Identifier: GPL-2.0+ 709f455dcSMasahiro Yamada */ 809f455dcSMasahiro Yamada 909f455dcSMasahiro Yamada /* Tegra20 Clock control functions */ 1009f455dcSMasahiro Yamada 1109f455dcSMasahiro Yamada #include <common.h> 1209f455dcSMasahiro Yamada #include <errno.h> 1309f455dcSMasahiro Yamada #include <asm/io.h> 1409f455dcSMasahiro Yamada #include <asm/arch/clock.h> 1509f455dcSMasahiro Yamada #include <asm/arch/tegra.h> 1609f455dcSMasahiro Yamada #include <asm/arch-tegra/clk_rst.h> 1709f455dcSMasahiro Yamada #include <asm/arch-tegra/timer.h> 1809f455dcSMasahiro Yamada #include <div64.h> 1909f455dcSMasahiro Yamada #include <fdtdec.h> 2009f455dcSMasahiro Yamada 2109f455dcSMasahiro Yamada /* 2209f455dcSMasahiro Yamada * Clock types that we can use as a source. The Tegra20 has muxes for the 2309f455dcSMasahiro Yamada * peripheral clocks, and in most cases there are four options for the clock 2409f455dcSMasahiro Yamada * source. This gives us a clock 'type' and exploits what commonality exists 2509f455dcSMasahiro Yamada * in the device. 2609f455dcSMasahiro Yamada * 2709f455dcSMasahiro Yamada * Letters are obvious, except for T which means CLK_M, and S which means the 2809f455dcSMasahiro Yamada * clock derived from 32KHz. Beware that CLK_M (also called OSC in the 2909f455dcSMasahiro Yamada * datasheet) and PLL_M are different things. The former is the basic 3009f455dcSMasahiro Yamada * clock supplied to the SOC from an external oscillator. The latter is the 3109f455dcSMasahiro Yamada * memory clock PLL. 3209f455dcSMasahiro Yamada * 3309f455dcSMasahiro Yamada * See definitions in clock_id in the header file. 3409f455dcSMasahiro Yamada */ 3509f455dcSMasahiro Yamada enum clock_type_id { 3609f455dcSMasahiro Yamada CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ 3709f455dcSMasahiro Yamada CLOCK_TYPE_MCPA, /* and so on */ 3809f455dcSMasahiro Yamada CLOCK_TYPE_MCPT, 3909f455dcSMasahiro Yamada CLOCK_TYPE_PCM, 4009f455dcSMasahiro Yamada CLOCK_TYPE_PCMT, 4109f455dcSMasahiro Yamada CLOCK_TYPE_PCMT16, /* CLOCK_TYPE_PCMT with 16-bit divider */ 4209f455dcSMasahiro Yamada CLOCK_TYPE_PCXTS, 4309f455dcSMasahiro Yamada CLOCK_TYPE_PDCT, 4409f455dcSMasahiro Yamada 4509f455dcSMasahiro Yamada CLOCK_TYPE_COUNT, 4609f455dcSMasahiro Yamada CLOCK_TYPE_NONE = -1, /* invalid clock type */ 4709f455dcSMasahiro Yamada }; 4809f455dcSMasahiro Yamada 4909f455dcSMasahiro Yamada enum { 5009f455dcSMasahiro Yamada CLOCK_MAX_MUX = 4 /* number of source options for each clock */ 5109f455dcSMasahiro Yamada }; 5209f455dcSMasahiro Yamada 5309f455dcSMasahiro Yamada /* 5409f455dcSMasahiro Yamada * Clock source mux for each clock type. This just converts our enum into 5509f455dcSMasahiro Yamada * a list of mux sources for use by the code. Note that CLOCK_TYPE_PCXTS 5609f455dcSMasahiro Yamada * is special as it has 5 sources. Since it also has a different number of 5709f455dcSMasahiro Yamada * bits in its register for the source, we just handle it with a special 5809f455dcSMasahiro Yamada * case in the code. 5909f455dcSMasahiro Yamada */ 6009f455dcSMasahiro Yamada #define CLK(x) CLOCK_ID_ ## x 6109f455dcSMasahiro Yamada static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX] = { 6209f455dcSMasahiro Yamada { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC) }, 6309f455dcSMasahiro Yamada { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO) }, 6409f455dcSMasahiro Yamada { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC) }, 6509f455dcSMasahiro Yamada { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE) }, 6609f455dcSMasahiro Yamada { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, 6709f455dcSMasahiro Yamada { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC) }, 6809f455dcSMasahiro Yamada { CLK(PERIPH), CLK(CGENERAL), CLK(XCPU), CLK(OSC) }, 6909f455dcSMasahiro Yamada { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC) }, 7009f455dcSMasahiro Yamada }; 7109f455dcSMasahiro Yamada 7209f455dcSMasahiro Yamada /* 7309f455dcSMasahiro Yamada * Clock peripheral IDs which sadly don't match up with PERIPH_ID. This is 7409f455dcSMasahiro Yamada * not in the header file since it is for purely internal use - we want 7509f455dcSMasahiro Yamada * callers to use the PERIPH_ID for all access to peripheral clocks to avoid 7609f455dcSMasahiro Yamada * confusion bewteen PERIPH_ID_... and PERIPHC_... 7709f455dcSMasahiro Yamada * 7809f455dcSMasahiro Yamada * We don't call this CLOCK_PERIPH_ID or PERIPH_CLOCK_ID as it would just be 7909f455dcSMasahiro Yamada * confusing. 8009f455dcSMasahiro Yamada * 8109f455dcSMasahiro Yamada * Note to SOC vendors: perhaps define a unified numbering for peripherals and 8209f455dcSMasahiro Yamada * use it for reset, clock enable, clock source/divider and even pinmuxing 8309f455dcSMasahiro Yamada * if you can. 8409f455dcSMasahiro Yamada */ 8509f455dcSMasahiro Yamada enum periphc_internal_id { 8609f455dcSMasahiro Yamada /* 0x00 */ 8709f455dcSMasahiro Yamada PERIPHC_I2S1, 8809f455dcSMasahiro Yamada PERIPHC_I2S2, 8909f455dcSMasahiro Yamada PERIPHC_SPDIF_OUT, 9009f455dcSMasahiro Yamada PERIPHC_SPDIF_IN, 9109f455dcSMasahiro Yamada PERIPHC_PWM, 9209f455dcSMasahiro Yamada PERIPHC_SPI1, 9309f455dcSMasahiro Yamada PERIPHC_SPI2, 9409f455dcSMasahiro Yamada PERIPHC_SPI3, 9509f455dcSMasahiro Yamada 9609f455dcSMasahiro Yamada /* 0x08 */ 9709f455dcSMasahiro Yamada PERIPHC_XIO, 9809f455dcSMasahiro Yamada PERIPHC_I2C1, 9909f455dcSMasahiro Yamada PERIPHC_DVC_I2C, 10009f455dcSMasahiro Yamada PERIPHC_TWC, 10109f455dcSMasahiro Yamada PERIPHC_0c, 10209f455dcSMasahiro Yamada PERIPHC_10, /* PERIPHC_SPI1, what is this really? */ 10309f455dcSMasahiro Yamada PERIPHC_DISP1, 10409f455dcSMasahiro Yamada PERIPHC_DISP2, 10509f455dcSMasahiro Yamada 10609f455dcSMasahiro Yamada /* 0x10 */ 10709f455dcSMasahiro Yamada PERIPHC_CVE, 10809f455dcSMasahiro Yamada PERIPHC_IDE0, 10909f455dcSMasahiro Yamada PERIPHC_VI, 11009f455dcSMasahiro Yamada PERIPHC_1c, 11109f455dcSMasahiro Yamada PERIPHC_SDMMC1, 11209f455dcSMasahiro Yamada PERIPHC_SDMMC2, 11309f455dcSMasahiro Yamada PERIPHC_G3D, 11409f455dcSMasahiro Yamada PERIPHC_G2D, 11509f455dcSMasahiro Yamada 11609f455dcSMasahiro Yamada /* 0x18 */ 11709f455dcSMasahiro Yamada PERIPHC_NDFLASH, 11809f455dcSMasahiro Yamada PERIPHC_SDMMC4, 11909f455dcSMasahiro Yamada PERIPHC_VFIR, 12009f455dcSMasahiro Yamada PERIPHC_EPP, 12109f455dcSMasahiro Yamada PERIPHC_MPE, 12209f455dcSMasahiro Yamada PERIPHC_MIPI, 12309f455dcSMasahiro Yamada PERIPHC_UART1, 12409f455dcSMasahiro Yamada PERIPHC_UART2, 12509f455dcSMasahiro Yamada 12609f455dcSMasahiro Yamada /* 0x20 */ 12709f455dcSMasahiro Yamada PERIPHC_HOST1X, 12809f455dcSMasahiro Yamada PERIPHC_21, 12909f455dcSMasahiro Yamada PERIPHC_TVO, 13009f455dcSMasahiro Yamada PERIPHC_HDMI, 13109f455dcSMasahiro Yamada PERIPHC_24, 13209f455dcSMasahiro Yamada PERIPHC_TVDAC, 13309f455dcSMasahiro Yamada PERIPHC_I2C2, 13409f455dcSMasahiro Yamada PERIPHC_EMC, 13509f455dcSMasahiro Yamada 13609f455dcSMasahiro Yamada /* 0x28 */ 13709f455dcSMasahiro Yamada PERIPHC_UART3, 13809f455dcSMasahiro Yamada PERIPHC_29, 13909f455dcSMasahiro Yamada PERIPHC_VI_SENSOR, 14009f455dcSMasahiro Yamada PERIPHC_2b, 14109f455dcSMasahiro Yamada PERIPHC_2c, 14209f455dcSMasahiro Yamada PERIPHC_SPI4, 14309f455dcSMasahiro Yamada PERIPHC_I2C3, 14409f455dcSMasahiro Yamada PERIPHC_SDMMC3, 14509f455dcSMasahiro Yamada 14609f455dcSMasahiro Yamada /* 0x30 */ 14709f455dcSMasahiro Yamada PERIPHC_UART4, 14809f455dcSMasahiro Yamada PERIPHC_UART5, 14909f455dcSMasahiro Yamada PERIPHC_VDE, 15009f455dcSMasahiro Yamada PERIPHC_OWR, 15109f455dcSMasahiro Yamada PERIPHC_NOR, 15209f455dcSMasahiro Yamada PERIPHC_CSITE, 15309f455dcSMasahiro Yamada 15409f455dcSMasahiro Yamada PERIPHC_COUNT, 15509f455dcSMasahiro Yamada 15609f455dcSMasahiro Yamada PERIPHC_NONE = -1, 15709f455dcSMasahiro Yamada }; 15809f455dcSMasahiro Yamada 15909f455dcSMasahiro Yamada /* 16009f455dcSMasahiro Yamada * Clock type for each peripheral clock source. We put the name in each 16109f455dcSMasahiro Yamada * record just so it is easy to match things up 16209f455dcSMasahiro Yamada */ 16309f455dcSMasahiro Yamada #define TYPE(name, type) type 16409f455dcSMasahiro Yamada static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { 16509f455dcSMasahiro Yamada /* 0x00 */ 16609f455dcSMasahiro Yamada TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), 16709f455dcSMasahiro Yamada TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), 16809f455dcSMasahiro Yamada TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), 16909f455dcSMasahiro Yamada TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), 17009f455dcSMasahiro Yamada TYPE(PERIPHC_PWM, CLOCK_TYPE_PCXTS), 17109f455dcSMasahiro Yamada TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), 17209f455dcSMasahiro Yamada TYPE(PERIPHC_SPI22, CLOCK_TYPE_PCMT), 17309f455dcSMasahiro Yamada TYPE(PERIPHC_SPI3, CLOCK_TYPE_PCMT), 17409f455dcSMasahiro Yamada 17509f455dcSMasahiro Yamada /* 0x08 */ 17609f455dcSMasahiro Yamada TYPE(PERIPHC_XIO, CLOCK_TYPE_PCMT), 17709f455dcSMasahiro Yamada TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), 17809f455dcSMasahiro Yamada TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), 17909f455dcSMasahiro Yamada TYPE(PERIPHC_TWC, CLOCK_TYPE_PCMT), 18009f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 18109f455dcSMasahiro Yamada TYPE(PERIPHC_SPI1, CLOCK_TYPE_PCMT), 18209f455dcSMasahiro Yamada TYPE(PERIPHC_DISP1, CLOCK_TYPE_PDCT), 18309f455dcSMasahiro Yamada TYPE(PERIPHC_DISP2, CLOCK_TYPE_PDCT), 18409f455dcSMasahiro Yamada 18509f455dcSMasahiro Yamada /* 0x10 */ 18609f455dcSMasahiro Yamada TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), 18709f455dcSMasahiro Yamada TYPE(PERIPHC_IDE0, CLOCK_TYPE_PCMT), 18809f455dcSMasahiro Yamada TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), 18909f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 19009f455dcSMasahiro Yamada TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), 19109f455dcSMasahiro Yamada TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), 19209f455dcSMasahiro Yamada TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), 19309f455dcSMasahiro Yamada TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), 19409f455dcSMasahiro Yamada 19509f455dcSMasahiro Yamada /* 0x18 */ 19609f455dcSMasahiro Yamada TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), 19709f455dcSMasahiro Yamada TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), 19809f455dcSMasahiro Yamada TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), 19909f455dcSMasahiro Yamada TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), 20009f455dcSMasahiro Yamada TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), 20109f455dcSMasahiro Yamada TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), 20209f455dcSMasahiro Yamada TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), 20309f455dcSMasahiro Yamada TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), 20409f455dcSMasahiro Yamada 20509f455dcSMasahiro Yamada /* 0x20 */ 20609f455dcSMasahiro Yamada TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), 20709f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 20809f455dcSMasahiro Yamada TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), 20909f455dcSMasahiro Yamada TYPE(PERIPHC_HDMI, CLOCK_TYPE_PDCT), 21009f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 21109f455dcSMasahiro Yamada TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), 21209f455dcSMasahiro Yamada TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), 21309f455dcSMasahiro Yamada TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), 21409f455dcSMasahiro Yamada 21509f455dcSMasahiro Yamada /* 0x28 */ 21609f455dcSMasahiro Yamada TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), 21709f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 21809f455dcSMasahiro Yamada TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), 21909f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 22009f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 22109f455dcSMasahiro Yamada TYPE(PERIPHC_SPI4, CLOCK_TYPE_PCMT), 22209f455dcSMasahiro Yamada TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), 22309f455dcSMasahiro Yamada TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), 22409f455dcSMasahiro Yamada 22509f455dcSMasahiro Yamada /* 0x30 */ 22609f455dcSMasahiro Yamada TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), 22709f455dcSMasahiro Yamada TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), 22809f455dcSMasahiro Yamada TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), 22909f455dcSMasahiro Yamada TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), 23009f455dcSMasahiro Yamada TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), 23109f455dcSMasahiro Yamada TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), 23209f455dcSMasahiro Yamada }; 23309f455dcSMasahiro Yamada 23409f455dcSMasahiro Yamada /* 23509f455dcSMasahiro Yamada * This array translates a periph_id to a periphc_internal_id 23609f455dcSMasahiro Yamada * 23709f455dcSMasahiro Yamada * Not present/matched up: 23809f455dcSMasahiro Yamada * uint vi_sensor; _VI_SENSOR_0, 0x1A8 23909f455dcSMasahiro Yamada * SPDIF - which is both 0x08 and 0x0c 24009f455dcSMasahiro Yamada * 24109f455dcSMasahiro Yamada */ 24209f455dcSMasahiro Yamada #define NONE(name) (-1) 24309f455dcSMasahiro Yamada #define OFFSET(name, value) PERIPHC_ ## name 24409f455dcSMasahiro Yamada static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { 24509f455dcSMasahiro Yamada /* Low word: 31:0 */ 24609f455dcSMasahiro Yamada NONE(CPU), 24709f455dcSMasahiro Yamada NONE(RESERVED1), 24809f455dcSMasahiro Yamada NONE(RESERVED2), 24909f455dcSMasahiro Yamada NONE(AC97), 25009f455dcSMasahiro Yamada NONE(RTC), 25109f455dcSMasahiro Yamada NONE(TMR), 25209f455dcSMasahiro Yamada PERIPHC_UART1, 25309f455dcSMasahiro Yamada PERIPHC_UART2, /* and vfir 0x68 */ 25409f455dcSMasahiro Yamada 25509f455dcSMasahiro Yamada /* 0x08 */ 25609f455dcSMasahiro Yamada NONE(GPIO), 25709f455dcSMasahiro Yamada PERIPHC_SDMMC2, 25809f455dcSMasahiro Yamada NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ 25909f455dcSMasahiro Yamada PERIPHC_I2S1, 26009f455dcSMasahiro Yamada PERIPHC_I2C1, 26109f455dcSMasahiro Yamada PERIPHC_NDFLASH, 26209f455dcSMasahiro Yamada PERIPHC_SDMMC1, 26309f455dcSMasahiro Yamada PERIPHC_SDMMC4, 26409f455dcSMasahiro Yamada 26509f455dcSMasahiro Yamada /* 0x10 */ 26609f455dcSMasahiro Yamada PERIPHC_TWC, 26709f455dcSMasahiro Yamada PERIPHC_PWM, 26809f455dcSMasahiro Yamada PERIPHC_I2S2, 26909f455dcSMasahiro Yamada PERIPHC_EPP, 27009f455dcSMasahiro Yamada PERIPHC_VI, 27109f455dcSMasahiro Yamada PERIPHC_G2D, 27209f455dcSMasahiro Yamada NONE(USBD), 27309f455dcSMasahiro Yamada NONE(ISP), 27409f455dcSMasahiro Yamada 27509f455dcSMasahiro Yamada /* 0x18 */ 27609f455dcSMasahiro Yamada PERIPHC_G3D, 27709f455dcSMasahiro Yamada PERIPHC_IDE0, 27809f455dcSMasahiro Yamada PERIPHC_DISP2, 27909f455dcSMasahiro Yamada PERIPHC_DISP1, 28009f455dcSMasahiro Yamada PERIPHC_HOST1X, 28109f455dcSMasahiro Yamada NONE(VCP), 28209f455dcSMasahiro Yamada NONE(RESERVED30), 28309f455dcSMasahiro Yamada NONE(CACHE2), 28409f455dcSMasahiro Yamada 28509f455dcSMasahiro Yamada /* Middle word: 63:32 */ 28609f455dcSMasahiro Yamada NONE(MEM), 28709f455dcSMasahiro Yamada NONE(AHBDMA), 28809f455dcSMasahiro Yamada NONE(APBDMA), 28909f455dcSMasahiro Yamada NONE(RESERVED35), 29009f455dcSMasahiro Yamada NONE(KBC), 29109f455dcSMasahiro Yamada NONE(STAT_MON), 29209f455dcSMasahiro Yamada NONE(PMC), 29309f455dcSMasahiro Yamada NONE(FUSE), 29409f455dcSMasahiro Yamada 29509f455dcSMasahiro Yamada /* 0x28 */ 29609f455dcSMasahiro Yamada NONE(KFUSE), 29709f455dcSMasahiro Yamada NONE(SBC1), /* SBC1, 0x34, is this SPI1? */ 29809f455dcSMasahiro Yamada PERIPHC_NOR, 29909f455dcSMasahiro Yamada PERIPHC_SPI1, 30009f455dcSMasahiro Yamada PERIPHC_SPI2, 30109f455dcSMasahiro Yamada PERIPHC_XIO, 30209f455dcSMasahiro Yamada PERIPHC_SPI3, 30309f455dcSMasahiro Yamada PERIPHC_DVC_I2C, 30409f455dcSMasahiro Yamada 30509f455dcSMasahiro Yamada /* 0x30 */ 30609f455dcSMasahiro Yamada NONE(DSI), 30709f455dcSMasahiro Yamada PERIPHC_TVO, /* also CVE 0x40 */ 30809f455dcSMasahiro Yamada PERIPHC_MIPI, 30909f455dcSMasahiro Yamada PERIPHC_HDMI, 31009f455dcSMasahiro Yamada PERIPHC_CSITE, 31109f455dcSMasahiro Yamada PERIPHC_TVDAC, 31209f455dcSMasahiro Yamada PERIPHC_I2C2, 31309f455dcSMasahiro Yamada PERIPHC_UART3, 31409f455dcSMasahiro Yamada 31509f455dcSMasahiro Yamada /* 0x38 */ 31609f455dcSMasahiro Yamada NONE(RESERVED56), 31709f455dcSMasahiro Yamada PERIPHC_EMC, 31809f455dcSMasahiro Yamada NONE(USB2), 31909f455dcSMasahiro Yamada NONE(USB3), 32009f455dcSMasahiro Yamada PERIPHC_MPE, 32109f455dcSMasahiro Yamada PERIPHC_VDE, 32209f455dcSMasahiro Yamada NONE(BSEA), 32309f455dcSMasahiro Yamada NONE(BSEV), 32409f455dcSMasahiro Yamada 32509f455dcSMasahiro Yamada /* Upper word 95:64 */ 32609f455dcSMasahiro Yamada NONE(SPEEDO), 32709f455dcSMasahiro Yamada PERIPHC_UART4, 32809f455dcSMasahiro Yamada PERIPHC_UART5, 32909f455dcSMasahiro Yamada PERIPHC_I2C3, 33009f455dcSMasahiro Yamada PERIPHC_SPI4, 33109f455dcSMasahiro Yamada PERIPHC_SDMMC3, 33209f455dcSMasahiro Yamada NONE(PCIE), 33309f455dcSMasahiro Yamada PERIPHC_OWR, 33409f455dcSMasahiro Yamada 33509f455dcSMasahiro Yamada /* 0x48 */ 33609f455dcSMasahiro Yamada NONE(AFI), 33709f455dcSMasahiro Yamada NONE(CORESIGHT), 33809f455dcSMasahiro Yamada NONE(PCIEXCLK), 33909f455dcSMasahiro Yamada NONE(AVPUCQ), 34009f455dcSMasahiro Yamada NONE(RESERVED76), 34109f455dcSMasahiro Yamada NONE(RESERVED77), 34209f455dcSMasahiro Yamada NONE(RESERVED78), 34309f455dcSMasahiro Yamada NONE(RESERVED79), 34409f455dcSMasahiro Yamada 34509f455dcSMasahiro Yamada /* 0x50 */ 34609f455dcSMasahiro Yamada NONE(RESERVED80), 34709f455dcSMasahiro Yamada NONE(RESERVED81), 34809f455dcSMasahiro Yamada NONE(RESERVED82), 34909f455dcSMasahiro Yamada NONE(RESERVED83), 35009f455dcSMasahiro Yamada NONE(IRAMA), 35109f455dcSMasahiro Yamada NONE(IRAMB), 35209f455dcSMasahiro Yamada NONE(IRAMC), 35309f455dcSMasahiro Yamada NONE(IRAMD), 35409f455dcSMasahiro Yamada 35509f455dcSMasahiro Yamada /* 0x58 */ 35609f455dcSMasahiro Yamada NONE(CRAM2), 35709f455dcSMasahiro Yamada }; 35809f455dcSMasahiro Yamada 35909f455dcSMasahiro Yamada /* 360722e000cSTom Warren * PLL divider shift/mask tables for all PLL IDs. 361722e000cSTom Warren */ 362722e000cSTom Warren struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { 363722e000cSTom Warren /* 364722e000cSTom Warren * T20 and T25 365722e000cSTom Warren * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.) 366722e000cSTom Warren * If lock_ena or lock_det are >31, they're not used in that PLL. 367722e000cSTom Warren */ 368722e000cSTom Warren 369722e000cSTom Warren { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x0F, 370722e000cSTom Warren .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 }, /* PLLC */ 371722e000cSTom Warren { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 0, .p_mask = 0, 372722e000cSTom Warren .lock_ena = 0, .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 }, /* PLLM */ 373722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, 374722e000cSTom Warren .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLP */ 375722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, 376722e000cSTom Warren .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLA */ 377722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01, 378722e000cSTom Warren .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLU */ 379722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, 380722e000cSTom Warren .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLD */ 381722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x0F, 382722e000cSTom Warren .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 0, .kvco_mask = 0 }, /* PLLX */ 383722e000cSTom Warren { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 0, .p_mask = 0, 384722e000cSTom Warren .lock_ena = 9, .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 }, /* PLLE */ 385722e000cSTom Warren { .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, 386722e000cSTom Warren .lock_ena = 18, .lock_det = 0, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLS */ 387722e000cSTom Warren }; 388722e000cSTom Warren 389722e000cSTom Warren /* 39009f455dcSMasahiro Yamada * Get the oscillator frequency, from the corresponding hardware configuration 39109f455dcSMasahiro Yamada * field. T20 has 4 frequencies that it supports. 39209f455dcSMasahiro Yamada */ 39309f455dcSMasahiro Yamada enum clock_osc_freq clock_get_osc_freq(void) 39409f455dcSMasahiro Yamada { 39509f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 39609f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 39709f455dcSMasahiro Yamada u32 reg; 39809f455dcSMasahiro Yamada 39909f455dcSMasahiro Yamada reg = readl(&clkrst->crc_osc_ctrl); 40009f455dcSMasahiro Yamada return (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; 40109f455dcSMasahiro Yamada } 40209f455dcSMasahiro Yamada 40309f455dcSMasahiro Yamada /* Returns a pointer to the clock source register for a peripheral */ 40409f455dcSMasahiro Yamada u32 *get_periph_source_reg(enum periph_id periph_id) 40509f455dcSMasahiro Yamada { 40609f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 40709f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 40809f455dcSMasahiro Yamada enum periphc_internal_id internal_id; 40909f455dcSMasahiro Yamada 41009f455dcSMasahiro Yamada assert(clock_periph_id_isvalid(periph_id)); 41109f455dcSMasahiro Yamada internal_id = periph_id_to_internal_id[periph_id]; 41209f455dcSMasahiro Yamada assert(internal_id != -1); 41309f455dcSMasahiro Yamada return &clkrst->crc_clk_src[internal_id]; 41409f455dcSMasahiro Yamada } 41509f455dcSMasahiro Yamada 416*d0ad8a5cSStephen Warren int get_periph_clock_info(enum periph_id periph_id, int *mux_bits, 417*d0ad8a5cSStephen Warren int *divider_bits, int *type) 418*d0ad8a5cSStephen Warren { 419*d0ad8a5cSStephen Warren enum periphc_internal_id internal_id; 420*d0ad8a5cSStephen Warren 421*d0ad8a5cSStephen Warren if (!clock_periph_id_isvalid(periph_id)) 422*d0ad8a5cSStephen Warren return -1; 423*d0ad8a5cSStephen Warren 424*d0ad8a5cSStephen Warren internal_id = periph_id_to_internal_id[periph_id]; 425*d0ad8a5cSStephen Warren if (!periphc_internal_id_isvalid(internal_id)) 426*d0ad8a5cSStephen Warren return -1; 427*d0ad8a5cSStephen Warren 428*d0ad8a5cSStephen Warren *type = clock_periph_type[internal_id]; 429*d0ad8a5cSStephen Warren if (!clock_type_id_isvalid(*type)) 430*d0ad8a5cSStephen Warren return -1; 431*d0ad8a5cSStephen Warren 432*d0ad8a5cSStephen Warren /* 433*d0ad8a5cSStephen Warren * Special cases here for the clock with a 4-bit source mux and I2C 434*d0ad8a5cSStephen Warren * with its 16-bit divisor 435*d0ad8a5cSStephen Warren */ 436*d0ad8a5cSStephen Warren if (*type == CLOCK_TYPE_PCXTS) 437*d0ad8a5cSStephen Warren *mux_bits = MASK_BITS_31_28; 438*d0ad8a5cSStephen Warren else 439*d0ad8a5cSStephen Warren *mux_bits = MASK_BITS_31_30; 440*d0ad8a5cSStephen Warren if (*type == CLOCK_TYPE_PCMT16) 441*d0ad8a5cSStephen Warren *divider_bits = 16; 442*d0ad8a5cSStephen Warren else 443*d0ad8a5cSStephen Warren *divider_bits = 8; 444*d0ad8a5cSStephen Warren 445*d0ad8a5cSStephen Warren return 0; 446*d0ad8a5cSStephen Warren } 447*d0ad8a5cSStephen Warren 448*d0ad8a5cSStephen Warren enum clock_id get_periph_clock_id(enum periph_id periph_id, int source) 449*d0ad8a5cSStephen Warren { 450*d0ad8a5cSStephen Warren enum periphc_internal_id internal_id; 451*d0ad8a5cSStephen Warren int type; 452*d0ad8a5cSStephen Warren 453*d0ad8a5cSStephen Warren if (!clock_periph_id_isvalid(periph_id)) 454*d0ad8a5cSStephen Warren return CLOCK_ID_NONE; 455*d0ad8a5cSStephen Warren 456*d0ad8a5cSStephen Warren internal_id = periph_id_to_internal_id[periph_id]; 457*d0ad8a5cSStephen Warren if (!periphc_internal_id_isvalid(internal_id)) 458*d0ad8a5cSStephen Warren return CLOCK_ID_NONE; 459*d0ad8a5cSStephen Warren 460*d0ad8a5cSStephen Warren type = clock_periph_type[internal_id]; 461*d0ad8a5cSStephen Warren if (!clock_type_id_isvalid(type)) 462*d0ad8a5cSStephen Warren return CLOCK_ID_NONE; 463*d0ad8a5cSStephen Warren 464*d0ad8a5cSStephen Warren return clock_source[type][source]; 465*d0ad8a5cSStephen Warren } 466*d0ad8a5cSStephen Warren 46709f455dcSMasahiro Yamada /** 46809f455dcSMasahiro Yamada * Given a peripheral ID and the required source clock, this returns which 46909f455dcSMasahiro Yamada * value should be programmed into the source mux for that peripheral. 47009f455dcSMasahiro Yamada * 47109f455dcSMasahiro Yamada * There is special code here to handle the one source type with 5 sources. 47209f455dcSMasahiro Yamada * 47309f455dcSMasahiro Yamada * @param periph_id peripheral to start 47409f455dcSMasahiro Yamada * @param source PLL id of required parent clock 47509f455dcSMasahiro Yamada * @param mux_bits Set to number of bits in mux register: 2 or 4 47609f455dcSMasahiro Yamada * @param divider_bits Set to number of divider bits (8 or 16) 47709f455dcSMasahiro Yamada * @return mux value (0-4, or -1 if not found) 47809f455dcSMasahiro Yamada */ 47909f455dcSMasahiro Yamada int get_periph_clock_source(enum periph_id periph_id, 48009f455dcSMasahiro Yamada enum clock_id parent, int *mux_bits, int *divider_bits) 48109f455dcSMasahiro Yamada { 48209f455dcSMasahiro Yamada enum clock_type_id type; 483*d0ad8a5cSStephen Warren int mux, err; 48409f455dcSMasahiro Yamada 485*d0ad8a5cSStephen Warren err = get_periph_clock_info(periph_id, mux_bits, divider_bits, &type); 486*d0ad8a5cSStephen Warren assert(!err); 48709f455dcSMasahiro Yamada 48809f455dcSMasahiro Yamada for (mux = 0; mux < CLOCK_MAX_MUX; mux++) 48909f455dcSMasahiro Yamada if (clock_source[type][mux] == parent) 49009f455dcSMasahiro Yamada return mux; 49109f455dcSMasahiro Yamada 49209f455dcSMasahiro Yamada /* 49309f455dcSMasahiro Yamada * Not found: it might be looking for the 'S' in CLOCK_TYPE_PCXTS 49409f455dcSMasahiro Yamada * which is not in our table. If not, then they are asking for a 49509f455dcSMasahiro Yamada * source which this peripheral can't access through its mux. 49609f455dcSMasahiro Yamada */ 49709f455dcSMasahiro Yamada assert(type == CLOCK_TYPE_PCXTS); 49809f455dcSMasahiro Yamada assert(parent == CLOCK_ID_SFROM32KHZ); 49909f455dcSMasahiro Yamada if (type == CLOCK_TYPE_PCXTS && parent == CLOCK_ID_SFROM32KHZ) 50009f455dcSMasahiro Yamada return 4; /* mux value for this clock */ 50109f455dcSMasahiro Yamada 50209f455dcSMasahiro Yamada /* if we get here, either us or the caller has made a mistake */ 50309f455dcSMasahiro Yamada printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, 50409f455dcSMasahiro Yamada parent); 50509f455dcSMasahiro Yamada return -1; 50609f455dcSMasahiro Yamada } 50709f455dcSMasahiro Yamada 50809f455dcSMasahiro Yamada void clock_set_enable(enum periph_id periph_id, int enable) 50909f455dcSMasahiro Yamada { 51009f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 51109f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 51209f455dcSMasahiro Yamada u32 *clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; 51309f455dcSMasahiro Yamada u32 reg; 51409f455dcSMasahiro Yamada 51509f455dcSMasahiro Yamada /* Enable/disable the clock to this peripheral */ 51609f455dcSMasahiro Yamada assert(clock_periph_id_isvalid(periph_id)); 51709f455dcSMasahiro Yamada reg = readl(clk); 51809f455dcSMasahiro Yamada if (enable) 51909f455dcSMasahiro Yamada reg |= PERIPH_MASK(periph_id); 52009f455dcSMasahiro Yamada else 52109f455dcSMasahiro Yamada reg &= ~PERIPH_MASK(periph_id); 52209f455dcSMasahiro Yamada writel(reg, clk); 52309f455dcSMasahiro Yamada } 52409f455dcSMasahiro Yamada 52509f455dcSMasahiro Yamada void reset_set_enable(enum periph_id periph_id, int enable) 52609f455dcSMasahiro Yamada { 52709f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 52809f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 52909f455dcSMasahiro Yamada u32 *reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; 53009f455dcSMasahiro Yamada u32 reg; 53109f455dcSMasahiro Yamada 53209f455dcSMasahiro Yamada /* Enable/disable reset to the peripheral */ 53309f455dcSMasahiro Yamada assert(clock_periph_id_isvalid(periph_id)); 53409f455dcSMasahiro Yamada reg = readl(reset); 53509f455dcSMasahiro Yamada if (enable) 53609f455dcSMasahiro Yamada reg |= PERIPH_MASK(periph_id); 53709f455dcSMasahiro Yamada else 53809f455dcSMasahiro Yamada reg &= ~PERIPH_MASK(periph_id); 53909f455dcSMasahiro Yamada writel(reg, reset); 54009f455dcSMasahiro Yamada } 54109f455dcSMasahiro Yamada 5420f925822SMasahiro Yamada #if CONFIG_IS_ENABLED(OF_CONTROL) 54309f455dcSMasahiro Yamada /* 54409f455dcSMasahiro Yamada * Convert a device tree clock ID to our peripheral ID. They are mostly 54509f455dcSMasahiro Yamada * the same but we are very cautious so we check that a valid clock ID is 54609f455dcSMasahiro Yamada * provided. 54709f455dcSMasahiro Yamada * 54809f455dcSMasahiro Yamada * @param clk_id Clock ID according to tegra20 device tree binding 54909f455dcSMasahiro Yamada * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid 55009f455dcSMasahiro Yamada */ 55109f455dcSMasahiro Yamada enum periph_id clk_id_to_periph_id(int clk_id) 55209f455dcSMasahiro Yamada { 55309f455dcSMasahiro Yamada if (clk_id > PERIPH_ID_COUNT) 55409f455dcSMasahiro Yamada return PERIPH_ID_NONE; 55509f455dcSMasahiro Yamada 55609f455dcSMasahiro Yamada switch (clk_id) { 55709f455dcSMasahiro Yamada case PERIPH_ID_RESERVED1: 55809f455dcSMasahiro Yamada case PERIPH_ID_RESERVED2: 55909f455dcSMasahiro Yamada case PERIPH_ID_RESERVED30: 56009f455dcSMasahiro Yamada case PERIPH_ID_RESERVED35: 56109f455dcSMasahiro Yamada case PERIPH_ID_RESERVED56: 56209f455dcSMasahiro Yamada case PERIPH_ID_PCIEXCLK: 56309f455dcSMasahiro Yamada case PERIPH_ID_RESERVED76: 56409f455dcSMasahiro Yamada case PERIPH_ID_RESERVED77: 56509f455dcSMasahiro Yamada case PERIPH_ID_RESERVED78: 56609f455dcSMasahiro Yamada case PERIPH_ID_RESERVED79: 56709f455dcSMasahiro Yamada case PERIPH_ID_RESERVED80: 56809f455dcSMasahiro Yamada case PERIPH_ID_RESERVED81: 56909f455dcSMasahiro Yamada case PERIPH_ID_RESERVED82: 57009f455dcSMasahiro Yamada case PERIPH_ID_RESERVED83: 57109f455dcSMasahiro Yamada case PERIPH_ID_RESERVED91: 57209f455dcSMasahiro Yamada return PERIPH_ID_NONE; 57309f455dcSMasahiro Yamada default: 57409f455dcSMasahiro Yamada return clk_id; 57509f455dcSMasahiro Yamada } 57609f455dcSMasahiro Yamada } 5770f925822SMasahiro Yamada #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ 57809f455dcSMasahiro Yamada 57909f455dcSMasahiro Yamada void clock_early_init(void) 58009f455dcSMasahiro Yamada { 58109f455dcSMasahiro Yamada /* 58209f455dcSMasahiro Yamada * PLLP output frequency set to 216MHz 58309f455dcSMasahiro Yamada * PLLC output frequency set to 600Mhz 58409f455dcSMasahiro Yamada * 58509f455dcSMasahiro Yamada * TODO: Can we calculate these values instead of hard-coding? 58609f455dcSMasahiro Yamada */ 58709f455dcSMasahiro Yamada switch (clock_get_osc_freq()) { 58809f455dcSMasahiro Yamada case CLOCK_OSC_FREQ_12_0: /* OSC is 12Mhz */ 58909f455dcSMasahiro Yamada clock_set_rate(CLOCK_ID_PERIPH, 432, 12, 1, 8); 59009f455dcSMasahiro Yamada clock_set_rate(CLOCK_ID_CGENERAL, 600, 12, 0, 8); 59109f455dcSMasahiro Yamada break; 59209f455dcSMasahiro Yamada 59309f455dcSMasahiro Yamada case CLOCK_OSC_FREQ_26_0: /* OSC is 26Mhz */ 59409f455dcSMasahiro Yamada clock_set_rate(CLOCK_ID_PERIPH, 432, 26, 1, 8); 59509f455dcSMasahiro Yamada clock_set_rate(CLOCK_ID_CGENERAL, 600, 26, 0, 8); 59609f455dcSMasahiro Yamada break; 59709f455dcSMasahiro Yamada 59809f455dcSMasahiro Yamada case CLOCK_OSC_FREQ_13_0: /* OSC is 13Mhz */ 59909f455dcSMasahiro Yamada clock_set_rate(CLOCK_ID_PERIPH, 432, 13, 1, 8); 60009f455dcSMasahiro Yamada clock_set_rate(CLOCK_ID_CGENERAL, 600, 13, 0, 8); 60109f455dcSMasahiro Yamada break; 60209f455dcSMasahiro Yamada case CLOCK_OSC_FREQ_19_2: 60309f455dcSMasahiro Yamada default: 60409f455dcSMasahiro Yamada /* 60509f455dcSMasahiro Yamada * These are not supported. It is too early to print a 60609f455dcSMasahiro Yamada * message and the UART likely won't work anyway due to the 60709f455dcSMasahiro Yamada * oscillator being wrong. 60809f455dcSMasahiro Yamada */ 60909f455dcSMasahiro Yamada break; 61009f455dcSMasahiro Yamada } 61109f455dcSMasahiro Yamada } 61209f455dcSMasahiro Yamada 61309f455dcSMasahiro Yamada void arch_timer_init(void) 61409f455dcSMasahiro Yamada { 61509f455dcSMasahiro Yamada } 61609f455dcSMasahiro Yamada 61709f455dcSMasahiro Yamada #define PMC_SATA_PWRGT 0x1ac 61809f455dcSMasahiro Yamada #define PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE (1 << 5) 61909f455dcSMasahiro Yamada #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1 << 4) 62009f455dcSMasahiro Yamada 62109f455dcSMasahiro Yamada #define PLLE_SS_CNTL 0x68 62209f455dcSMasahiro Yamada #define PLLE_SS_CNTL_SSCINCINTRV(x) (((x) & 0x3f) << 24) 62309f455dcSMasahiro Yamada #define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) 62409f455dcSMasahiro Yamada #define PLLE_SS_CNTL_SSCBYP (1 << 12) 62509f455dcSMasahiro Yamada #define PLLE_SS_CNTL_INTERP_RESET (1 << 11) 62609f455dcSMasahiro Yamada #define PLLE_SS_CNTL_BYPASS_SS (1 << 10) 62709f455dcSMasahiro Yamada #define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) 62809f455dcSMasahiro Yamada 62909f455dcSMasahiro Yamada #define PLLE_BASE 0x0e8 63009f455dcSMasahiro Yamada #define PLLE_BASE_ENABLE_CML (1 << 31) 63109f455dcSMasahiro Yamada #define PLLE_BASE_ENABLE (1 << 30) 63209f455dcSMasahiro Yamada #define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) 63309f455dcSMasahiro Yamada #define PLLE_BASE_PLDIV(x) (((x) & 0x3f) << 16) 63409f455dcSMasahiro Yamada #define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) 63509f455dcSMasahiro Yamada #define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) 63609f455dcSMasahiro Yamada 63709f455dcSMasahiro Yamada #define PLLE_MISC 0x0ec 63809f455dcSMasahiro Yamada #define PLLE_MISC_SETUP_BASE(x) (((x) & 0xffff) << 16) 63909f455dcSMasahiro Yamada #define PLLE_MISC_PLL_READY (1 << 15) 64009f455dcSMasahiro Yamada #define PLLE_MISC_LOCK (1 << 11) 64109f455dcSMasahiro Yamada #define PLLE_MISC_LOCK_ENABLE (1 << 9) 64209f455dcSMasahiro Yamada #define PLLE_MISC_SETUP_EXT(x) (((x) & 0x3) << 2) 64309f455dcSMasahiro Yamada 64409f455dcSMasahiro Yamada static int tegra_plle_train(void) 64509f455dcSMasahiro Yamada { 64609f455dcSMasahiro Yamada unsigned int timeout = 2000; 64709f455dcSMasahiro Yamada unsigned long value; 64809f455dcSMasahiro Yamada 64909f455dcSMasahiro Yamada value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); 65009f455dcSMasahiro Yamada value |= PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; 65109f455dcSMasahiro Yamada writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); 65209f455dcSMasahiro Yamada 65309f455dcSMasahiro Yamada value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); 65409f455dcSMasahiro Yamada value |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; 65509f455dcSMasahiro Yamada writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); 65609f455dcSMasahiro Yamada 65709f455dcSMasahiro Yamada value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); 65809f455dcSMasahiro Yamada value &= ~PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; 65909f455dcSMasahiro Yamada writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); 66009f455dcSMasahiro Yamada 66109f455dcSMasahiro Yamada do { 66209f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 66309f455dcSMasahiro Yamada if (value & PLLE_MISC_PLL_READY) 66409f455dcSMasahiro Yamada break; 66509f455dcSMasahiro Yamada 66609f455dcSMasahiro Yamada udelay(100); 66709f455dcSMasahiro Yamada } while (--timeout); 66809f455dcSMasahiro Yamada 66909f455dcSMasahiro Yamada if (timeout == 0) { 67009f455dcSMasahiro Yamada error("timeout waiting for PLLE to become ready"); 67109f455dcSMasahiro Yamada return -ETIMEDOUT; 67209f455dcSMasahiro Yamada } 67309f455dcSMasahiro Yamada 67409f455dcSMasahiro Yamada return 0; 67509f455dcSMasahiro Yamada } 67609f455dcSMasahiro Yamada 67709f455dcSMasahiro Yamada int tegra_plle_enable(void) 67809f455dcSMasahiro Yamada { 67909f455dcSMasahiro Yamada unsigned int timeout = 1000; 68009f455dcSMasahiro Yamada u32 value; 68109f455dcSMasahiro Yamada int err; 68209f455dcSMasahiro Yamada 68309f455dcSMasahiro Yamada /* disable PLLE clock */ 68409f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); 68509f455dcSMasahiro Yamada value &= ~PLLE_BASE_ENABLE_CML; 68609f455dcSMasahiro Yamada value &= ~PLLE_BASE_ENABLE; 68709f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); 68809f455dcSMasahiro Yamada 68909f455dcSMasahiro Yamada /* clear lock enable and setup field */ 69009f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 69109f455dcSMasahiro Yamada value &= ~PLLE_MISC_LOCK_ENABLE; 69209f455dcSMasahiro Yamada value &= ~PLLE_MISC_SETUP_BASE(0xffff); 69309f455dcSMasahiro Yamada value &= ~PLLE_MISC_SETUP_EXT(0x3); 69409f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); 69509f455dcSMasahiro Yamada 69609f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 69709f455dcSMasahiro Yamada if ((value & PLLE_MISC_PLL_READY) == 0) { 69809f455dcSMasahiro Yamada err = tegra_plle_train(); 69909f455dcSMasahiro Yamada if (err < 0) { 70009f455dcSMasahiro Yamada error("failed to train PLLE: %d", err); 70109f455dcSMasahiro Yamada return err; 70209f455dcSMasahiro Yamada } 70309f455dcSMasahiro Yamada } 70409f455dcSMasahiro Yamada 70509f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 70609f455dcSMasahiro Yamada value |= PLLE_MISC_SETUP_BASE(0x7); 70709f455dcSMasahiro Yamada value |= PLLE_MISC_LOCK_ENABLE; 70809f455dcSMasahiro Yamada value |= PLLE_MISC_SETUP_EXT(0); 70909f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); 71009f455dcSMasahiro Yamada 71109f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); 71209f455dcSMasahiro Yamada value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | 71309f455dcSMasahiro Yamada PLLE_SS_CNTL_BYPASS_SS; 71409f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); 71509f455dcSMasahiro Yamada 71609f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); 71709f455dcSMasahiro Yamada value |= PLLE_BASE_ENABLE_CML | PLLE_BASE_ENABLE; 71809f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); 71909f455dcSMasahiro Yamada 72009f455dcSMasahiro Yamada do { 72109f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 72209f455dcSMasahiro Yamada if (value & PLLE_MISC_LOCK) 72309f455dcSMasahiro Yamada break; 72409f455dcSMasahiro Yamada 72509f455dcSMasahiro Yamada udelay(2); 72609f455dcSMasahiro Yamada } while (--timeout); 72709f455dcSMasahiro Yamada 72809f455dcSMasahiro Yamada if (timeout == 0) { 72909f455dcSMasahiro Yamada error("timeout waiting for PLLE to lock"); 73009f455dcSMasahiro Yamada return -ETIMEDOUT; 73109f455dcSMasahiro Yamada } 73209f455dcSMasahiro Yamada 73309f455dcSMasahiro Yamada udelay(50); 73409f455dcSMasahiro Yamada 73509f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); 73609f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_SSCINCINTRV(0x3f); 73709f455dcSMasahiro Yamada value |= PLLE_SS_CNTL_SSCINCINTRV(0x18); 73809f455dcSMasahiro Yamada 73909f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_SSCINC(0xff); 74009f455dcSMasahiro Yamada value |= PLLE_SS_CNTL_SSCINC(0x01); 74109f455dcSMasahiro Yamada 74209f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_SSCBYP; 74309f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_INTERP_RESET; 74409f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_BYPASS_SS; 74509f455dcSMasahiro Yamada 74609f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); 74709f455dcSMasahiro Yamada value |= PLLE_SS_CNTL_SSCMAX(0x24); 74809f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); 74909f455dcSMasahiro Yamada 75009f455dcSMasahiro Yamada return 0; 75109f455dcSMasahiro Yamada } 7526dbcc962SStephen Warren 7536dbcc962SStephen Warren struct periph_clk_init periph_clk_init_table[] = { 7546dbcc962SStephen Warren { PERIPH_ID_SPI1, CLOCK_ID_PERIPH }, 7556dbcc962SStephen Warren { PERIPH_ID_SBC1, CLOCK_ID_PERIPH }, 7566dbcc962SStephen Warren { PERIPH_ID_SBC2, CLOCK_ID_PERIPH }, 7576dbcc962SStephen Warren { PERIPH_ID_SBC3, CLOCK_ID_PERIPH }, 7586dbcc962SStephen Warren { PERIPH_ID_SBC4, CLOCK_ID_PERIPH }, 7596dbcc962SStephen Warren { PERIPH_ID_HOST1X, CLOCK_ID_PERIPH }, 7606dbcc962SStephen Warren { PERIPH_ID_DISP1, CLOCK_ID_CGENERAL }, 7616dbcc962SStephen Warren { PERIPH_ID_NDFLASH, CLOCK_ID_PERIPH }, 7626dbcc962SStephen Warren { PERIPH_ID_SDMMC1, CLOCK_ID_PERIPH }, 7636dbcc962SStephen Warren { PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH }, 7646dbcc962SStephen Warren { PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH }, 7656dbcc962SStephen Warren { PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH }, 7666dbcc962SStephen Warren { PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ }, 7676dbcc962SStephen Warren { PERIPH_ID_DVC_I2C, CLOCK_ID_PERIPH }, 7686dbcc962SStephen Warren { PERIPH_ID_I2C1, CLOCK_ID_PERIPH }, 7696dbcc962SStephen Warren { PERIPH_ID_I2C2, CLOCK_ID_PERIPH }, 7706dbcc962SStephen Warren { PERIPH_ID_I2C3, CLOCK_ID_PERIPH }, 7716dbcc962SStephen Warren { -1, }, 7726dbcc962SStephen Warren }; 773