109f455dcSMasahiro Yamada /* 2722e000cSTom Warren * (C) Copyright 2010-2015 3722e000cSTom Warren * NVIDIA Corporation <www.nvidia.com> 409f455dcSMasahiro Yamada * 5722e000cSTom Warren * SPDX-License-Identifier: GPL-2.0+ 609f455dcSMasahiro Yamada */ 709f455dcSMasahiro Yamada 809f455dcSMasahiro Yamada /* Tegra30 Clock control functions */ 909f455dcSMasahiro Yamada 1009f455dcSMasahiro Yamada #include <common.h> 1109f455dcSMasahiro Yamada #include <errno.h> 1209f455dcSMasahiro Yamada #include <asm/io.h> 1309f455dcSMasahiro Yamada #include <asm/arch/clock.h> 1409f455dcSMasahiro Yamada #include <asm/arch/tegra.h> 1509f455dcSMasahiro Yamada #include <asm/arch-tegra/clk_rst.h> 1609f455dcSMasahiro Yamada #include <asm/arch-tegra/timer.h> 1709f455dcSMasahiro Yamada #include <div64.h> 1809f455dcSMasahiro Yamada #include <fdtdec.h> 1909f455dcSMasahiro Yamada 2009f455dcSMasahiro Yamada /* 2109f455dcSMasahiro Yamada * Clock types that we can use as a source. The Tegra30 has muxes for the 2209f455dcSMasahiro Yamada * peripheral clocks, and in most cases there are four options for the clock 2309f455dcSMasahiro Yamada * source. This gives us a clock 'type' and exploits what commonality exists 2409f455dcSMasahiro Yamada * in the device. 2509f455dcSMasahiro Yamada * 2609f455dcSMasahiro Yamada * Letters are obvious, except for T which means CLK_M, and S which means the 2709f455dcSMasahiro Yamada * clock derived from 32KHz. Beware that CLK_M (also called OSC in the 2809f455dcSMasahiro Yamada * datasheet) and PLL_M are different things. The former is the basic 2909f455dcSMasahiro Yamada * clock supplied to the SOC from an external oscillator. The latter is the 3009f455dcSMasahiro Yamada * memory clock PLL. 3109f455dcSMasahiro Yamada * 3209f455dcSMasahiro Yamada * See definitions in clock_id in the header file. 3309f455dcSMasahiro Yamada */ 3409f455dcSMasahiro Yamada enum clock_type_id { 3509f455dcSMasahiro Yamada CLOCK_TYPE_AXPT, /* PLL_A, PLL_X, PLL_P, CLK_M */ 3609f455dcSMasahiro Yamada CLOCK_TYPE_MCPA, /* and so on */ 3709f455dcSMasahiro Yamada CLOCK_TYPE_MCPT, 3809f455dcSMasahiro Yamada CLOCK_TYPE_PCM, 3909f455dcSMasahiro Yamada CLOCK_TYPE_PCMT, 4009f455dcSMasahiro Yamada CLOCK_TYPE_PCMT16, 4109f455dcSMasahiro Yamada CLOCK_TYPE_PDCT, 4209f455dcSMasahiro Yamada CLOCK_TYPE_ACPT, 4309f455dcSMasahiro Yamada CLOCK_TYPE_ASPTE, 4409f455dcSMasahiro Yamada CLOCK_TYPE_PMDACD2T, 4509f455dcSMasahiro Yamada CLOCK_TYPE_PCST, 4609f455dcSMasahiro Yamada 4709f455dcSMasahiro Yamada CLOCK_TYPE_COUNT, 4809f455dcSMasahiro Yamada CLOCK_TYPE_NONE = -1, /* invalid clock type */ 4909f455dcSMasahiro Yamada }; 5009f455dcSMasahiro Yamada 5109f455dcSMasahiro Yamada enum { 5209f455dcSMasahiro Yamada CLOCK_MAX_MUX = 8 /* number of source options for each clock */ 5309f455dcSMasahiro Yamada }; 5409f455dcSMasahiro Yamada 5509f455dcSMasahiro Yamada /* 5609f455dcSMasahiro Yamada * Clock source mux for each clock type. This just converts our enum into 5709f455dcSMasahiro Yamada * a list of mux sources for use by the code. 5809f455dcSMasahiro Yamada * 5909f455dcSMasahiro Yamada * Note: 6009f455dcSMasahiro Yamada * The extra column in each clock source array is used to store the mask 6109f455dcSMasahiro Yamada * bits in its register for the source. 6209f455dcSMasahiro Yamada */ 6309f455dcSMasahiro Yamada #define CLK(x) CLOCK_ID_ ## x 6409f455dcSMasahiro Yamada static enum clock_id clock_source[CLOCK_TYPE_COUNT][CLOCK_MAX_MUX+1] = { 6509f455dcSMasahiro Yamada { CLK(AUDIO), CLK(XCPU), CLK(PERIPH), CLK(OSC), 6609f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 6709f455dcSMasahiro Yamada MASK_BITS_31_30}, 6809f455dcSMasahiro Yamada { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(AUDIO), 6909f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 7009f455dcSMasahiro Yamada MASK_BITS_31_30}, 7109f455dcSMasahiro Yamada { CLK(MEMORY), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), 7209f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 7309f455dcSMasahiro Yamada MASK_BITS_31_30}, 7409f455dcSMasahiro Yamada { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(NONE), 7509f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 7609f455dcSMasahiro Yamada MASK_BITS_31_30}, 7709f455dcSMasahiro Yamada { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), 7809f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 7909f455dcSMasahiro Yamada MASK_BITS_31_30}, 8009f455dcSMasahiro Yamada { CLK(PERIPH), CLK(CGENERAL), CLK(MEMORY), CLK(OSC), 8109f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 8209f455dcSMasahiro Yamada MASK_BITS_31_30}, 8309f455dcSMasahiro Yamada { CLK(PERIPH), CLK(DISPLAY), CLK(CGENERAL), CLK(OSC), 8409f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 8509f455dcSMasahiro Yamada MASK_BITS_31_30}, 8609f455dcSMasahiro Yamada { CLK(AUDIO), CLK(CGENERAL), CLK(PERIPH), CLK(OSC), 8709f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 8809f455dcSMasahiro Yamada MASK_BITS_31_30}, 8909f455dcSMasahiro Yamada { CLK(AUDIO), CLK(SFROM32KHZ), CLK(PERIPH), CLK(OSC), 9009f455dcSMasahiro Yamada CLK(EPCI), CLK(NONE), CLK(NONE), CLK(NONE), 9109f455dcSMasahiro Yamada MASK_BITS_31_29}, 9209f455dcSMasahiro Yamada { CLK(PERIPH), CLK(MEMORY), CLK(DISPLAY), CLK(AUDIO), 9309f455dcSMasahiro Yamada CLK(CGENERAL), CLK(DISPLAY2), CLK(OSC), CLK(NONE), 9409f455dcSMasahiro Yamada MASK_BITS_31_29}, 9509f455dcSMasahiro Yamada { CLK(PERIPH), CLK(CGENERAL), CLK(SFROM32KHZ), CLK(OSC), 9609f455dcSMasahiro Yamada CLK(NONE), CLK(NONE), CLK(NONE), CLK(NONE), 9709f455dcSMasahiro Yamada MASK_BITS_31_28} 9809f455dcSMasahiro Yamada }; 9909f455dcSMasahiro Yamada 10009f455dcSMasahiro Yamada /* 10109f455dcSMasahiro Yamada * Clock type for each peripheral clock source. We put the name in each 10209f455dcSMasahiro Yamada * record just so it is easy to match things up 10309f455dcSMasahiro Yamada */ 10409f455dcSMasahiro Yamada #define TYPE(name, type) type 10509f455dcSMasahiro Yamada static enum clock_type_id clock_periph_type[PERIPHC_COUNT] = { 10609f455dcSMasahiro Yamada /* 0x00 */ 10709f455dcSMasahiro Yamada TYPE(PERIPHC_I2S1, CLOCK_TYPE_AXPT), 10809f455dcSMasahiro Yamada TYPE(PERIPHC_I2S2, CLOCK_TYPE_AXPT), 10909f455dcSMasahiro Yamada TYPE(PERIPHC_SPDIF_OUT, CLOCK_TYPE_AXPT), 11009f455dcSMasahiro Yamada TYPE(PERIPHC_SPDIF_IN, CLOCK_TYPE_PCM), 11109f455dcSMasahiro Yamada TYPE(PERIPHC_PWM, CLOCK_TYPE_PCST), /* only PWM uses b29:28 */ 11209f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 11309f455dcSMasahiro Yamada TYPE(PERIPHC_SBC2, CLOCK_TYPE_PCMT), 11409f455dcSMasahiro Yamada TYPE(PERIPHC_SBC3, CLOCK_TYPE_PCMT), 11509f455dcSMasahiro Yamada 11609f455dcSMasahiro Yamada /* 0x08 */ 11709f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 11809f455dcSMasahiro Yamada TYPE(PERIPHC_I2C1, CLOCK_TYPE_PCMT16), 11909f455dcSMasahiro Yamada TYPE(PERIPHC_DVC_I2C, CLOCK_TYPE_PCMT16), 12009f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 12109f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 12209f455dcSMasahiro Yamada TYPE(PERIPHC_SBC1, CLOCK_TYPE_PCMT), 12309f455dcSMasahiro Yamada TYPE(PERIPHC_DISP1, CLOCK_TYPE_PMDACD2T), 12409f455dcSMasahiro Yamada TYPE(PERIPHC_DISP2, CLOCK_TYPE_PMDACD2T), 12509f455dcSMasahiro Yamada 12609f455dcSMasahiro Yamada /* 0x10 */ 12709f455dcSMasahiro Yamada TYPE(PERIPHC_CVE, CLOCK_TYPE_PDCT), 12809f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 12909f455dcSMasahiro Yamada TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), 13009f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 13109f455dcSMasahiro Yamada TYPE(PERIPHC_SDMMC1, CLOCK_TYPE_PCMT), 13209f455dcSMasahiro Yamada TYPE(PERIPHC_SDMMC2, CLOCK_TYPE_PCMT), 13309f455dcSMasahiro Yamada TYPE(PERIPHC_G3D, CLOCK_TYPE_MCPA), 13409f455dcSMasahiro Yamada TYPE(PERIPHC_G2D, CLOCK_TYPE_MCPA), 13509f455dcSMasahiro Yamada 13609f455dcSMasahiro Yamada /* 0x18 */ 13709f455dcSMasahiro Yamada TYPE(PERIPHC_NDFLASH, CLOCK_TYPE_PCMT), 13809f455dcSMasahiro Yamada TYPE(PERIPHC_SDMMC4, CLOCK_TYPE_PCMT), 13909f455dcSMasahiro Yamada TYPE(PERIPHC_VFIR, CLOCK_TYPE_PCMT), 14009f455dcSMasahiro Yamada TYPE(PERIPHC_EPP, CLOCK_TYPE_MCPA), 14109f455dcSMasahiro Yamada TYPE(PERIPHC_MPE, CLOCK_TYPE_MCPA), 14209f455dcSMasahiro Yamada TYPE(PERIPHC_MIPI, CLOCK_TYPE_PCMT), /* MIPI base-band HSI */ 14309f455dcSMasahiro Yamada TYPE(PERIPHC_UART1, CLOCK_TYPE_PCMT), 14409f455dcSMasahiro Yamada TYPE(PERIPHC_UART2, CLOCK_TYPE_PCMT), 14509f455dcSMasahiro Yamada 14609f455dcSMasahiro Yamada /* 0x20 */ 14709f455dcSMasahiro Yamada TYPE(PERIPHC_HOST1X, CLOCK_TYPE_MCPA), 14809f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 14909f455dcSMasahiro Yamada TYPE(PERIPHC_TVO, CLOCK_TYPE_PDCT), 15009f455dcSMasahiro Yamada TYPE(PERIPHC_HDMI, CLOCK_TYPE_PMDACD2T), 15109f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 15209f455dcSMasahiro Yamada TYPE(PERIPHC_TVDAC, CLOCK_TYPE_PDCT), 15309f455dcSMasahiro Yamada TYPE(PERIPHC_I2C2, CLOCK_TYPE_PCMT16), 15409f455dcSMasahiro Yamada TYPE(PERIPHC_EMC, CLOCK_TYPE_MCPT), 15509f455dcSMasahiro Yamada 15609f455dcSMasahiro Yamada /* 0x28 */ 15709f455dcSMasahiro Yamada TYPE(PERIPHC_UART3, CLOCK_TYPE_PCMT), 15809f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 15909f455dcSMasahiro Yamada TYPE(PERIPHC_VI, CLOCK_TYPE_MCPA), 16009f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 16109f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 16209f455dcSMasahiro Yamada TYPE(PERIPHC_SBC4, CLOCK_TYPE_PCMT), 16309f455dcSMasahiro Yamada TYPE(PERIPHC_I2C3, CLOCK_TYPE_PCMT16), 16409f455dcSMasahiro Yamada TYPE(PERIPHC_SDMMC3, CLOCK_TYPE_PCMT), 16509f455dcSMasahiro Yamada 16609f455dcSMasahiro Yamada /* 0x30 */ 16709f455dcSMasahiro Yamada TYPE(PERIPHC_UART4, CLOCK_TYPE_PCMT), 16809f455dcSMasahiro Yamada TYPE(PERIPHC_UART5, CLOCK_TYPE_PCMT), 16909f455dcSMasahiro Yamada TYPE(PERIPHC_VDE, CLOCK_TYPE_PCMT), 17009f455dcSMasahiro Yamada TYPE(PERIPHC_OWR, CLOCK_TYPE_PCMT), 17109f455dcSMasahiro Yamada TYPE(PERIPHC_NOR, CLOCK_TYPE_PCMT), 17209f455dcSMasahiro Yamada TYPE(PERIPHC_CSITE, CLOCK_TYPE_PCMT), 17309f455dcSMasahiro Yamada TYPE(PERIPHC_I2S0, CLOCK_TYPE_AXPT), 17409f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 17509f455dcSMasahiro Yamada 17609f455dcSMasahiro Yamada /* 0x38h */ /* Jumps to reg offset 0x3B0h - new for T30 */ 17709f455dcSMasahiro Yamada TYPE(PERIPHC_G3D2, CLOCK_TYPE_MCPA), 17809f455dcSMasahiro Yamada TYPE(PERIPHC_MSELECT, CLOCK_TYPE_PCMT), 17909f455dcSMasahiro Yamada TYPE(PERIPHC_TSENSOR, CLOCK_TYPE_PCST), /* s/b PCTS */ 18009f455dcSMasahiro Yamada TYPE(PERIPHC_I2S3, CLOCK_TYPE_AXPT), 18109f455dcSMasahiro Yamada TYPE(PERIPHC_I2S4, CLOCK_TYPE_AXPT), 18209f455dcSMasahiro Yamada TYPE(PERIPHC_I2C4, CLOCK_TYPE_PCMT16), 18309f455dcSMasahiro Yamada TYPE(PERIPHC_SBC5, CLOCK_TYPE_PCMT), 18409f455dcSMasahiro Yamada TYPE(PERIPHC_SBC6, CLOCK_TYPE_PCMT), 18509f455dcSMasahiro Yamada 18609f455dcSMasahiro Yamada /* 0x40 */ 18709f455dcSMasahiro Yamada TYPE(PERIPHC_AUDIO, CLOCK_TYPE_ACPT), 18809f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 18909f455dcSMasahiro Yamada TYPE(PERIPHC_DAM0, CLOCK_TYPE_ACPT), 19009f455dcSMasahiro Yamada TYPE(PERIPHC_DAM1, CLOCK_TYPE_ACPT), 19109f455dcSMasahiro Yamada TYPE(PERIPHC_DAM2, CLOCK_TYPE_ACPT), 19209f455dcSMasahiro Yamada TYPE(PERIPHC_HDA2CODEC2X, CLOCK_TYPE_PCMT), 19309f455dcSMasahiro Yamada TYPE(PERIPHC_ACTMON, CLOCK_TYPE_PCST), /* MASK 31:30 */ 19409f455dcSMasahiro Yamada TYPE(PERIPHC_EXTPERIPH1, CLOCK_TYPE_ASPTE), 19509f455dcSMasahiro Yamada 19609f455dcSMasahiro Yamada /* 0x48 */ 19709f455dcSMasahiro Yamada TYPE(PERIPHC_EXTPERIPH2, CLOCK_TYPE_ASPTE), 19809f455dcSMasahiro Yamada TYPE(PERIPHC_EXTPERIPH3, CLOCK_TYPE_ASPTE), 19909f455dcSMasahiro Yamada TYPE(PERIPHC_NANDSPEED, CLOCK_TYPE_PCMT), 20009f455dcSMasahiro Yamada TYPE(PERIPHC_I2CSLOW, CLOCK_TYPE_PCST), /* MASK 31:30 */ 20109f455dcSMasahiro Yamada TYPE(PERIPHC_SYS, CLOCK_TYPE_NONE), 20209f455dcSMasahiro Yamada TYPE(PERIPHC_SPEEDO, CLOCK_TYPE_PCMT), 20309f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 20409f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 20509f455dcSMasahiro Yamada 20609f455dcSMasahiro Yamada /* 0x50 */ 20709f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 20809f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 20909f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 21009f455dcSMasahiro Yamada TYPE(PERIPHC_NONE, CLOCK_TYPE_NONE), 21109f455dcSMasahiro Yamada TYPE(PERIPHC_SATAOOB, CLOCK_TYPE_PCMT), /* offset 0x420h */ 21209f455dcSMasahiro Yamada TYPE(PERIPHC_SATA, CLOCK_TYPE_PCMT), 21309f455dcSMasahiro Yamada TYPE(PERIPHC_HDA, CLOCK_TYPE_PCMT), 21409f455dcSMasahiro Yamada }; 21509f455dcSMasahiro Yamada 21609f455dcSMasahiro Yamada /* 21709f455dcSMasahiro Yamada * This array translates a periph_id to a periphc_internal_id 21809f455dcSMasahiro Yamada * 21909f455dcSMasahiro Yamada * Not present/matched up: 22009f455dcSMasahiro Yamada * uint vi_sensor; _VI_SENSOR_0, 0x1A8 22109f455dcSMasahiro Yamada * SPDIF - which is both 0x08 and 0x0c 22209f455dcSMasahiro Yamada * 22309f455dcSMasahiro Yamada */ 22409f455dcSMasahiro Yamada #define NONE(name) (-1) 22509f455dcSMasahiro Yamada #define OFFSET(name, value) PERIPHC_ ## name 22609f455dcSMasahiro Yamada static s8 periph_id_to_internal_id[PERIPH_ID_COUNT] = { 22709f455dcSMasahiro Yamada /* Low word: 31:0 */ 22809f455dcSMasahiro Yamada NONE(CPU), 22909f455dcSMasahiro Yamada NONE(COP), 23009f455dcSMasahiro Yamada NONE(TRIGSYS), 23109f455dcSMasahiro Yamada NONE(RESERVED3), 23209f455dcSMasahiro Yamada NONE(RESERVED4), 23309f455dcSMasahiro Yamada NONE(TMR), 23409f455dcSMasahiro Yamada PERIPHC_UART1, 23509f455dcSMasahiro Yamada PERIPHC_UART2, /* and vfir 0x68 */ 23609f455dcSMasahiro Yamada 23709f455dcSMasahiro Yamada /* 8 */ 23809f455dcSMasahiro Yamada NONE(GPIO), 23909f455dcSMasahiro Yamada PERIPHC_SDMMC2, 24009f455dcSMasahiro Yamada NONE(SPDIF), /* 0x08 and 0x0c, unclear which to use */ 24109f455dcSMasahiro Yamada PERIPHC_I2S1, 24209f455dcSMasahiro Yamada PERIPHC_I2C1, 24309f455dcSMasahiro Yamada PERIPHC_NDFLASH, 24409f455dcSMasahiro Yamada PERIPHC_SDMMC1, 24509f455dcSMasahiro Yamada PERIPHC_SDMMC4, 24609f455dcSMasahiro Yamada 24709f455dcSMasahiro Yamada /* 16 */ 24809f455dcSMasahiro Yamada NONE(RESERVED16), 24909f455dcSMasahiro Yamada PERIPHC_PWM, 25009f455dcSMasahiro Yamada PERIPHC_I2S2, 25109f455dcSMasahiro Yamada PERIPHC_EPP, 25209f455dcSMasahiro Yamada PERIPHC_VI, 25309f455dcSMasahiro Yamada PERIPHC_G2D, 25409f455dcSMasahiro Yamada NONE(USBD), 25509f455dcSMasahiro Yamada NONE(ISP), 25609f455dcSMasahiro Yamada 25709f455dcSMasahiro Yamada /* 24 */ 25809f455dcSMasahiro Yamada PERIPHC_G3D, 25909f455dcSMasahiro Yamada NONE(RESERVED25), 26009f455dcSMasahiro Yamada PERIPHC_DISP2, 26109f455dcSMasahiro Yamada PERIPHC_DISP1, 26209f455dcSMasahiro Yamada PERIPHC_HOST1X, 26309f455dcSMasahiro Yamada NONE(VCP), 26409f455dcSMasahiro Yamada PERIPHC_I2S0, 26509f455dcSMasahiro Yamada NONE(CACHE2), 26609f455dcSMasahiro Yamada 26709f455dcSMasahiro Yamada /* Middle word: 63:32 */ 26809f455dcSMasahiro Yamada NONE(MEM), 26909f455dcSMasahiro Yamada NONE(AHBDMA), 27009f455dcSMasahiro Yamada NONE(APBDMA), 27109f455dcSMasahiro Yamada NONE(RESERVED35), 27209f455dcSMasahiro Yamada NONE(RESERVED36), 27309f455dcSMasahiro Yamada NONE(STAT_MON), 27409f455dcSMasahiro Yamada NONE(RESERVED38), 27509f455dcSMasahiro Yamada NONE(RESERVED39), 27609f455dcSMasahiro Yamada 27709f455dcSMasahiro Yamada /* 40 */ 27809f455dcSMasahiro Yamada NONE(KFUSE), 27909f455dcSMasahiro Yamada PERIPHC_SBC1, 28009f455dcSMasahiro Yamada PERIPHC_NOR, 28109f455dcSMasahiro Yamada NONE(RESERVED43), 28209f455dcSMasahiro Yamada PERIPHC_SBC2, 28309f455dcSMasahiro Yamada NONE(RESERVED45), 28409f455dcSMasahiro Yamada PERIPHC_SBC3, 28509f455dcSMasahiro Yamada PERIPHC_DVC_I2C, 28609f455dcSMasahiro Yamada 28709f455dcSMasahiro Yamada /* 48 */ 28809f455dcSMasahiro Yamada NONE(DSI), 28909f455dcSMasahiro Yamada PERIPHC_TVO, /* also CVE 0x40 */ 29009f455dcSMasahiro Yamada PERIPHC_MIPI, 29109f455dcSMasahiro Yamada PERIPHC_HDMI, 29209f455dcSMasahiro Yamada NONE(CSI), 29309f455dcSMasahiro Yamada PERIPHC_TVDAC, 29409f455dcSMasahiro Yamada PERIPHC_I2C2, 29509f455dcSMasahiro Yamada PERIPHC_UART3, 29609f455dcSMasahiro Yamada 29709f455dcSMasahiro Yamada /* 56 */ 29809f455dcSMasahiro Yamada NONE(RESERVED56), 29909f455dcSMasahiro Yamada PERIPHC_EMC, 30009f455dcSMasahiro Yamada NONE(USB2), 30109f455dcSMasahiro Yamada NONE(USB3), 30209f455dcSMasahiro Yamada PERIPHC_MPE, 30309f455dcSMasahiro Yamada PERIPHC_VDE, 30409f455dcSMasahiro Yamada NONE(BSEA), 30509f455dcSMasahiro Yamada NONE(BSEV), 30609f455dcSMasahiro Yamada 30709f455dcSMasahiro Yamada /* Upper word 95:64 */ 30809f455dcSMasahiro Yamada PERIPHC_SPEEDO, 30909f455dcSMasahiro Yamada PERIPHC_UART4, 31009f455dcSMasahiro Yamada PERIPHC_UART5, 31109f455dcSMasahiro Yamada PERIPHC_I2C3, 31209f455dcSMasahiro Yamada PERIPHC_SBC4, 31309f455dcSMasahiro Yamada PERIPHC_SDMMC3, 31409f455dcSMasahiro Yamada NONE(PCIE), 31509f455dcSMasahiro Yamada PERIPHC_OWR, 31609f455dcSMasahiro Yamada 31709f455dcSMasahiro Yamada /* 72 */ 31809f455dcSMasahiro Yamada NONE(AFI), 31909f455dcSMasahiro Yamada PERIPHC_CSITE, 32009f455dcSMasahiro Yamada NONE(PCIEXCLK), 32109f455dcSMasahiro Yamada NONE(AVPUCQ), 32209f455dcSMasahiro Yamada NONE(RESERVED76), 32309f455dcSMasahiro Yamada NONE(RESERVED77), 32409f455dcSMasahiro Yamada NONE(RESERVED78), 32509f455dcSMasahiro Yamada NONE(DTV), 32609f455dcSMasahiro Yamada 32709f455dcSMasahiro Yamada /* 80 */ 32809f455dcSMasahiro Yamada PERIPHC_NANDSPEED, 32909f455dcSMasahiro Yamada PERIPHC_I2CSLOW, 33009f455dcSMasahiro Yamada NONE(DSIB), 33109f455dcSMasahiro Yamada NONE(RESERVED83), 33209f455dcSMasahiro Yamada NONE(IRAMA), 33309f455dcSMasahiro Yamada NONE(IRAMB), 33409f455dcSMasahiro Yamada NONE(IRAMC), 33509f455dcSMasahiro Yamada NONE(IRAMD), 33609f455dcSMasahiro Yamada 33709f455dcSMasahiro Yamada /* 88 */ 33809f455dcSMasahiro Yamada NONE(CRAM2), 33909f455dcSMasahiro Yamada NONE(RESERVED89), 34009f455dcSMasahiro Yamada NONE(MDOUBLER), 34109f455dcSMasahiro Yamada NONE(RESERVED91), 34209f455dcSMasahiro Yamada NONE(SUSOUT), 34309f455dcSMasahiro Yamada NONE(RESERVED93), 34409f455dcSMasahiro Yamada NONE(RESERVED94), 34509f455dcSMasahiro Yamada NONE(RESERVED95), 34609f455dcSMasahiro Yamada 34709f455dcSMasahiro Yamada /* V word: 31:0 */ 34809f455dcSMasahiro Yamada NONE(CPUG), 34909f455dcSMasahiro Yamada NONE(CPULP), 35009f455dcSMasahiro Yamada PERIPHC_G3D2, 35109f455dcSMasahiro Yamada PERIPHC_MSELECT, 35209f455dcSMasahiro Yamada PERIPHC_TSENSOR, 35309f455dcSMasahiro Yamada PERIPHC_I2S3, 35409f455dcSMasahiro Yamada PERIPHC_I2S4, 35509f455dcSMasahiro Yamada PERIPHC_I2C4, 35609f455dcSMasahiro Yamada 35709f455dcSMasahiro Yamada /* 08 */ 35809f455dcSMasahiro Yamada PERIPHC_SBC5, 35909f455dcSMasahiro Yamada PERIPHC_SBC6, 36009f455dcSMasahiro Yamada PERIPHC_AUDIO, 36109f455dcSMasahiro Yamada NONE(APBIF), 36209f455dcSMasahiro Yamada PERIPHC_DAM0, 36309f455dcSMasahiro Yamada PERIPHC_DAM1, 36409f455dcSMasahiro Yamada PERIPHC_DAM2, 36509f455dcSMasahiro Yamada PERIPHC_HDA2CODEC2X, 36609f455dcSMasahiro Yamada 36709f455dcSMasahiro Yamada /* 16 */ 36809f455dcSMasahiro Yamada NONE(ATOMICS), 36909f455dcSMasahiro Yamada NONE(RESERVED17), 37009f455dcSMasahiro Yamada NONE(RESERVED18), 37109f455dcSMasahiro Yamada NONE(RESERVED19), 37209f455dcSMasahiro Yamada NONE(RESERVED20), 37309f455dcSMasahiro Yamada NONE(RESERVED21), 37409f455dcSMasahiro Yamada NONE(RESERVED22), 37509f455dcSMasahiro Yamada PERIPHC_ACTMON, 37609f455dcSMasahiro Yamada 37709f455dcSMasahiro Yamada /* 24 */ 37809f455dcSMasahiro Yamada NONE(RESERVED24), 37909f455dcSMasahiro Yamada NONE(RESERVED25), 38009f455dcSMasahiro Yamada NONE(RESERVED26), 38109f455dcSMasahiro Yamada NONE(RESERVED27), 38209f455dcSMasahiro Yamada PERIPHC_SATA, 38309f455dcSMasahiro Yamada PERIPHC_HDA, 38409f455dcSMasahiro Yamada NONE(RESERVED30), 38509f455dcSMasahiro Yamada NONE(RESERVED31), 38609f455dcSMasahiro Yamada 38709f455dcSMasahiro Yamada /* W word: 31:0 */ 38809f455dcSMasahiro Yamada NONE(HDA2HDMICODEC), 38909f455dcSMasahiro Yamada NONE(SATACOLD), 39009f455dcSMasahiro Yamada NONE(RESERVED0_PCIERX0), 39109f455dcSMasahiro Yamada NONE(RESERVED1_PCIERX1), 39209f455dcSMasahiro Yamada NONE(RESERVED2_PCIERX2), 39309f455dcSMasahiro Yamada NONE(RESERVED3_PCIERX3), 39409f455dcSMasahiro Yamada NONE(RESERVED4_PCIERX4), 39509f455dcSMasahiro Yamada NONE(RESERVED5_PCIERX5), 39609f455dcSMasahiro Yamada 39709f455dcSMasahiro Yamada /* 40 */ 39809f455dcSMasahiro Yamada NONE(CEC), 39909f455dcSMasahiro Yamada NONE(RESERVED6_PCIE2), 40009f455dcSMasahiro Yamada NONE(RESERVED7_EMC), 40109f455dcSMasahiro Yamada NONE(RESERVED8_HDMI), 40209f455dcSMasahiro Yamada NONE(RESERVED9_SATA), 40309f455dcSMasahiro Yamada NONE(RESERVED10_MIPI), 40409f455dcSMasahiro Yamada NONE(EX_RESERVED46), 40509f455dcSMasahiro Yamada NONE(EX_RESERVED47), 40609f455dcSMasahiro Yamada }; 40709f455dcSMasahiro Yamada 40809f455dcSMasahiro Yamada /* 409722e000cSTom Warren * PLL divider shift/mask tables for all PLL IDs. 410722e000cSTom Warren */ 411722e000cSTom Warren struct clk_pll_info tegra_pll_info_table[CLOCK_ID_PLL_COUNT] = { 412722e000cSTom Warren /* 413722e000cSTom Warren * T30: some deviations from T2x. 414722e000cSTom Warren * NOTE: If kcp_mask/kvco_mask == 0, they're not used in that PLL (PLLX, etc.) 415722e000cSTom Warren * If lock_ena or lock_det are >31, they're not used in that PLL. 416722e000cSTom Warren */ 417722e000cSTom Warren 418722e000cSTom Warren { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x0F, 419722e000cSTom Warren .lock_ena = 24, .lock_det = 27, .kcp_shift = 28, .kcp_mask = 3, .kvco_shift = 27, .kvco_mask = 1 }, /* PLLC */ 420722e000cSTom Warren { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 0, .p_mask = 0, 421722e000cSTom Warren .lock_ena = 0, .lock_det = 27, .kcp_shift = 1, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 }, /* PLLM */ 422722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, 423722e000cSTom Warren .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLP */ 424722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, 425722e000cSTom Warren .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLA */ 426722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x01, 427722e000cSTom Warren .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLU */ 428722e000cSTom Warren { .m_shift = 0, .m_mask = 0x1F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, 429722e000cSTom Warren .lock_ena = 22, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLD */ 430722e000cSTom Warren { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 20, .p_mask = 0x0F, 431722e000cSTom Warren .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 0, .kvco_mask = 0 }, /* PLLX */ 432722e000cSTom Warren { .m_shift = 0, .m_mask = 0xFF, .n_shift = 8, .n_mask = 0xFF, .p_shift = 0, .p_mask = 0, 433722e000cSTom Warren .lock_ena = 9, .lock_det = 11, .kcp_shift = 6, .kcp_mask = 3, .kvco_shift = 0, .kvco_mask = 1 }, /* PLLE */ 434722e000cSTom Warren { .m_shift = 0, .m_mask = 0x0F, .n_shift = 8, .n_mask = 0x3FF, .p_shift = 20, .p_mask = 0x07, 435722e000cSTom Warren .lock_ena = 18, .lock_det = 27, .kcp_shift = 8, .kcp_mask = 0xF, .kvco_shift = 4, .kvco_mask = 0xF }, /* PLLS (RESERVED) */ 436722e000cSTom Warren }; 437722e000cSTom Warren 438722e000cSTom Warren /* 43909f455dcSMasahiro Yamada * Get the oscillator frequency, from the corresponding hardware configuration 44009f455dcSMasahiro Yamada * field. Note that T30 supports 3 new higher freqs, but we map back 44109f455dcSMasahiro Yamada * to the old T20 freqs. Support for the higher oscillators is TBD. 44209f455dcSMasahiro Yamada */ 44309f455dcSMasahiro Yamada enum clock_osc_freq clock_get_osc_freq(void) 44409f455dcSMasahiro Yamada { 44509f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 44609f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 44709f455dcSMasahiro Yamada u32 reg; 44809f455dcSMasahiro Yamada 44909f455dcSMasahiro Yamada reg = readl(&clkrst->crc_osc_ctrl); 45009f455dcSMasahiro Yamada reg = (reg & OSC_FREQ_MASK) >> OSC_FREQ_SHIFT; 45109f455dcSMasahiro Yamada 45209f455dcSMasahiro Yamada if (reg & 1) /* one of the newer freqs */ 45309f455dcSMasahiro Yamada printf("Warning: OSC_FREQ is unsupported! (%d)\n", reg); 45409f455dcSMasahiro Yamada 45509f455dcSMasahiro Yamada return reg >> 2; /* Map to most common (T20) freqs */ 45609f455dcSMasahiro Yamada } 45709f455dcSMasahiro Yamada 45809f455dcSMasahiro Yamada /* Returns a pointer to the clock source register for a peripheral */ 45909f455dcSMasahiro Yamada u32 *get_periph_source_reg(enum periph_id periph_id) 46009f455dcSMasahiro Yamada { 46109f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 46209f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 46309f455dcSMasahiro Yamada enum periphc_internal_id internal_id; 46409f455dcSMasahiro Yamada 46509f455dcSMasahiro Yamada /* Coresight is a special case */ 46609f455dcSMasahiro Yamada if (periph_id == PERIPH_ID_CSI) 46709f455dcSMasahiro Yamada return &clkrst->crc_clk_src[PERIPH_ID_CSI+1]; 46809f455dcSMasahiro Yamada 46909f455dcSMasahiro Yamada assert(periph_id >= PERIPH_ID_FIRST && periph_id < PERIPH_ID_COUNT); 47009f455dcSMasahiro Yamada internal_id = periph_id_to_internal_id[periph_id]; 47109f455dcSMasahiro Yamada assert(internal_id != -1); 47209f455dcSMasahiro Yamada if (internal_id >= PERIPHC_VW_FIRST) { 47309f455dcSMasahiro Yamada internal_id -= PERIPHC_VW_FIRST; 47409f455dcSMasahiro Yamada return &clkrst->crc_clk_src_vw[internal_id]; 47509f455dcSMasahiro Yamada } else 47609f455dcSMasahiro Yamada return &clkrst->crc_clk_src[internal_id]; 47709f455dcSMasahiro Yamada } 47809f455dcSMasahiro Yamada 479*d0ad8a5cSStephen Warren int get_periph_clock_info(enum periph_id periph_id, int *mux_bits, 480*d0ad8a5cSStephen Warren int *divider_bits, int *type) 481*d0ad8a5cSStephen Warren { 482*d0ad8a5cSStephen Warren enum periphc_internal_id internal_id; 483*d0ad8a5cSStephen Warren 484*d0ad8a5cSStephen Warren if (!clock_periph_id_isvalid(periph_id)) 485*d0ad8a5cSStephen Warren return -1; 486*d0ad8a5cSStephen Warren 487*d0ad8a5cSStephen Warren internal_id = periph_id_to_internal_id[periph_id]; 488*d0ad8a5cSStephen Warren if (!periphc_internal_id_isvalid(internal_id)) 489*d0ad8a5cSStephen Warren return -1; 490*d0ad8a5cSStephen Warren 491*d0ad8a5cSStephen Warren *type = clock_periph_type[internal_id]; 492*d0ad8a5cSStephen Warren if (!clock_type_id_isvalid(*type)) 493*d0ad8a5cSStephen Warren return -1; 494*d0ad8a5cSStephen Warren 495*d0ad8a5cSStephen Warren *mux_bits = clock_source[*type][CLOCK_MAX_MUX]; 496*d0ad8a5cSStephen Warren 497*d0ad8a5cSStephen Warren if (*type == CLOCK_TYPE_PCMT16) 498*d0ad8a5cSStephen Warren *divider_bits = 16; 499*d0ad8a5cSStephen Warren else 500*d0ad8a5cSStephen Warren *divider_bits = 8; 501*d0ad8a5cSStephen Warren 502*d0ad8a5cSStephen Warren return 0; 503*d0ad8a5cSStephen Warren } 504*d0ad8a5cSStephen Warren 505*d0ad8a5cSStephen Warren enum clock_id get_periph_clock_id(enum periph_id periph_id, int source) 506*d0ad8a5cSStephen Warren { 507*d0ad8a5cSStephen Warren enum periphc_internal_id internal_id; 508*d0ad8a5cSStephen Warren int type; 509*d0ad8a5cSStephen Warren 510*d0ad8a5cSStephen Warren if (!clock_periph_id_isvalid(periph_id)) 511*d0ad8a5cSStephen Warren return CLOCK_ID_NONE; 512*d0ad8a5cSStephen Warren 513*d0ad8a5cSStephen Warren internal_id = periph_id_to_internal_id[periph_id]; 514*d0ad8a5cSStephen Warren if (!periphc_internal_id_isvalid(internal_id)) 515*d0ad8a5cSStephen Warren return CLOCK_ID_NONE; 516*d0ad8a5cSStephen Warren 517*d0ad8a5cSStephen Warren type = clock_periph_type[internal_id]; 518*d0ad8a5cSStephen Warren if (!clock_type_id_isvalid(type)) 519*d0ad8a5cSStephen Warren return CLOCK_ID_NONE; 520*d0ad8a5cSStephen Warren 521*d0ad8a5cSStephen Warren return clock_source[type][source]; 522*d0ad8a5cSStephen Warren } 523*d0ad8a5cSStephen Warren 52409f455dcSMasahiro Yamada /** 52509f455dcSMasahiro Yamada * Given a peripheral ID and the required source clock, this returns which 52609f455dcSMasahiro Yamada * value should be programmed into the source mux for that peripheral. 52709f455dcSMasahiro Yamada * 52809f455dcSMasahiro Yamada * There is special code here to handle the one source type with 5 sources. 52909f455dcSMasahiro Yamada * 53009f455dcSMasahiro Yamada * @param periph_id peripheral to start 53109f455dcSMasahiro Yamada * @param source PLL id of required parent clock 53209f455dcSMasahiro Yamada * @param mux_bits Set to number of bits in mux register: 2 or 4 53309f455dcSMasahiro Yamada * @param divider_bits Set to number of divider bits (8 or 16) 53409f455dcSMasahiro Yamada * @return mux value (0-4, or -1 if not found) 53509f455dcSMasahiro Yamada */ 53609f455dcSMasahiro Yamada int get_periph_clock_source(enum periph_id periph_id, 53709f455dcSMasahiro Yamada enum clock_id parent, int *mux_bits, int *divider_bits) 53809f455dcSMasahiro Yamada { 53909f455dcSMasahiro Yamada enum clock_type_id type; 540*d0ad8a5cSStephen Warren int mux, err; 54109f455dcSMasahiro Yamada 542*d0ad8a5cSStephen Warren err = get_periph_clock_info(periph_id, mux_bits, divider_bits, &type); 543*d0ad8a5cSStephen Warren assert(!err); 54409f455dcSMasahiro Yamada 54509f455dcSMasahiro Yamada for (mux = 0; mux < CLOCK_MAX_MUX; mux++) 54609f455dcSMasahiro Yamada if (clock_source[type][mux] == parent) 54709f455dcSMasahiro Yamada return mux; 54809f455dcSMasahiro Yamada 54909f455dcSMasahiro Yamada /* if we get here, either us or the caller has made a mistake */ 55009f455dcSMasahiro Yamada printf("Caller requested bad clock: periph=%d, parent=%d\n", periph_id, 55109f455dcSMasahiro Yamada parent); 55209f455dcSMasahiro Yamada return -1; 55309f455dcSMasahiro Yamada } 55409f455dcSMasahiro Yamada 55509f455dcSMasahiro Yamada void clock_set_enable(enum periph_id periph_id, int enable) 55609f455dcSMasahiro Yamada { 55709f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 55809f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 55909f455dcSMasahiro Yamada u32 *clk; 56009f455dcSMasahiro Yamada u32 reg; 56109f455dcSMasahiro Yamada 56209f455dcSMasahiro Yamada /* Enable/disable the clock to this peripheral */ 56309f455dcSMasahiro Yamada assert(clock_periph_id_isvalid(periph_id)); 56409f455dcSMasahiro Yamada if ((int)periph_id < (int)PERIPH_ID_VW_FIRST) 56509f455dcSMasahiro Yamada clk = &clkrst->crc_clk_out_enb[PERIPH_REG(periph_id)]; 56609f455dcSMasahiro Yamada else 56709f455dcSMasahiro Yamada clk = &clkrst->crc_clk_out_enb_vw[PERIPH_REG(periph_id)]; 56809f455dcSMasahiro Yamada reg = readl(clk); 56909f455dcSMasahiro Yamada if (enable) 57009f455dcSMasahiro Yamada reg |= PERIPH_MASK(periph_id); 57109f455dcSMasahiro Yamada else 57209f455dcSMasahiro Yamada reg &= ~PERIPH_MASK(periph_id); 57309f455dcSMasahiro Yamada writel(reg, clk); 57409f455dcSMasahiro Yamada } 57509f455dcSMasahiro Yamada 57609f455dcSMasahiro Yamada void reset_set_enable(enum periph_id periph_id, int enable) 57709f455dcSMasahiro Yamada { 57809f455dcSMasahiro Yamada struct clk_rst_ctlr *clkrst = 57909f455dcSMasahiro Yamada (struct clk_rst_ctlr *)NV_PA_CLK_RST_BASE; 58009f455dcSMasahiro Yamada u32 *reset; 58109f455dcSMasahiro Yamada u32 reg; 58209f455dcSMasahiro Yamada 58309f455dcSMasahiro Yamada /* Enable/disable reset to the peripheral */ 58409f455dcSMasahiro Yamada assert(clock_periph_id_isvalid(periph_id)); 58509f455dcSMasahiro Yamada if (periph_id < PERIPH_ID_VW_FIRST) 58609f455dcSMasahiro Yamada reset = &clkrst->crc_rst_dev[PERIPH_REG(periph_id)]; 58709f455dcSMasahiro Yamada else 58809f455dcSMasahiro Yamada reset = &clkrst->crc_rst_dev_vw[PERIPH_REG(periph_id)]; 58909f455dcSMasahiro Yamada reg = readl(reset); 59009f455dcSMasahiro Yamada if (enable) 59109f455dcSMasahiro Yamada reg |= PERIPH_MASK(periph_id); 59209f455dcSMasahiro Yamada else 59309f455dcSMasahiro Yamada reg &= ~PERIPH_MASK(periph_id); 59409f455dcSMasahiro Yamada writel(reg, reset); 59509f455dcSMasahiro Yamada } 59609f455dcSMasahiro Yamada 5970f925822SMasahiro Yamada #if CONFIG_IS_ENABLED(OF_CONTROL) 59809f455dcSMasahiro Yamada /* 59909f455dcSMasahiro Yamada * Convert a device tree clock ID to our peripheral ID. They are mostly 60009f455dcSMasahiro Yamada * the same but we are very cautious so we check that a valid clock ID is 60109f455dcSMasahiro Yamada * provided. 60209f455dcSMasahiro Yamada * 60309f455dcSMasahiro Yamada * @param clk_id Clock ID according to tegra30 device tree binding 60409f455dcSMasahiro Yamada * @return peripheral ID, or PERIPH_ID_NONE if the clock ID is invalid 60509f455dcSMasahiro Yamada */ 60609f455dcSMasahiro Yamada enum periph_id clk_id_to_periph_id(int clk_id) 60709f455dcSMasahiro Yamada { 60809f455dcSMasahiro Yamada if (clk_id > PERIPH_ID_COUNT) 60909f455dcSMasahiro Yamada return PERIPH_ID_NONE; 61009f455dcSMasahiro Yamada 61109f455dcSMasahiro Yamada switch (clk_id) { 61209f455dcSMasahiro Yamada case PERIPH_ID_RESERVED3: 61309f455dcSMasahiro Yamada case PERIPH_ID_RESERVED4: 61409f455dcSMasahiro Yamada case PERIPH_ID_RESERVED16: 61509f455dcSMasahiro Yamada case PERIPH_ID_RESERVED24: 61609f455dcSMasahiro Yamada case PERIPH_ID_RESERVED35: 61709f455dcSMasahiro Yamada case PERIPH_ID_RESERVED43: 61809f455dcSMasahiro Yamada case PERIPH_ID_RESERVED45: 61909f455dcSMasahiro Yamada case PERIPH_ID_RESERVED56: 62009f455dcSMasahiro Yamada case PERIPH_ID_PCIEXCLK: 62109f455dcSMasahiro Yamada case PERIPH_ID_RESERVED76: 62209f455dcSMasahiro Yamada case PERIPH_ID_RESERVED77: 62309f455dcSMasahiro Yamada case PERIPH_ID_RESERVED78: 62409f455dcSMasahiro Yamada case PERIPH_ID_RESERVED83: 62509f455dcSMasahiro Yamada case PERIPH_ID_RESERVED89: 62609f455dcSMasahiro Yamada case PERIPH_ID_RESERVED91: 62709f455dcSMasahiro Yamada case PERIPH_ID_RESERVED93: 62809f455dcSMasahiro Yamada case PERIPH_ID_RESERVED94: 62909f455dcSMasahiro Yamada case PERIPH_ID_RESERVED95: 63009f455dcSMasahiro Yamada return PERIPH_ID_NONE; 63109f455dcSMasahiro Yamada default: 63209f455dcSMasahiro Yamada return clk_id; 63309f455dcSMasahiro Yamada } 63409f455dcSMasahiro Yamada } 6350f925822SMasahiro Yamada #endif /* CONFIG_IS_ENABLED(OF_CONTROL) */ 63609f455dcSMasahiro Yamada 63709f455dcSMasahiro Yamada void clock_early_init(void) 63809f455dcSMasahiro Yamada { 63909f455dcSMasahiro Yamada tegra30_set_up_pllp(); 64009f455dcSMasahiro Yamada } 64109f455dcSMasahiro Yamada 64209f455dcSMasahiro Yamada void arch_timer_init(void) 64309f455dcSMasahiro Yamada { 64409f455dcSMasahiro Yamada } 64509f455dcSMasahiro Yamada 64609f455dcSMasahiro Yamada #define PMC_SATA_PWRGT 0x1ac 64709f455dcSMasahiro Yamada #define PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE (1 << 5) 64809f455dcSMasahiro Yamada #define PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL (1 << 4) 64909f455dcSMasahiro Yamada 65009f455dcSMasahiro Yamada #define PLLE_SS_CNTL 0x68 65109f455dcSMasahiro Yamada #define PLLE_SS_CNTL_SSCINCINTRV(x) (((x) & 0x3f) << 24) 65209f455dcSMasahiro Yamada #define PLLE_SS_CNTL_SSCINC(x) (((x) & 0xff) << 16) 65309f455dcSMasahiro Yamada #define PLLE_SS_CNTL_SSCBYP (1 << 12) 65409f455dcSMasahiro Yamada #define PLLE_SS_CNTL_INTERP_RESET (1 << 11) 65509f455dcSMasahiro Yamada #define PLLE_SS_CNTL_BYPASS_SS (1 << 10) 65609f455dcSMasahiro Yamada #define PLLE_SS_CNTL_SSCMAX(x) (((x) & 0x1ff) << 0) 65709f455dcSMasahiro Yamada 65809f455dcSMasahiro Yamada #define PLLE_BASE 0x0e8 65909f455dcSMasahiro Yamada #define PLLE_BASE_ENABLE_CML (1 << 31) 66009f455dcSMasahiro Yamada #define PLLE_BASE_ENABLE (1 << 30) 66109f455dcSMasahiro Yamada #define PLLE_BASE_PLDIV_CML(x) (((x) & 0xf) << 24) 66209f455dcSMasahiro Yamada #define PLLE_BASE_PLDIV(x) (((x) & 0x3f) << 16) 66309f455dcSMasahiro Yamada #define PLLE_BASE_NDIV(x) (((x) & 0xff) << 8) 66409f455dcSMasahiro Yamada #define PLLE_BASE_MDIV(x) (((x) & 0xff) << 0) 66509f455dcSMasahiro Yamada 66609f455dcSMasahiro Yamada #define PLLE_MISC 0x0ec 66709f455dcSMasahiro Yamada #define PLLE_MISC_SETUP_BASE(x) (((x) & 0xffff) << 16) 66809f455dcSMasahiro Yamada #define PLLE_MISC_PLL_READY (1 << 15) 66909f455dcSMasahiro Yamada #define PLLE_MISC_LOCK (1 << 11) 67009f455dcSMasahiro Yamada #define PLLE_MISC_LOCK_ENABLE (1 << 9) 67109f455dcSMasahiro Yamada #define PLLE_MISC_SETUP_EXT(x) (((x) & 0x3) << 2) 67209f455dcSMasahiro Yamada 67309f455dcSMasahiro Yamada static int tegra_plle_train(void) 67409f455dcSMasahiro Yamada { 67509f455dcSMasahiro Yamada unsigned int timeout = 2000; 67609f455dcSMasahiro Yamada unsigned long value; 67709f455dcSMasahiro Yamada 67809f455dcSMasahiro Yamada value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); 67909f455dcSMasahiro Yamada value |= PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; 68009f455dcSMasahiro Yamada writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); 68109f455dcSMasahiro Yamada 68209f455dcSMasahiro Yamada value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); 68309f455dcSMasahiro Yamada value |= PMC_SATA_PWRGT_PLLE_IDDQ_SWCTL; 68409f455dcSMasahiro Yamada writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); 68509f455dcSMasahiro Yamada 68609f455dcSMasahiro Yamada value = readl(NV_PA_PMC_BASE + PMC_SATA_PWRGT); 68709f455dcSMasahiro Yamada value &= ~PMC_SATA_PWRGT_PLLE_IDDQ_OVERRIDE; 68809f455dcSMasahiro Yamada writel(value, NV_PA_PMC_BASE + PMC_SATA_PWRGT); 68909f455dcSMasahiro Yamada 69009f455dcSMasahiro Yamada do { 69109f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 69209f455dcSMasahiro Yamada if (value & PLLE_MISC_PLL_READY) 69309f455dcSMasahiro Yamada break; 69409f455dcSMasahiro Yamada 69509f455dcSMasahiro Yamada udelay(100); 69609f455dcSMasahiro Yamada } while (--timeout); 69709f455dcSMasahiro Yamada 69809f455dcSMasahiro Yamada if (timeout == 0) { 69909f455dcSMasahiro Yamada error("timeout waiting for PLLE to become ready"); 70009f455dcSMasahiro Yamada return -ETIMEDOUT; 70109f455dcSMasahiro Yamada } 70209f455dcSMasahiro Yamada 70309f455dcSMasahiro Yamada return 0; 70409f455dcSMasahiro Yamada } 70509f455dcSMasahiro Yamada 70609f455dcSMasahiro Yamada int tegra_plle_enable(void) 70709f455dcSMasahiro Yamada { 70809f455dcSMasahiro Yamada unsigned int cpcon = 11, p = 18, n = 150, m = 1, timeout = 1000; 70909f455dcSMasahiro Yamada u32 value; 71009f455dcSMasahiro Yamada int err; 71109f455dcSMasahiro Yamada 71209f455dcSMasahiro Yamada /* disable PLLE clock */ 71309f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); 71409f455dcSMasahiro Yamada value &= ~PLLE_BASE_ENABLE_CML; 71509f455dcSMasahiro Yamada value &= ~PLLE_BASE_ENABLE; 71609f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); 71709f455dcSMasahiro Yamada 71809f455dcSMasahiro Yamada /* clear lock enable and setup field */ 71909f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 72009f455dcSMasahiro Yamada value &= ~PLLE_MISC_LOCK_ENABLE; 72109f455dcSMasahiro Yamada value &= ~PLLE_MISC_SETUP_BASE(0xffff); 72209f455dcSMasahiro Yamada value &= ~PLLE_MISC_SETUP_EXT(0x3); 72309f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); 72409f455dcSMasahiro Yamada 72509f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 72609f455dcSMasahiro Yamada if ((value & PLLE_MISC_PLL_READY) == 0) { 72709f455dcSMasahiro Yamada err = tegra_plle_train(); 72809f455dcSMasahiro Yamada if (err < 0) { 72909f455dcSMasahiro Yamada error("failed to train PLLE: %d", err); 73009f455dcSMasahiro Yamada return err; 73109f455dcSMasahiro Yamada } 73209f455dcSMasahiro Yamada } 73309f455dcSMasahiro Yamada 73409f455dcSMasahiro Yamada /* configure PLLE */ 73509f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); 73609f455dcSMasahiro Yamada 73709f455dcSMasahiro Yamada value &= ~PLLE_BASE_PLDIV_CML(0x0f); 73809f455dcSMasahiro Yamada value |= PLLE_BASE_PLDIV_CML(cpcon); 73909f455dcSMasahiro Yamada 74009f455dcSMasahiro Yamada value &= ~PLLE_BASE_PLDIV(0x3f); 74109f455dcSMasahiro Yamada value |= PLLE_BASE_PLDIV(p); 74209f455dcSMasahiro Yamada 74309f455dcSMasahiro Yamada value &= ~PLLE_BASE_NDIV(0xff); 74409f455dcSMasahiro Yamada value |= PLLE_BASE_NDIV(n); 74509f455dcSMasahiro Yamada 74609f455dcSMasahiro Yamada value &= ~PLLE_BASE_MDIV(0xff); 74709f455dcSMasahiro Yamada value |= PLLE_BASE_MDIV(m); 74809f455dcSMasahiro Yamada 74909f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); 75009f455dcSMasahiro Yamada 75109f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 75209f455dcSMasahiro Yamada value |= PLLE_MISC_SETUP_BASE(0x7); 75309f455dcSMasahiro Yamada value |= PLLE_MISC_LOCK_ENABLE; 75409f455dcSMasahiro Yamada value |= PLLE_MISC_SETUP_EXT(0); 75509f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_MISC); 75609f455dcSMasahiro Yamada 75709f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); 75809f455dcSMasahiro Yamada value |= PLLE_SS_CNTL_SSCBYP | PLLE_SS_CNTL_INTERP_RESET | 75909f455dcSMasahiro Yamada PLLE_SS_CNTL_BYPASS_SS; 76009f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); 76109f455dcSMasahiro Yamada 76209f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_BASE); 76309f455dcSMasahiro Yamada value |= PLLE_BASE_ENABLE_CML | PLLE_BASE_ENABLE; 76409f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_BASE); 76509f455dcSMasahiro Yamada 76609f455dcSMasahiro Yamada do { 76709f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_MISC); 76809f455dcSMasahiro Yamada if (value & PLLE_MISC_LOCK) 76909f455dcSMasahiro Yamada break; 77009f455dcSMasahiro Yamada 77109f455dcSMasahiro Yamada udelay(2); 77209f455dcSMasahiro Yamada } while (--timeout); 77309f455dcSMasahiro Yamada 77409f455dcSMasahiro Yamada if (timeout == 0) { 77509f455dcSMasahiro Yamada error("timeout waiting for PLLE to lock"); 77609f455dcSMasahiro Yamada return -ETIMEDOUT; 77709f455dcSMasahiro Yamada } 77809f455dcSMasahiro Yamada 77909f455dcSMasahiro Yamada udelay(50); 78009f455dcSMasahiro Yamada 78109f455dcSMasahiro Yamada value = readl(NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); 78209f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_SSCINCINTRV(0x3f); 78309f455dcSMasahiro Yamada value |= PLLE_SS_CNTL_SSCINCINTRV(0x18); 78409f455dcSMasahiro Yamada 78509f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_SSCINC(0xff); 78609f455dcSMasahiro Yamada value |= PLLE_SS_CNTL_SSCINC(0x01); 78709f455dcSMasahiro Yamada 78809f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_SSCBYP; 78909f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_INTERP_RESET; 79009f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_BYPASS_SS; 79109f455dcSMasahiro Yamada 79209f455dcSMasahiro Yamada value &= ~PLLE_SS_CNTL_SSCMAX(0x1ff); 79309f455dcSMasahiro Yamada value |= PLLE_SS_CNTL_SSCMAX(0x24); 79409f455dcSMasahiro Yamada writel(value, NV_PA_CLK_RST_BASE + PLLE_SS_CNTL); 79509f455dcSMasahiro Yamada 79609f455dcSMasahiro Yamada return 0; 79709f455dcSMasahiro Yamada } 7986dbcc962SStephen Warren 7996dbcc962SStephen Warren struct periph_clk_init periph_clk_init_table[] = { 8006dbcc962SStephen Warren { PERIPH_ID_SBC1, CLOCK_ID_PERIPH }, 8016dbcc962SStephen Warren { PERIPH_ID_SBC2, CLOCK_ID_PERIPH }, 8026dbcc962SStephen Warren { PERIPH_ID_SBC3, CLOCK_ID_PERIPH }, 8036dbcc962SStephen Warren { PERIPH_ID_SBC4, CLOCK_ID_PERIPH }, 8046dbcc962SStephen Warren { PERIPH_ID_SBC5, CLOCK_ID_PERIPH }, 8056dbcc962SStephen Warren { PERIPH_ID_SBC6, CLOCK_ID_PERIPH }, 8066dbcc962SStephen Warren { PERIPH_ID_HOST1X, CLOCK_ID_PERIPH }, 8076dbcc962SStephen Warren { PERIPH_ID_DISP1, CLOCK_ID_CGENERAL }, 8086dbcc962SStephen Warren { PERIPH_ID_NDFLASH, CLOCK_ID_PERIPH }, 8096dbcc962SStephen Warren { PERIPH_ID_SDMMC1, CLOCK_ID_PERIPH }, 8106dbcc962SStephen Warren { PERIPH_ID_SDMMC2, CLOCK_ID_PERIPH }, 8116dbcc962SStephen Warren { PERIPH_ID_SDMMC3, CLOCK_ID_PERIPH }, 8126dbcc962SStephen Warren { PERIPH_ID_SDMMC4, CLOCK_ID_PERIPH }, 8136dbcc962SStephen Warren { PERIPH_ID_PWM, CLOCK_ID_SFROM32KHZ }, 8146dbcc962SStephen Warren { PERIPH_ID_DVC_I2C, CLOCK_ID_PERIPH }, 8156dbcc962SStephen Warren { PERIPH_ID_I2C1, CLOCK_ID_PERIPH }, 8166dbcc962SStephen Warren { PERIPH_ID_I2C2, CLOCK_ID_PERIPH }, 8176dbcc962SStephen Warren { PERIPH_ID_I2C3, CLOCK_ID_PERIPH }, 8186dbcc962SStephen Warren { PERIPH_ID_I2C4, CLOCK_ID_PERIPH }, 8196dbcc962SStephen Warren { -1, }, 8206dbcc962SStephen Warren }; 821