/* * * (C) COPYRIGHT 2011-2016 ARM Limited. All rights reserved. * * This program is free software and is provided to you under the terms of the * GNU General Public License version 2 as published by the Free Software * Foundation, and any use by you of this program is subject to the terms * of such GNU licence. * * A copy of the licence is included with the program, and can also be obtained * from Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. * */ #include #include #include "mali_kbase_cpu_vexpress.h" #define HZ_IN_MHZ (1000000) #define CORETILE_EXPRESS_A9X4_SCC_START (0x100E2000) #define MOTHERBOARD_SYS_CFG_START (0x10000000) #define SYS_CFGDATA_OFFSET (0x000000A0) #define SYS_CFGCTRL_OFFSET (0x000000A4) #define SYS_CFGSTAT_OFFSET (0x000000A8) #define SYS_CFGCTRL_START_BIT_VALUE (1 << 31) #define READ_REG_BIT_VALUE (0 << 30) #define DCC_DEFAULT_BIT_VALUE (0 << 26) #define SYS_CFG_OSC_FUNC_BIT_VALUE (1 << 20) #define SITE_DEFAULT_BIT_VALUE (1 << 16) #define BOARD_STACK_POS_DEFAULT_BIT_VALUE (0 << 12) #define DEVICE_DEFAULT_BIT_VALUE (2 << 0) #define SYS_CFG_COMPLETE_BIT_VALUE (1 << 0) #define SYS_CFG_ERROR_BIT_VALUE (1 << 1) #define FEED_REG_BIT_MASK (0x0F) #define FCLK_PA_DIVIDE_BIT_SHIFT (0x03) #define FCLK_PB_DIVIDE_BIT_SHIFT (0x07) #define FCLK_PC_DIVIDE_BIT_SHIFT (0x0B) #define AXICLK_PA_DIVIDE_BIT_SHIFT (0x0F) #define AXICLK_PB_DIVIDE_BIT_SHIFT (0x13) /* the following three values used for reading * HBI value of the LogicTile daughterboard */ #define VE_MOTHERBOARD_PERIPHERALS_SMB_CS7 (0x10000000) #define VE_SYS_PROC_ID1_OFFSET (0x00000088) #define VE_LOGIC_TILE_HBI_MASK (0x00000FFF) #define IS_SINGLE_BIT_SET(val, pos) (val&(1<> FCLK_PA_DIVIDE_BIT_SHIFT); /* CFGRW0[10:7] */ pb_divide = ((reg_val & (FEED_REG_BIT_MASK << FCLK_PB_DIVIDE_BIT_SHIFT)) >> FCLK_PB_DIVIDE_BIT_SHIFT); *cpu_clock = osc2_value * (pa_divide + 1) / (pb_divide + 1); } else if (IS_SINGLE_BIT_SET(reg_val, 1)) { /* CFGRW0[1] - CLKOC */ /* CFGRW0[6:3] */ pa_divide = ((reg_val & (FEED_REG_BIT_MASK << FCLK_PA_DIVIDE_BIT_SHIFT)) >> FCLK_PA_DIVIDE_BIT_SHIFT); /* CFGRW0[14:11] */ pc_divide = ((reg_val & (FEED_REG_BIT_MASK << FCLK_PC_DIVIDE_BIT_SHIFT)) >> FCLK_PC_DIVIDE_BIT_SHIFT); *cpu_clock = osc2_value * (pa_divide + 1) / (pc_divide + 1); } else if (IS_SINGLE_BIT_SET(reg_val, 2)) { /* CFGRW0[2] - FACLK */ /* CFGRW0[18:15] */ pa_divide = ((reg_val & (FEED_REG_BIT_MASK << AXICLK_PA_DIVIDE_BIT_SHIFT)) >> AXICLK_PA_DIVIDE_BIT_SHIFT); /* CFGRW0[22:19] */ pb_divide = ((reg_val & (FEED_REG_BIT_MASK << AXICLK_PB_DIVIDE_BIT_SHIFT)) >> AXICLK_PB_DIVIDE_BIT_SHIFT); *cpu_clock = osc2_value * (pa_divide + 1) / (pb_divide + 1); } else { err = -EIO; } set_reg_error: ongoing_request: raw_spin_unlock(&syscfg_lock); *cpu_clock /= HZ_IN_MHZ; if (!err) cpu_clock_speed = *cpu_clock; iounmap(scc_reg); scc_reg_map_failed: iounmap(syscfg_reg); syscfg_reg_map_failed: return err; } /** * kbase_get_platform_logic_tile_type - determines which LogicTile type * is used by Versatile Express * * When platform_config build parameter is specified as vexpress, i.e., * platform_config=vexpress, GPU frequency may vary dependent on the * particular platform. The GPU frequency depends on the LogicTile type. * * This function determines which LogicTile type is used by the platform by * reading the HBI value of the daughterboard which holds the LogicTile: * * 0x217 HBI0217 Virtex-6 * 0x192 HBI0192 Virtex-5 * 0x247 HBI0247 Virtex-7 * * Return: HBI value of the logic tile daughterboard, zero if not accessible */ static u32 kbase_get_platform_logic_tile_type(void) { void __iomem *syscfg_reg = NULL; u32 sys_procid1 = 0; syscfg_reg = ioremap(VE_MOTHERBOARD_PERIPHERALS_SMB_CS7 + VE_SYS_PROC_ID1_OFFSET, 4); if (NULL != syscfg_reg) { sys_procid1 = readl(syscfg_reg); iounmap(syscfg_reg); } return sys_procid1 & VE_LOGIC_TILE_HBI_MASK; } u32 kbase_get_platform_min_freq(void) { u32 ve_logic_tile = kbase_get_platform_logic_tile_type(); switch (ve_logic_tile) { case 0x217: /* Virtex 6, HBI0217 */ return VE_VIRTEX6_GPU_FREQ_MIN; case 0x247: /* Virtex 7, HBI0247 */ return VE_VIRTEX7_GPU_FREQ_MIN; default: /* all other logic tiles, i.e., Virtex 5 HBI0192 * or unsuccessful reading from the platform - * fall back to some default value */ return VE_DEFAULT_GPU_FREQ_MIN; } } u32 kbase_get_platform_max_freq(void) { u32 ve_logic_tile = kbase_get_platform_logic_tile_type(); switch (ve_logic_tile) { case 0x217: /* Virtex 6, HBI0217 */ return VE_VIRTEX6_GPU_FREQ_MAX; case 0x247: /* Virtex 7, HBI0247 */ return VE_VIRTEX7_GPU_FREQ_MAX; default: /* all other logic tiles, i.e., Virtex 5 HBI0192 * or unsuccessful reading from the platform - * fall back to some default value */ return VE_DEFAULT_GPU_FREQ_MAX; } }