/* * Copyright (c) 2024 hydrogenium2020-offical * Copyright (c) 2018 naehrwert * * This program is free software; you can redistribute it and/or modify it * under the terms and conditions of the GNU General Public License, * version 2, as published by the Free Software Foundation. * * This program is distributed in the hope it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include "types.h" /*! Generic clock descriptor. */ typedef struct _clk_rst_t { u16 reset; u16 enable; u16 source; u8 index; u8 clk_src; u8 clk_div; } clk_rst_t; /* soc-specific */ #define TEGRA_CLK_M_KHZ 12000 #define TEGRA_PLLX_KHZ 2000000 #define TEGRA_PLLP_KHZ (408000) #define TEGRA_PLLC_KHZ (600000) #define TEGRA_PLLD_KHZ (925000) #define TEGRA_PLLU_KHZ (960000) #define TEGRA_SCLK_KHZ (300000) #define TEGRA_HCLK_RATIO 1 #define TEGRA_HCLK_KHZ (TEGRA_SCLK_KHZ / (1 + TEGRA_HCLK_RATIO)) #define TEGRA_PCLK_RATIO 0 #define TEGRA_PCLK_KHZ (TEGRA_HCLK_KHZ / (1 + TEGRA_PCLK_RATIO)) #define CLK_RST_CONTROLLER_OSC_CTRL 0x50 #define CLK_OSC_DRIVE_STRENGTH 7 //PLLC #define CLK_RST_CONTROLLER_PLLC_BASE 0x80 #define CLK_RST_CONTROLLER_PLLC_MISC 0x8c #define CLK_RST_CONTROLLER_PLLC_MISC_PLLC_LOCK_ENABLE_SHIFT 24 #define CLK_RST_CONTROLLER_PLLC_MISC2 0x88 #define CLK_RST_CONTROLLER_PLLC_BASE_PLLC_BYPASS_SHIFT 31 #define CLK_RST_CONTROLLER_PLLC_OUT 0x84 #define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE 0x30 #define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE_AHB_RATE_SHIFT 4 #define CLK_RST_CONTROLLER_CLK_SYSTEM_RATE_APB_RATE_SHIFT 0 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY 0x28 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SYS_STATE_SHIFT 28 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SYS_STATE_IDLE 1 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SYS_STATE_RUN 2 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLC_OUT1 1 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLP_OUT4 2 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLP_OUT3 3 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_PLLP_OUT2 4 #define CLK_RST_CONTROLLER_SCLK_BURST_POLICY_SWAKEUP_RUN_SOURCE_SHIFT 4 //PLLP #define CLK_RST_CONTROLLER_PLLP_OUTA 0xA4 #define CLK_RST_CONTROLLER_PLLP_OUTB 0xA8 #define CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RATIO_SHIFT 8 #define CLK_RST_CONTROLLER_PLLP_OUTA_PLLP_OUT1_OVRRIDE_SHIFT 2 #define CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_CLKEN_SHIFT 1 #define CLK_RST_CONTROLLER_PLLM_OUT_PLLM_OUT1_RSTN_SHIFT 0 //PLLX #define PLLX_MISC3_IDDQ (1U << 3) #define CLK_RST_CONTROLLER_PLLX_BASE 0xe0 #define CLK_RST_CONTROLLER_PLLX_MISC 0xe4 #define CLK_RST_CONTROLLER_PLLX_MISC_3 0x518 #define CLK_RST_CONTROLLER_PLLX_MISC_PLLX_LOCK_ENABLE_SHIFT 18 //PLLU #define CLK_RST_CONTROLLER_PLLU_BASE 0xc0 #define CLK_RST_CONTROLLER_PLLU_MISC 0xcc #define CLK_RST_CONTROLLER_PLLU_MISC_PLLU_LOCK_ENABLE_SHIFT 22 //PLLDP (Graphis PLL) #define CLK_RST_CONTROLLER_PLLDP_SS_CFG 0x598 #define CLK_RST_CONTROLLER_PLLDP_BASE 0x590 #define CLK_RST_CONTROLLER_PLLDP_MISC 0x594 #define CLK_RST_CONTROLLER_PLLDP_MISC_0_PLLDP_LOCK_ENABLE_SHIFT 30 #define PLL_OUT1_SHIFT 0 #define PLL_OUT2_SHIFT 16 #define PLL_OUT3_SHIFT 0 #define PLL_OUT4_SHIFT 16 #define PLL_BASE_DIVN_SHIFT 8 #define PLL_BASE_DIVM_SHIFT 0 #define PLL_BASE_DIVP_SHIFT 20 #define PLL_MISC_CPCON_SHIFT 8 #define PLL_MISC_LFCON_SHIFT 4 #define CLK_RST_CONTROLLER_PLLC_BASE_PLLC_ENABLE_SHIFT 30 #define CLK_RST_CONTROLLER_PLLC_BASE_PLLC_LOCK_SHIFT 27 #define PLLCX_BASE_LOCK BIT(27) #define DIV_ROUND_UP(x, y) ({ \ __typeof__(x) _div_local_x = (x); \ __typeof__(y) _div_local_y = (y); \ (_div_local_x + _div_local_y - 1) / _div_local_y; \ }) #define CLK_DIVIDER(REF, FREQ) (DIV_ROUND_UP(((REF) * 2), (FREQ)) - 2) //MC #define CLK_RST_CONTROLLER_CLK_SOURCE_EMC 0x19c #define CLK_RST_CONTROLLER_CLK_ENB_H_SET 0x328 #define CLK_RST_CONTROLLER_CLK_ENB_X_SET 0x284 #define CLK_RST_CONTROLLER_RST_DEV_H_SET 0x308 #define CLK_RST_CONTROLLER_LVL2_CLK_GATE_OVRD 0x3a4 //Reset #define CLK_RST_CONTROLLER_RST_DEVICES_L 0x4 #define CLK_RST_CONTROLLER_RST_DEVICES_H 0x8 #define CLK_RST_CONTROLLER_RST_DEVICES_U 0xC #define CLK_RST_CONTROLLER_CLK_OUT_ENB_L 0x10 #define CLK_RST_CONTROLLER_CLK_OUT_ENB_H 0x14 #define CLK_RST_CONTROLLER_CLK_OUT_ENB_U 0x18 //UART #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTA 0x178 #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTB 0x17C #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTC 0x1A0 #define CLK_RST_CONTROLLER_CLK_SOURCE_UARTD 0x1C0 enum CLK_L_DEV { CLK_L_UARTA = 6, CLK_L_UARTB = 7, }; enum CLK_H_DEV { CLK_H_UARTC = 23, }; enum CLK_U_DEV { CLK_U_UARTD = 1, }; enum { CLK_OSC_XOE = 0x1 << 0, CLK_OSC_XOFS_SHIFT = 4, CLK_OSC_XOFS_MASK = 0x3f << CLK_OSC_XOFS_SHIFT, CLK_OSC_FREQ_SHIFT = 28, CLK_OSC_FREQ_MASK = 0xf << CLK_OSC_FREQ_SHIFT }; struct pll_dividers { u32 n : 10; u32 m : 8; u32 p : 4; u32 cpcon : 4; u32 lfcon : 4; u32 : 2; }; /* Some PLLs have more restrictive divider bit lengths or are missing some * fields. Make sure to use the right struct in the osc_table definition to get * compile-time checking, but keep the bits aligned with struct pll_dividers so * they can be used interchangeably at run time. Add new formats as required. */ struct pllcx_dividers { u32 n : 8; u32 : 2; u32 m : 8; u32 p : 4; u32 : 10; }; struct pllpad_dividers { u32 n : 10; u32 m : 5; u32 : 3; u32 p : 3; u32 : 1; u32 cpcon : 4; u32 : 6; }; struct pllu_dividers { u32 n : 10; u32 m : 5; u32 : 3; u32 p : 1; u32 : 3; u32 cpcon : 4; u32 lfcon : 4; u32 : 2; }; union __attribute__((transparent_union)) pll_fields { u32 raw; struct pll_dividers div; struct pllcx_dividers cx; struct pllpad_dividers pad; struct pllu_dividers u; }; void clock_enable(const clk_rst_t *clk); void clock_disable(const clk_rst_t *clk); void clock_enable_cl_dvfs(); void clock_enable_i2c(u32 idx); void clock_enable_uart(u32 idx); void config_oscillators(); int clock_uart_use_src_div(u32 idx, u32 baud);